6.4 KiB
6.4 KiB
Role-Based Access Control (RBAC)
Overview
RBAC provides fine-grained permission management through a flexible role and permission model. Administrators can create custom roles, assign specific permissions, and control user access to features and resources.
Architecture
Backend Components:
RoleService: Role and permission management- Role routes (routes/roles.ts): REST API endpoints
- RBAC middleware (middleware/rbac.ts): Permission enforcement
Frontend Components:
RolesView: Main roles management pageRoleTable: Roles list with actionsRoleForm: Create/edit role dialogProtectedRoute: Route guard componentuseAuthhook: Permission checking
Database Schema
roles table:
CREATE TABLE roles (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE COLLATE NOCASE,
description TEXT,
priority INTEGER DEFAULT 0,
created_at TEXT DEFAULT (datetime('now')),
updated_at TEXT DEFAULT (datetime('now'))
);
permissions table:
CREATE TABLE permissions (
id INTEGER PRIMARY KEY AUTOINCREMENT,
name TEXT NOT NULL UNIQUE,
description TEXT,
resource TEXT NOT NULL,
action TEXT NOT NULL,
created_at TEXT DEFAULT (datetime('now'))
);
Default Permissions
| Permission | Description | Resource | Action |
|---|---|---|---|
| games.read | View and browse games | games | read |
| games.play | Play games in browser | games | play |
| games.download | Download game files | games | download |
| playlists.read | View playlists | playlists | read |
| playlists.create | Create new playlists | playlists | create |
| playlists.update | Update existing playlists | playlists | update |
| playlists.delete | Delete playlists | playlists | delete |
| users.read | View user accounts | users | read |
| users.create | Create new user accounts | users | create |
| users.update | Update user accounts | users | update |
| users.delete | Delete user accounts | users | delete |
| roles.read | View roles and permissions | roles | read |
| roles.create | Create new roles | roles | create |
| roles.update | Update roles and permissions | roles | update |
| roles.delete | Delete roles | roles | delete |
| settings.read | View system settings | settings | read |
| settings.update | Update system settings | settings | update |
| activities.read | View activity logs | activities | read |
Default Roles
Admin (priority: 100):
- All permissions granted
- Can manage users, roles, and settings
User (priority: 50):
- games.read, games.play, games.download
- playlists.read, playlists.create, playlists.update, playlists.delete
- Cannot manage users, roles, settings
Guest (priority: 0):
- games.read, playlists.read
- Read-only access only
API Endpoints
GET /api/roles
Get all roles with their permissions.
- Permission: roles.read
- Response: Array of roles with assigned permissions
GET /api/roles/:id
Get single role by ID with permissions.
- Permission: roles.read
- Response: Role object with full permission list
POST /api/roles
Create a new role with permissions.
- Permission: roles.create
- Body:
{ "name", "description", "priority", "permissionIds" } - Response: Created role (201)
PATCH /api/roles/:id
Update role metadata (name, description, priority).
- Permission: roles.update
- Response: Updated role
PUT /api/roles/:id/permissions
Update role permissions (replaces all).
- Permission: roles.update
- Body:
{ "permissionIds": [1, 2, 3] } - Response: Updated role with new permissions
DELETE /api/roles/:id
Delete a role.
- Permission: roles.delete
- Rules: Cannot delete system roles (admin, user, guest) or roles with assigned users
Frontend Permission Checking
// useAuth hook
const { hasPermission, hasAnyPermission, hasAllPermissions } = useAuth();
// Check single permission
if (hasPermission('users.create')) {
// Show create user UI
}
// Check multiple permissions (OR logic)
if (hasAnyPermission('users.create', 'roles.create')) {
// Show admin menu
}
// Check multiple permissions (AND logic)
if (hasAllPermissions('users.read', 'users.update')) {
// Show advanced user management
}
Protected Routes
<Route
path="/admin/users"
element={
<ProtectedRoute requiredPermissions={['users.read']}>
<UsersView />
</ProtectedRoute>
}
/>
Permission Caching
Performance Optimization:
- User permissions cached for 5 minutes
- Role permissions cached for 10 minutes
- Automatic cleanup every 5 minutes
- Cache invalidated when permissions change
- 90%+ reduction in database queries
Cache Management (Admin):
GET /_cache/permissions/stats- View cache statisticsPOST /_cache/permissions/clear- Manually clear cache
Best Practices
- Follow {resource}.{action} naming convention
- Grant minimum permissions needed (principle of least privilege)
- Use system roles (admin, user, guest) as foundation
- Always validate on backend even if UI hides features
- Show friendly "unauthorized" messages
- Log role and permission changes for audit trail
- Test thoroughly to verify permissions work as expected
Common Pitfalls
- Frontend checks only - Must also validate on backend
- Missing middleware - Ensure requirePermission() applied to routes
- Incorrect permission names - Must match exactly
- Stale cached permissions - Clear cache after changes
- Not checking user active status - Deactivated users should be blocked
Troubleshooting
Permission denied errors:
- Verify user has correct role
- Check role has required permission
- Validate role-permission mapping exists
- Check if user is active
UI shows unauthorized content:
- Frontend permission check may be incorrect
- Check if user permissions loaded
- Verify hasPermission() logic
- Inspect auth state in DevTools
Backend allows unauthorized access:
- Ensure requirePermission() middleware applied
- Check middleware order (auth before RBAC)
- Verify permission names match exactly
- Look for missing middleware on routes