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