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

237 lines
8.7 KiB
Markdown

# 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:**
```java
@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:**
```java
@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:
```java
.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):
```html
<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