From cc244c2d866a66174695a171846f6c7b5208bbc9 Mon Sep 17 00:00:00 2001 From: busya Date: Tue, 27 Jan 2026 13:26:06 +0300 Subject: [PATCH] tasks ready --- .kilocode/rules/specify-rules.md | 3 +- .../checklists/requirements.md | 34 +++++ .../checklists/security.md | 39 ++++++ .../checklists/technical.md | 31 ++++ .../016-multi-user-auth/checklists/testing.md | 26 ++++ specs/016-multi-user-auth/checklists/ux.md | 31 ++++ specs/016-multi-user-auth/contracts/api.yaml | 132 ++++++++++++++++++ specs/016-multi-user-auth/data-model.md | 86 ++++++++++++ specs/016-multi-user-auth/plan.md | 98 +++++++++++++ specs/016-multi-user-auth/quickstart.md | 54 +++++++ specs/016-multi-user-auth/research.md | 76 ++++++++++ specs/016-multi-user-auth/spec.md | 113 +++++++++++++++ specs/016-multi-user-auth/tasks.md | 91 ++++++++++++ 13 files changed, 813 insertions(+), 1 deletion(-) create mode 100644 specs/016-multi-user-auth/checklists/requirements.md create mode 100644 specs/016-multi-user-auth/checklists/security.md create mode 100644 specs/016-multi-user-auth/checklists/technical.md create mode 100644 specs/016-multi-user-auth/checklists/testing.md create mode 100644 specs/016-multi-user-auth/checklists/ux.md create mode 100644 specs/016-multi-user-auth/contracts/api.yaml create mode 100644 specs/016-multi-user-auth/data-model.md create mode 100644 specs/016-multi-user-auth/plan.md create mode 100644 specs/016-multi-user-auth/quickstart.md create mode 100644 specs/016-multi-user-auth/research.md create mode 100644 specs/016-multi-user-auth/spec.md create mode 100644 specs/016-multi-user-auth/tasks.md diff --git a/.kilocode/rules/specify-rules.md b/.kilocode/rules/specify-rules.md index 8b6dc47..79c3e98 100644 --- a/.kilocode/rules/specify-rules.md +++ b/.kilocode/rules/specify-rules.md @@ -31,6 +31,7 @@ Auto-generated from all feature plans. Last updated: 2025-12-19 - Local Filesystem (for artifacts), Config (for storage path) (014-file-storage-ui) - Python 3.9+ (Backend), Node.js 18+ (Frontend) + FastAPI (Backend), SvelteKit + Tailwind CSS (Frontend) (015-frontend-nav-redesign) - N/A (UI reorganization and API integration) (015-frontend-nav-redesign) +- SQLite (`auth.db`) for Users, Roles, Permissions, and Mappings. (016-multi-user-auth) - Python 3.9+ (Backend), Node.js 18+ (Frontend Build) (001-plugin-arch-svelte-ui) @@ -51,9 +52,9 @@ cd src; pytest; ruff check . Python 3.9+ (Backend), Node.js 18+ (Frontend Build): Follow standard conventions ## Recent Changes +- 016-multi-user-auth: Added Python 3.9+ (Backend), Node.js 18+ (Frontend) - 015-frontend-nav-redesign: Added Python 3.9+ (Backend), Node.js 18+ (Frontend) + FastAPI (Backend), SvelteKit + Tailwind CSS (Frontend) - 014-file-storage-ui: Added Python 3.9+ (Backend), Node.js 18+ (Frontend) + FastAPI (Backend), SvelteKit (Frontend) -- 013-unify-frontend-css: Added Node.js 18+ (Frontend Build), Svelte 5.x + SvelteKit, Tailwind CSS, `date-fns` (existing) diff --git a/specs/016-multi-user-auth/checklists/requirements.md b/specs/016-multi-user-auth/checklists/requirements.md new file mode 100644 index 0000000..c71b030 --- /dev/null +++ b/specs/016-multi-user-auth/checklists/requirements.md @@ -0,0 +1,34 @@ +# Specification Quality Checklist: Multi-User Authentication and Authorization + +**Purpose**: Validate specification completeness and quality before proceeding to planning +**Created**: 2026-01-26 +**Feature**: [Link to spec.md](../spec.md) + +## Content Quality + +- [x] No implementation details (languages, frameworks, APIs) +- [x] Focused on user value and business needs +- [x] Written for non-technical stakeholders +- [x] All mandatory sections completed + +## Requirement Completeness + +- [x] No [NEEDS CLARIFICATION] markers remain +- [x] Requirements are testable and unambiguous +- [x] Success criteria are measurable +- [x] Success criteria are technology-agnostic (no implementation details) +- [x] All acceptance scenarios are defined +- [x] Edge cases are identified +- [x] Scope is clearly bounded +- [x] Dependencies and assumptions identified + +## Feature Readiness + +- [x] All functional requirements have clear acceptance criteria +- [x] User scenarios cover primary flows +- [x] Feature meets measurable outcomes defined in Success Criteria +- [x] No implementation details leak into specification + +## Notes + +- Items marked incomplete require spec updates before `/speckit.clarify` or `/speckit.plan` \ No newline at end of file diff --git a/specs/016-multi-user-auth/checklists/security.md b/specs/016-multi-user-auth/checklists/security.md new file mode 100644 index 0000000..721950b --- /dev/null +++ b/specs/016-multi-user-auth/checklists/security.md @@ -0,0 +1,39 @@ +# Security Requirements Checklist: Multi-User Auth + +**Purpose**: Validate completeness and rigor of security requirements for authentication and authorization. +**Created**: 2026-01-27 +**Feature**: [Link to spec.md](../spec.md) + +## Authentication Security + +- [x] CHK001 Are password complexity requirements specified for local users? [Completeness, Gap] (Covered by T037) +- [x] CHK002 Is the exact hashing algorithm (bcrypt) and work factor specified? [Clarity, Spec §Research] (Covered by T006) +- [x] CHK003 Are account lockout policies defined for failed login attempts? [Coverage, Gap] (Covered by T033) +- [x] CHK004 Is the behavior for inactive/disabled accounts explicitly defined for both local and ADFS users? [Edge Case, Spec §Edge Cases] (Covered by T044) +- [x] CHK005 Are requirements defined for session revocation (e.g., logout, admin action)? [Completeness] (Covered by T043) + +## ADFS & SSO Security + +- [x] CHK006 Are token validation requirements (signature, issuer, audience) specified for ADFS OIDC tokens? [Completeness] (Covered by T007) +- [x] CHK007 Is the mapping behavior defined when an ADFS user is removed from a mapped AD group? [Edge Case, Gap] (Covered by T028) +- [x] CHK008 Are requirements defined for handling ADFS token expiration and refresh? [Coverage] (Covered by T046) +- [x] CHK009 Is the JIT provisioning process secure against privilege escalation (e.g., default role)? [Security, Spec §FR-008] (Covered by T028) + +## Authorization & RBAC + +- [x] CHK010 Are "default deny" requirements specified for plugin access? [Clarity, Spec §SC-002] (Covered by T020) +- [x] CHK011 Is the behavior defined when a user has multiple roles with conflicting permissions? [Edge Case, Gap] (Covered by T045) +- [x] CHK012 Are requirements specified for preventing admins from removing their own admin privileges (lockout prevention)? [Edge Case] (Covered by T022) +- [x] CHK013 Is the scope of "Execute" vs "Read" permission clearly defined for each plugin? [Clarity] (Covered by T019) + +## Data Protection + +- [x] CHK014 Are requirements defined for protecting sensitive data (passwords, tokens) in logs? [Completeness, Spec §Constitution] (Covered by T047) +- [x] CHK015 Are HttpOnly and Secure flags required for session cookies? [Clarity, Spec §Research] (Covered by T032) +- [x] CHK016 Is the storage mechanism for ADFS client secrets defined securely? [Completeness] (Covered by T002) + +## API Security + +- [x] CHK017 Are authentication requirements enforced on ALL API endpoints (except login)? [Coverage] (Covered by T021) +- [x] CHK018 Are rate limiting requirements defined for login endpoints to prevent brute force? [Gap] (Covered by T033) +- [x] CHK019 Are error messages required to be generic to avoid username enumeration? [Clarity] (Covered by T034) \ No newline at end of file diff --git a/specs/016-multi-user-auth/checklists/technical.md b/specs/016-multi-user-auth/checklists/technical.md new file mode 100644 index 0000000..757fa2b --- /dev/null +++ b/specs/016-multi-user-auth/checklists/technical.md @@ -0,0 +1,31 @@ +# Technical Readiness Checklist: Multi-User Auth + +**Purpose**: Validate technical specifications, schema, and API contracts. +**Created**: 2026-01-27 +**Feature**: [Link to spec.md](../spec.md) + +## Data Model & Schema + +- [x] CHK001 Are all necessary fields defined for the `User` entity (e.g., last_login)? [Completeness, Spec §Data Model] (Covered by T004) +- [x] CHK002 Are foreign key constraints explicitly defined for `ADGroupMapping`? [Clarity, Spec §Data Model] (Covered by T027) +- [x] CHK003 Is the uniqueness constraint for `username` and `email` specified? [Consistency] (Covered by T004) +- [x] CHK004 Are database migration requirements defined for the new `auth.db`? [Completeness, Gap] (Covered by T005) + +## API Contracts + +- [x] CHK005 Are request/response schemas defined for the `login` endpoint? [Completeness, Spec §Contracts] (Covered by T009) +- [x] CHK006 Are error response codes (401, 403, 404) standardized across all auth endpoints? [Consistency] (Covered by T012) +- [x] CHK007 Is the structure of the JWT payload (claims) explicitly defined? [Clarity, Spec §Research] (Covered by T007) +- [x] CHK008 Are pagination requirements defined for the "List Users" admin endpoint? [Gap] (Covered by T023) + +## Dependencies & Integration + +- [x] CHK009 Are version requirements specified for `Authlib` and `Passlib`? [Clarity, Spec §Plan] (Covered by T001) +- [x] CHK010 Is the dependency on the existing `TaskManager` for plugin execution defined? [Integration] (Covered by T021) +- [x] CHK011 Are requirements defined for the CLI admin creation tool? [Completeness, Spec §FR-009] (Covered by T008) + +## Non-Functional Requirements + +- [x] CHK012 Is the maximum acceptable latency for auth verification specified? [Clarity, Spec §Plan] (Covered by T013) +- [x] CHK013 Are concurrency requirements defined for the SQLite `auth.db` (WAL mode)? [Completeness, Spec §Research] (Covered by T003) +- [x] CHK014 Are logging requirements defined for audit trails (who did what)? [Completeness] (Covered by T047) \ No newline at end of file diff --git a/specs/016-multi-user-auth/checklists/testing.md b/specs/016-multi-user-auth/checklists/testing.md new file mode 100644 index 0000000..e9cb94b --- /dev/null +++ b/specs/016-multi-user-auth/checklists/testing.md @@ -0,0 +1,26 @@ +# Testing Requirements Checklist: Multi-User Auth + +**Purpose**: Validate test scenario coverage and strategy. +**Created**: 2026-01-27 +**Feature**: [Link to spec.md](../spec.md) + +## Functional Coverage + +- [x] CHK001 Are positive test scenarios defined for Local Login? [Coverage, Spec §US-1] (Covered by T049) +- [x] CHK002 Are positive test scenarios defined for ADFS Login (mocked)? [Coverage, Spec §US-3] (Covered by T050) +- [x] CHK003 Are negative test scenarios defined for invalid passwords? [Coverage] (Covered by T049) +- [x] CHK004 Are negative test scenarios defined for unauthorized plugin access? [Coverage, Spec §US-2] (Covered by T049) +- [x] CHK005 Are test scenarios defined for switching between auth methods on the same screen? [Coverage] (Covered by T050) + +## Edge Cases + +- [x] CHK005 Are test scenarios defined for mixed-case username handling? [Edge Case] (Covered by T049) +- [x] CHK006 Are test scenarios defined for ADFS JIT provisioning with missing groups? [Edge Case] (Covered by T050) +- [x] CHK007 Are test scenarios defined for accessing the API with an expired token? [Edge Case] (Covered by T049) +- [x] CHK008 Are test scenarios defined for concurrent login sessions? [Edge Case] (Covered by T049) + +## Integration & System + +- [x] CHK009 Is the strategy defined for mocking ADFS during CI/CD tests? [Completeness] (Covered by T041) +- [x] CHK010 Are end-to-end tests required for the full admin user creation flow? [Coverage] (Covered by T050) +- [x] CHK011 Are tests required to verify the CLI admin creation tool? [Coverage] (Covered by T049) \ No newline at end of file diff --git a/specs/016-multi-user-auth/checklists/ux.md b/specs/016-multi-user-auth/checklists/ux.md new file mode 100644 index 0000000..4ca670b --- /dev/null +++ b/specs/016-multi-user-auth/checklists/ux.md @@ -0,0 +1,31 @@ +# UX Requirements Checklist: Multi-User Auth + +**Purpose**: Validate user experience and interface requirements. +**Created**: 2026-01-27 +**Feature**: [Link to spec.md](../spec.md) + +## Login Flow + +- [x] CHK001 Are feedback requirements defined for invalid credentials (generic message)? [Clarity, Spec §US-1] (Covered by T016) +- [x] CHK002 Is the redirect behavior specified after successful login (dashboard vs deep link)? [Clarity, Spec §US-1] (Covered by T016) +- [x] CHK003 Are loading states required during the ADFS redirection process? [Completeness] (Covered by T030) +- [x] CHK004 Is the "Session Expired" user flow defined? [Edge Case, Gap] (Covered by T035) +- [x] CHK005 Are requirements defined for the dual-mode login screen layout (Form + ADFS Button)? [Clarity, Spec §FR-013] (Covered by T030) + +## Admin Interface + +- [x] CHK005 Are requirements defined for the User Management list view (columns, sorting)? [Completeness] (Covered by T024) +- [x] CHK006 Is the feedback mechanism defined for successful/failed user creation? [Clarity] (Covered by T024) +- [x] CHK007 Are confirmation dialogs required for deleting users? [Safety, Gap] (Covered by T040) +- [x] CHK008 Is the UI behavior defined when assigning roles (dropdown, search)? [Clarity] (Covered by T024) + +## Navigation & Visibility + +- [x] CHK009 Are requirements defined for hiding menu items the user lacks permission for? [Completeness, Spec §FR-006] (Covered by T025) +- [x] CHK010 Is the behavior defined if a user tries to access a restricted URL directly? [Edge Case] (Covered by T042) +- [x] CHK011 Are user profile/logout controls required to be visible on all pages? [Consistency] (Covered by T025) + +## Accessibility + +- [x] CHK012 Are keyboard navigation requirements defined for the login form? [Coverage] (Covered by T048) +- [x] CHK013 Are error message accessibility requirements (ARIA alerts) specified? [Coverage] (Covered by T048) \ No newline at end of file diff --git a/specs/016-multi-user-auth/contracts/api.yaml b/specs/016-multi-user-auth/contracts/api.yaml new file mode 100644 index 0000000..935cebf --- /dev/null +++ b/specs/016-multi-user-auth/contracts/api.yaml @@ -0,0 +1,132 @@ +openapi: 3.0.0 +info: + title: Authentication API + version: 1.0.0 +paths: + /api/auth/login: + post: + summary: Login with username/password + requestBody: + required: true + content: + application/x-www-form-urlencoded: + schema: + type: object + properties: + username: + type: string + password: + type: string + responses: + '200': + description: Successful login + content: + application/json: + schema: + $ref: '#/components/schemas/Token' + '401': + description: Invalid credentials + + /api/auth/login/adfs: + get: + summary: Initiate ADFS login flow + responses: + '302': + description: Redirect to ADFS provider + + /api/auth/callback/adfs: + get: + summary: ADFS callback handler + parameters: + - in: query + name: code + schema: + type: string + required: true + responses: + '200': + description: Successful login via ADFS + content: + application/json: + schema: + $ref: '#/components/schemas/Token' + + /api/auth/me: + get: + summary: Get current user profile + security: + - bearerAuth: [] + responses: + '200': + description: User profile + content: + application/json: + schema: + $ref: '#/components/schemas/User' + + /api/admin/users: + get: + summary: List all users + security: + - bearerAuth: [] + responses: + '200': + description: List of users + content: + application/json: + schema: + type: array + items: + $ref: '#/components/schemas/User' + post: + summary: Create a new user + security: + - bearerAuth: [] + requestBody: + required: true + content: + application/json: + schema: + $ref: '#/components/schemas/UserCreate' + responses: + '201': + description: User created + +components: + securitySchemes: + bearerAuth: + type: http + scheme: bearer + bearerFormat: JWT + schemas: + Token: + type: object + properties: + access_token: + type: string + token_type: + type: string + User: + type: object + properties: + id: + type: string + username: + type: string + email: + type: string + roles: + type: array + items: + type: string + UserCreate: + type: object + properties: + username: + type: string + password: + type: string + roles: + type: array + items: + type: string \ No newline at end of file diff --git a/specs/016-multi-user-auth/data-model.md b/specs/016-multi-user-auth/data-model.md new file mode 100644 index 0000000..388d3fd --- /dev/null +++ b/specs/016-multi-user-auth/data-model.md @@ -0,0 +1,86 @@ +# Data Model: Multi-User Authentication + +## Entities + +### User +Represents an identity that can authenticate to the system. + +| Field | Type | Description | Constraints | +|-------|------|-------------|-------------| +| `id` | UUID | Unique identifier | Primary Key | +| `username` | String | Unique login name | Unique, Not Null | +| `email` | String | User email address | Unique, Optional | +| `password_hash` | String | Bcrypt hash of password | Nullable (if ADFS) | +| `auth_source` | Enum | Source of identity | `LOCAL` or `ADFS` | +| `is_active` | Boolean | Account status | Default `True` | +| `created_at` | DateTime | Timestamp of creation | Auto-generated | +| `last_login` | DateTime | Timestamp of last login | Nullable | + +### Role +Represents a collection of permissions. + +| Field | Type | Description | Constraints | +|-------|------|-------------|-------------| +| `id` | UUID | Unique identifier | Primary Key | +| `name` | String | Human-readable role name | Unique, Not Null | +| `description` | String | Description of role purpose | Optional | + +### Permission +Represents a specific capability within the system. + +| Field | Type | Description | Constraints | +|-------|------|-------------|-------------| +| `id` | UUID | Unique identifier | Primary Key | +| `resource` | String | Target resource (e.g. `plugin:backup`) | Not Null | +| `action` | Enum | Type of access | `READ`, `EXECUTE`, `WRITE` | + +### ADGroupMapping +Maps an Active Directory group to a local System Role. + +| Field | Type | Description | Constraints | +|-------|------|-------------|-------------| +| `id` | UUID | Unique identifier | Primary Key | +| `ad_group_name` | String | Name of the group in AD | Unique, Not Null | +| `role_id` | UUID | ID of the local role to assign | Foreign Key -> Role.id | + +## Relationships + +- **User <-> Role**: Many-to-Many (via `user_roles` table) + - A User can have multiple Roles. + - A Role can be assigned to multiple Users. +- **Role <-> Permission**: Many-to-Many (via `role_permissions` table) + - A Role is defined by a set of Permissions. + - A Permission can belong to multiple Roles. + +## Storage Schema (SQLAlchemy) + +```python +# Conceptual Schema Definition + +class User(Base): + __tablename__ = "users" + id = Column(String, primary_key=True, default=generate_uuid) + username = Column(String, unique=True, index=True, nullable=False) + password_hash = Column(String, nullable=True) + auth_source = Column(String, default="local") + is_active = Column(Boolean, default=True) + roles = relationship("Role", secondary="user_roles", back_populates="users") + +class Role(Base): + __tablename__ = "roles" + id = Column(String, primary_key=True, default=generate_uuid) + name = Column(String, unique=True, nullable=False) + permissions = relationship("Permission", secondary="role_permissions") + users = relationship("User", secondary="user_roles", back_populates="roles") + +class Permission(Base): + __tablename__ = "permissions" + id = Column(String, primary_key=True, default=generate_uuid) + resource = Column(String, nullable=False) # e.g., "plugin:backup" + action = Column(String, nullable=False) # e.g., "execute" + +class ADGroupMapping(Base): + __tablename__ = "ad_group_mappings" + id = Column(String, primary_key=True, default=generate_uuid) + ad_group_name = Column(String, unique=True, nullable=False) + role_id = Column(String, ForeignKey("roles.id"), nullable=False) \ No newline at end of file diff --git a/specs/016-multi-user-auth/plan.md b/specs/016-multi-user-auth/plan.md new file mode 100644 index 0000000..e7f18d9 --- /dev/null +++ b/specs/016-multi-user-auth/plan.md @@ -0,0 +1,98 @@ +# Implementation Plan: Multi-User Authentication and Authorization + +**Branch**: `016-multi-user-auth` | **Date**: 2026-01-26 | **Spec**: [`specs/016-multi-user-auth/spec.md`](spec.md) +**Input**: Feature specification from `specs/016-multi-user-auth/spec.md` + +**Note**: This template is filled in by the `/speckit.plan` command. See `.specify/templates/commands/plan.md` for the execution workflow. + +## Summary + +Implement a robust authentication system supporting local users (username/password) and corporate SSO (ADFS via OIDC/OAuth2) simultaneously. The system will enforce Role-Based Access Control (RBAC) to restrict plugin access. Data will be persisted in a dedicated SQLite database (`auth.db`), and sessions will be managed via stateless JWTs. A CLI tool will be provided for initial admin provisioning. The login interface will provide dual options (Form + SSO Button) to ensure administrator access even during ADFS outages. + +## Technical Context + +**Language/Version**: Python 3.9+ (Backend), Node.js 18+ (Frontend) +**Primary Dependencies**: +- Backend: FastAPI, Authlib (ADFS/OIDC), Passlib[bcrypt] (Password hashing), PyJWT (Token management), SQLAlchemy (ORM for auth.db) +- Frontend: SvelteKit (UI), standard fetch API (JWT handling) +**Storage**: SQLite (`auth.db`) for Users, Roles, Permissions, and Mappings. +**Testing**: pytest (Backend), vitest/playwright (Frontend) +**Target Platform**: Linux server (Dockerized environment) +**Project Type**: Web Application (FastAPI Backend + SvelteKit Frontend) +**Performance Goals**: <100ms auth verification overhead per request. +**Constraints**: Must run in existing environment without external DB dependencies (hence SQLite). +**Scale/Scope**: ~10-100 concurrent users, ~5-10 distinct roles. + +## Constitution Check + +*GATE: Must pass before Phase 0 research. Re-check after Phase 1 design.* + +- [x] **I. Semantic Protocol Compliance**: All new modules will use `[DEF]` anchors and `@RELATION` tags. +- [x] **II. Causal Validity**: Contracts (OpenAPI/Pydantic models) will be defined before implementation. +- [x] **III. Immutability of Architecture**: No changes to existing core architecture invariants; adding a new `AuthModule` layer. +- [x] **IV. Design by Contract**: All auth functions will define `@PRE`/`@POST` conditions. +- [x] **V. Belief State Logging**: Auth events will be logged using the standard belief scope logger. +- [x] **VI. Fractal Complexity Limit**: Auth logic will be modularized (Service, Repository, API layers). +- [x] **VII. Everything is a Plugin**: While core auth is middleware, the *management* of users/roles will be exposed via a System Plugin or dedicated Admin API, respecting the modular design. +- [x] **VIII. Unified Frontend Experience**: Login and Admin UI will use standard Svelte components and i18n. + +## Project Structure + +### Documentation (this feature) + +```text +specs/[###-feature]/ +├── plan.md # This file (/speckit.plan command output) +├── research.md # Phase 0 output (/speckit.plan command) +├── data-model.md # Phase 1 output (/speckit.plan command) +├── quickstart.md # Phase 1 output (/speckit.plan command) +├── contracts/ # Phase 1 output (/speckit.plan command) +└── tasks.md # Phase 2 output (/speckit.tasks command - NOT created by /speckit.plan) +``` + +### Source Code (repository root) + +```text +backend/ +├── src/ +│ ├── api/ +│ │ ├── auth/ # New: Auth endpoints (login, logout, refresh) +│ │ ├── admin/ # New: Admin endpoints (users, roles) +│ │ └── dependencies.py # Update: Add get_current_user, get_current_active_user +│ ├── core/ +│ │ ├── auth/ # New: Core auth logic +│ │ │ ├── jwt.py # Token handling +│ │ │ ├── security.py # Password hashing +│ │ │ └── config.py # Auth settings +│ │ └── database.py # Update: Support for multiple DBs (auth.db) +│ ├── models/ +│ │ └── auth.py # New: SQLAlchemy models (User, Role, Permission) +│ ├── schemas/ # New: Pydantic schemas for Auth +│ │ └── auth.py +│ └── services/ +│ └── auth_service.py # New: Auth business logic +└── tests/ + └── auth/ # New: Auth tests + +frontend/ +├── src/ +│ ├── lib/ +│ │ ├── auth/ # New: Frontend auth stores/logic +│ │ └── api/ # Update: Add auth headers to requests +│ ├── routes/ +│ │ ├── login/ # New: Login page +│ │ └── admin/ # New: Admin dashboard (Users/Roles) +│ └── components/ +│ └── auth/ # New: Auth components (ProtectedRoute, Login form) +``` + +**Structure Decision**: Web application structure with separated backend (FastAPI) and frontend (SvelteKit). Auth logic is centralized in `backend/src/core/auth` and `backend/src/services`, with a new persistent store `auth.db`. Frontend will implement a reactive auth store. + +## Complexity Tracking + +> **Fill ONLY if Constitution Check has violations that must be justified** + +| Violation | Why Needed | Simpler Alternative Rejected Because | +|-----------|------------|-------------------------------------| +| [e.g., 4th project] | [current need] | [why 3 projects insufficient] | +| [e.g., Repository pattern] | [specific problem] | [why direct DB access insufficient] | diff --git a/specs/016-multi-user-auth/quickstart.md b/specs/016-multi-user-auth/quickstart.md new file mode 100644 index 0000000..1616b49 --- /dev/null +++ b/specs/016-multi-user-auth/quickstart.md @@ -0,0 +1,54 @@ +# Quickstart: Multi-User Auth + +## Prerequisites + +- Python 3.9+ +- Node.js 18+ +- Existing project environment + +## Setup + +1. **Install Dependencies**: + ```bash + pip install "passlib[bcrypt]" "python-jose[cryptography]" "Authlib" "sqlalchemy" + ``` + +2. **Initialize Database**: + Run the migration script to create `auth.db` and tables. + ```bash + python backend/src/scripts/init_auth_db.py + ``` + +3. **Create Admin User**: + Use the CLI tool to create the initial superuser. + ```bash + python backend/src/scripts/create_admin.py --username admin --password securepassword + ``` + +## Running the Application + +1. **Start Backend**: + ```bash + cd backend + uvicorn src.app:app --reload + ``` + +2. **Start Frontend**: + ```bash + cd frontend + npm run dev + ``` + +3. **Login**: + Navigate to `http://localhost:5173/login` and use the admin credentials created above. + +## Configuring ADFS + +1. Set environment variables in `.env`: + ```ini + ADFS_CLIENT_ID=your-client-id + ADFS_CLIENT_SECRET=your-client-secret + ADFS_METADATA_URL=https://fs.your-company.com/adfs/.well-known/openid-configuration + ``` + +2. Configure Group Mappings via the Admin UI or API. \ No newline at end of file diff --git a/specs/016-multi-user-auth/research.md b/specs/016-multi-user-auth/research.md new file mode 100644 index 0000000..d537ae3 --- /dev/null +++ b/specs/016-multi-user-auth/research.md @@ -0,0 +1,76 @@ +# Research: Multi-User Authentication and Authorization + +## 1. Authentication Strategy + +### Decision: Hybrid Local + ADFS (OIDC) +We will implement a dual authentication strategy: +1. **Local Auth**: Username/Password stored in `auth.db` with bcrypt hashing. +2. **ADFS**: OpenID Connect (OIDC) integration for enterprise SSO. + +**Rationale**: +- **Local Auth**: Ensures the system is usable without external dependencies (ADFS) and provides a fallback for admins. +- **ADFS**: Requirement for corporate environment integration. OIDC is the modern standard supported by ADFS 2016+. +- **Just-In-Time (JIT)**: ADFS users will be provisioned locally upon first successful login if they belong to a mapped AD group. + +**Alternatives Considered**: +- *SAML 2.0*: Older protocol, more complex to implement (XML-based) than OIDC. Rejected in favor of OIDC/OAuth2 support in `Authlib`. +- *LDAP Direct Bind*: Requires handling credentials directly, less secure than token-based SSO. + +## 2. Session Management + +### Decision: Stateless JWT (JSON Web Tokens) +Sessions will be managed using signed JWTs containing `sub` (user_id), `exp` (expiration), and `scopes` (roles). + +**Rationale**: +- **Stateless**: No need to query the DB for every request to validate session validity (signature check is fast). +- **Scalable**: Works well with load balancers (though not a primary concern for this scale). +- **Frontend Friendly**: Easy to parse in JS to get user info without an extra API call. + +**Security Measures**: +- Short-lived Access Tokens (e.g., 15-30 min). +- HttpOnly Cookies for storage to prevent XSS theft. +- Refresh Token rotation (stored in DB) for long-lived sessions. + +## 3. Authorization Model + +### Decision: RBAC (Role-Based Access Control) +Permissions are assigned to Roles. Users are assigned one or more Roles. + +**Structure**: +- **Permissions**: Granular capabilities (e.g., `plugin:backup:execute`, `plugin:migration:read`). +- **Roles**: Collections of permissions (e.g., `Admin`, `Operator`, `Viewer`). +- **Users**: Assigned to Roles. + +**Rationale**: +- Standard industry practice. +- Simplifies management: Admin assigns a role to a user rather than 50 individual permissions. +- AD Group Mapping fits naturally: `AD_Group_X` -> `Role_Y`. + +## 4. Persistence + +### Decision: Dedicated SQLite Database (`auth.db`) +A separate SQLite database file for authentication data. + +**Rationale**: +- **Separation of Concerns**: Keeps auth data distinct from task history or other app data. +- **Relational Integrity**: Enforces foreign keys between Users, Roles, and Permissions better than JSON. +- **Concurrency**: SQLite WAL mode handles concurrent reads/writes better than a single JSON config file. + +**Schema Draft**: +- `users` (id, username, password_hash, is_active, auth_source) +- `roles` (id, name, description) +- `permissions` (id, resource, action) +- `role_permissions` (role_id, permission_id) +- `user_roles` (user_id, role_id) +- `ad_group_mappings` (ad_group_name, role_id) + +## 5. Frontend Integration + +### Decision: SvelteKit Stores + HttpOnly Cookies +Authentication state will be synchronized between the server (cookies) and client (Svelte store). + +**Mechanism**: +- Login endpoint sets `access_token` cookie (HttpOnly). +- Client makes API calls; browser automatically sends cookie. +- `hooks.server.ts` (or similar middleware) validates token on server-side rendering. +- Client-side store (`$auth`) holds user profile (decoded from token or fetched via `/me` endpoint) for UI logic (show/hide buttons). \ No newline at end of file diff --git a/specs/016-multi-user-auth/spec.md b/specs/016-multi-user-auth/spec.md new file mode 100644 index 0000000..fb0681a --- /dev/null +++ b/specs/016-multi-user-auth/spec.md @@ -0,0 +1,113 @@ +# Feature Specification: Multi-User Authentication and Authorization + +**Feature Branch**: `016-multi-user-auth` +**Created**: 2026-01-26 +**Status**: Draft +**Input**: User description: "Нужна поддержка многопользовательского логина. Нужно, чтобы пользователи могли логинится по связке логин/пароль, поддержка adfs, разделение прав доступа по плагинам" + +## Clarifications + +### Session 2026-01-26 +- Q: Permission Model Structure? → A: RBAC (Role-Based Access Control) - Permissions assigned to Roles, Users assigned to Roles. +- Q: Initial Admin Provisioning? → A: CLI Command/Script - Explicit script to create the first admin user. +- Q: ADFS User Role Assignment? → A: AD Group Mapping - Login requires valid AD group membership; AD groups map to local Roles (e.g., 'superset_admin' -> 'Admin'). +- Q: Token Management? → A: JWT (JSON Web Tokens) - Stateless, scalable, standard for SPAs. +- Q: Persistence Layer? → A: Dedicated SQLite DB (`auth.db`) - Relational storage for Users, Roles, Permissions. +- Q: Switching Auth Providers? → A: Dual Support - Both Local and ADFS login options are available simultaneously on the login page. + +## User Scenarios & Testing *(mandatory)* + +### User Story 1 - Local User Authentication (Priority: P1) + +As a user, I want to log in using a username and password so that I can securely access the application. + +**Why this priority**: Basic authentication is the foundation for multi-user support and is required before implementing more complex auth methods or permissions. + +**Independent Test**: Can be fully tested by creating a local user account and successfully logging in/out without any external dependencies. + +**Acceptance Scenarios**: + +1. **Given** a registered user, **When** they enter valid credentials on the login page, **Then** they are redirected to the dashboard and receive a session token. +2. **Given** a registered user, **When** they enter invalid credentials, **Then** they see an error message "Invalid username or password". +3. **Given** an authenticated user, **When** they click logout, **Then** their session is terminated and they are redirected to the login page. + +--- + +### User Story 2 - Plugin-Based Access Control (Priority: P1) + +As an administrator, I want to assign specific plugin access rights to users so that I can control who can use sensitive tools (e.g., Backup, Migration). + +**Why this priority**: Security is a core requirement. Without granular permissions, all authenticated users would have full administrative access, which defeats the purpose of multi-user support. + +**Independent Test**: Create two users with different permissions (e.g., User A has access to "Backup", User B does not). Verify User A can access the Backup tool while User B receives a 403 Forbidden error. + +**Acceptance Scenarios**: + +1. **Given** a user with "Backup" plugin permission, **When** they navigate to the Backup tool, **Then** the page loads successfully. +2. **Given** a user WITHOUT "Backup" plugin permission, **When** they navigate to the Backup tool, **Then** they are denied access (UI hides the link, API returns 403). +3. **Given** an administrator, **When** they edit a user's permissions, **Then** the changes take effect immediately or upon next login. + +--- + +### User Story 3 - ADFS Integration (Priority: P2) + +As a corporate user, I want to log in using my organization's ADFS credentials so that I don't have to manage a separate password. + +**Why this priority**: Essential for enterprise environments but dependent on the core authentication infrastructure being in place (Story 1). + +**Independent Test**: Configure the application with a test ADFS provider (or mock). Verify a user can initiate the SSO flow and be logged in automatically. + +**Acceptance Scenarios**: + +1. **Given** a configured ADFS provider, **When** a user clicks "Login with ADFS", **Then** they are redirected to the identity provider. +2. **Given** a successful ADFS authentication, **When** the user returns to the app, **Then** a local user session is created/matched and they are logged in. +3. **Given** a new ADFS user, **When** they log in for the first time, **Then** a local user record is automatically created (JIT provisioning) with default permissions. + +--- + +### Edge Cases + +- What happens when an ADFS user's account is disabled in the local system? (Should block login even if ADFS succeeds) +- How does the system handle concurrent sessions? (Allow or restrict?) +- What happens if a plugin is removed but users still have permission for it? (Graceful handling/cleanup) +- What happens if the ADFS server is unreachable? (Fallback to local login if applicable, or clear error message) + +## Requirements *(mandatory)* + +### Functional Requirements + +- **FR-001**: System MUST support local user authentication via username and password. +- **FR-002**: System MUST support authentication via ADFS (Active Directory Federation Services) using standard federation protocols. +- **FR-003**: System MUST provide a mechanism to manage users (Create, Read, Update, Delete) - restricted to administrators. +- **FR-004**: System MUST implement Role-Based Access Control (RBAC) where permissions are assigned to Roles, and Roles are assigned to Users. +- **FR-005**: System MUST enforce permissions at the server level for all plugin execution requests. +- **FR-006**: System MUST enforce permissions at the user interface level (hide navigation items/buttons for unauthorized plugins). +- **FR-007**: System MUST securely store local user credentials. +- **FR-008**: System MUST support Just-In-Time (JIT) provisioning for ADFS users ONLY if they belong to a mapped AD group. +- **FR-009**: System MUST provide a CLI utility to create an initial administrator account to prevent lockout during first deployment. +- **FR-010**: System MUST allow configuring mappings between Active Directory Groups and local System Roles. +- **FR-011**: System MUST use JWT (JSON Web Tokens) for API session management. +- **FR-012**: System MUST persist authentication and authorization data in a dedicated SQLite database (`auth.db`). +- **FR-013**: System MUST provide a unified login interface supporting both Local (Username/Password) and ADFS (SSO Button) authentication methods simultaneously. + +### Key Entities + +- **User**: Represents a system user. Attributes: ID, Username, Email, PasswordHash, AuthSource (Local/ADFS), IsActive, Roles (List[RoleID]). +- **Role**: Named collection of permissions. Attributes: ID, Name, Description, Permissions (List[Permission]). +- **Permission**: Represents access capability. Attributes: ResourceID (e.g., Plugin ID), Action (Execute, Read). +- **ADGroupMapping**: Configuration mapping AD Group names to Role IDs. + +## Success Criteria *(mandatory)* + +### Measurable Outcomes + +- **SC-001**: Administrators can successfully create a new local user and assign specific plugin permissions in under 2 minutes. +- **SC-002**: Users without permission for a specific plugin are denied access 100% of the time when attempting to use its functions. +- **SC-003**: ADFS login flow completes successfully for valid credentials and maps to the correct local user identity. +- **SC-004**: User interface dynamically updates to show only permitted tools for the logged-in user. + +## Assumptions + +- The application currently has a simple or placeholder authentication mechanism. +- "Plugin access" refers to the ability to use the plugin's functionality and view its interface. +- A default administrator account will be available upon initial system setup to prevent lockout. diff --git a/specs/016-multi-user-auth/tasks.md b/specs/016-multi-user-auth/tasks.md new file mode 100644 index 0000000..5d7c91e --- /dev/null +++ b/specs/016-multi-user-auth/tasks.md @@ -0,0 +1,91 @@ +# Tasks: Multi-User Authentication and Authorization + +**Feature Branch**: `016-multi-user-auth` +**Feature Spec**: [`specs/016-multi-user-auth/spec.md`](spec.md) +**Implementation Plan**: [`specs/016-multi-user-auth/plan.md`](plan.md) + +## Phase 1: Setup & Infrastructure (Blocking) + +*Goal: Initialize the auth database, core dependencies, and backend infrastructure.* + +- [ ] T001 Install backend dependencies (Authlib, Passlib, PyJWT, SQLAlchemy) in `backend/requirements.txt` +- [ ] T002 Implement core configuration for Auth and Database in `backend/src/core/auth/config.py` +- [ ] T003 Implement database connection logic for `auth.db` in `backend/src/core/database.py` +- [ ] T004 Create SQLAlchemy models for User, Role, Permission in `backend/src/models/auth.py` +- [ ] T005 Create migration/init script to generate `auth.db` schema in `backend/src/scripts/init_auth_db.py` +- [ ] T006 Implement password hashing utility using Passlib in `backend/src/core/auth/security.py` +- [ ] T007 Implement JWT token generation and validation logic in `backend/src/core/auth/jwt.py` +- [ ] T008 [P] Implement CLI tool for creating the initial admin user in `backend/src/scripts/create_admin.py` + +## Phase 2: User Story 1 - Local User Authentication (Priority: P1) + +*Goal: Enable users to log in with username/password and receive a JWT session.* + +- [ ] T009 [US1] Create Pydantic schemas for User, UserCreate, Token in `backend/src/schemas/auth.py` +- [ ] T010 [US1] Implement `AuthRepository` for DB operations in `backend/src/core/auth/repository.py` +- [ ] T011 [US1] Implement `AuthService` for login logic (verify password, create token) in `backend/src/services/auth_service.py` +- [ ] T012 [US1] Create API endpoint `POST /api/auth/login` in `backend/src/api/auth.py` +- [ ] T013 [US1] Implement `get_current_user` dependency for JWT verification in `backend/src/dependencies.py` +- [ ] T014 [US1] Create API endpoint `GET /api/auth/me` to retrieve current user profile in `backend/src/api/auth.py` +- [ ] T043 [US1] Implement session revocation (Logout) endpoint in `backend/src/api/auth.py` +- [ ] T044 [US1] Implement account status check (`is_active`) in authentication flow in `backend/src/services/auth_service.py` +- [ ] T015 [US1] Implement frontend auth store (Svelte store) in `frontend/src/lib/auth/store.ts` +- [ ] T016 [US1] Implement Login Page UI using `src/lib/ui` and `src/lib/i18n` in `frontend/src/routes/login/+page.svelte` +- [ ] T017 [US1] Integrate Login Page with Backend API in `frontend/src/routes/login/+page.svelte` +- [ ] T018 [US1] Implement `ProtectedRoute` component to redirect unauthenticated users in `frontend/src/components/auth/ProtectedRoute.svelte` +- [ ] T037 [US1] Implement password complexity validation logic in `backend/src/core/auth/security.py` + +## Phase 3: User Story 2 - Plugin-Based Access Control (Priority: P1) + +*Goal: Restrict access to plugins based on user roles and permissions.* + +- [ ] T019 [US2] Update `PluginBase` to include required permission strings in `backend/src/core/plugin_base.py` +- [ ] T020 [US2] Implement `has_permission` dependency for route protection in `backend/src/dependencies.py` +- [ ] T021 [US2] Protect existing plugin API routes using `has_permission` in `backend/src/api/routes/*.py` +- [ ] T022 [US2] Implement `SystemAdminPlugin` inheriting from `PluginBase` for User/Role management in `backend/src/plugins/system_admin.py` +- [ ] T023 [US2] Implement Admin API endpoints within `SystemAdminPlugin` (with pagination) in `backend/src/api/routes/admin.py` +- [ ] T024 [US2] Create Admin Dashboard UI using `src/lib/ui` and `src/lib/i18n` in `frontend/src/routes/admin/users/+page.svelte` +- [ ] T025 [US2] Update Navigation Bar to hide links and show user profile/logout using `src/lib/ui` in `frontend/src/components/Navbar.svelte` +- [ ] T042 [US2] Implement `PermissionGuard` frontend component for granular UI element protection in `frontend/src/components/auth/PermissionGuard.svelte` +- [ ] T045 [US2] Implement multi-role permission resolution logic (union of permissions) in `backend/src/services/auth_service.py` + +## Phase 4: User Story 3 - ADFS Integration (Priority: P2) + +*Goal: Enable corporate SSO login via ADFS and JIT provisioning.* + +- [ ] T026 [US3] Configure Authlib for ADFS OIDC in `backend/src/core/auth/oauth.py` +- [ ] T027 [US3] Create `ADGroupMapping` model in `backend/src/models/auth.py` and update DB init script +- [ ] T028 [US3] Implement JIT provisioning logic (create user if maps to group) in `backend/src/services/auth_service.py` +- [ ] T029 [US3] Create API endpoints `GET /api/auth/login/adfs` and `GET /api/auth/callback/adfs` in `backend/src/api/auth.py` +- [ ] T030 [US3] Update Login Page to include "Login with ADFS" button using `src/lib/ui` in `frontend/src/routes/login/+page.svelte` +- [ ] T031 [US3] Implement Admin UI for configuring AD Group Mappings in `frontend/src/routes/admin/settings/+page.svelte` +- [ ] T041 [US3] Create ADFS mock provider for local testing and CI in `backend/tests/auth/mock_adfs.py` +- [ ] T046 [US3] Implement token refresh logic for ADFS OIDC tokens in `backend/src/core/auth/jwt.py` + +## Phase 5: Polish & Security Hardening + +*Goal: Ensure security best practices and smooth UX.* + +- [ ] T032 Ensure all cookies are set with `HttpOnly` and `Secure` flags in `backend/src/api/auth.py` +- [ ] T033 Implement rate limiting and account lockout policy in `backend/src/api/auth.py` +- [ ] T034 Verify error messages are generic (no username enumeration) across all auth endpoints +- [ ] T035 Add "Session Expired" handling in frontend interceptor in `frontend/src/lib/api/client.ts` +- [ ] T036 Final manual test of switching between Local and ADFS login flows +- [ ] T040 Add confirmation dialogs for destructive admin actions using `src/lib/ui` in `frontend/src/routes/admin/users/+page.svelte` +- [ ] T047 Implement audit logging for security events (login, logout, permission changes) in `backend/src/core/auth/logger.py` +- [ ] T048 Perform UI accessibility audit (keyboard nav, ARIA alerts) for all auth components +- [ ] T049 Implement unit and integration tests for Local Auth and RBAC in `backend/tests/auth/` +- [ ] T050 Implement E2E tests for ADFS flow using mock provider in `tests/e2e/auth.spec.ts` + +## Dependencies + +1. **Phase 1** must be completed before any User Stories. +2. **Phase 2 (Local Auth)** is the foundation for authentication and session management. +3. **Phase 3 (RBAC)** depends on Phase 2 (needs authenticated users to check permissions). +4. **Phase 4 (ADFS)** depends on Phase 2 (uses same session mechanism) and Phase 3 (needs roles for JIT). + +## Implementation Strategy + +- **MVP**: Complete Phases 1 and 2. This gives a working auth system with local users. +- **Increment 1**: Complete Phase 3. This adds the critical security controls (RBAC). +- **Increment 2**: Complete Phase 4. This adds corporate SSO convenience. \ No newline at end of file