Skip to main content

sofie_tenancy/
acting.rs

1use sofie::core::RuleText;
2use sofie::http::{CurrentSession, RequestContext};
3use sofie::prelude::*;
4use sofie_identity::AccountId;
5
6use crate::organization::{OrganizationArea, OrganizationMember, OrganizationRole, membership};
7use sofie::db::{Context, Resolve};
8
9const GONE: RuleText = RuleText::new(
10    "tenancy.rule.gone",
11    "You are no longer a member of this organization.",
12);
13
14/// Read on every request, so a removed member or a changed role counts at once.
15pub struct Acting {
16    member: OrganizationMember,
17}
18
19impl Acting {
20    #[must_use]
21    pub fn member(&self) -> &OrganizationMember {
22        &self.member
23    }
24
25    #[must_use]
26    pub fn role(&self) -> OrganizationRole {
27        self.member.role()
28    }
29
30    #[must_use]
31    pub fn into_member(self) -> OrganizationMember {
32        self.member
33    }
34
35    pub(crate) fn owning(&self) -> Result<()> {
36        if self.role() != OrganizationRole::Owner {
37            return Err(ONLY_AN_OWNER.into());
38        }
39        Ok(())
40    }
41}
42
43const ONLY_AN_OWNER: RuleText = RuleText::new(
44    "tenancy.rule.only_an_owner",
45    "Only an owner renames, hands over or deletes the organization.",
46);
47
48impl<O: OrganizationArea, M> Resolve<RequestContext<O, M>> for Acting {
49    async fn resolve(context: &mut RequestContext<O, M>) -> Result<Self> {
50        let organization = Principal::<O>::resolve(context).await?.id();
51        let current = CurrentSession::resolve(context).await?;
52        let session = current.id().ok_or(Error::NotFound)?;
53        let unscoped = context.db().read();
54        let account = match current.account() {
55            Some(account) => AccountId::from_uuid(account),
56            None => sofie_identity::sessions::account_of(&unscoped, session)
57                .await?
58                .ok_or_else(|| Error::from(GONE))?,
59        };
60        let member = membership(&unscoped, organization, account)
61            .await?
62            .ok_or_else(|| Error::from(GONE))?;
63        Ok(Self { member })
64    }
65}