directlx-claude-config/plans/refactored-tinkering-island.md

8.7 KiB

Admin Password Reset Feature Implementation Plan

Context

The HiveOps management portal currently lacks password management functionality. Portal users can update their profile (name, email) but cannot change passwords. The management page needs the ability for administrators to reset user passwords.

User Requirement: Admin users should be able to manually set new passwords for portal users through the management interface.

Current State:

  • User entity has passwordHash field with BCrypt encoding (strength 12)
  • No password change/reset endpoints exist
  • Customer management exists at /portal/customers but no portal user management
  • Audit logging system already in place for admin actions
  • Portal uses Thymeleaf + Spring Boot with role-based access control

Implementation Approach

Architecture Decision

Create a new Portal Users Management section at /portal/users (separate from customer management) to:

  • Maintain separation between Customers (licensees) and Users (portal accounts)
  • Allow future extensions (user creation, role changes, account management)
  • Follow existing portal pattern of dedicated sections

Backend Changes

1. Create PortalUserController.java

Path: /src/main/java/com/hiveops/mgmt/controller/portal/PortalUserController.java

Endpoints:

  • GET /portal/users - List all users (paginated, searchable)
  • GET /portal/users/{id} - View user details
  • GET /portal/users/{id}/reset-password - Show password reset form
  • POST /portal/users/{id}/reset-password - Process password reset
  • POST /portal/users/{id}/enable - Enable user account
  • POST /portal/users/{id}/disable - Disable user account

Patterns to follow:

  • Use @PreAuthorize("hasRole('ADMIN')") for authorization
  • Follow PortalCustomerController patterns (flash messages, error handling, audit logging)
  • Extract client IP using getClientIp() helper method

2. Create ResetPasswordRequest.java DTO

Path: /src/main/java/com/hiveops/mgmt/dto/request/ResetPasswordRequest.java

Fields:

@NotBlank(message = "New password is required")
@Size(min = 8, max = 100, message = "Password must be between 8 and 100 characters")
private String newPassword;

@NotBlank(message = "Password confirmation is required")
private String confirmPassword;

Add custom validator to ensure passwords match.

3. Enhance UserService.java

Path: /src/main/java/com/hiveops/mgmt/service/UserService.java

New methods:

  • Page<User> findAll(Pageable pageable) - Paginated user list
  • Page<User> searchUsers(String query, Pageable pageable) - Search by email/name
  • User resetPassword(Long userId, String newPassword, User adminUser, String ipAddress) - Reset with BCrypt encoding and audit logging
  • User enableUser(Long userId, User adminUser, String ipAddress) - Enable user
  • User disableUser(Long userId, User adminUser, String ipAddress) - Disable user

Key logic:

  • Use injected PasswordEncoder for BCrypt hashing
  • Call AuditService.log() for all operations
  • Prevent admin from disabling themselves

4. Enhance UserRepository.java

Path: /src/main/java/com/hiveops/mgmt/repository/UserRepository.java

New methods:

@Query("SELECT u FROM User u WHERE " +
       "LOWER(u.email) LIKE LOWER(CONCAT('%', :query, '%')) OR " +
       "LOWER(u.name) LIKE LOWER(CONCAT('%', :query, '%'))")
Page<User> search(@Param("query") String query, Pageable pageable);

5. Update AuditLog.java

Path: /src/main/java/com/hiveops/mgmt/entity/AuditLog.java

Add enum values:

  • USER_PASSWORD_RESET
  • USER_ENABLED
  • USER_DISABLED

6. Enhance AuditService.java

Path: /src/main/java/com/hiveops/mgmt/service/AuditService.java

New methods:

  • logPasswordReset(User targetUser, User adminUser, String ipAddress)
  • logUserEnabled(User targetUser, User adminUser, String ipAddress)
  • logUserDisabled(User targetUser, User adminUser, String ipAddress)

Log details should include target user email and admin email.

7. Update SecurityConfig.java

Path: /src/main/java/com/hiveops/mgmt/config/SecurityConfig.java

Add authorization rule:

.requestMatchers("/portal/users/**").hasRole("ADMIN")

Frontend Changes

8. Create User List Template

Path: /src/main/resources/templates/portal/users/list.html

Features:

  • Table: Email, Name, Role, Status (badge), Last Login, Created Date
  • Search bar (filter by email/name)
  • Role filter dropdown
  • Action buttons: View, Reset Password
  • Pagination (follow customers/list.html pattern)

