# Permissions and Access Control ## Purpose Explain role-based permissions, account ownership rules, and how viewsets enforce access across the stack. ## Code Locations (exact paths) - Role-based permissions: `backend/igny8_core/auth/permissions.py` - User roles and helpers: `backend/igny8_core/auth/models.py` - Account context middleware: `backend/igny8_core/auth/middleware.py` - Base viewsets with override/bypass logic: `backend/igny8_core/api/base.py` - DRF settings: `backend/igny8_core/settings.py` ## High-Level Responsibilities - Enforce role-based access (developer, owner, admin, editor, viewer, system_bot). - Enforce tenant/site/sector scoping with selective overrides for privileged roles. - Block access when accounts lack active plans. ## Detailed Behavior - Roles are stored on `User.role`; helper methods (`is_admin_or_developer`, `is_developer`, `is_system_account_user`, `has_role`) drive bypass logic. - Permission classes: - `IsOwnerOrAdmin`: allows authenticated users with roles owner/admin/developer or superuser. - `IsEditorOrAbove`: allows editor/admin/owner/developer or superuser. - `IsViewerOrAbove`: allows any authenticated user. - `AccountPermission`: ensures the user is authenticated, not a system bot unless intended, and matches object account when present; system bots bypass account checks. - Base viewsets: - `AccountModelViewSet` filters by `account` unless `is_admin_or_developer` or `is_system_account_user` is true; create sets `account` automatically; delete protects system account slugs. - `SiteSectorModelViewSet` extends filtering to `site`/`sector` when models have those fields. - Middleware: - `AccountContextMiddleware` denies requests when user lacks an account or active plan (403/402), logging out session users and returning JSON errors. - System accounts (`aws-admin`, `default-account`, `default`) and system bots are privileged; system accounts are protected from deletion. ## Data Structures / Models Involved (no code) - `User` with `role` and account FK. - `Account` with `status` and `plan` used for gating. - `SiteUserAccess` for per-site grants evaluated by `User.get_accessible_sites`. ## Execution Flow - Middleware validates account/plan and sets `request.account`. - DRF authentication sets `request.user`; permission classes on views (and base viewsets) check role/account match. - Querysets are filtered by tenant/site/sector; privileged roles may bypass filtering. - Soft-delete or delete operations respect system account protection. ## Cross-Module Interactions - All module viewsets inherit base classes, so account/site/sector scoping and role-based bypass apply uniformly. - Integration endpoints using API key auth rely on `request.site`/`request.account` set earlier. ## State Transitions (if applicable) - Account status and plan activation affect access; changing these alters middleware decisions immediately due to per-request user refresh. ## Error Handling - Middleware returns structured JSON errors for missing account or inactive plan. - Base viewsets wrap permission and validation failures into unified error responses. - Permission classes return standard DRF permission denials for unauthenticated/unauthorized users. ## Tenancy Rules - Default: filter data to `request.account`; site/sector models further constrain by site/sector. - Overrides: developers/admins/system-account users can see across accounts; system bots can access any account/object; system accounts cannot be deleted. ## Billing Rules (if applicable) - Active plan required; enforced in middleware before permission checks. ## Background Tasks / Schedulers (if applicable) - Background tasks should be invoked with account/site identifiers to maintain the same isolation rules; role checks occur at request time, not within tasks. ## Key Design Considerations - Centralize role checks to avoid per-view duplication. - Maintain middleware-first gating to prevent expensive processing before authorization. - Preserve protection of system accounts and allow ops-level overrides without compromising tenant isolation. ## How Developers Should Work With This Module - Apply permission classes (`IsOwnerOrAdmin`, `IsEditorOrAbove`, etc.) on viewsets/endpoints as needed. - Always inherit from `AccountModelViewSet`/`SiteSectorModelViewSet` for scoped data access. - Avoid bypassing middleware plan checks; if admin-only, use explicit admin routes instead. - When adding new privileged behaviors, reuse `User` role helpers and system-account detection.