Skip to main content

nythos_core/auth/
revoke.rs

1use crate::{NythosResult, RevocationChecker, SessionId, SessionStore, TenantId, UserId};
2
3/// Input for revoking a single session.
4#[derive(Debug, Clone, Copy, PartialEq, Eq)]
5pub struct RevokeSessionInput {
6    session_id: SessionId,
7}
8
9impl RevokeSessionInput {
10    pub const fn new(session_id: SessionId) -> Self {
11        Self { session_id }
12    }
13
14    pub const fn session_id(&self) -> SessionId {
15        self.session_id
16    }
17}
18
19/// Input for revoking all sessions for a user within a tenant.
20#[derive(Debug, Clone, Copy, PartialEq, Eq)]
21pub struct RevokeAllSessionsInput {
22    tenant_id: TenantId,
23    user_id: UserId,
24}
25
26impl RevokeAllSessionsInput {
27    pub const fn new(tenant_id: TenantId, user_id: UserId) -> Self {
28        Self { tenant_id, user_id }
29    }
30
31    pub const fn tenant_id(&self) -> TenantId {
32        self.tenant_id
33    }
34
35    pub const fn user_id(&self) -> UserId {
36        self.user_id
37    }
38}
39
40/// Domain result for revoke operations.
41#[derive(Debug, Clone, Copy, PartialEq, Eq)]
42pub struct RevokeResult {
43    revoked: bool,
44}
45
46impl RevokeResult {
47    pub const fn new(revoked: bool) -> Self {
48        Self { revoked }
49    }
50
51    pub const fn revoked(&self) -> bool {
52        self.revoked
53    }
54}
55
56/// Service for revoking a single session.
57pub struct RevokeSessionService<'a, S, C> {
58    session_store: &'a S,
59    revocation_checker: &'a C,
60}
61
62impl<'a, S, C> RevokeSessionService<'a, S, C>
63where
64    S: SessionStore,
65    C: RevocationChecker,
66{
67    pub fn new(session_store: &'a S, revocation_checker: &'a C) -> Self {
68        Self {
69            session_store,
70            revocation_checker,
71        }
72    }
73
74    pub async fn revoke(&self, input: RevokeSessionInput) -> NythosResult<RevokeResult> {
75        if self
76            .revocation_checker
77            .is_revoked(input.session_id())
78            .await?
79        {
80            return Ok(RevokeResult::new(false));
81        }
82
83        self.session_store
84            .revoke_session(input.session_id())
85            .await?;
86        Ok(RevokeResult::new(true))
87    }
88}
89
90/// Service for revoking all sessions for a user within a tenant.
91pub struct RevokeAllSessionsService<'a, S> {
92    session_store: &'a S,
93}
94
95impl<'a, S> RevokeAllSessionsService<'a, S>
96where
97    S: SessionStore,
98{
99    pub fn new(session_store: &'a S) -> Self {
100        Self { session_store }
101    }
102
103    pub async fn revoke_all(&self, input: RevokeAllSessionsInput) -> NythosResult<RevokeResult> {
104        self.session_store
105            .revoke_all_for_user(input.tenant_id(), input.user_id())
106            .await?;
107
108        Ok(RevokeResult::new(true))
109    }
110}