shield_memory/
storage.rs

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}