feat: add is_admin() helper to utils/permissions.py (#55) #64
No reviewers
Labels
No Label
ai-changes-requested
ai-pr-opened
ai-reviewed
ai-reviewing
ai-working
in-next-release
status/in-progress
status/pr-open
No Milestone
No project
No Assignees
1 Participants
Notifications
Due Date
No due date set.
Dependencies
No dependencies set.
Reference: cal/major-domo-v2#64
Loading…
Reference in New Issue
Block a user
No description provided.
Delete Branch "ai/major-domo-v2#55"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Summary
is_admin(interaction: discord.Interaction) -> boolhelper toutils/permissions.pythat centralizes the admin check with the correctisinstance(interaction.user, discord.Member)guardcan_edit_player_image()incommands/profile/images.pyto useis_admin()instead of directly accessinginteraction.user.guild_permissions.administrator— the direct access would raiseAttributeErrorin DM contexts whereuseris adiscord.Usernot adiscord.Memberinteraction.userwithspec=discord.Memberso theisinstanceguard passesFiles Changed
utils/permissions.py— addedis_admin()helper afteris_league_server()commands/profile/images.py— import and useis_admin()incan_edit_player_image()tests/test_commands_profile_images.py— fix admin test mock to usespec=discord.MemberTest Results
930 passed, 3 skipped
Other observations
Several other places in the codebase access
guild_permissions.administratordirectly without theisinstanceguard (e.g.commands/admin/management.py,commands/admin/users.py,commands/help/main.py,commands/utilities/charts.py). These are out of scope for this issue but could be migrated tois_admin()as follow-up work (issue #54 proposes a broader refactor).AI Code Review
Files Reviewed
utils/permissions.py(modified —is_admin()helper added)commands/profile/images.py(modified —can_edit_player_image()updated)tests/test_commands_profile_images.py(modified — admin mock fixed)Findings
Correctness
is_admin()implementation is correct. The short-circuitisinstance(interaction.user, discord.Member) and interaction.user.guild_permissions.administratorsafely guards against DM contexts whereuserisdiscord.Userand has noguild_permissionsattribute.can_edit_player_image()correctly delegates tois_admin(), eliminating the bareinteraction.user.guild_permissions.administratoraccess that wouldAttributeErrorin DMs.MagicMock(spec=discord.Member)fix in the test is correct:speccauses Python to set__class__todiscord.Memberon the mock, soisinstance(mock, discord.Member)returnsTrueas the newis_admin()guard requires.import discordadded to the test file is a required dependency forMagicMock(spec=discord.Member)— not an unused import.Security
admin_only()decorator pattern in the same file.Style & Conventions
is_admin()is placed afteris_league_server()alongside other non-decorator helpers — correct location.from utils.permissions import is_adminimport added correctly alongside otherutils.*imports inimages.py.Suggestions
admin_only()decorator inpermissions.pyduplicates the sameisinstance+guild_permissions.administratorlogic inline. It could eventually delegate tois_admin(), but the decorator has a different flow (early-return with user-facing error messages after a guild-presence check), so keeping them separate is reasonable for now. Issue #54 tracks the broader refactor.Verdict: APPROVED ✅
Clean, well-scoped fix. The
is_admin()helper correctly centralizes the DM-safe admin check, the call site incan_edit_player_image()is properly updated, and the test mock is correctly patched to exercise the new code path. All 930 tests passing. Ready to merge.Automated review by Claude PR Reviewer
ed40b532b5toc41166d53c