reifydb_auth/service/
token.rs1use std::collections::HashMap;
5
6use reifydb_catalog::{drop_expired_tokens, drop_token, drop_tokens_by_identity, find_token_by_value};
7use reifydb_core::interface::{
8 auth::AuthStep,
9 catalog::token::{Token, TokenId},
10};
11use reifydb_transaction::transaction::Transaction;
12use reifydb_value::value::{datetime::DateTime, identity::IdentityId};
13
14use super::AuthService;
15
16impl AuthService {
17 pub fn validate_token(&self, token: &str) -> Option<Token> {
18 let mut txn = self.engine.begin_query().ok()?;
19
20 if let Ok(Some(def)) = find_token_by_value(&mut Transaction::Query(&mut txn), token) {
21 if let Some(expires_at) = def.expires_at
22 && expires_at < self.now().ok()?
23 {
24 return None;
25 }
26 return Some(def);
27 }
28
29 self.validate_catalog_token(token)
30 }
31
32 fn validate_catalog_token(&self, token: &str) -> Option<Token> {
33 let provider = self.auth_registry.get("token")?;
34
35 let mut txn = self.engine.begin_query().ok()?;
36 let catalog = self.engine.catalog();
37
38 let auths = catalog.list_authentications_by_method(&mut Transaction::Query(&mut txn), "token").ok()?;
39
40 let creds = HashMap::from([("token".to_string(), token.to_string())]);
41
42 for auth in auths {
43 if let Ok(AuthStep::Authenticated) = provider.authenticate(&auth.properties, &creds)
44 && let Ok(Some(ident)) =
45 catalog.find_identity(&mut Transaction::Query(&mut txn), auth.identity)
46 && ident.enabled
47 {
48 return Some(Token {
49 id: 0,
50 token: token.to_string(),
51 identity: ident.id,
52 expires_at: None,
53 created_at: DateTime::default(),
54 });
55 }
56 }
57
58 None
59 }
60
61 pub fn revoke_token(&self, token: &str) -> bool {
62 let def = match self.find_token(token) {
63 Some(def) => def,
64 None => return false,
65 };
66 self.drop_and_commit(def.id)
67 }
68
69 #[inline]
70 fn find_token(&self, token: &str) -> Option<Token> {
71 let mut txn = self.engine.begin_query().ok()?;
72 match find_token_by_value(&mut Transaction::Query(&mut txn), token) {
73 Ok(Some(def)) => Some(def),
74 _ => None,
75 }
76 }
77
78 #[inline]
79 fn drop_and_commit(&self, id: TokenId) -> bool {
80 let mut admin = match self.engine.begin_admin() {
81 Ok(a) => a,
82 Err(_) => return false,
83 };
84
85 if drop_token(&mut admin, id).is_err() {
86 return false;
87 }
88
89 admin.commit().is_ok()
90 }
91
92 pub fn revoke_all(&self, identity: IdentityId) {
93 if let Ok(mut admin) = self.engine.begin_admin()
94 && drop_tokens_by_identity(&mut admin, identity).is_ok()
95 {
96 let _ = admin.commit();
97 }
98 }
99
100 pub fn cleanup_expired(&self) {
101 if let (Ok(mut admin), Ok(now)) = (self.engine.begin_admin(), self.now())
102 && drop_expired_tokens(&mut admin, now).is_ok()
103 {
104 let _ = admin.commit();
105 }
106 self.challenges.cleanup_expired();
107 }
108}