Skip to main content

arc_auth_core/
lib.rs

1use async_trait::async_trait;
2use serde::{Deserialize, Serialize};
3use thiserror::Error;
4
5#[derive(Clone, Debug, Deserialize, Serialize, PartialEq, Eq)]
6pub struct Identity {
7    pub id: String,
8    pub name: String,
9    pub email: String,
10    pub active: bool,
11    pub roles: Vec<String>,
12}
13
14impl Identity {
15    pub fn has_role(&self, role: &str) -> bool {
16        self.roles.iter().any(|assigned| assigned == role)
17    }
18}
19
20#[derive(Debug, Error)]
21pub enum AuthError {
22    #[error("invalid credentials")]
23    InvalidCredentials,
24    #[error("identity not found")]
25    NotFound,
26    #[error("email is already registered")]
27    DuplicateEmail,
28    #[error("invalid input: {0}")]
29    InvalidInput(String),
30    #[error("identity store unavailable: {0}")]
31    Store(String),
32}
33
34#[async_trait]
35pub trait IdentityStore: Send + Sync {
36    async fn authenticate(&self, email: &str, password: &str) -> Result<Identity, AuthError>;
37    async fn get(&self, id: &str) -> Result<Option<Identity>, AuthError>;
38    async fn list(&self) -> Result<Vec<Identity>, AuthError>;
39    async fn has_users(&self) -> Result<bool, AuthError>;
40    async fn create_user(
41        &self,
42        name: &str,
43        email: &str,
44        password: &str,
45        roles: &[String],
46    ) -> Result<Identity, AuthError>;
47    async fn update_profile(
48        &self,
49        id: &str,
50        name: &str,
51        email: &str,
52    ) -> Result<Identity, AuthError>;
53    async fn change_password(&self, id: &str, password: &str) -> Result<(), AuthError>;
54    async fn set_roles(&self, id: &str, roles: &[String]) -> Result<Identity, AuthError>;
55}
56
57pub trait AuthorizationPolicy: Send + Sync {
58    fn permits(&self, identity: &Identity, required_roles: &[&str]) -> bool;
59}