systemprompt_traits/
auth.rs1use async_trait::async_trait;
4use std::sync::Arc;
5use systemprompt_identifiers::UserId;
6
7pub type AuthResult<T> = Result<T, AuthProviderError>;
8
9#[derive(Debug, thiserror::Error)]
10#[non_exhaustive]
11pub enum AuthProviderError {
12 #[error("Invalid credentials")]
13 InvalidCredentials,
14
15 #[error("User not found")]
16 UserNotFound,
17
18 #[error("Invalid token")]
19 InvalidToken,
20
21 #[error("Token expired")]
22 TokenExpired,
23
24 #[error("Insufficient permissions")]
25 InsufficientPermissions,
26
27 #[error("Internal error: {0}")]
28 Internal(String),
29}
30
31#[derive(Debug, Clone)]
32pub struct AuthUser {
33 pub id: UserId,
34 pub name: String,
35 pub email: String,
36 pub roles: Vec<String>,
37 pub is_active: bool,
38}
39
40#[derive(Debug, Clone, Default)]
47pub struct FederatedIdentityClaims {
48 pub email: Option<String>,
49 pub email_verified: bool,
54 pub name: Option<String>,
55 pub preferred_username: Option<String>,
56 pub roles: Vec<String>,
57}
58
59#[async_trait]
60pub trait UserProvider: Send + Sync {
61 async fn find_by_id(&self, id: &UserId) -> AuthResult<Option<AuthUser>>;
62 async fn find_by_email(&self, email: &str) -> AuthResult<Option<AuthUser>>;
63 async fn find_by_name(&self, name: &str) -> AuthResult<Option<AuthUser>>;
64 async fn create_user(
65 &self,
66 name: &str,
67 email: &str,
68 full_name: Option<&str>,
69 ) -> AuthResult<AuthUser>;
70 async fn create_anonymous(&self, fingerprint: &str) -> AuthResult<AuthUser>;
71 async fn assign_roles(&self, user_id: &UserId, roles: &[String]) -> AuthResult<()>;
72
73 async fn find_or_create_federated(
79 &self,
80 issuer: &str,
81 external_sub: &str,
82 claims: &FederatedIdentityClaims,
83 ) -> AuthResult<UserId>;
84}
85
86#[async_trait]
87pub trait RoleProvider: Send + Sync {
88 async fn get_roles(&self, user_id: &UserId) -> AuthResult<Vec<String>>;
89 async fn assign_role(&self, user_id: &UserId, role: &str) -> AuthResult<()>;
90 async fn revoke_role(&self, user_id: &UserId, role: &str) -> AuthResult<()>;
91 async fn list_users_by_role(&self, role: &str) -> AuthResult<Vec<AuthUser>>;
92}
93
94pub type DynUserProvider = Arc<dyn UserProvider>;
95pub type DynRoleProvider = Arc<dyn RoleProvider>;