turash/bugulma/frontend/AUTH_AND_PERMISSIONS.md

422 lines
8.8 KiB
Markdown

# Authentication, Authorization & Permissions System
## Overview
Complete authentication, authorization, and permission system for the admin panel and application.
## Architecture
### 1. Authentication (`AuthContext`)
**Location**: `contexts/AuthContext.tsx`
**Features**:
- User login/logout
- Token management (JWT)
- Server-side token validation
- User state management
- Auto-refresh user data
**User Interface**:
```typescript
interface User {
id: string;
email: string;
name: string;
role: UserRole; // 'admin' | 'user' | 'content_manager' | 'viewer'
permissions?: string[]; // Optional granular permissions from backend
}
```
**Usage**:
```tsx
import { useAuth } from '@/contexts/AuthContext';
const { user, login, logout, isAuthenticated, isLoading, refreshUser } = useAuth();
```
### 2. Permissions System (`types/permissions.ts`)
**Permission Types**:
- `organizations:*` - Organization management
- `localization:*` - Translation management
- `content:*` - Content management
- `users:*` - User management
- `analytics:*` - Analytics access
- `settings:*` - Settings management
- `system:*` - System administration
**Roles**:
- `admin` - Full access to all permissions
- `content_manager` - Content and localization management
- `viewer` - Read-only access
- `user` - Regular user (no admin permissions)
**Role-Permission Mapping**:
- Defined in `ROLE_PERMISSIONS` constant
- Easy to extend and modify
- Type-safe
### 3. Permission Hooks
#### `usePermissions()`
**Location**: `hooks/usePermissions.ts`
**Features**:
- Check single permission
- Check multiple permissions (any/all)
- Role checks (isAdmin, isContentManager, etc.)
- Memoized for performance
**Usage**:
```tsx
import { usePermissions } from '@/hooks/usePermissions';
const {
role,
checkPermission,
checkAnyPermission,
checkAllPermissions,
isAdmin,
isContentManager,
isViewer,
} = usePermissions();
// Check single permission
if (checkPermission('organizations:update')) {
// Show edit button
}
// Check multiple (any)
if (checkAnyPermission(['organizations:update', 'organizations:create'])) {
// Show action menu
}
// Check multiple (all)
if (checkAllPermissions(['organizations:read', 'organizations:update'])) {
// Show full editor
}
```
#### `useAdmin()`
**Location**: `hooks/useAdmin.ts`
**Features**:
- Combines admin context with permissions
- Convenience methods for common checks
- Admin stats access
**Usage**:
```tsx
import { useAdmin } from '@/hooks/useAdmin';
const {
isAdminMode,
adminStats,
refreshAdminStats,
canManageOrganizations,
canManageUsers,
canAccessSettings,
} = useAdmin();
```
### 4. Admin Context (`AdminContext`)
**Location**: `contexts/AdminContext.tsx`
**Features**:
- Admin-specific state
- Admin statistics (pending verifications, translations, alerts)
- Auto-refresh stats
- Only active for admin users
**Usage**:
```tsx
import { useAdmin as useAdminContext } from '@/contexts/AdminContext';
const { isAdminMode, adminStats, refreshAdminStats } = useAdminContext();
```
### 5. Route Protection Components
#### `ProtectedRoute`
**Location**: `components/auth/ProtectedRoute.tsx`
**Features**:
- Role-based protection
- Permission-based protection
- Loading states
- Redirect handling
**Usage**:
```tsx
<ProtectedRoute requiredRole="admin" permission="organizations:read">
<OrganizationsPage />
</ProtectedRoute>
```
#### `AdminRoute`
**Location**: `components/auth/AdminRoute.tsx`
**Features**:
- Specifically for admin routes
- Automatic admin role check
- Optional permission checks
- Better error messages
**Usage**:
```tsx
<AdminRoute permission="organizations:update">
<OrganizationEditPage />
</AdminRoute>
```
### 6. Permission-Based UI Components
#### `RequirePermission`
**Location**: `components/auth/RequirePermission.tsx`
**Features**:
- Conditionally render content
- Show error or fallback
- Supports multiple permissions
**Usage**:
```tsx
<RequirePermission
permission="organizations:delete"
fallback={<div>No permission</div>}
>
<DeleteButton />
</RequirePermission>
```
#### `PermissionGate`
**Location**: `components/auth/PermissionGate.tsx`
**Features**:
- Hide/show UI elements
- Lighter weight than RequirePermission
- No navigation, just conditional rendering
**Usage**:
```tsx
<PermissionGate permission="organizations:update">
<EditButton />
</PermissionGate>
```
## Provider Setup
**Location**: `providers/AppProvider.tsx`
```tsx
<AuthProvider>
<AdminProvider>
{/* Other providers */}
</AdminProvider>
</AuthProvider>
```
## Usage Examples
### Example 1: Protected Admin Route
```tsx
// In AppRouter.tsx
<Route
path="/admin/organizations"
element={
<AdminRoute permission="organizations:read">
<AdminLayout>
<OrganizationsPage />
</AdminLayout>
</AdminRoute>
}
/>
```
### Example 2: Permission-Based Button
```tsx
import { PermissionGate } from '@/components/auth';
const OrganizationActions = ({ org }) => {
return (
<div className="flex gap-2">
<PermissionGate permission="organizations:update">
<Button onClick={() => edit(org)}>Edit</Button>
</PermissionGate>
<PermissionGate permission="organizations:delete">
<Button variant="destructive" onClick={() => delete(org)}>
Delete
</Button>
</PermissionGate>
<PermissionGate permission="organizations:verify">
<Button onClick={() => verify(org)}>Verify</Button>
</PermissionGate>
</div>
);
};
```
### Example 3: Admin Dashboard with Stats
```tsx
import { useAdmin } from '@/hooks/useAdmin';
const AdminDashboard = () => {
const { adminStats, refreshAdminStats, canAccessAnalytics } = useAdmin();
return (
<div>
{adminStats && (
<div>
<p>Pending Verifications: {adminStats.pendingVerifications}</p>
<p>Pending Translations: {adminStats.pendingTranslations}</p>
</div>
)}
{canAccessAnalytics && (
<AnalyticsSection />
)}
</div>
);
};
```
### Example 4: Conditional Menu Items
```tsx
const AdminSidebar = () => {
const { checkPermission } = usePermissions();
return (
<nav>
<NavItem to="/admin/organizations">Organizations</NavItem>
{checkPermission('localization:read') && (
<NavItem to="/admin/localization">Localization</NavItem>
)}
{checkPermission('users:read') && (
<NavItem to="/admin/users">Users</NavItem>
)}
{checkPermission('settings:read') && (
<NavItem to="/admin/settings">Settings</NavItem>
)}
</nav>
);
};
```
## Backend Integration
### Token Structure
The JWT token should include:
```json
{
"user_id": "uuid",
"email": "user@example.com",
"name": "User Name",
"role": "admin",
"permissions": ["organizations:read", "organizations:update", ...]
}
```
### API Endpoints
- `POST /api/v1/auth/login` - Login
- `GET /api/v1/auth/me` - Get current user (token validation)
- `POST /api/v1/auth/logout` - Logout (optional, client-side cleanup)
### Backend Middleware
- `AuthMiddleware` - Validates JWT token
- `RequireRole` - Checks role
- Future: `RequirePermission` - Checks specific permissions
## Security Considerations
1. **Token Validation**: Always validated server-side
2. **Client-Side Checks**: UI-only, never trusted for security
3. **Permission Checks**: Backend must enforce all permissions
4. **Token Storage**: localStorage (consider httpOnly cookies for production)
5. **Auto-Refresh**: Tokens should be refreshed before expiry
6. **Logout**: Clears all auth-related storage
## Future Enhancements
1. **Granular Permissions from Backend**: Support for user-specific permissions
2. **Permission Groups**: Group permissions for easier management
3. **Audit Logging**: Track permission checks and access attempts
4. **Token Refresh**: Automatic token refresh before expiry
5. **Multi-Factor Authentication**: 2FA support
6. **Session Management**: Multiple active sessions
7. **Role Hierarchy**: Support for role inheritance
## Migration Notes
### Updating Existing Code
1. **Replace role checks**:
```tsx
// Old
{user?.role === 'admin' && <AdminButton />}
// New
<PermissionGate permission="organizations:update">
<AdminButton />
</PermissionGate>
```
2. **Update ProtectedRoute usage**:
```tsx
// Old
<ProtectedRoute requiredRole="admin">
<AdminPage />
</ProtectedRoute>
// New (for admin routes)
<AdminRoute permission="organizations:read">
<AdminPage />
</AdminRoute>
```
3. **Use permission hooks**:
```tsx
// Old
const isAdmin = user?.role === 'admin';
// New
const { isAdmin, checkPermission } = usePermissions();
```
## Testing
### Unit Tests Needed
- Permission checking logic
- Role-to-permission mapping
- Route protection components
- Permission gate components
### Integration Tests Needed
- Login flow
- Token validation
- Permission-based UI rendering
- Route protection
- Admin context state