Split up models
Signed-off-by: Nikolaos Karaolidis <nick@karaolidis.com>
This commit is contained in:
@@ -2,10 +2,7 @@ use non_empty_string::NonEmptyString;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
ops::{Deref, DerefMut},
|
||||
};
|
||||
use std::collections::HashMap;
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct UsersFile {
|
||||
@@ -27,68 +24,8 @@ pub struct UserFile {
|
||||
pub extra: Option<HashMap<NonEmptyString, Value>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct User {
|
||||
pub displayname: NonEmptyString,
|
||||
pub email: Option<String>,
|
||||
pub password: NonEmptyString,
|
||||
pub disabled: bool,
|
||||
pub groups: Vec<NonEmptyString>,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub extra: Option<HashMap<NonEmptyString, Value>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Users {
|
||||
pub users: HashMap<NonEmptyString, User>,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub extra: Option<HashMap<NonEmptyString, Value>>,
|
||||
}
|
||||
|
||||
impl Deref for Users {
|
||||
type Target = HashMap<NonEmptyString, User>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.users
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for Users {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.users
|
||||
}
|
||||
}
|
||||
|
||||
impl From<UserFile> for User {
|
||||
fn from(user_file: UserFile) -> Self {
|
||||
Self {
|
||||
displayname: user_file.displayname,
|
||||
email: user_file.email,
|
||||
password: user_file.password,
|
||||
disabled: user_file.disabled.unwrap_or(false),
|
||||
groups: user_file.groups.unwrap_or_default(),
|
||||
extra: user_file.extra,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<UsersFile> for Users {
|
||||
fn from(users_file: UsersFile) -> Self {
|
||||
Self {
|
||||
users: users_file
|
||||
.users
|
||||
.into_iter()
|
||||
.map(|(key, user)| (key, User::from(user)))
|
||||
.collect(),
|
||||
extra: users_file.extra,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<User> for UserFile {
|
||||
fn from(user: User) -> Self {
|
||||
impl From<super::users::User> for UserFile {
|
||||
fn from(user: super::users::User) -> Self {
|
||||
Self {
|
||||
displayname: user.displayname,
|
||||
email: user.email,
|
||||
@@ -104,8 +41,8 @@ impl From<User> for UserFile {
|
||||
}
|
||||
}
|
||||
|
||||
impl From<Users> for UsersFile {
|
||||
fn from(users: Users) -> Self {
|
||||
impl From<super::users::Users> for UsersFile {
|
||||
fn from(users: super::users::Users) -> Self {
|
||||
Self {
|
||||
users: users
|
||||
.users
|
||||
@@ -116,45 +53,3 @@ impl From<Users> for UsersFile {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Group {
|
||||
pub users: Vec<NonEmptyString>,
|
||||
}
|
||||
|
||||
pub struct Groups {
|
||||
pub groups: HashMap<NonEmptyString, Group>,
|
||||
}
|
||||
|
||||
impl Deref for Groups {
|
||||
type Target = HashMap<NonEmptyString, Group>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.groups
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for Groups {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.groups
|
||||
}
|
||||
}
|
||||
|
||||
impl From<UsersFile> for Groups {
|
||||
fn from(users_file: UsersFile) -> Self {
|
||||
users_file.users.into_iter().fold(
|
||||
Self {
|
||||
groups: HashMap::new(),
|
||||
},
|
||||
|mut acc, (key, user)| {
|
||||
for group in user.groups.unwrap_or_default() {
|
||||
acc.entry(group)
|
||||
.or_insert_with(|| Group { users: Vec::new() })
|
||||
.users
|
||||
.push(key.clone());
|
||||
}
|
||||
acc
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
||||
|
49
src/models/groups.rs
Normal file
49
src/models/groups.rs
Normal file
@@ -0,0 +1,49 @@
|
||||
use non_empty_string::NonEmptyString;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
ops::{Deref, DerefMut},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Group {
|
||||
pub users: Vec<NonEmptyString>,
|
||||
}
|
||||
|
||||
pub struct Groups {
|
||||
pub groups: HashMap<NonEmptyString, Group>,
|
||||
}
|
||||
|
||||
impl Deref for Groups {
|
||||
type Target = HashMap<NonEmptyString, Group>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.groups
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for Groups {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.groups
|
||||
}
|
||||
}
|
||||
|
||||
impl From<super::authelia::UsersFile> for Groups {
|
||||
fn from(users_file: super::authelia::UsersFile) -> Self {
|
||||
users_file.users.into_iter().fold(
|
||||
Self {
|
||||
groups: HashMap::new(),
|
||||
},
|
||||
|mut acc, (key, user)| {
|
||||
for group in user.groups.unwrap_or_default() {
|
||||
acc.entry(group)
|
||||
.or_insert_with(|| Group { users: Vec::new() })
|
||||
.users
|
||||
.push(key.clone());
|
||||
}
|
||||
acc
|
||||
},
|
||||
)
|
||||
}
|
||||
}
|
@@ -1 +1,3 @@
|
||||
pub mod authelia;
|
||||
pub mod groups;
|
||||
pub mod users;
|
||||
|
68
src/models/users.rs
Normal file
68
src/models/users.rs
Normal file
@@ -0,0 +1,68 @@
|
||||
use non_empty_string::NonEmptyString;
|
||||
use serde::{Deserialize, Serialize};
|
||||
use serde_json::Value;
|
||||
|
||||
use std::{
|
||||
collections::HashMap,
|
||||
ops::{Deref, DerefMut},
|
||||
};
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct User {
|
||||
pub displayname: NonEmptyString,
|
||||
pub email: Option<String>,
|
||||
pub password: NonEmptyString,
|
||||
pub disabled: bool,
|
||||
pub groups: Vec<NonEmptyString>,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub extra: Option<HashMap<NonEmptyString, Value>>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Serialize, Deserialize)]
|
||||
pub struct Users {
|
||||
pub users: HashMap<NonEmptyString, User>,
|
||||
|
||||
#[serde(flatten)]
|
||||
pub extra: Option<HashMap<NonEmptyString, Value>>,
|
||||
}
|
||||
|
||||
impl Deref for Users {
|
||||
type Target = HashMap<NonEmptyString, User>;
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
&self.users
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for Users {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
&mut self.users
|
||||
}
|
||||
}
|
||||
|
||||
impl From<super::authelia::UserFile> for User {
|
||||
fn from(user_file: super::authelia::UserFile) -> Self {
|
||||
Self {
|
||||
displayname: user_file.displayname,
|
||||
email: user_file.email,
|
||||
password: user_file.password,
|
||||
disabled: user_file.disabled.unwrap_or(false),
|
||||
groups: user_file.groups.unwrap_or_default(),
|
||||
extra: user_file.extra,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<super::authelia::UsersFile> for Users {
|
||||
fn from(users_file: super::authelia::UsersFile) -> Self {
|
||||
Self {
|
||||
users: users_file
|
||||
.users
|
||||
.into_iter()
|
||||
.map(|(key, user)| (key, User::from(user)))
|
||||
.collect(),
|
||||
extra: users_file.extra,
|
||||
}
|
||||
}
|
||||
}
|
@@ -11,7 +11,7 @@ use log::error;
|
||||
use non_empty_string::NonEmptyString;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{models::authelia, routes::auth, state::State};
|
||||
use crate::{models::groups, routes::auth, state::State};
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
struct GroupResponse {
|
||||
@@ -19,8 +19,8 @@ struct GroupResponse {
|
||||
users: Vec<NonEmptyString>,
|
||||
}
|
||||
|
||||
impl From<(NonEmptyString, authelia::Group)> for GroupResponse {
|
||||
fn from((groupname, group): (NonEmptyString, authelia::Group)) -> Self {
|
||||
impl From<(NonEmptyString, groups::Group)> for GroupResponse {
|
||||
fn from((groupname, group): (NonEmptyString, groups::Group)) -> Self {
|
||||
Self {
|
||||
groupname,
|
||||
users: group.users,
|
||||
@@ -30,8 +30,8 @@ impl From<(NonEmptyString, authelia::Group)> for GroupResponse {
|
||||
|
||||
type GroupsResponse = HashMap<NonEmptyString, GroupResponse>;
|
||||
|
||||
impl From<authelia::Groups> for GroupsResponse {
|
||||
fn from(groups: authelia::Groups) -> Self {
|
||||
impl From<groups::Groups> for GroupsResponse {
|
||||
fn from(groups: groups::Groups) -> Self {
|
||||
groups
|
||||
.groups
|
||||
.into_iter()
|
||||
@@ -74,7 +74,7 @@ pub struct GroupCreate {
|
||||
users: Vec<NonEmptyString>,
|
||||
}
|
||||
|
||||
impl From<GroupCreate> for authelia::Group {
|
||||
impl From<GroupCreate> for groups::Group {
|
||||
fn from(update: GroupCreate) -> Self {
|
||||
Self {
|
||||
users: update.users,
|
||||
@@ -97,7 +97,7 @@ pub async fn create(
|
||||
return Err(StatusCode::CONFLICT);
|
||||
}
|
||||
|
||||
let group_created = authelia::Group::from(group_create);
|
||||
let group_created = groups::Group::from(group_create);
|
||||
|
||||
for username in &group_created.users {
|
||||
if !users.contains_key(username) {
|
||||
@@ -125,7 +125,7 @@ pub struct GroupUpdate {
|
||||
users: Vec<NonEmptyString>,
|
||||
}
|
||||
|
||||
impl From<GroupUpdate> for authelia::Group {
|
||||
impl From<GroupUpdate> for groups::Group {
|
||||
fn from(update: GroupUpdate) -> Self {
|
||||
Self {
|
||||
users: update.users,
|
||||
@@ -150,7 +150,7 @@ pub async fn update(
|
||||
.unwrap_or_else(|| groupname.clone());
|
||||
|
||||
let group_existing = groups.get(&groupname).ok_or(StatusCode::NOT_FOUND)?;
|
||||
let group_updated = authelia::Group::from(group_update);
|
||||
let group_updated = groups::Group::from(group_update);
|
||||
|
||||
if groupname != new_groupname
|
||||
&& (groupname == state.config.oauth.admin_group
|
||||
|
@@ -12,7 +12,7 @@ use non_empty_string::NonEmptyString;
|
||||
use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::{
|
||||
models::authelia, routes::auth, state::State, utils::crypto::generate_random_password_hash,
|
||||
models::users, routes::auth, state::State, utils::crypto::generate_random_password_hash,
|
||||
};
|
||||
|
||||
#[derive(Debug, Serialize)]
|
||||
@@ -23,8 +23,8 @@ struct UserResponse {
|
||||
groups: Option<Vec<NonEmptyString>>,
|
||||
}
|
||||
|
||||
impl From<(NonEmptyString, authelia::User)> for UserResponse {
|
||||
fn from((username, user): (NonEmptyString, authelia::User)) -> Self {
|
||||
impl From<(NonEmptyString, users::User)> for UserResponse {
|
||||
fn from((username, user): (NonEmptyString, users::User)) -> Self {
|
||||
Self {
|
||||
username,
|
||||
displayname: user.displayname,
|
||||
@@ -36,8 +36,8 @@ impl From<(NonEmptyString, authelia::User)> for UserResponse {
|
||||
|
||||
type UsersResponse = HashMap<NonEmptyString, UserResponse>;
|
||||
|
||||
impl From<authelia::Users> for UsersResponse {
|
||||
fn from(users: authelia::Users) -> Self {
|
||||
impl From<users::Users> for UsersResponse {
|
||||
fn from(users: users::Users) -> Self {
|
||||
users
|
||||
.users
|
||||
.into_iter()
|
||||
@@ -84,7 +84,7 @@ pub struct UserCreate {
|
||||
}
|
||||
|
||||
#[allow(clippy::fallible_impl_from)]
|
||||
impl From<UserCreate> for authelia::User {
|
||||
impl From<UserCreate> for users::User {
|
||||
fn from(user_create: UserCreate) -> Self {
|
||||
Self {
|
||||
displayname: user_create.displayname,
|
||||
@@ -112,7 +112,7 @@ pub async fn create(
|
||||
return Err(StatusCode::CONFLICT);
|
||||
}
|
||||
|
||||
let user_created = authelia::User::from(user_create);
|
||||
let user_created = users::User::from(user_create);
|
||||
users.users.insert(username.clone(), user_created.clone());
|
||||
|
||||
state.save_users(users).map_err(|e| {
|
||||
@@ -132,7 +132,7 @@ pub struct UserUpdate {
|
||||
groups: Option<Vec<NonEmptyString>>,
|
||||
}
|
||||
|
||||
impl From<(Self, UserUpdate)> for authelia::User {
|
||||
impl From<(Self, UserUpdate)> for users::User {
|
||||
fn from((user_existing, user_update): (Self, UserUpdate)) -> Self {
|
||||
Self {
|
||||
displayname: user_update.displayname,
|
||||
@@ -162,7 +162,7 @@ pub async fn update(
|
||||
.unwrap_or_else(|| username.clone());
|
||||
|
||||
let user_existing = users.remove(&username).ok_or(StatusCode::NOT_FOUND)?;
|
||||
let user_updated = authelia::User::from((user_existing, user_update));
|
||||
let user_updated = users::User::from((user_existing, user_update));
|
||||
|
||||
users
|
||||
.users
|
||||
|
@@ -3,34 +3,33 @@ use std::error::Error;
|
||||
use crate::{models, state::State};
|
||||
|
||||
impl State {
|
||||
pub fn load_users(&self) -> Result<models::authelia::Users, Box<dyn Error + Send + Sync>> {
|
||||
pub fn load_users(&self) -> Result<models::users::Users, Box<dyn Error + Send + Sync>> {
|
||||
let file_contents = std::fs::read_to_string(&self.config.authelia.user_database)?;
|
||||
let users_file: models::authelia::UsersFile = serde_yaml::from_str(&file_contents)?;
|
||||
let users = models::authelia::Users::from(users_file);
|
||||
let users = models::users::Users::from(users_file);
|
||||
Ok(users)
|
||||
}
|
||||
|
||||
pub fn load_groups(&self) -> Result<models::authelia::Groups, Box<dyn Error + Send + Sync>> {
|
||||
pub fn load_groups(&self) -> Result<models::groups::Groups, Box<dyn Error + Send + Sync>> {
|
||||
let file_contents = std::fs::read_to_string(&self.config.authelia.user_database)?;
|
||||
let users_file = serde_yaml::from_str::<models::authelia::UsersFile>(&file_contents)?;
|
||||
let groups = models::authelia::Groups::from(users_file);
|
||||
let groups = models::groups::Groups::from(users_file);
|
||||
Ok(groups)
|
||||
}
|
||||
|
||||
pub fn load_users_and_groups(
|
||||
&self,
|
||||
) -> Result<(models::authelia::Users, models::authelia::Groups), Box<dyn Error + Send + Sync>>
|
||||
{
|
||||
) -> Result<(models::users::Users, models::groups::Groups), Box<dyn Error + Send + Sync>> {
|
||||
let file_contents = std::fs::read_to_string(&self.config.authelia.user_database)?;
|
||||
let users_file = serde_yaml::from_str::<models::authelia::UsersFile>(&file_contents)?;
|
||||
let users = models::authelia::Users::from(users_file.clone());
|
||||
let groups = models::authelia::Groups::from(users_file);
|
||||
let users = models::users::Users::from(users_file.clone());
|
||||
let groups = models::groups::Groups::from(users_file);
|
||||
Ok((users, groups))
|
||||
}
|
||||
|
||||
pub fn save_users(
|
||||
&self,
|
||||
users: models::authelia::Users,
|
||||
users: models::users::Users,
|
||||
) -> Result<(), Box<dyn Error + Send + Sync>> {
|
||||
let users_file = models::authelia::UsersFile::from(users);
|
||||
let file_contents = serde_yaml::to_string(&users_file)?;
|
||||
|
Reference in New Issue
Block a user