rustical_store/auth/
mod.rs1pub mod middleware;
2mod principal;
3use crate::error::Error;
4use async_trait::async_trait;
5
6mod principal_type;
7pub use principal_type::*;
8
9mod error;
10pub use error::UnauthorizedError;
11
12pub use principal::{AppToken, Principal};
13
14#[async_trait]
16pub trait AuthenticationProvider: Send + Sync + 'static {
17 async fn get_principals(&self) -> Result<Vec<Principal>, crate::Error>;
19
20 async fn get_principal(&self, id: &str) -> Result<Option<Principal>, crate::Error>;
23
24 async fn remove_principal(&self, id: &str) -> Result<(), crate::Error>;
25
26 async fn insert_principal(&self, user: Principal, overwrite: bool) -> Result<(), crate::Error>;
30
31 async fn validate_password(
34 &self,
35 user_id: &str,
36 password_input: &str,
37 ) -> Result<Option<Principal>, Error> {
38 let user: Principal = match self.get_principal(user_id).await? {
39 Some(user) => user,
40 None => return Ok(None),
41 };
42 let Some(password) = &user.password else {
43 return Ok(None);
44 };
45
46 if password_auth::verify_password(password_input, password.as_ref()).is_ok() {
47 return Ok(Some(user));
48 }
49 Ok(None)
50 }
51
52 async fn validate_app_token(
54 &self,
55 user_id: &str,
56 token: &str,
57 ) -> Result<Option<Principal>, Error> {
58 let (token_id_prefix, token) = token.split_once('_').unwrap_or(("", token));
63
64 for app_token in &self.get_app_tokens(user_id).await? {
65 if !app_token.id.starts_with(token_id_prefix) {
67 continue;
68 }
69 if password_auth::verify_password(token, app_token.token.as_ref()).is_ok() {
70 return self.get_principal(user_id).await;
71 }
72 }
73 Ok(None)
74 }
75
76 async fn add_app_token(
78 &self,
79 user_id: &str,
80 name: String,
81 token: String,
82 ) -> Result<String, Error>;
83 async fn remove_app_token(&self, user_id: &str, token_id: &str) -> Result<(), Error>;
84
85 async fn get_app_tokens(&self, principal: &str) -> Result<Vec<AppToken>, Error>;
86
87 async fn add_membership(&self, principal: &str, member_of: &str) -> Result<(), Error>;
88
89 async fn remove_membership(&self, principal: &str, member_of: &str) -> Result<(), Error>;
90
91 async fn list_members(&self, principal: &str) -> Result<Vec<String>, Error>;
92}
93
94pub use middleware::AuthenticationMiddleware;