tasks ready

This commit is contained in:
2026-01-27 13:26:06 +03:00
parent d10c23e658
commit cc244c2d86
13 changed files with 813 additions and 1 deletions

View File

@@ -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`

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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)

View File

@@ -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

View File

@@ -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)

View File

@@ -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] |

View File

@@ -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.

View File

@@ -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).

View File

@@ -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.

View File

@@ -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.