feat: implement admin account disable functionality

This commit is contained in:
ispik
2026-04-11 14:00:50 +03:00
parent 26faa18d6e
commit 6e78f0b9c0
6 changed files with 89 additions and 8 deletions

View File

@@ -3,6 +3,7 @@ mod mongodb;
mod reference;
use authifier::config::Captcha;
use authifier::config::EmailExpiryConfig;
use authifier::config::EmailVerificationConfig;
use authifier::config::PasswordScanning;
use authifier::config::ResolveIp;
@@ -10,10 +11,10 @@ use authifier::config::SMTPSettings;
use authifier::config::Shield;
use authifier::config::Template;
use authifier::config::Templates;
use authifier::config::EmailExpiryConfig;
use authifier::Authifier;
use rand::Rng;
use revolt_config::config;
use revolt_result::Result;
#[cfg(feature = "mongodb")]
pub use self::mongodb::*;
@@ -251,4 +252,22 @@ impl Database {
event_channel: None,
}
}
pub async fn disable_authifier_account(&self, user_id: &str) -> Result<()> {
let auth = self.clone().to_authifier().await;
let mut account = auth
.database
.find_account(user_id)
.await
.map_err(|_| create_database_error!("find_account", "accounts"))?;
account.disabled = true;
auth.database
.save_account(&account)
.await
.map_err(|_| create_database_error!("save_account", "accounts"))?;
Ok(())
}
}

View File

@@ -288,6 +288,8 @@ auto_derived! {
Search = 14,
ManageNotes = 15,
Discover = 16,
AccountDisable = 17,
}
pub enum AdminAuditItemActions {
@@ -317,7 +319,10 @@ auto_derived! {
ServerSetFlags,
ServerInstanceBanAllMembers,
ServerBanMember,
ServerUnbanMember
ServerUnbanMember,
// Accounts
AccountDisable
}
// Joiner payloads
@@ -365,6 +370,7 @@ impl AdminAuditItemActions {
AdminAuditItemActions::ServerBanMember => true,
AdminAuditItemActions::ServerUnbanMember => true,
AdminAuditItemActions::ServerFetchMembers => false,
AdminAuditItemActions::AccountDisable => true,
}
}
}

View File

@@ -37,9 +37,7 @@ impl IntoResponse for Error {
ErrorType::NotAMember => StatusCode::BAD_REQUEST,
ErrorType::AlreadyPinned => StatusCode::BAD_REQUEST,
ErrorType::NotPinned => StatusCode::BAD_REQUEST,
ErrorType::InSlowmode {
retry_after: _,
} => StatusCode::TOO_MANY_REQUESTS,
ErrorType::InSlowmode { retry_after: _ } => StatusCode::TOO_MANY_REQUESTS,
ErrorType::InviteExists => StatusCode::BAD_REQUEST,
ErrorType::CantCreateServers => StatusCode::FORBIDDEN,
@@ -98,6 +96,8 @@ impl IntoResponse for Error {
ErrorType::NoEmbedData => StatusCode::BAD_REQUEST,
ErrorType::ImATeaPot => StatusCode::IM_A_TEAPOT,
ErrorType::PrivilegedAccount => StatusCode::FORBIDDEN,
};
(status, Json(&self)).into_response()

View File

@@ -190,6 +190,9 @@ pub enum ErrorType {
feature: String,
},
// ? Admin API relate errors
PrivilegedAccount,
// :)
ImATeaPot,
}

View File

@@ -43,9 +43,7 @@ impl<'r> Responder<'r, 'static> for Error {
ErrorType::NotAMember => Status::BadRequest,
ErrorType::AlreadyPinned => Status::BadRequest,
ErrorType::NotPinned => Status::BadRequest,
ErrorType::InSlowmode {
retry_after: _,
} => Status::TooManyRequests,
ErrorType::InSlowmode { retry_after: _ } => Status::TooManyRequests,
ErrorType::InvalidFlagValue => Status::BadRequest,
ErrorType::InviteExists => Status::BadRequest,
@@ -104,6 +102,8 @@ impl<'r> Responder<'r, 'static> for Error {
ErrorType::VosoUnavailable => Status::BadRequest,
ErrorType::ImATeaPot => Status::ImATeapot,
ErrorType::PrivilegedAccount => Status::Forbidden,
};
// Serialize the error data structure into JSON.

View File

@@ -0,0 +1,53 @@
use crate::routes::admin::util::{
create_audit_action, flatten_authorized_user, user_has_permission,
};
use revolt_database::util::reference::Reference;
use revolt_database::{AdminAuthorization, Database};
use revolt_models::v0::{self};
use revolt_result::{create_error, Result};
use rocket::serde::json::Json;
use rocket::State;
/// Disable an account. Requires AccountDisable permissions
#[openapi(tag = "Admin")]
#[post("/accounts/disable/<id>")]
pub async fn admin_account_disable(
db: &State<Database>,
auth: AdminAuthorization,
id: Reference<'_>,
) -> Result<()> {
let user = flatten_authorized_user(&auth);
if !user_has_permission(user, v0::AdminUserPermissionFlags::AccountDisable) {
return Err(create_error!(MissingPermission {
permission: "AccountDisable".to_string()
}));
}
let target = id.as_user(db).await?;
if target.privileged {
return Err(create_error!(PrivilegedAccount));
}
let admin = db.admin_user_fetch(&target.id).await.ok();
if let Some(admin) = admin {
if user_has_permission(&admin, v0::AdminUserPermissionFlags::AccountDisable) {
return Err(create_error!(PrivilegedAccount));
}
}
create_audit_action(
db,
&user.id,
v0::AdminAuditItemActions::AccountDisable,
None,
Some(id.id),
None,
)
.await?;
db.disable_authifier_account(&target.id).await?;
Ok(())
}