add auth system: users, login, JWT, protected routes
Domain: User entity, AuthPort/PasswordHashPort/SecretStore ports. Adapters: auth (argon2 hashing, JWT tokens), secret-store (env-based), config-sqlite user repository, http-api auth routes + extractors. Application: auth_service. SPA: login page, auth client, protected router.
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
use domain::{
|
||||
ConfigRepository, DataSource, DataSourceId, Layout, LayoutPreset, LayoutPresetId, WidgetConfig,
|
||||
WidgetId,
|
||||
ConfigRepository, DataSource, DataSourceId, Layout, LayoutPreset, LayoutPresetId, User,
|
||||
WidgetConfig, WidgetId,
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
use std::sync::RwLock;
|
||||
@@ -16,6 +16,7 @@ pub struct MemoryConfigStore {
|
||||
data_sources: RwLock<HashMap<DataSourceId, DataSource>>,
|
||||
layout: RwLock<Option<Layout>>,
|
||||
presets: RwLock<HashMap<LayoutPresetId, LayoutPreset>>,
|
||||
users: RwLock<Vec<User>>,
|
||||
}
|
||||
|
||||
impl Default for MemoryConfigStore {
|
||||
@@ -25,6 +26,7 @@ impl Default for MemoryConfigStore {
|
||||
data_sources: RwLock::new(HashMap::new()),
|
||||
layout: RwLock::new(None),
|
||||
presets: RwLock::new(HashMap::new()),
|
||||
users: RwLock::new(Vec::new()),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -156,4 +158,30 @@ impl ConfigRepository for MemoryConfigStore {
|
||||
guard.remove(&id);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn get_user_by_username(&self, username: &str) -> Result<Option<User>, Self::Error> {
|
||||
let guard = self
|
||||
.users
|
||||
.read()
|
||||
.map_err(|_| MemoryConfigError::LockPoisoned)?;
|
||||
Ok(guard.iter().find(|u| u.username == username).cloned())
|
||||
}
|
||||
|
||||
async fn save_user(&self, user: &User) -> Result<(), Self::Error> {
|
||||
let mut guard = self
|
||||
.users
|
||||
.write()
|
||||
.map_err(|_| MemoryConfigError::LockPoisoned)?;
|
||||
guard.retain(|u| u.id != user.id);
|
||||
guard.push(user.clone());
|
||||
Ok(())
|
||||
}
|
||||
|
||||
async fn count_users(&self) -> Result<u32, Self::Error> {
|
||||
let guard = self
|
||||
.users
|
||||
.read()
|
||||
.map_err(|_| MemoryConfigError::LockPoisoned)?;
|
||||
Ok(guard.len() as u32)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user