feat: add MODERATOR role for delegated moderation#74
Merged
Conversation
Introduces an intermediate MODERATOR role between APPROVED_USER and SUPERADMIN. Moderators can approve/reject access requests and block/unblock regular users, but cannot assign roles, manage others' keys, view the audit log, or send announcements. - models/enums.py: add UserRole.MODERATOR - db/schema.sql: add MODERATOR to users.role CHECK constraint - db/database.py: migration v17 recreates users table with new CHECK constraint; _validate_enum_values updated accordingly - services/users.py: new require_moderator_or_admin(), require_approved_or_admin now accepts MODERATOR; block/unblock/approve/reject/list methods downgraded from require_superadmin to require_moderator_or_admin; block_user prevents moderator from blocking another moderator - services/access_approval.py: approve/reject/list_pending/get_request accept moderators - bot/guards.py: expose require_moderator_or_admin guard - bot/keyboards/admin.py: moderator_panel_keyboard(); user_actions_keyboard accepts actor_role param — hides admin-only buttons for moderators, shows assign/revoke moderator buttons for superadmins - bot/handlers/admin.py: /moderator command and panel callback; setmoderator toggle handler; updated block/unblock/request handlers to use require_moderator_or_admin and pass actor_role to keyboards https://claude.ai/code/session_01LVGnWPcQ82ZnFS1D2JcULd
|
You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard. |
… _migrate_v17 SQLite silently ignores PRAGMA foreign_keys changes inside an open transaction. Previous migrations accumulate writes in an implicit transaction, causing DROP TABLE users to fail with FK constraint errors. Fix by flushing with await self.commit() first, then operating on the raw connection with explicit commit/rollback. https://claude.ai/code/session_01LVGnWPcQ82ZnFS1D2JcULd
Block and unblock handler stubs used require_superadmin which no longer matches the handlers that now call require_moderator_or_admin. https://claude.ai/code/session_01LVGnWPcQ82ZnFS1D2JcULd
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
MODERATORrole betweenAPPROVED_USERandSUPERADMIN, solving the problem of having no intermediate delegation optionChanges
Model layer
models/enums.py:UserRole.MODERATOR = "MODERATOR"db/schema.sql:users.roleCHECK constraint updated for fresh installsdb/database.py: migration v17 recreates users table with expanded CHECK constraint;_validate_enum_valuesupdatedService layer
services/users.py: newrequire_moderator_or_admin();require_approved_or_adminnow accepts MODERATOR (so moderators can use their own VPN keys); block/unblock/approve/reject/list methods now accept MODERATOR;block_userprevents a moderator from blocking another moderatorservices/access_approval.py: approve, reject, list_pending, get_request now accept MODERATORBot layer
bot/guards.py: exportsrequire_moderator_or_adminbot/keyboards/admin.py:moderator_panel_keyboard()(requests + users only);user_actions_keyboardgainsactor_roleparam — hides admin-only actions for moderators, shows "Назначить/Снять модератора" toggle for superadminsbot/handlers/admin.py:/moderatorcommand andadmin:moderator_panelcallback;admin:setmoderator:{id}toggle handler (SUPERADMIN only viaset_role); block/unblock/request handlers updated to accept moderators and passactor_roleto keyboardsTest plan
/moderatorshows panel with only "Заявки на доступ" and "Пользователи"/admin→ AccessDenied; audit log callback → AccessDenied; announce callback → AccessDeniedpython init_db.pybootstraps with MODERATOR in CHECK constrainthttps://claude.ai/code/session_01LVGnWPcQ82ZnFS1D2JcULd
Generated by Claude Code