fix(discord): extend role-scope fix to slash surface + fixture update

Sibling-site fix: _evaluate_slash_authorization was the fourth
_is_allowed_user caller and didn't pass guild/is_dm through, so slash
interactions would take the DM branch regardless of whether they came
from a guild channel. Now reads interaction.guild + in_dm and forwards.

Also updates test_discord_slash_auth fixture (_make_interaction) so
the SimpleNamespace guild mock has a get_member(uid)->None method —
required by the new guild-scoped fallback path in _is_allowed_user.
Tests exercising positive role paths still work via user.roles.

Three new regression tests in test_discord_roles_dm_scope:
- Slash DM + role in mutual public guild → rejected
- Slash in guild B + role only in guild A → rejected
- Slash in guild B + role in guild B → allowed (positive control)

368 Discord tests pass. test_discord_free_channel_skips_auto_thread
also fails on clean main (pre-existing, unrelated to this fix).
This commit is contained in:
Teknium 2026-05-07 05:43:55 -07:00
parent ef1e565570
commit 5c045b8f6c
3 changed files with 105 additions and 2 deletions

View file

@ -2305,7 +2305,16 @@ class DiscordAdapter(BasePlatformAdapter):
return (True, None)
user_id = str(user.id)
if not self._is_allowed_user(user_id, author=user):
# Pass guild + is_dm so role check is scoped to the originating
# guild and cross-guild DM bypass (#12136) can't land via the
# slash surface either.
interaction_guild = getattr(interaction, "guild", None)
if not self._is_allowed_user(
user_id,
author=user,
guild=interaction_guild,
is_dm=in_dm,
):
return (
False,
"user not in DISCORD_ALLOWED_USERS / DISCORD_ALLOWED_ROLES",