Aller au contenu principal

User Management & Access Control System - User Story

Story Overview​

Story ID: EMTB-002
Epic: Data Management & User System Enhancement
Story Name: User Management & Access Control System
Story Type: Brownfield Enhancement
Priority: High
Estimated Effort: 21 Story Points

User Story​

As a system administrator and business user
I want comprehensive user management with role-based access control and secure authentication workflows
So that I can manage user access, ensure data security, maintain client-user relationships, and provide appropriate permissions across all system functions while preserving existing user-client associations.

Acceptance Criteria​

AC1: Enhanced User CRUD Operations with Role-Based Permissions​

Given the existing User model with basic fields (email, nom, prenom, role, password, clientId)
When I perform user management operations
Then the system must:

  • Support comprehensive CRUD operations with role-based authorization
  • Implement user creation with automatic reference generation and validation
  • Provide user profile management with secure password handling
  • Support role assignment and modification with proper authorization checks
  • Maintain audit trails for all user management operations
  • Preserve existing Client-User relationships and associations

AC2: User Authentication Workflows and Session Management​

Given users with different roles and access requirements
When they authenticate and use the system
Then the system must:

  • Implement secure JWT-based authentication with refresh token support
  • Support multi-factor authentication for administrative users
  • Provide session management with configurable timeout policies
  • Implement password strength validation and expiration policies
  • Support account lockout mechanisms after failed login attempts
  • Maintain authentication audit logs with security event tracking

AC3: Client-User Relationship Management with Access Restrictions​

Given the existing Client-User relationship structure
When managing user access to client data
Then the system must:

  • Enforce client-specific data access based on user-client associations
  • Support multiple users per client with different permission levels
  • Implement hierarchical access control (admin > manager > user)
  • Provide client-scoped data visibility and modification permissions
  • Support temporary access delegation and time-limited permissions
  • Maintain referential integrity for all client-user relationships

AC4: Role-Based System Integration and Access Control​

Given the comprehensive system entities (Sites, Reclamations, Factures, ApporteurAffaire, etc.)
When users access different system functions
Then the system must:

  • Implement granular permissions for all entity operations (read, write, delete)
  • Support role-based access to financial data (Factures, FacturePartenaire)
  • Provide appropriate access controls for site management and reclamation workflows
  • Implement data export permissions with audit logging
  • Support bulk operation permissions with proper authorization
  • Ensure secure access to document management and file operations

AC5: User Profile Management and Account Security​

Given users requiring profile management and security features
When they manage their accounts and security settings
Then the system must:

  • Provide comprehensive user profile management with data validation
  • Support secure password change workflows with current password verification
  • Implement account recovery mechanisms with multi-step verification
  • Support user preference management and system configuration
  • Provide personal audit trail access for user activities
  • Support account deactivation and reactivation workflows

AC6: Administrative User Management Tools​

Given system administrators requiring user management capabilities
When they perform administrative user operations
Then the system must:

  • Provide comprehensive user search and filtering capabilities
  • Support bulk user operations (creation, role updates, deactivation)
  • Implement user activity monitoring and reporting
  • Support user impersonation for troubleshooting (with audit trails)
  • Provide role management and permission assignment interfaces
  • Support user data export and backup operations

AC7: Integration with Existing System Components​

Given the established system architecture with ImportService, ClientService, etc.
When integrating user management across all components
Then the system must:

  • Maintain backward compatibility with existing service patterns
  • Integrate authentication checks into all existing controllers
  • Support user context in import operations and audit trails
  • Preserve existing Client service functionality with added user authorization
  • Integrate user permissions into file upload and document management
  • Support user-scoped data operations across all entities

Technical Requirements​

Enhanced User Service Architecture​

