Skip to main content

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 = "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}