From e36fc9738bac0de4f3fcbccba521f1e3754f7ae7 Mon Sep 17 00:00:00 2001 From: Zomatree Date: Thu, 6 Nov 2025 20:26:31 +0000 Subject: [PATCH] fix: prevent timing out members which have TimeoutMembers permission --- crates/core/result/src/axum.rs | 1 + crates/core/result/src/lib.rs | 1 + crates/core/result/src/rocket.rs | 1 + crates/delta/src/routes/servers/member_edit.rs | 15 +++++++++++++-- 4 files changed, 16 insertions(+), 2 deletions(-) diff --git a/crates/core/result/src/axum.rs b/crates/core/result/src/axum.rs index e4caf818..08ad0b41 100644 --- a/crates/core/result/src/axum.rs +++ b/crates/core/result/src/axum.rs @@ -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, diff --git a/crates/core/result/src/lib.rs b/crates/core/result/src/lib.rs index 10b56d5d..5ae2ac2a 100644 --- a/crates/core/result/src/lib.rs +++ b/crates/core/result/src/lib.rs @@ -138,6 +138,7 @@ pub enum ErrorType { NotPrivileged, CannotGiveMissingPermissions, NotOwner, + IsElevated, // ? General errors DatabaseError { diff --git a/crates/core/result/src/rocket.rs b/crates/core/result/src/rocket.rs index 1d996a17..f450d88b 100644 --- a/crates/core/result/src/rocket.rs +++ b/crates/core/result/src/rocket.rs @@ -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, diff --git a/crates/delta/src/routes/servers/member_edit.rs b/crates/delta/src/routes/servers/member_edit.rs index e33935e8..74ac5d72 100644 --- a/crates/delta/src/routes/servers/member_edit.rs +++ b/crates/delta/src/routes/servers/member_edit.rs @@ -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)?;