interface UserManagementService {
// CRUD Operations with Authorization
createUser(createUserDto: CreateUserDto, currentUser: AuthUser): Promise<User>;
updateUser(id: number, updateUserDto: UpdateUserDto, currentUser: AuthUser): Promise<User>;
deleteUser(id: number, currentUser: AuthUser): Promise<void>;
findUsersByClient(clientId: number, currentUser: AuthUser): Promise<User[]>;

// Role and Permission Management
assignRole(userId: number, role: UserRole, currentUser: AuthUser): Promise<User>;
updatePermissions(userId: number, permissions: Permission[], currentUser: AuthUser): Promise<User>;
validateUserAccess(userId: number, resource: string, action: string): Promise<boolean>;

// Account Security
changePassword(userId: number, passwordChangeDto: PasswordChangeDto): Promise<void>;
enableMFA(userId: number, mfaConfig: MFAConfiguration): Promise<MFASetupResult>;
lockAccount(userId: number, reason: string, currentUser: AuthUser): Promise<void>;
}

interface AuthenticationService {
// Authentication Workflows
authenticate(loginDto: LoginDto): Promise<AuthenticationResult>;
refreshToken(refreshToken: string): Promise<TokenResult>;
logout(userId: number, sessionId: string): Promise<void>;

// Session Management
validateSession(sessionToken: string): Promise<SessionValidationResult>;
getUserSessions(userId: number): Promise<UserSession[]>;
terminateSession(sessionId: string, currentUser: AuthUser): Promise<void>;

// Security Features
validateMFA(userId: number, mfaToken: string): Promise<boolean>;
recordSecurityEvent(event: SecurityEvent): Promise<void>;
checkAccountLockout(email: string): Promise<AccountLockoutStatus>;
}

User Model Enhancement​

interface ExtendedUser {
id: number;
email: string;
nom: string;
prenom: string;
role: UserRole;
password: string; // Hashed
clientId?: number;
client?: Client;

// Enhanced Security Fields
lastLogin?: Date;
failedLoginAttempts: number;
accountLockedUntil?: Date;
passwordChangedAt: Date;
mfaEnabled: boolean;
mfaSecret?: string;

// Permission and Access Control
permissions: Permission[];
isActive: boolean;
mustChangePassword: boolean;
sessionTimeout: number;

// Audit Fields
createdAt: Date;
updatedAt: Date;
createdBy?: number;
lastModifiedBy?: number;
}

enum UserRole {
SUPER_ADMIN = 'SUPER_ADMIN',
ADMIN = 'ADMIN',
MANAGER = 'MANAGER',
USER = 'USER',
CLIENT_USER = 'CLIENT_USER',
READONLY = 'READONLY'
}

interface Permission {
id: number;
resource: string; // 'client', 'site', 'reclamation', 'facture', etc.
action: string; // 'create', 'read', 'update', 'delete', 'export'
scope: 'all' | 'client' | 'own';
conditions?: Record<string, any>;
}

Authentication and Authorization Architecture​

interface AuthGuard {
canActivate(context: ExecutionContext): boolean | Promise<boolean>;
validatePermissions(user: AuthUser, resource: string, action: string): Promise<boolean>;
checkClientAccess(user: AuthUser, clientId: number): Promise<boolean>;
}

interface RoleBasedGuard extends AuthGuard {
requiredRoles: UserRole[];
allowClientUsers: boolean;
resourcePermissions: ResourcePermission[];
}

interface SessionManager {
createSession(user: User, loginContext: LoginContext): Promise<UserSession>;
validateSession(sessionToken: string): Promise<SessionValidationResult>;
refreshSession(sessionId: string): Promise<UserSession>;
terminateSession(sessionId: string): Promise<void>;
cleanupExpiredSessions(): Promise<number>;
}

Audit Trail Integration​

interface UserAuditLog {
id: string;
userId: number;
action: 'login' | 'logout' | 'create' | 'update' | 'delete' | 'access_denied' | 'password_change';
resource?: string;
resourceId?: string;
ipAddress: string;
userAgent: string;
timestamp: Date;
success: boolean;
details: Record<string, any>;
securityLevel: 'low' | 'medium' | 'high' | 'critical';
}

