add: update user secondary role api

This commit is contained in:
trisua 2025-06-23 19:49:52 -04:00
parent 9528d71b2a
commit 0ae64de989
3 changed files with 113 additions and 67 deletions

View file

@ -16,10 +16,73 @@ use tetratto_shared::{
unix_epoch_timestamp,
};
use crate::{auto_method, DataManager};
use oiseau::{PostgresRow, execute, get, query_row, params};
use oiseau::PostgresRow;
macro_rules! update_role_fn {
($name:ident, $role_ty:ty, $col:literal) => {
pub async fn $name(
&self,
id: usize,
role: $role_ty,
user: User,
force: bool,
) -> Result<()> {
let other_user = self.get_user_by_id(id).await?;
use oiseau::{execute, get, query_row, params};
if !force {
// check permission
if !user.permissions.check(FinePermission::MANAGE_USERS) {
return Err(Error::NotAllowed);
}
if other_user.permissions.check_manager() && !user.permissions.check_admin() {
return Err(Error::MiscError(
"Cannot manage the role of other managers".to_string(),
));
}
if other_user.permissions == user.permissions {
return Err(Error::MiscError(
"Cannot manage users of equal level to you".to_string(),
));
}
}
// ...
let conn = match self.0.connect().await {
Ok(c) => c,
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
};
let res = execute!(
&conn,
&format!("UPDATE users SET {} = $1 WHERE id = $2", $col),
params![&(role.bits() as i32), &(id as i64)]
);
if let Err(e) = res {
return Err(Error::DatabaseError(e.to_string()));
}
self.cache_clear_user(&other_user).await;
// create audit log entry
self.create_audit_log_entry(AuditLogEntry::new(
user.id,
format!(
"invoked `{}` with x value `{}` and y value `{}`",
$col,
other_user.id,
role.bits()
),
))
.await?;
// ...
Ok(())
}
};
}
impl DataManager {
/// Get a [`User`] from an SQL row.
@ -47,7 +110,7 @@ impl DataManager {
grants: serde_json::from_str(&get!(x->19(String)).to_string()).unwrap(),
associated: serde_json::from_str(&get!(x->20(String)).to_string()).unwrap(),
invite_code: get!(x->21(i64)) as usize,
secondary_permissions: SecondaryPermission::from_bits(get!(x->7(i32)) as u32).unwrap(),
secondary_permissions: SecondaryPermission::from_bits(get!(x->22(i32)) as u32).unwrap(),
}
}
@ -623,67 +686,6 @@ impl DataManager {
Ok(())
}
pub async fn update_user_role(
&self,
id: usize,
role: FinePermission,
user: User,
force: bool,
) -> Result<()> {
let other_user = self.get_user_by_id(id).await?;
if !force {
// check permission
if !user.permissions.check(FinePermission::MANAGE_USERS) {
return Err(Error::NotAllowed);
}
if other_user.permissions.check_manager() && !user.permissions.check_admin() {
return Err(Error::MiscError(
"Cannot manage the role of other managers".to_string(),
));
}
if other_user.permissions == user.permissions {
return Err(Error::MiscError(
"Cannot manage users of equal level to you".to_string(),
));
}
}
// ...
let conn = match self.0.connect().await {
Ok(c) => c,
Err(e) => return Err(Error::DatabaseConnection(e.to_string())),
};
let res = execute!(
&conn,
"UPDATE users SET permissions = $1 WHERE id = $2",
params![&(role.bits() as i32), &(id as i64)]
);
if let Err(e) = res {
return Err(Error::DatabaseError(e.to_string()));
}
self.cache_clear_user(&other_user).await;
// create audit log entry
self.create_audit_log_entry(AuditLogEntry::new(
user.id,
format!(
"invoked `update_user_role` with x value `{}` and y value `{}`",
other_user.id,
role.bits()
),
))
.await?;
// ...
Ok(())
}
pub async fn seen_user(&self, user: &User) -> Result<()> {
let conn = match self.0.connect().await {
Ok(c) => c,
@ -843,6 +845,13 @@ impl DataManager {
.await;
}
update_role_fn!(update_user_role, FinePermission, "permissions");
update_role_fn!(
update_user_secondary_role,
SecondaryPermission,
"secondary_permissions"
);
auto_method!(update_user_tokens(Vec<Token>)@get_user_by_id -> "UPDATE users SET tokens = $1 WHERE id = $2" --serde --cache-key-tmpl=cache_clear_user);
auto_method!(update_user_grants(Vec<AuthGrant>)@get_user_by_id -> "UPDATE users SET grants = $1 WHERE id = $2" --serde --cache-key-tmpl=cache_clear_user);
auto_method!(update_user_settings(UserSettings)@get_user_by_id -> "UPDATE users SET settings = $1 WHERE id = $2" --serde --cache-key-tmpl=cache_clear_user);