Files
bambuddy/backend/app/schemas/auth.py
T
maziggy 89229a5ecc Add group-based permissions system with granular access control
Implement a full permissions system replacing simple admin/user roles:

Backend:
- Add Group model with many-to-many user relationship
- Add 50+ granular permissions (resource:action pattern)
- Create default groups: Administrators, Operators, Viewers
- Add permission-checking dependencies for route protection
- Add groups API endpoints (CRUD, user assignment)
- Add change password endpoint for users
- Update backup/restore to include groups
- Migrate existing users to groups on startup

Frontend:
- Add GroupsPage for managing groups and permissions
- Add permission helpers to AuthContext (hasPermission, hasAnyPermission)
- Add PermissionRoute component for protected routes
- Disable buttons/features based on permissions (with tooltips)
- Add change password modal in sidebar for all users
- Add forgot password info modal on login page
- Show user groups in UsersPage with group assignment

Testing:
- Add integration tests for groups API
- Add tests for user-group assignments
- Add tests for change password endpoint
- Seed default groups in test fixtures

Closes #28 #161
2026-01-31 12:50:15 +01:00

68 lines
1.4 KiB
Python

from pydantic import BaseModel
class GroupBrief(BaseModel):
"""Brief group info for embedding in user responses."""
id: int
name: str
class Config:
from_attributes = True
class LoginRequest(BaseModel):
username: str
password: str
class LoginResponse(BaseModel):
access_token: str
token_type: str = "bearer"
user: "UserResponse"
class UserCreate(BaseModel):
username: str
password: str
role: str = "user"
group_ids: list[int] | None = None
class UserUpdate(BaseModel):
username: str | None = None
password: str | None = None
role: str | None = None
is_active: bool | None = None
group_ids: list[int] | None = None
class UserResponse(BaseModel):
id: int
username: str
role: str # Deprecated, kept for backward compatibility
is_active: bool
is_admin: bool # Computed from role and group membership
groups: list[GroupBrief] = []
permissions: list[str] = [] # All permissions from groups
created_at: str
class Config:
from_attributes = True
class ChangePasswordRequest(BaseModel):
current_password: str
new_password: str
class SetupRequest(BaseModel):
auth_enabled: bool
admin_username: str | None = None
admin_password: str | None = None
class SetupResponse(BaseModel):
auth_enabled: bool
admin_created: bool | None = None