interface SecurityEventLogger {
logAuthentication(user: User, result: AuthenticationResult, context: LoginContext): Promise<void>;
logAuthorization(user: User, resource: string, action: string, granted: boolean): Promise<void>;
logSecurityViolation(violation: SecurityViolation): Promise<void>;
logDataAccess(user: User, entity: string, entityId: string, action: string): Promise<void>;
}

Test Automation Requirements​

Comprehensive User Management Test Coverage​

  1. User CRUD Operations with Role-Based Permissions

    describe('User CRUD Operations', () => {
    test('Admin can create users with all roles', async () => {
    const admin = createMockUser({ role: UserRole.ADMIN });
    const newUser = await userService.createUser(createUserDto, admin);
    expect(newUser).toHaveProperty('id');
    expect(auditService.logs).toContain(expect.objectContaining({
    action: 'create',
    userId: admin.id
    }));
    });

    test('Manager cannot create admin users', async () => {
    const manager = createMockUser({ role: UserRole.MANAGER });
    const createAdminDto = { ...createUserDto, role: UserRole.ADMIN };
    await expect(userService.createUser(createAdminDto, manager))
    .rejects.toThrow('Insufficient permissions');
    });

    test('Client users can only view their client data', async () => {
    const clientUser = createMockUser({
    role: UserRole.CLIENT_USER,
    clientId: 1
    });
    const users = await userService.findUsersByClient(1, clientUser);
    expect(users).toHaveLength(greaterThan(0));

    await expect(userService.findUsersByClient(2, clientUser))
    .rejects.toThrow('Access denied');
    });
    });
  2. Authentication Workflows and Security Tests

    describe('Authentication Security', () => {
    test('Password strength validation enforced', async () => {
    const weakPassword = 'weak';
    const strongPassword = 'StrongP@ssw0rd123';

    await expect(authService.authenticate({
    email: 'user@test.com',
    password: weakPassword
    })).rejects.toThrow('Password does not meet requirements');

    const result = await authService.authenticate({
    email: 'user@test.com',
    password: strongPassword
    });
    expect(result).toHaveProperty('accessToken');
    });

    test('Account lockout after failed attempts', async () => {
    const email = 'user@test.com';

    // Simulate 5 failed login attempts
    for (let i = 0; i < 5; i++) {
    await expect(authService.authenticate({
    email,
    password: 'wrongpassword'
    })).rejects.toThrow();
    }

    const lockoutStatus = await authService.checkAccountLockout(email);
    expect(lockoutStatus.isLocked).toBe(true);
    expect(lockoutStatus.lockedUntil).toBeDefined();
    });

    test('MFA validation workflow', async () => {
    const user = createMockUser({ mfaEnabled: true });

    const authResult = await authService.authenticate({
    email: user.email,
    password: 'correct_password'
    });

    expect(authResult.requiresMFA).toBe(true);
    expect(authResult.accessToken).toBeUndefined();

    const mfaResult = await authService.validateMFA(
    user.id,
    generateValidMFAToken(user.mfaSecret)
    );
    expect(mfaResult).toBe(true);
    });
    });
  3. Role-Based Access Control Integration Tests

    describe('RBAC Integration', () => {
    test('Client data access restrictions', async () => {
    const clientUser = createMockUser({
    role: UserRole.CLIENT_USER,
    clientId: 1
    });

    // Can access own client's sites
    const ownSites = await siteService.findByClient(1, clientUser);
    expect(ownSites).toHaveLength(greaterThan(0));

    // Cannot access other client's sites
    await expect(siteService.findByClient(2, clientUser))
    .rejects.toThrow('Access denied');

    // Cannot access administrative functions
    await expect(userService.findAll(clientUser))
    .rejects.toThrow('Insufficient permissions');
    });

    test('Financial data access control', async () => {
    const readOnlyUser = createMockUser({ role: UserRole.READONLY });
    const managerUser = createMockUser({ role: UserRole.MANAGER });

    // Read-only user can view but not modify
    const factures = await factureService.findAll(readOnlyUser);
    expect(factures).toBeDefined();

    await expect(factureService.create(createFactureDto, readOnlyUser))
    .rejects.toThrow('Insufficient permissions');

    // Manager can create and modify
    const newFacture = await factureService.create(createFactureDto, managerUser);
    expect(newFacture).toHaveProperty('id');
    });

    test('Import operations with user context', async () => {
    const adminUser = createMockUser({ role: UserRole.ADMIN });
    const clientUser = createMockUser({
    role: UserRole.CLIENT_USER,
    clientId: 1
    });

    // Admin can import for any client
    await expect(importService.importClients(importData, adminUser))
    .resolves.toBeDefined();

    // Client user cannot perform import operations
    await expect(importService.importClients(importData, clientUser))
    .rejects.toThrow('Insufficient permissions');

    // Verify audit trails include user context
    const auditLogs = await auditService.getImportLogs();
    expect(auditLogs[0]).toHaveProperty('userId', adminUser.id);
    });
    });
  4. Session Management and Security Tests

    describe('Session Management', () => {
    test('Session timeout enforcement', async () => {
    const user = createMockUser({ sessionTimeout: 1800 }); // 30 minutes
    const session = await sessionManager.createSession(user, loginContext);

    // Fast-forward time beyond timeout
    jest.advanceTimersByTime(1801 * 1000); // 30 minutes + 1 second

    const validation = await sessionManager.validateSession(session.token);
    expect(validation.isValid).toBe(false);
    expect(validation.reason).toBe('session_expired');
    });

    test('Concurrent session limits', async () => {
    const user = createMockUser({ maxConcurrentSessions: 2 });

    // Create maximum allowed sessions
    const session1 = await sessionManager.createSession(user, loginContext1);
    const session2 = await sessionManager.createSession(user, loginContext2);

    expect(session1.isValid).toBe(true);
    expect(session2.isValid).toBe(true);

    // Third session should invalidate oldest
    const session3 = await sessionManager.createSession(user, loginContext3);

    const validation1 = await sessionManager.validateSession(session1.token);
    expect(validation1.isValid).toBe(false);
    expect(validation1.reason).toBe('session_limit_exceeded');
    });

    test('Token refresh workflow', async () => {
    const user = createMockUser();
    const authResult = await authService.authenticate(loginDto);

    expect(authResult).toHaveProperty('accessToken');
    expect(authResult).toHaveProperty('refreshToken');

    // Use refresh token to get new access token
    const refreshResult = await authService.refreshToken(authResult.refreshToken);
    expect(refreshResult).toHaveProperty('accessToken');
    expect(refreshResult.accessToken).not.toBe(authResult.accessToken);
    });
    });
  5. Integration with Existing System Components

    describe('System Integration', () => {
    test('Backward compatibility with existing services', async () => {
    // Ensure existing client service methods work unchanged
    const clients = await clientService.findAll();
    expect(clients).toBeDefined();
    expect(Array.isArray(clients)).toBe(true);

    // New authorization should not break existing functionality
    const admin = createMockUser({ role: UserRole.ADMIN });
    const clientsWithAuth = await clientService.findAll(admin);
    expect(clientsWithAuth).toEqual(clients);
    });

    test('User context preservation in all operations', async () => {
    const user = createMockUser({ role: UserRole.MANAGER, clientId: 1 });

    const client = await clientService.findOne(1, user);
    const site = await siteService.create(createSiteDto, user);
    const reclamation = await reclamationService.create(createReclamationDto, user);

    // Verify all operations are audited with user context
    const auditLogs = await auditService.getUserAuditLog(user.id);
    expect(auditLogs).toHaveLength(3);
    expect(auditLogs.every(log => log.userId === user.id)).toBe(true);
    });

    test('File operations with user authorization', async () => {
    const clientUser = createMockUser({
    role: UserRole.CLIENT_USER,
    clientId: 1
    });

    // Can upload files for own client
    const uploadResult = await fileService.uploadDocument(
    'convention.pdf',
    documentBuffer,
    { clientId: 1 },
    clientUser
    );
    expect(uploadResult).toHaveProperty('path');

    // Cannot upload files for other clients
    await expect(fileService.uploadDocument(
    'mandat.pdf',
    documentBuffer,
    { clientId: 2 },
    clientUser
    )).rejects.toThrow('Access denied');
    });
    });

