196 lines
4.9 KiB
Rust
196 lines
4.9 KiB
Rust
use crate::models::service::ServiceGroup;
|
|
use bitflags::bitflags;
|
|
use j_db::database::Database;
|
|
use j_db::model::JdbModel;
|
|
use poise::serenity_prelude::UserId;
|
|
use serde::{Deserialize, Serialize};
|
|
use std::collections::{HashMap, HashSet};
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct User {
|
|
pub discord_uuid: UserId,
|
|
id: Option<u64>,
|
|
}
|
|
|
|
impl User {
|
|
pub fn new(discord_uuid: UserId) -> Self {
|
|
Self {
|
|
discord_uuid,
|
|
id: None,
|
|
}
|
|
}
|
|
|
|
pub fn find_user_by_id(
|
|
db: &Database,
|
|
uuid: UserId,
|
|
) -> Result<Option<User>, j_db::error::JDbError> {
|
|
let user = db
|
|
.filter(|_, user: &User| user.discord_uuid == uuid)?
|
|
.next();
|
|
|
|
Ok(user)
|
|
}
|
|
}
|
|
|
|
impl j_db::model::JdbModel for User {
|
|
fn id(&self) -> Option<u64> {
|
|
self.id
|
|
}
|
|
|
|
fn set_id(&mut self, id: u64) {
|
|
self.id = Some(id);
|
|
}
|
|
|
|
fn tree() -> String {
|
|
"User".to_string()
|
|
}
|
|
}
|
|
|
|
bitflags! {
|
|
#[derive(Serialize, Deserialize, Copy, Debug, Clone, PartialEq)]
|
|
pub struct Permissions: u32 {
|
|
const Status = 0b00001;
|
|
const Start = 0b00010;
|
|
const Stop = 0b00100;
|
|
const Restart = 0b01000;
|
|
}
|
|
}
|
|
|
|
#[derive(Debug, Clone, Serialize, Deserialize)]
|
|
pub struct UserGroup {
|
|
pub name: String,
|
|
pub description: String,
|
|
pub members: HashSet<u64>,
|
|
pub permissions: HashMap<u64, Permissions>,
|
|
|
|
id: Option<u64>,
|
|
}
|
|
|
|
impl UserGroup {
|
|
pub fn new(name: &str, description: &str) -> Self {
|
|
Self {
|
|
name: name.to_string(),
|
|
description: description.to_string(),
|
|
members: HashSet::new(),
|
|
permissions: Default::default(),
|
|
id: None,
|
|
}
|
|
}
|
|
|
|
pub fn find_group_by_name(
|
|
db: &Database,
|
|
name: &str,
|
|
) -> Result<Option<Self>, j_db::error::JDbError> {
|
|
let group = db
|
|
.filter(|_, group: &UserGroup| group.name.eq_ignore_ascii_case(name))?
|
|
.next();
|
|
|
|
Ok(group)
|
|
}
|
|
|
|
pub fn add_user_to_group(
|
|
db: &Database,
|
|
group_name: &str,
|
|
user_id: u64,
|
|
) -> Result<Self, j_db::error::JDbError> {
|
|
let mut group =
|
|
Self::find_group_by_name(db, group_name)?.ok_or(j_db::error::JDbError::NotFound)?;
|
|
|
|
group.members.insert(user_id);
|
|
|
|
let group = db.insert(group)?;
|
|
|
|
Ok(group)
|
|
}
|
|
|
|
pub fn set_group_permission(
|
|
db: &Database,
|
|
group_name: &str,
|
|
service_group: u64,
|
|
permissions: Permissions,
|
|
) -> Result<Self, j_db::error::JDbError> {
|
|
let mut group =
|
|
Self::find_group_by_name(db, group_name)?.ok_or(j_db::error::JDbError::NotFound)?;
|
|
|
|
group.permissions.insert(service_group, permissions);
|
|
|
|
let group = db.insert(group)?;
|
|
|
|
Ok(group)
|
|
}
|
|
|
|
pub fn get_user_groups(
|
|
db: &Database,
|
|
user: u64,
|
|
) -> Result<Vec<UserGroup>, j_db::error::JDbError> {
|
|
Ok(db
|
|
.filter(|_, group: &UserGroup| group.members.contains(&user))?
|
|
.collect())
|
|
}
|
|
|
|
pub fn check_if_user_has_permission(
|
|
db: &Database,
|
|
user: u64,
|
|
service: u64,
|
|
permission: Permissions,
|
|
) -> Result<bool, j_db::error::JDbError> {
|
|
let user_groups = Self::get_user_groups(db, user)?;
|
|
let service_group = ServiceGroup::get_service_groups(db, service)?;
|
|
|
|
Ok(Self::check_perm(permission, user_groups, service_group))
|
|
}
|
|
|
|
fn check_perm(
|
|
permission: Permissions,
|
|
user_groups: Vec<UserGroup>,
|
|
service_group: Vec<ServiceGroup>,
|
|
) -> bool {
|
|
let mut unified_permission_map: HashMap<u64, Permissions> = HashMap::new();
|
|
|
|
for user_group in user_groups {
|
|
for (group, permission) in user_group.permissions {
|
|
#[allow(clippy::map_entry)]
|
|
if unified_permission_map.contains_key(&group) {
|
|
let perm1 = unified_permission_map.get_mut(&group).unwrap();
|
|
*perm1 |= permission;
|
|
} else {
|
|
unified_permission_map.insert(group, permission);
|
|
}
|
|
}
|
|
}
|
|
|
|
let service_group_ids: HashSet<u64> = service_group
|
|
.iter()
|
|
.map(|service_group| service_group.id().unwrap())
|
|
.collect();
|
|
|
|
for service_group in service_group_ids {
|
|
let perm = unified_permission_map.get(&service_group);
|
|
|
|
if let Some(perm) = perm {
|
|
let check_perm = (permission & *perm) == permission;
|
|
|
|
if check_perm {
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
false
|
|
}
|
|
}
|
|
|
|
impl JdbModel for UserGroup {
|
|
fn id(&self) -> Option<u64> {
|
|
self.id
|
|
}
|
|
|
|
fn set_id(&mut self, id: u64) {
|
|
self.id = Some(id);
|
|
}
|
|
|
|
fn tree() -> String {
|
|
"UserGroup".to_string()
|
|
}
|
|
}
|