fix: prevent timing out members which have TimeoutMembers permission

This commit is contained in:
Zomatree
2025-11-06 20:26:31 +00:00
parent 657a3f08e5
commit e36fc9738b
4 changed files with 16 additions and 2 deletions

View File

@@ -62,6 +62,7 @@ impl IntoResponse for Error {
ErrorType::NotPrivileged => StatusCode::FORBIDDEN,
ErrorType::CannotGiveMissingPermissions => StatusCode::FORBIDDEN,
ErrorType::NotOwner => StatusCode::FORBIDDEN,
ErrorType::IsElevated => StatusCode::FORBIDDEN,
ErrorType::DatabaseError { .. } => StatusCode::INTERNAL_SERVER_ERROR,
ErrorType::InternalError => StatusCode::INTERNAL_SERVER_ERROR,

View File

@@ -138,6 +138,7 @@ pub enum ErrorType {
NotPrivileged,
CannotGiveMissingPermissions,
NotOwner,
IsElevated,
// ? General errors
DatabaseError {

View File

@@ -69,6 +69,7 @@ impl<'r> Responder<'r, 'static> for Error {
ErrorType::NotPrivileged => Status::Forbidden,
ErrorType::CannotGiveMissingPermissions => Status::Forbidden,
ErrorType::NotOwner => Status::Forbidden,
ErrorType::IsElevated => Status::Forbidden,
ErrorType::DatabaseError { .. } => Status::InternalServerError,
ErrorType::InternalError => Status::InternalServerError,

View File

@@ -32,12 +32,17 @@ pub async fn edit(
// Fetch server and member
let mut server = server.as_server(db).await?;
let target_user = member.as_user(db).await?;
let mut member = member.as_member(db, &server.id).await?;
// Fetch our currrent permissions
let mut query = DatabasePermissionQuery::new(db, &user).server(&server);
let permissions = calculate_server_permissions(&mut query).await;
// Fetch target permissions
let mut target_query = DatabasePermissionQuery::new(db, &target_user).server(&server).member(&member);
let target_permissions = calculate_server_permissions(&mut target_query).await;
// Check permissions in server
if data.nickname.is_some() || data.remove.contains(&v0::FieldsMember::Nickname) {
if user.id == member.id.user {
@@ -60,8 +65,14 @@ pub async fn edit(
}
if data.timeout.is_some() || data.remove.contains(&v0::FieldsMember::Timeout) {
if data.timeout.is_some() && member.id.user == user.id {
return Err(create_error!(CannotTimeoutYourself));
if data.timeout.is_some() {
if member.id.user == user.id {
return Err(create_error!(CannotTimeoutYourself));
}
if target_permissions.has_channel_permission(ChannelPermission::TimeoutMembers) {
return Err(create_error!(IsElevated))
}
}
permissions.throw_if_lacking_channel_permission(ChannelPermission::TimeoutMembers)?;