Performance and Security Tests​

describe('Performance and Security', () => {
test('Authentication performance under load', async () => {
const concurrentLogins = 100;
const startTime = Date.now();

const promises = Array.from({ length: concurrentLogins }, (_, i) =>
authService.authenticate({
email: `user${i}@test.com`,
password: 'ValidP@ssw0rd123'
})
);

const results = await Promise.allSettled(promises);
const endTime = Date.now();

expect(endTime - startTime).toBeLessThan(5000); // 5 seconds max
expect(results.filter(r => r.status === 'fulfilled')).toHaveLength(concurrentLogins);
});

test('SQL injection prevention in user queries', async () => {
const maliciousEmail = "admin@test.com'; DROP TABLE users; --";

await expect(authService.authenticate({
email: maliciousEmail,
password: 'password'
})).rejects.toThrow('Invalid email format');

// Verify users table still exists
const users = await userService.findAll(createMockAdmin());
expect(users).toBeDefined();
});

test('Password hash security validation', async () => {
const password = 'SecureP@ssw0rd123';
const user = await userService.create({
email: 'test@example.com',
password,
nom: 'Test',
prenom: 'User'
}, createMockAdmin());

// Password should be hashed, not stored in plain text
expect(user.password).not.toBe(password);
expect(user.password).toMatch(/^\$2[aby]\$\d+\$/); // bcrypt pattern

// Verify password validation works
const authResult = await authService.authenticate({
email: user.email,
password
});
expect(authResult).toHaveProperty('accessToken');
});
});

