Skip to main content

crates_docs/server/auth/
token.rs

1//! Token store and token information
2
3/// Simple in-memory token store (production should use Redis or database)
4#[derive(Default)]
5pub struct TokenStore {
6    tokens: std::sync::RwLock<std::collections::HashMap<String, TokenInfo>>,
7}
8
9/// OAuth token information
10#[derive(Debug, Clone, serde::Deserialize, serde::Serialize)]
11pub struct TokenInfo {
12    /// Access token
13    pub access_token: String,
14    /// Refresh token (optional)
15    pub refresh_token: Option<String>,
16    /// Token expiration time
17    pub expires_at: chrono::DateTime<chrono::Utc>,
18    /// Authorization scopes
19    pub scopes: Vec<String>,
20    /// User ID (optional)
21    pub user_id: Option<String>,
22    /// User email (optional)
23    pub user_email: Option<String>,
24}
25
26impl TokenStore {
27    /// Create a new token store
28    #[must_use]
29    pub fn new() -> Self {
30        Self::default()
31    }
32
33    /// Store token
34    pub fn store_token(&self, key: String, token: TokenInfo) {
35        let mut tokens = self.tokens.write().expect("Token store RwLock poisoned");
36        tokens.insert(key, token);
37    }
38
39    /// Get token
40    pub fn get_token(&self, key: &str) -> Option<TokenInfo> {
41        let tokens = self.tokens.read().expect("Token store RwLock poisoned");
42        tokens.get(key).cloned()
43    }
44
45    /// Remove token
46    pub fn remove_token(&self, key: &str) {
47        let mut tokens = self.tokens.write().expect("Token store RwLock poisoned");
48        tokens.remove(key);
49    }
50
51    /// Cleanup expired tokens
52    pub fn cleanup_expired(&self) {
53        let now = chrono::Utc::now();
54        let mut tokens = self.tokens.write().expect("Token store RwLock poisoned");
55        tokens.retain(|_, token| token.expires_at > now);
56    }
57}