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
14pub 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}