Definition of Done​

Functional Requirements​

  • Enhanced User CRUD operations with comprehensive role-based authorization
  • JWT-based authentication with refresh token support and session management
  • Multi-factor authentication for administrative users operational
  • Client-User relationship management with proper access restrictions
  • Role-based access control integrated across all system entities
  • User profile management and account security features functional
  • Administrative user management tools with search, filtering, and bulk operations
  • Integration with existing ImportService and audit trail systems

Quality Requirements​

  • 98%+ test coverage for all user management and authentication logic
  • All existing service functionality preserved without breaking changes
  • Security audit completed for authentication and authorization implementation
  • Performance benchmarks met for authentication under concurrent load
  • Password security and encryption standards validated
  • Session management security and timeout policies verified
  • Comprehensive audit trail coverage for all user operations

Integration Requirements​

  • Backward compatibility verified with all existing controllers and services
  • User context properly integrated into ImportService operations
  • Client-User relationships maintained with enhanced access control
  • File upload and document management integrated with user permissions
  • All entity services updated with role-based authorization
  • Database migrations completed for user model enhancements
  • API endpoints secured with appropriate authentication and authorization

Security Requirements​

  • Authentication security measures validated (password strength, MFA, lockout)
  • Authorization system tested against privilege escalation attempts
  • Session security implemented with appropriate timeout and management
  • Audit trails comprehensive and tamper-resistant
  • Data access controls verified for client data segregation
  • Security event logging operational with appropriate alerting
  • Input validation and SQL injection prevention verified

Risk Mitigation​

