Skip to content

feat: Add user management and self-service password change#39

Merged
marevol merged 2 commits into
mainfrom
feat/user-management
Feb 14, 2026
Merged

feat: Add user management and self-service password change#39
marevol merged 2 commits into
mainfrom
feat/user-management

Conversation

@marevol

@marevol marevol commented Feb 14, 2026

Copy link
Copy Markdown
Collaborator

Summary

Add admin-only user management (CRUD, activate/deactivate, password reset) and self-service password change for all authenticated users, with full frontend UI and i18n support.

Changes Made

Backend (11 files)

  • UserViewSet — Full CRUD with per-action permissions: IsAdminUser for management, IsAuthenticated for self-service password change
  • DenyApiKeyAccess permission — Unconditionally blocks API key auth on user management endpoints (API keys with read/write scopes cannot access these endpoints)
  • Service layer (user_service.py) — Business logic for create, activate, deactivate, and password reset
  • Serializers (serializers/user.py) — 5 serializers for list, create, update, admin password reset, and self password change with Django password validation
  • Admin resource visibilityOwnedResourceMixin / CreatedByResourceMixin bypass for is_staff users, allowing admins to view all projects and resources
  • is_staff on auth endpoint — Exposed on /auth/user/ so frontend can determine admin status

Frontend (8 files)

  • UserManagementPage — DataTable with create user dialog, deactivate confirmation, and password reset dialog (admin only)
  • PasswordChangePage — Self-service password change with old/new/confirm validation (all users)
  • Async router guard — Fetches user profile before checking requiresAdmin meta, preventing redirect on page reload
  • Admin sidebar section — Conditionally shown for is_staff users
  • i18n — English and Japanese translations for all user management strings

Tests (1 file, 14 cases)

  • User list permissions (admin, regular, anonymous)
  • User create permissions
  • Deactivate/activate lifecycle (including self-deactivation guard)
  • Admin password reset
  • Self-service password change (valid + wrong old password)
  • API key blocking (with realistic read/write scopes)
  • Admin project visibility

Testing

# Backend tests — all 14 pass
cd backend && uv run pytest recotem/tests/test_user_management.py -v

# Linting — clean
ruff check backend/
ruff format --check backend/

Breaking Changes

None — additive changes only. Existing endpoints and behavior are unchanged.

Additional Notes

  • No database migration needed — uses existing Django User model fields (is_staff, is_active, date_joined, last_login)
  • pagination_class = None on UserViewSet since this is an admin-only endpoint with limited users
  • DELETE method excluded from UserViewSet; deactivation (is_active=False) is used instead of hard delete

marevol and others added 2 commits February 14, 2026 14:39
Add admin-only user management (CRUD, activate/deactivate, password
reset) and self-service password change for all authenticated users.

Backend:
- UserViewSet with per-action permissions (IsAdminUser for management,
  IsAuthenticated for password change)
- DenyApiKeyAccess permission to block API key auth on user endpoints
- Service layer for user lifecycle operations
- Admin users can view all projects/resources (OwnedResourceMixin bypass)
- is_staff exposed on /auth/user/ endpoint

Frontend:
- UserManagementPage with DataTable, create/deactivate/reset dialogs
- PasswordChangePage for self-service password change
- Admin-only sidebar section with route guard
- Async router guard to handle page reload (fetches user before check)
- i18n support (en/ja)

Tests: 14 test cases covering permissions, CRUD, API key blocking, and
admin project visibility.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@marevol marevol merged commit 69a3225 into main Feb 14, 2026
9 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant