Skip to main content

sofie_tenancy/
acting.rs

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