1use alloc::string::String;
4
5#[cfg(feature = "schemars")]
6use schemars::JsonSchema;
7#[cfg(feature = "serde")]
8use serde::{Deserialize, Serialize};
9
10use crate::{TeamId, TenantCtx, TenantId, UserId};
11
12#[derive(Clone, Debug, PartialEq, Eq, Hash)]
14#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
15#[cfg_attr(feature = "schemars", derive(JsonSchema))]
16pub struct Impersonation {
17 pub actor_id: UserId,
19 #[cfg_attr(
21 feature = "serde",
22 serde(default, skip_serializing_if = "Option::is_none")
23 )]
24 pub reason: Option<String>,
25}
26
27#[derive(Clone, Debug, PartialEq, Eq, Hash)]
29#[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
30#[cfg_attr(feature = "schemars", derive(JsonSchema))]
31pub struct TenantIdentity {
32 pub tenant_id: TenantId,
34 #[cfg_attr(
36 feature = "serde",
37 serde(default, skip_serializing_if = "Option::is_none")
38 )]
39 pub team_id: Option<TeamId>,
40 #[cfg_attr(
42 feature = "serde",
43 serde(default, skip_serializing_if = "Option::is_none")
44 )]
45 pub user_id: Option<UserId>,
46 #[cfg_attr(
48 feature = "serde",
49 serde(default, skip_serializing_if = "Option::is_none")
50 )]
51 pub impersonation: Option<Impersonation>,
52}
53
54impl TenantIdentity {
55 pub fn new(tenant_id: TenantId) -> Self {
57 Self {
58 tenant_id,
59 team_id: None,
60 user_id: None,
61 impersonation: None,
62 }
63 }
64}
65
66impl From<&TenantCtx> for TenantIdentity {
67 fn from(ctx: &TenantCtx) -> Self {
68 Self {
69 tenant_id: ctx.tenant_id.clone(),
70 team_id: ctx.team_id.clone().or_else(|| ctx.team.clone()),
71 user_id: ctx.user_id.clone().or_else(|| ctx.user.clone()),
72 impersonation: ctx.impersonation.clone(),
73 }
74 }
75}
76
77impl TenantCtx {
78 pub fn identity(&self) -> TenantIdentity {
80 TenantIdentity::from(self)
81 }
82
83 pub fn impersonated_by(&self) -> Option<&Impersonation> {
85 self.impersonation.as_ref()
86 }
87
88 pub fn with_identity(mut self, identity: TenantIdentity) -> Self {
90 self.tenant = identity.tenant_id.clone();
91 self.tenant_id = identity.tenant_id;
92 self.team = identity.team_id.clone();
93 self.team_id = identity.team_id;
94 self.user = identity.user_id.clone();
95 self.user_id = identity.user_id;
96 self.impersonation = identity.impersonation;
97 self
98 }
99}