feat: suspend user accounts from the staff console (GDPR Art. 18)#607
Open
Joe-Heffer-Shef wants to merge 1 commit into
Open
feat: suspend user accounts from the staff console (GDPR Art. 18)#607Joe-Heffer-Shef wants to merge 1 commit into
Joe-Heffer-Shef wants to merge 1 commit into
Conversation
Implements the Right to Restriction of Processing: staff can temporarily freeze a user account so they cannot log in, while retaining all their data. - Add ConsoleSuspendUserView (confirm + suspend) and ConsoleUnsuspendUserView to the staff console, reusing Django's is_active flag (no migration, no cascade delete). Guards prevent suspending yourself or a superuser. - Show all users in the console list with an Active/Suspended status column, and add suspend/lift-suspension actions on the user detail page. - Show a clear "account has been suspended" message on login for suspended users with valid credentials, instead of the generic error. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Collaborator
Author
|
Follow-up for the audit trail tracked in #608. |
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.
Closes #584
Summary
Implements the Right to Restriction of Processing (UK GDPR Article 18): staff can temporarily suspend a user account — the user can no longer log in or submit data, but all their personal data and survey responses are retained, not deleted. The action is fully reversible. This is distinct from full erasure (#570).
Built on Django's existing
User.is_activeflag, so there is no migration and no cascade deletion.Changes
home/views/console.py)ConsoleSuspendUserView— GET renders a confirmation page, POST setsis_active=False. Guarded against suspending yourself or a superuser (raisesPermissionDenied).ConsoleUnsuspendUserView— POST restoresis_active=True.ConsoleUserListViewnow lists all users (previously active-only, which would have hidden suspended accounts).home/urls.py) —admin_suspend_user,admin_unsuspend_user.console/suspend_user_confirm.html— mirrors the existing remove-member confirm dialog (type the email to enable submit); copy makes clear data is retained.console/users.html— new Status column (Active / Suspended badges).console/user_detail.html— Suspended badge + Suspend account / Lift suspension actions (hidden for self and superusers).home/views/auth.py) — a suspended user with correct credentials sees a clear "Your account has been suspended" message instead of the generic error. Only shown when the password actually matches, so it does not reveal which emails exist.Acceptance criteria
Testing
python manage.py test home.tests.test_console_views home.tests.test_user_views→ 45 tests OKpython manage.py check --fail-level WARNING→ no issuesmakemigrations --check --dry-run→ no changes detected10 new tests cover staff-only access, the suspend/unsuspend round-trip, no-cascade (memberships survive), the self/superuser guards (403), suspended-user visibility in the list, and the clear-vs-generic login messages.
Follow-up
An audit trail (who/when) is out of scope here — a separate audit-log PR is in flight. Follow-up issue to wire suspension into it will be linked.
🤖 Generated with Claude Code