9. Create User View Template

Path: /src/main/resources/templates/portal/users/view.html

Layout: Two-column (8-4 grid) following customers/view.html

Left column: User details card (email, name, role, status, UUID, timestamps, licenses)

Right column: Actions card (Reset Password button, Enable/Disable button)

10. Create Password Reset Form

Path: /src/main/resources/templates/portal/users/reset-password.html

Form fields:

  • Display user email (read-only context)
  • New Password (password input)
  • Confirm Password (password input)
  • Password requirements hint box (Bootstrap alert)
  • Cancel and Reset Password buttons

Validation:

  • Server-side validation errors with .invalid-feedback
  • Match validation for password confirmation

11. Update Sidebar Navigation

Path: /src/main/resources/templates/portal/layout/base.html

Add menu item (after Customers):

<a th:href="@{/portal/users}"
   th:classappend="${activePage == 'users'} ? 'active' : ''"
   class="list-group-item list-group-item-action bg-dark text-white-50"
   sec:authorize="hasRole('ADMIN')">
    <i class="bi bi-person-badge me-2"></i>Users
</a>

Security & Validation

Password Requirements:

  • Minimum 8 characters
  • Maximum 100 characters
  • Passwords must match (confirmation)
  • BCrypt encoding with strength 12 (existing)

Authorization:

  • All endpoints require ADMIN role
  • Cannot reset own password through this interface
  • Cannot disable own account

Audit Logging:

  • Every password reset logged with target user email, admin email, and IP address
  • Enable/disable actions also logged

Implementation Sequence

  1. Update AuditLog entity (add enum values)
  2. Update AuditService (add logging methods)
  3. Update UserRepository (add search method)
  4. Create ResetPasswordRequest DTO
  5. Update UserService (add password reset and user management methods)
  6. Create PortalUserController
  7. Update SecurityConfig (add authorization rule)
  8. Create templates directory: /templates/portal/users/
  9. Create list.html template
  10. Create view.html template
  11. Create reset-password.html template
  12. Update base.html (add sidebar menu item)

Verification

Manual Testing:

  1. Login as admin user (admin@directlx.dev / admin123)
  2. Navigate to Users menu item in sidebar
  3. Verify user list displays with search functionality
  4. Click on a user to view details
  5. Click Reset Password and set a new password
  6. Verify password validation (min length, match requirement)
  7. Submit form and verify success message
  8. Verify audit log entry was created
  9. Test login with new password
  10. Test Enable/Disable functionality
  11. Verify admin cannot disable own account

Database Verification:

  • Check users table - password_hash should be updated
  • Check audit_logs table - USER_PASSWORD_RESET entry should exist with correct details

Critical Files

Backend (Create/Modify):

  • /src/main/java/com/hiveops/mgmt/controller/portal/PortalUserController.java (NEW)
  • /src/main/java/com/hiveops/mgmt/dto/request/ResetPasswordRequest.java (NEW)
  • /src/main/java/com/hiveops/mgmt/service/UserService.java (MODIFY - add methods)
  • /src/main/java/com/hiveops/mgmt/repository/UserRepository.java (MODIFY - add search)
  • /src/main/java/com/hiveops/mgmt/entity/AuditLog.java (MODIFY - add enums)
  • /src/main/java/com/hiveops/mgmt/service/AuditService.java (MODIFY - add methods)
  • /src/main/java/com/hiveops/mgmt/config/SecurityConfig.java (MODIFY - add rule)

Frontend (Create):

  • /src/main/resources/templates/portal/users/list.html (NEW)
  • /src/main/resources/templates/portal/users/view.html (NEW)
  • /src/main/resources/templates/portal/users/reset-password.html (NEW)

Frontend (Modify):

  • /src/main/resources/templates/portal/layout/base.html (MODIFY - add menu item)

Reusable Components

Existing utilities to leverage:

  • PasswordEncoder bean (SecurityConfig.java) - BCrypt strength 12
  • AuditService.log() - Audit logging pattern
  • getClientIp(HttpServletRequest) - IP extraction helper
  • Flash messages pattern from PortalCustomerController
  • Pagination pattern from customers/list.html
  • Bootstrap 5 components and styling
  • Thymeleaf validation error display patterns