# RBAC Quick Start Guide ## โœ… **Implementation Complete!** Role-Based Access Control (RBAC) has been successfully implemented with **three roles**: | Role | Description | Default on Creation | |------|-------------|---------------------| | **USER** | Standard workflow participant | โœ… YES | | **MANAGEMENT** | Read access to all data | โŒ Must assign | | **ADMIN** | Full system access | โŒ Must assign | --- ## ๐Ÿš€ **Quick Start - 3 Steps** ### Step 1: Run Migration ```bash cd Re_Backend npm run migrate ``` **What it does:** - โœ… Creates `user_role_enum` type - โœ… Adds `role` column to `users` table - โœ… Migrates existing `is_admin` data to `role` - โœ… Creates index for performance --- ### Step 2: Assign Roles to Users **Option A: Via SQL Script (Recommended for initial setup)** ```bash # Edit the script first with your user emails nano scripts/assign-user-roles.sql # Run the script psql -d royal_enfield_db -f scripts/assign-user-roles.sql ``` **Option B: Via SQL Command (Quick assignment)** ```sql -- Make specific users ADMIN UPDATE users SET role = 'ADMIN', is_admin = true WHERE email IN ('admin@royalenfield.com', 'it.admin@royalenfield.com'); -- Make specific users MANAGEMENT UPDATE users SET role = 'MANAGEMENT', is_admin = false WHERE email IN ('manager@royalenfield.com', 'auditor@royalenfield.com'); -- Verify roles SELECT email, display_name, role, is_admin FROM users ORDER BY role, email; ``` **Option C: Via API (After system is running)** ```bash # Update user role (requires ADMIN token) curl -X PUT http://localhost:5000/api/v1/admin/users/{userId}/role \ -H "Authorization: Bearer YOUR_ADMIN_TOKEN" \ -H "Content-Type: application/json" \ -d '{"role": "MANAGEMENT"}' ``` --- ### Step 3: Restart Backend ```bash npm run dev # Development # or npm start # Production ``` --- ## ๐Ÿ“ก **New API Endpoints (ADMIN Only)** ### 1. Update User Role ```http PUT /api/v1/admin/users/:userId/role Authorization: Bearer {admin-token} Content-Type: application/json { "role": "MANAGEMENT" } ``` **Response:** ```json { "success": true, "message": "User role updated from USER to MANAGEMENT", "data": { "userId": "uuid", "email": "user@example.com", "role": "MANAGEMENT", "previousRole": "USER" } } ``` ### 2. Get Users by Role ```http GET /api/v1/admin/users/by-role?role=MANAGEMENT Authorization: Bearer {admin-token} ``` **Response:** ```json { "success": true, "data": [...users...], "summary": { "ADMIN": 2, "MANAGEMENT": 5, "USER": 150, "total": 157 } } ``` ### 3. Get Role Statistics ```http GET /api/v1/admin/users/role-statistics Authorization: Bearer {admin-token} ``` **Response:** ```json { "success": true, "data": [ { "role": "ADMIN", "count": 2, "active_count": 2, "inactive_count": 0 }, { "role": "MANAGEMENT", "count": 5, "active_count": 5, "inactive_count": 0 }, { "role": "USER", "count": 150, "active_count": 148, "inactive_count": 2 } ] } ``` --- ## ๐Ÿ›ก๏ธ **Using RBAC in Your Code** ### Middleware Examples ```typescript import { requireAdmin, requireManagement, requireRole } from '@middlewares/authorization.middleware'; // ADMIN only router.post('/admin/config', authenticate, requireAdmin, controller.updateConfig); // MANAGEMENT or ADMIN router.get('/reports/all', authenticate, requireManagement, controller.getAllReports); // Flexible (custom roles) router.get('/analytics', authenticate, requireRole(['MANAGEMENT', 'ADMIN']), controller.getAnalytics); ``` ### Controller Examples ```typescript import { hasManagementAccess, hasAdminAccess } from '@middlewares/authorization.middleware'; export async function getWorkflows(req: Request, res: Response) { const user = req.user; // MANAGEMENT & ADMIN: See all workflows if (hasManagementAccess(user)) { return await WorkflowRequest.findAll(); } // USER: See only own workflows return await WorkflowRequest.findAll({ where: { initiatorId: user.userId } }); } ``` --- ## ๐Ÿ“‹ **Role Permissions Matrix** | Feature | USER | MANAGEMENT | ADMIN | |---------|------|------------|-------| | Create requests | โœ… | โœ… | โœ… | | View own requests | โœ… | โœ… | โœ… | | View all requests | โŒ | โœ… Read-only | โœ… Full access | | Approve/Reject (if assigned) | โœ… | โœ… | โœ… | | Organization dashboard | โŒ | โœ… | โœ… | | Export reports | โŒ | โœ… | โœ… | | System configuration | โŒ | โŒ | โœ… | | Manage user roles | โŒ | โŒ | โœ… | | Holiday management | โŒ | โŒ | โœ… | | Audit logs | โŒ | โŒ | โœ… | --- ## ๐Ÿงช **Testing Your RBAC** ### Test 1: Verify Migration ```sql -- Check role distribution SELECT role, COUNT(*) as count FROM users GROUP BY role; -- Check specific user SELECT email, role, is_admin FROM users WHERE email = 'your-email@royalenfield.com'; ``` ### Test 2: Test API Access ```bash # Try accessing admin endpoint with USER role (should fail) curl -X GET http://localhost:5000/api/v1/admin/configurations \ -H "Authorization: Bearer {user-token}" # Expected: 403 Forbidden # Try accessing admin endpoint with ADMIN role (should succeed) curl -X GET http://localhost:5000/api/v1/admin/configurations \ -H "Authorization: Bearer {admin-token}" # Expected: 200 OK ``` --- ## ๐Ÿ”„ **Migration Path** ### Existing Code Compatibility โœ… **All existing code continues to work!** ```typescript // Old code (still works) if (user.isAdmin) { // Admin logic } // New code (recommended) if (user.role === 'ADMIN') { // Admin logic } ``` ### When to Update `is_admin` The system **automatically syncs** `is_admin` with `role`: ```typescript user.role = 'ADMIN'; โ†’ is_admin = true (auto-synced) user.role = 'USER'; โ†’ is_admin = false (auto-synced) user.role = 'MANAGEMENT'; โ†’ is_admin = false (auto-synced) ``` --- ## ๐Ÿ“ **Files Created/Modified** ### Created Files: 1. โœ… `src/migrations/20251112-add-user-roles.ts` - Database migration 2. โœ… `scripts/assign-user-roles.sql` - Role assignment script 3. โœ… `docs/RBAC_IMPLEMENTATION.md` - Full documentation 4. โœ… `docs/RBAC_QUICK_START.md` - This guide ### Modified Files: 1. โœ… `src/models/User.ts` - Added role field + helper methods 2. โœ… `src/middlewares/authorization.middleware.ts` - Added RBAC middleware 3. โœ… `src/controllers/admin.controller.ts` - Added role management endpoints 4. โœ… `src/routes/admin.routes.ts` - Added role management routes 5. โœ… `src/types/user.types.ts` - Added UserRole type 6. โœ… `backend_structure.txt` - Updated users table schema --- ## ๐ŸŽฏ **Next Steps** ### 1. Run Migration ```bash npm run migrate ``` ### 2. Assign Initial Roles ```bash # Edit with your emails nano scripts/assign-user-roles.sql # Run script psql -d royal_enfield_db -f scripts/assign-user-roles.sql ``` ### 3. Test the System ```bash # Restart backend npm run dev # Check roles curl http://localhost:5000/api/v1/admin/users/role-statistics \ -H "Authorization: Bearer {admin-token}" ``` ### 4. Update Frontend (Optional - for role-based UI) ```typescript // In AuthContext or user service interface User { role: 'USER' | 'MANAGEMENT' | 'ADMIN'; } // Show admin menu only for ADMIN {user.role === 'ADMIN' && } // Show management dashboard for MANAGEMENT + ADMIN {(user.role === 'MANAGEMENT' || user.role === 'ADMIN') && } ``` --- ## โš ๏ธ **Important Notes** 1. **Backward Compatibility**: `is_admin` field is kept but DEPRECATED 2. **Self-Demotion Prevention**: Admins cannot remove their own admin role 3. **Default Role**: All new users get 'USER' role automatically 4. **Role Sync**: `is_admin` is automatically synced with `role === 'ADMIN'` --- ## ๐Ÿ’ก **Pro Tips** ### Assign Roles by Department ```sql -- Make all IT dept users ADMIN UPDATE users SET role = 'ADMIN', is_admin = true WHERE department = 'IT' AND is_active = true; -- Make all managers MANAGEMENT role UPDATE users SET role = 'MANAGEMENT', is_admin = false WHERE designation ILIKE '%manager%' OR designation ILIKE '%head%'; ``` ### Check Your Own Role ```sql SELECT email, role, is_admin FROM users WHERE email = 'your-email@royalenfield.com'; ``` --- ## ๐Ÿ“ž **Support** For issues or questions: - **Documentation**: `docs/RBAC_IMPLEMENTATION.md` - **Migration File**: `src/migrations/20251112-add-user-roles.ts` - **Assignment Script**: `scripts/assign-user-roles.sql` **Your RBAC system is production-ready!** ๐ŸŽ‰