auth_framework/
user_context.rs1use serde::{Deserialize, Serialize};
4use std::collections::HashMap;
5use uuid::Uuid;
6
7#[derive(Debug, Clone, Serialize, Deserialize)]
9pub struct UserContext {
10 pub user_id: String,
11 pub username: String,
12 pub email: Option<String>,
13 pub scopes: crate::types::Scopes,
14 pub authenticated_at: std::time::SystemTime,
15 pub session_id: String,
16 pub attributes: crate::types::UserAttributesString,
17}
18
19impl UserContext {
20 pub fn new(user_id: String, username: String, email: Option<String>) -> Self {
21 Self {
22 user_id,
23 username,
24 email,
25 scopes: crate::types::Scopes::empty(),
26 authenticated_at: std::time::SystemTime::now(),
27 session_id: Uuid::new_v4().to_string(),
28 attributes: crate::types::UserAttributesString::empty(),
29 }
30 }
31
32 pub fn with_scopes(mut self, scopes: Vec<String>) -> Self {
33 self.scopes = scopes.into();
34 self
35 }
36
37 pub fn add_attribute(&mut self, key: String, value: String) {
38 self.attributes.insert(key, value);
39 }
40
41 pub fn has_scope(&self, scope: &str) -> bool {
42 self.scopes.contains(&scope.to_string())
43 }
44}
45
46impl UserContext {
49 pub fn builder(user_id: impl Into<String>, username: impl Into<String>) -> UserContextBuilder {
51 UserContextBuilder::new(user_id.into(), username.into())
52 }
53}
54
55pub struct UserContextBuilder {
57 user_id: String,
58 username: String,
59 email: Option<String>,
60 scopes: Vec<String>,
61 attributes: HashMap<String, String>,
62}
63
64impl UserContextBuilder {
65 pub fn new(user_id: String, username: String) -> Self {
66 Self {
67 user_id,
68 username,
69 email: None,
70 scopes: Vec::new(),
71 attributes: HashMap::new(),
72 }
73 }
74
75 pub fn email(mut self, email: impl Into<String>) -> Self {
76 self.email = Some(email.into());
77 self
78 }
79
80 pub fn scope(mut self, scope: impl Into<String>) -> Self {
81 self.scopes.push(scope.into());
82 self
83 }
84
85 pub fn scopes(mut self, scopes: Vec<String>) -> Self {
86 self.scopes = scopes;
87 self
88 }
89
90 pub fn attribute(mut self, key: impl Into<String>, value: impl Into<String>) -> Self {
91 self.attributes.insert(key.into(), value.into());
92 self
93 }
94
95 pub fn build(self) -> UserContext {
96 let mut ctx = UserContext::new(self.user_id, self.username, self.email);
97 ctx.scopes = self.scopes.into();
98 ctx.attributes = self.attributes.into();
99 ctx
100 }
101}
102
103#[derive(Debug, Clone)]
104pub struct SessionStore {
105 sessions: std::collections::HashMap<String, UserContext>,
106}
107
108impl SessionStore {
109 pub fn new() -> Self {
110 Self {
111 sessions: HashMap::new(),
112 }
113 }
114
115 pub fn create_session(&mut self, user_context: UserContext) -> String {
116 let session_id = user_context.session_id.clone();
117 self.sessions.insert(session_id.clone(), user_context);
118 session_id
119 }
120
121 pub fn get_session(&self, session_id: &str) -> Option<&UserContext> {
122 self.sessions.get(session_id)
123 }
124
125 pub fn invalidate_session(&mut self, session_id: &str) -> bool {
126 self.sessions.remove(session_id).is_some()
127 }
128
129 pub fn validate_session(&self, session_id: &str) -> bool {
130 self.sessions.contains_key(session_id)
131 }
132}
133
134impl Default for SessionStore {
135 fn default() -> Self {
136 Self::new()
137 }
138}