chore: added documentation
This commit is contained in:
78
docs/authentication.md
Normal file
78
docs/authentication.md
Normal file
@@ -0,0 +1,78 @@
|
||||
# Authentication & Authorization
|
||||
|
||||
## Overview
|
||||
|
||||
Trackpull uses session-based authentication backed by a SQLite database. There are two roles: **admin** and **user**. Passwords are hashed using werkzeug's PBKDF2-based scheme — no plaintext is ever stored.
|
||||
|
||||
---
|
||||
|
||||
## Login Flow
|
||||
|
||||
1. User submits credentials via `POST /login`.
|
||||
2. `get_user_by_username()` looks up the record in the `users` table.
|
||||
3. `check_password_hash()` verifies the submitted password against the stored hash.
|
||||
4. On success, Flask session is populated with `user_id`, `username`, and `role`.
|
||||
5. User is redirected to the main app. On failure, the login page re-renders with an error.
|
||||
|
||||
Logout is a simple `GET /logout` that clears the session and redirects to `/login`.
|
||||
|
||||
---
|
||||
|
||||
## Authorization Enforcement
|
||||
|
||||
A `@app.before_request` hook runs before every request. If the session lacks a `user_id`, the request is redirected to `/login`.
|
||||
|
||||
Public (unauthenticated) routes are whitelisted:
|
||||
- `/login`
|
||||
- `/logout`
|
||||
- `/static/*`
|
||||
- `/offline`
|
||||
- `/sw.js`
|
||||
|
||||
Admin-only routes check `session["role"] == "admin"` via a `require_admin()` helper. Unauthorized admin access returns `403`.
|
||||
|
||||
---
|
||||
|
||||
## Role Permissions
|
||||
|
||||
| Action | User | Admin |
|
||||
|--------|------|-------|
|
||||
| Download (Votify/Monochrome/Unified) | Yes | Yes |
|
||||
| View own jobs & files | Yes | Yes |
|
||||
| Cancel/delete own jobs | Yes | Yes |
|
||||
| Change own password | Yes | Yes |
|
||||
| View any user's jobs/files | No | Yes |
|
||||
| Manage users (create/delete/reset) | No | Yes |
|
||||
| Upload cookies.txt / device.wvd | No | Yes |
|
||||
| Change global settings | No | Yes |
|
||||
|
||||
---
|
||||
|
||||
## Admin Seeding
|
||||
|
||||
On first run, if no users exist in the database, an admin account is created automatically from `ADMIN_USERNAME` and `ADMIN_PASSWORD` environment variables (see [docker-deployment.md](docker-deployment.md)).
|
||||
|
||||
---
|
||||
|
||||
## Session Security
|
||||
|
||||
- Sessions are encrypted using Flask's `SECRET_KEY` env var (should be a 32-byte random hex string).
|
||||
- Sessions survive application restarts because the key is stable.
|
||||
- There is no token-based auth or "remember me" — sessions expire when the browser closes by default.
|
||||
|
||||
---
|
||||
|
||||
## Password Management
|
||||
|
||||
- `update_user_password()` in `db.py` re-hashes and saves a new password.
|
||||
- Users change their own password at `POST /api/account/password`.
|
||||
- Admins reset any user's password at `POST /api/admin/users/<id>/password`.
|
||||
|
||||
---
|
||||
|
||||
## Key Files
|
||||
|
||||
| File | Relevance |
|
||||
|------|-----------|
|
||||
| [app.py](../app.py) | Route definitions, `before_request` hook, `require_admin()` |
|
||||
| [db.py](../db.py) | `create_user`, `get_user_by_username`, `verify_password`, `update_user_password` |
|
||||
Reference in New Issue
Block a user