Skip to main content

systemprompt_users/services/
user_provider.rs

1use async_trait::async_trait;
2use systemprompt_identifiers::UserId;
3use systemprompt_traits::{
4    AuthProviderError, AuthResult, AuthUser, FederatedIdentityClaims, UserProvider,
5};
6
7
8use crate::UserService;
9
10#[derive(Debug, Clone)]
11pub struct UserProviderImpl {
12    user_service: UserService,
13}
14
15impl UserProviderImpl {
16    pub const fn new(user_service: UserService) -> Self {
17        Self { user_service }
18    }
19}
20
21impl From<crate::User> for AuthUser {
22    fn from(user: crate::User) -> Self {
23        let is_active = user.is_active();
24        Self {
25            id: user.id,
26            name: user.name,
27            email: user.email,
28            roles: user.roles,
29            is_active,
30        }
31    }
32}
33
34#[async_trait]
35impl UserProvider for UserProviderImpl {
36    async fn find_by_id(&self, id: &UserId) -> AuthResult<Option<AuthUser>> {
37        self.user_service
38            .find_by_id(id)
39            .await
40            .map(|opt| opt.map(AuthUser::from))
41            .map_err(|e| AuthProviderError::Internal(e.to_string()))
42    }
43
44    async fn find_by_email(&self, email: &str) -> AuthResult<Option<AuthUser>> {
45        self.user_service
46            .find_by_email(email)
47            .await
48            .map(|opt| opt.map(AuthUser::from))
49            .map_err(|e| AuthProviderError::Internal(e.to_string()))
50    }
51
52    async fn find_by_name(&self, name: &str) -> AuthResult<Option<AuthUser>> {
53        self.user_service
54            .find_by_name(name)
55            .await
56            .map(|opt| opt.map(AuthUser::from))
57            .map_err(|e| AuthProviderError::Internal(e.to_string()))
58    }
59
60    async fn create_user(
61        &self,
62        name: &str,
63        email: &str,
64        full_name: Option<&str>,
65    ) -> AuthResult<AuthUser> {
66        self.user_service
67            .create(name, email, full_name, None)
68            .await
69            .map(AuthUser::from)
70            .map_err(|e| AuthProviderError::Internal(e.to_string()))
71    }
72
73    async fn create_anonymous(&self, fingerprint: &str) -> AuthResult<AuthUser> {
74        self.user_service
75            .create_anonymous(fingerprint)
76            .await
77            .map(AuthUser::from)
78            .map_err(|e| AuthProviderError::Internal(e.to_string()))
79    }
80
81    async fn assign_roles(&self, user_id: &UserId, roles: &[String]) -> AuthResult<()> {
82        self.user_service
83            .assign_roles(user_id, roles)
84            .await
85            .map(|_| ())
86            .map_err(|e| AuthProviderError::Internal(e.to_string()))
87    }
88
89    async fn find_or_create_federated(
90        &self,
91        issuer: &str,
92        external_sub: &str,
93        claims: &FederatedIdentityClaims,
94    ) -> AuthResult<UserId> {
95        self.user_service
96            .find_or_create_federated(issuer, external_sub, claims)
97            .await
98            .map(|u| u.id)
99            .map_err(|e| AuthProviderError::Internal(e.to_string()))
100    }
101}