Skip to main content

sofie_identity/membership/
roles.rs

1use sofie::db::{Outcome, Plan, Stamp};
2use sofie::prelude::*;
3
4use super::{Membership, held};
5use crate::AccountId;
6use crate::account::{Account, Distrusted};
7use crate::role::RoleId;
8
9/// A role given to an account whose address nobody proved, as `add_member` adopting one,
10/// distrusts it.
11pub struct RoleAssigned {
12    membership: Membership,
13    distrusted: Option<(Account, Distrusted)>,
14}
15
16pub async fn assign_role(
17    read: &Read,
18    clock: &Clock,
19    account: AccountId,
20    area: &str,
21    role: Option<RoleId>,
22) -> Result<RoleAssigned> {
23    let mut membership = held(read, account, area).await?.ok_or(Error::NotFound)?;
24    let distrusted = if gives(&membership, role) {
25        unproven(read, account, clock).await?
26    } else {
27        None
28    };
29    membership.role = role;
30    Ok(RoleAssigned {
31        membership,
32        distrusted,
33    })
34}
35
36pub(super) fn gives(membership: &Membership, role: Option<RoleId>) -> bool {
37    role.is_some() && membership.role != role
38}
39
40pub(super) async fn unproven(
41    read: &Read,
42    account: AccountId,
43    clock: &Clock,
44) -> Result<Option<(Account, Distrusted)>> {
45    let mut account = Account::stored(read, account).await?;
46    if account.is_confirmed() {
47        return Ok(None);
48    }
49    let distrusted = account.distrust(read, clock.now()).await?;
50    Ok(Some((account, distrusted)))
51}
52
53impl Outcome for RoleAssigned {
54    fn plan(&self, plan: &mut Plan<'_>) -> Result<()> {
55        self.membership.plan(plan)?;
56        self.distrusted.plan(plan)
57    }
58
59    fn committed(&mut self, stamp: Stamp) {
60        self.membership.committed(stamp);
61        self.distrusted.committed(stamp);
62    }
63}
64
65pub(crate) async fn granted(read: &Read, area: &str, account: AccountId) -> Result<Vec<String>> {
66    let role = held(read, account, area)
67        .await?
68        .and_then(|membership| membership.role);
69    match role {
70        Some(role) => crate::role_grant::granted(read, role).await,
71        None => Ok(Vec::new()),
72    }
73}