From 0af376c26b149a5a0286608ebe3869587780a949 Mon Sep 17 00:00:00 2001 From: Kenyon Hopkins <133072610+bluecords@users.noreply.github.com> Date: Sat, 20 Jun 2026 14:33:28 -0400 Subject: [PATCH] fix: server owner should bypass rank check on channel role-permission overrides (#805) fix: allow true server owner to bypass rank check on channel role-permission overrides The set_role_permissions route blocks editing a role's channel permission overrides whenever role.rank <= the acting member's rank (NotElevated), to prevent privilege-escalation loops. However this check has no exemption for the server's true owner (server.owner == user.id). If an owner has assigned themselves their own top-level role (e.g. "Admin"/"Server Admin" - extremely common since most server setups have the owner hold their highest role for visible status/cosmetics), that role's rank is necessarily equal to their own computed member rank, so the check incorrectly throws NotElevated for the owner too - even though server owners by definition outrank every role and every member, owner-held roles included. This produces a confusing experience: the owner cannot edit channel-level overrides for their own top role via the UI, with no clear explanation, and may reasonably believe something is broken or their permissions are miscconfigured (they aren't). This adds a short-circuit: if the acting user is the server's owner, skip the rank comparison entirely, matching how Stoat already treats true ownership as an absolute bypass elsewhere in the permission system (e.g. channel-visibility lockout cascades). Signed-off-by: bluecords <133072610+bluecords@users.noreply.github.com> --- crates/delta/src/routes/channels/permissions_set.rs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/crates/delta/src/routes/channels/permissions_set.rs b/crates/delta/src/routes/channels/permissions_set.rs index 545f6bb8..7ab648d1 100644 --- a/crates/delta/src/routes/channels/permissions_set.rs +++ b/crates/delta/src/routes/channels/permissions_set.rs @@ -29,7 +29,9 @@ pub async fn set_role_permissions( if let Some(server) = query.server_ref() { if let Some(role) = server.roles.get(&role_id) { - if role.rank <= query.get_member_rank().unwrap_or(i64::MIN) { + if server.owner != user.id + && role.rank <= query.get_member_rank().unwrap_or(i64::MIN) + { return Err(create_error!(NotElevated)); }