1use std::sync::{Arc, Mutex};
2
3use async_trait::async_trait;
4use shield::{
5 CreateEmailAddress, CreateUser, EmailAddress, Storage, StorageError, UpdateUser, User as _,
6};
7use uuid::Uuid;
8
9use crate::user::User;
10
11pub const MEMORY_STORAGE_ID: &str = "memory";
12
13#[derive(Clone, Debug, Default)]
14pub struct MemoryStorage {
15 pub(crate) users: Arc<Mutex<Vec<User>>>,
16 #[cfg(feature = "method-oauth")]
17 pub(crate) oauth: crate::providers::oauth::OauthMemoryStorage,
18 #[cfg(feature = "method-oidc")]
19 pub(crate) oidc: crate::providers::oidc::OidcMemoryStorage,
20}
21
22impl MemoryStorage {
23 pub fn new() -> Self {
24 Self::default()
25 }
26}
27
28#[async_trait]
29impl Storage<User> for MemoryStorage {
30 fn id(&self) -> String {
31 MEMORY_STORAGE_ID.to_owned()
32 }
33
34 async fn user_by_id(&self, user_id: &str) -> Result<Option<User>, StorageError> {
35 Ok(self
36 .users
37 .lock()
38 .map_err(|err| StorageError::Engine(err.to_string()))?
39 .iter()
40 .find(|user| user.id() == user_id)
41 .cloned())
42 }
43
44 async fn user_by_email(&self, email: &str) -> Result<Option<User>, StorageError> {
45 Ok(self
46 .users
47 .lock()
48 .map_err(|err| StorageError::Engine(err.to_string()))?
49 .iter()
50 .find(|user| {
51 user.email_addresses
52 .iter()
53 .any(|email_address| email_address.email == email)
54 })
55 .cloned())
56 }
57
58 async fn create_user(
59 &self,
60 user: CreateUser,
61 email_address: CreateEmailAddress,
62 ) -> Result<User, StorageError> {
63 let user_id = Uuid::new_v4().to_string();
64
65 let user = User {
66 id: user_id.clone(),
67 name: user.name,
68 email_addresses: vec![EmailAddress {
69 id: Uuid::new_v4().to_string(),
70 email: email_address.email,
71 is_primary: email_address.is_primary,
72 is_verified: email_address.is_verified,
73 verification_token: email_address.verification_token,
74 verification_token_expired_at: email_address.verification_token_expired_at,
75 verified_at: email_address.verified_at,
76 user_id,
77 }],
78 };
79
80 self.users
81 .lock()
82 .map_err(|err| StorageError::Engine(err.to_string()))?
83 .push(user.clone());
84
85 Ok(user)
86 }
87
88 async fn update_user(&self, user: UpdateUser) -> Result<User, StorageError> {
89 let mut users = self
90 .users
91 .lock()
92 .map_err(|err| StorageError::Engine(err.to_string()))?;
93
94 let user_mut = users
95 .iter_mut()
96 .find(|u| u.id() == user.id)
97 .ok_or_else(|| StorageError::NotFound("User".to_owned(), user.id.clone()))?;
98
99 if let Some(name) = user.name {
100 user_mut.name = name;
101 }
102
103 Ok(user_mut.clone())
104 }
105
106 async fn delete_user(&self, user_id: &str) -> Result<(), StorageError> {
107 self.users
108 .lock()
109 .map_err(|err| StorageError::Engine(err.to_string()))?
110 .retain(|user| user.id != user_id);
111
112 Ok(())
113 }
114}