diff --git a/crates/store/src/auth/mod.rs b/crates/store/src/auth/mod.rs index 5b91c17..b03a38d 100644 --- a/crates/store/src/auth/mod.rs +++ b/crates/store/src/auth/mod.rs @@ -1,7 +1,6 @@ pub mod middleware; pub mod static_user_store; pub mod user; -pub mod user_store; use crate::error::Error; use async_trait::async_trait; diff --git a/crates/store/src/auth/static_user_store.rs b/crates/store/src/auth/static_user_store.rs index 699c0f7..11d02c6 100644 --- a/crates/store/src/auth/static_user_store.rs +++ b/crates/store/src/auth/static_user_store.rs @@ -7,31 +7,18 @@ use super::AuthenticationProvider; #[derive(Debug, Clone, Deserialize, Serialize, Default)] pub struct StaticUserStoreConfig { - pub users: Vec, -} - -#[derive(Debug, Clone, Deserialize, Serialize)] -pub struct UserEntry { - #[serde(flatten)] - pub user: User, - #[serde(default)] - pub app_tokens: Vec, + pub users: Vec, } #[derive(Debug, Clone, Deserialize, Serialize)] pub struct StaticUserStore { - pub users: HashMap, + pub users: HashMap, } impl StaticUserStore { pub fn new(config: StaticUserStoreConfig) -> Self { Self { - users: HashMap::from_iter( - config - .users - .into_iter() - .map(|user_entry| (user_entry.user.id.clone(), user_entry)), - ), + users: HashMap::from_iter(config.users.into_iter().map(|user| (user.id.clone(), user))), } } } @@ -39,26 +26,26 @@ impl StaticUserStore { #[async_trait] impl AuthenticationProvider for StaticUserStore { async fn validate_user_token(&self, user_id: &str, token: &str) -> Result, Error> { - let user_entry: UserEntry = match self.users.get(user_id) { + let user: User = match self.users.get(user_id) { Some(user) => user.clone(), None => return Ok(None), }; // Try app tokens first since they are cheaper to calculate // They can afford less iterations since they can be generated with high entropy - for app_token in &user_entry.app_tokens { + for app_token in &user.app_tokens { if password_auth::verify_password(token, app_token).is_ok() { - return Ok(Some(user_entry.user)); + return Ok(Some(user)); } } - let password = match &user_entry.user.password { + let password = match &user.password { Some(password) => password, None => return Ok(None), }; if password_auth::verify_password(token, password).is_ok() { - return Ok(Some(user_entry.user)); + return Ok(Some(user)); } Ok(None) diff --git a/crates/store/src/auth/user.rs b/crates/store/src/auth/user.rs index aa741fe..5e8f545 100644 --- a/crates/store/src/auth/user.rs +++ b/crates/store/src/auth/user.rs @@ -12,6 +12,12 @@ pub struct User { pub id: String, pub displayname: Option, pub password: Option, + #[serde(default)] + pub app_tokens: Vec, + #[serde(default)] + pub groups: Vec, + #[serde(skip)] + pub inherited_groups: Vec, } #[derive(Clone, Debug, Display)] diff --git a/crates/store/src/auth/user_store.rs b/crates/store/src/auth/user_store.rs deleted file mode 100644 index fdc0e4d..0000000 --- a/crates/store/src/auth/user_store.rs +++ /dev/null @@ -1,8 +0,0 @@ -use crate::{auth::User, error::Error}; -use async_trait::async_trait; - -#[async_trait] -pub trait UserStore: Send + Sync + 'static { - async fn get_user(&self, id: &str) -> Result, Error>; - async fn put_user(&self, user: User) -> Result<(), Error>; -} diff --git a/src/commands/mod.rs b/src/commands/mod.rs index cb0dcc4..8ba92a2 100644 --- a/src/commands/mod.rs +++ b/src/commands/mod.rs @@ -4,7 +4,7 @@ use password_hash::PasswordHasher; use pbkdf2::Params; use rand::{rngs::OsRng, RngCore}; use rustical_frontend::FrontendConfig; -use rustical_store::auth::{static_user_store::UserEntry, StaticUserStoreConfig, User}; +use rustical_store::auth::{StaticUserStoreConfig, User}; use crate::config::{ AuthConfig, Config, DataStoreConfig, DavPushConfig, HttpConfig, SqliteDataStoreConfig, @@ -26,15 +26,14 @@ pub fn cmd_gen_config(_args: GenConfigArgs) -> anyhow::Result<()> { let config = Config { http: HttpConfig::default(), auth: AuthConfig::Static(StaticUserStoreConfig { - users: vec![UserEntry { - user: User { - id: "default".to_owned(), - displayname: Some("Default user".to_owned()), - password: Some( - "generate a password hash with rustical pwhash --algorithm argon2" - .to_owned(), - ), - }, + users: vec![User { + id: "default".to_owned(), + displayname: Some("Default user".to_owned()), + password: Some( + "generate a password hash with rustical pwhash --algorithm argon2".to_owned(), + ), + groups: vec![], + inherited_groups: vec![], app_tokens: vec![ "generate an app token hash with rustical pwhash --algorithm pbkdf2".to_owned(), ],