shield_memory/
storage.rs

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
use std::sync::{Arc, Mutex};

use async_trait::async_trait;
use shield::{
    CreateEmailAddress, CreateUser, EmailAddress, Storage, StorageError, UpdateUser, User as _,
};
use uuid::Uuid;

use crate::user::User;

pub const MEMORY_STORAGE_ID: &str = "memory";

#[derive(Clone, Debug, Default)]
pub struct MemoryStorage {
    pub(crate) users: Arc<Mutex<Vec<User>>>,
    #[cfg(feature = "provider-oidc")]
    pub(crate) oidc: crate::providers::oidc::OidcMemoryStorage,
}

impl MemoryStorage {
    pub fn new() -> Self {
        Self::default()
    }
}

#[async_trait]
impl Storage<User> for MemoryStorage {
    fn id(&self) -> String {
        MEMORY_STORAGE_ID.to_owned()
    }

    async fn user_by_id(&self, user_id: &str) -> Result<Option<User>, StorageError> {
        Ok(self
            .users
            .lock()
            .map_err(|err| StorageError::Engine(err.to_string()))?
            .iter()
            .find(|user| user.id() == user_id)
            .cloned())
    }

    async fn user_by_email(&self, email: &str) -> Result<Option<User>, StorageError> {
        Ok(self
            .users
            .lock()
            .map_err(|err| StorageError::Engine(err.to_string()))?
            .iter()
            .find(|user| {
                user.email_addresses
                    .iter()
                    .any(|email_address| email_address.email == email)
            })
            .cloned())
    }

    async fn create_user(
        &self,
        user: CreateUser,
        email_address: CreateEmailAddress,
    ) -> Result<User, StorageError> {
        let user_id = Uuid::new_v4().to_string();

        let user = User {
            id: user_id.clone(),
            name: user.name,
            email_addresses: vec![EmailAddress {
                id: Uuid::new_v4().to_string(),
                email: email_address.email,
                is_primary: email_address.is_primary,
                is_verified: email_address.is_verified,
                verification_token: email_address.verification_token,
                verification_token_expired_at: email_address.verification_token_expired_at,
                verified_at: email_address.verified_at,
                user_id,
            }],
        };

        self.users
            .lock()
            .map_err(|err| StorageError::Engine(err.to_string()))?
            .push(user.clone());

        Ok(user)
    }

    async fn update_user(&self, user: UpdateUser) -> Result<User, StorageError> {
        let mut users = self
            .users
            .lock()
            .map_err(|err| StorageError::Engine(err.to_string()))?;

        let user_mut = users
            .iter_mut()
            .find(|u| u.id() == user.id)
            .ok_or_else(|| StorageError::NotFound("User".to_owned(), user.id.clone()))?;

        if let Some(name) = user.name {
            user_mut.name = name;
        }

        Ok(user_mut.clone())
    }

    async fn delete_user(&self, user_id: &str) -> Result<(), StorageError> {
        self.users
            .lock()
            .map_err(|err| StorageError::Engine(err.to_string()))?
            .retain(|user| user.id != user_id);

        Ok(())
    }
}