Primary Risks and Mitigations​

  1. Risk: Breaking existing user-client relationships during enhancement

    • Mitigation: All database changes are additive, existing relationships preserved
    • Testing: Comprehensive migration testing with existing data validation
  2. Risk: Performance impact from authentication and authorization overhead

    • Mitigation: Efficient JWT token validation and role caching mechanisms
    • Monitoring: Real-time performance metrics for authentication endpoints
  3. Risk: Security vulnerabilities in authentication implementation

    • Mitigation: Industry-standard security practices, comprehensive security audit
    • Testing: Penetration testing and security vulnerability assessments
  4. Risk: User experience degradation from complex authorization

    • Mitigation: Intuitive role-based permissions with clear error messages
    • Validation: User acceptance testing with different role scenarios
  5. Risk: Data access control bypass or privilege escalation

    • Mitigation: Multi-layered authorization checks at service and controller levels
    • Testing: Extensive RBAC testing with attack scenario simulations

Dependencies and Assumptions​

Technical Dependencies​

  • Existing User model and Client relationships must remain functional
  • JWT library integration for secure token management
  • bcrypt or similar for password hashing and validation
  • Database support for new user security and audit fields
  • Integration with existing Prisma service patterns

Business Assumptions​

  • Role hierarchy and permissions align with business requirements
  • Client data segregation requirements are clearly defined
  • Administrative access patterns support operational needs
  • Password and security policies meet compliance requirements
  • Audit retention and security logging meet regulatory needs

Integration Assumptions​

  • All existing services can be enhanced with user context without breaking changes
  • ImportService integration maintains existing functionality
  • File upload and document management systems support user-based authorization
  • Client-User relationship patterns remain consistent
  • Audit trail integration aligns with existing logging infrastructure

Success Metrics​

Security Metrics​

  • Authentication Success Rate: > 99.9% for valid credentials
  • Security Incidents: Zero privilege escalation or unauthorized access incidents
  • Session Security: 100% session validation accuracy
  • Audit Coverage: 100% audit trail coverage for user operations

Performance Metrics​

  • Authentication Latency: < 200ms average response time
  • Authorization Check Latency: < 50ms for permission validation
  • Concurrent User Support: Support for 500+ concurrent authenticated users
  • Token Refresh Performance: < 100ms for token refresh operations

Business Metrics​

  • User Adoption: > 95% successful user onboarding
  • Role Assignment Accuracy: 100% correct role and permission assignments
  • Client Data Segregation: Zero cross-client data access violations
  • Administrative Efficiency: 80% reduction in user management time

Integration Metrics​

  • Backward Compatibility: 100% existing functionality preserved
  • Service Integration: All services successfully enhanced with user context
  • Import Operation Security: 100% import operations include user audit trails
  • File Operation Security: All file operations properly authorized

Implementation Notes​

Development Approach​

This enhancement follows a brownfield development pattern, significantly expanding the basic User model and empty UserModule into a comprehensive user management and access control system. The implementation preserves all existing Client-User relationships while adding robust authentication, authorization, and audit capabilities that integrate seamlessly with all system components.

Backward Compatibility Strategy​

All existing User model fields and Client relationships are preserved. The UserModule will be enhanced from its current empty state to include comprehensive service, controller, and authentication components. New security features are implemented as enhancements that work alongside existing patterns, ensuring zero disruption to current Client-User associations while providing significant security and management improvements.

Architecture Integration Considerations​

The user management system integrates deeply with the existing NestJS service architecture, following established patterns from ClientService and other entity services. Authentication and authorization are designed as cross-cutting concerns that enhance all existing controllers and services while maintaining their current interfaces and functionality. The role-based access control system leverages the existing Client relationships to provide appropriate data segregation and permissions.

Security Architecture Notes​

The implementation follows industry security best practices with JWT-based authentication, bcrypt password hashing, role-based authorization, and comprehensive audit logging. Multi-factor authentication is implemented for administrative users, and session management includes appropriate timeout and security policies. All user operations are logged for compliance and security monitoring, with audit trails integrated into the existing system logging infrastructure.