systemprompt_users/services/
user_provider.rs1use 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}