add: update user secondary role api
This commit is contained in:
parent
9528d71b2a
commit
0ae64de989
3 changed files with 113 additions and 67 deletions
|
@ -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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue