cyaxon_authifier/database/
dummy.rs1use crate::{
2 models::{Account, Invite, MFATicket, Session, EmailVerification, DeletionInfo},
3 Result, Success, Error
4};
5
6use futures::lock::Mutex;
7use std::sync::Arc;
8use std::collections::HashMap;
9
10use super::{definition::AbstractDatabase, Migration};
11
12#[derive(Default, Clone)]
13pub struct DummyDb {
14 pub accounts: Arc<Mutex<HashMap<String, Account>>>,
15 pub invites: Arc<Mutex<HashMap<String, Invite>>>,
16 pub sessions: Arc<Mutex<HashMap<String, Session>>>,
17 pub tickets: Arc<Mutex<HashMap<String, MFATicket>>>,
18}
19
20#[async_trait]
21impl AbstractDatabase for DummyDb {
22 async fn run_migration(&self, migration: Migration) -> Success {
24 println!("skip migration {:?}", migration);
25 Ok(())
26 }
27
28 async fn find_account(&self, id: &str) -> Result<Account> {
30 let accounts = self.accounts.lock().await;
31 accounts.get(id).cloned().ok_or(Error::UnknownUser)
32 }
33
34 async fn find_account_by_normalized_email(
36 &self,
37 normalized_email: &str,
38 ) -> Result<Option<Account>> {
39 let accounts = self.accounts.lock().await;
40 Ok(accounts.values()
41 .find(|account| account.email_normalized == normalized_email)
42 .cloned())
43 }
44
45 async fn find_account_with_email_verification(&self, token_to_match: &str) -> Result<Account> {
47 let accounts = self.accounts.lock().await;
48 accounts.values()
49 .find(|account| match &account.verification {
50 EmailVerification::Pending { token, .. } | EmailVerification::Moving { token, .. } => token == token_to_match,
51 _ => false
52 })
53 .cloned()
54 .ok_or(Error::InvalidToken)
55 }
56
57 async fn find_account_with_password_reset(&self, token: &str) -> Result<Account> {
59 let accounts = self.accounts.lock().await;
60 accounts.values()
61 .find(|account| if let Some(reset) = &account.password_reset {
62 reset.token == token
63 } else {
64 false
65 })
66 .cloned()
67 .ok_or(Error::InvalidToken)
68 }
69
70 async fn find_account_with_deletion_token(&self, token_to_match: &str) -> Result<Account> {
72 let accounts = self.accounts.lock().await;
73 accounts.values()
74 .find(|account| if let Some(DeletionInfo::WaitingForVerification { token, .. }) = &account.deletion {
75 token == token_to_match
76 } else {
77 false
78 })
79 .cloned()
80 .ok_or(Error::InvalidToken)
81 }
82
83 async fn find_invite(&self, id: &str) -> Result<Invite> {
85 let invites = self.invites.lock().await;
86 invites.get(id).cloned().ok_or(Error::InvalidInvite)
87 }
88
89 async fn find_session(&self, id: &str) -> Result<Session> {
91 let sessions = self.sessions.lock().await;
92 sessions.get(id).cloned().ok_or(Error::UnknownUser)
93 }
94
95 async fn find_sessions(&self, user_id: &str) -> Result<Vec<Session>> {
97 let sessions = self.sessions.lock().await;
98 Ok(sessions
99 .values()
100 .filter(|session| session.user_id == user_id)
101 .cloned()
102 .collect())
103 }
104
105 async fn find_sessions_with_subscription(&self, user_ids: &[String]) -> Result<Vec<Session>> {
107 let sessions = self.sessions.lock().await;
108 Ok(sessions
109 .values()
110 .filter(|session| session.subscription.is_some() && user_ids.contains(&session.id))
111 .cloned()
112 .collect())
113 }
114
115 async fn find_session_by_token(&self, token: &str) -> Result<Option<Session>> {
117 let sessions = self.sessions.lock().await;
118 Ok(sessions.values()
119 .find(|session| session.token == token)
120 .cloned())
121 }
122
123 async fn find_ticket_by_token(&self, token: &str) -> Result<Option<MFATicket>> {
125 let tickets = self.tickets.lock().await;
126 Ok(tickets.values()
127 .find(|ticket| ticket.token == token)
128 .cloned())
129 }
130
131 async fn save_account(&self, account: &Account) -> Success {
133 let mut accounts = self.accounts.lock().await;
134 accounts.insert(account.id.to_string(), account.clone());
135 Ok(())
136 }
137
138 async fn save_session(&self, session: &Session) -> Success {
140 let mut sessions = self.sessions.lock().await;
141 sessions.insert(session.id.to_string(), session.clone());
142 Ok(())
143 }
144
145 async fn save_invite(&self, invite: &Invite) -> Success {
147 let mut invites = self.invites.lock().await;
148 invites.insert(invite.id.to_string(), invite.clone());
149 Ok(())
150 }
151
152 async fn save_ticket(&self, ticket: &MFATicket) -> Success {
154 let mut tickets = self.tickets.lock().await;
155 tickets.insert(ticket.id.to_string(), ticket.clone());
156 Ok(())
157 }
158
159 async fn delete_session(&self, id: &str) -> Success {
161 let mut sessions = self.sessions.lock().await;
162 if sessions.remove(id).is_some() {
163 Ok(())
164 } else {
165 Err(Error::InvalidSession)
166 }
167 }
168
169 async fn delete_all_sessions(&self, user_id: &str, ignore: Option<String>) -> Success {
171 let mut sessions = self.sessions.lock().await;
172 sessions.retain(|_, session|
173 if session.user_id == user_id {
174 if let Some(ignore) = &ignore {
175 ignore == &session.id
176 } else {
177 false
178 }
179 } else {
180 true
181 }
182 );
183
184 Ok(())
185 }
186
187 async fn delete_ticket(&self, id: &str) -> Success {
189 let mut tickets = self.tickets.lock().await;
190 if tickets.remove(id).is_some() {
191 Ok(())
192 } else {
193 Err(Error::InvalidToken)
194 }
195 }
196}