git init
This commit is contained in:
1 parent
2b7e0d23c0
commit
5b649f96f2
6 files changed
+404
No files matched your search
@@ -0,0 +1,83 @@
|
||||
# CLAUDE.md
|
||||
|
||||
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
|
||||
|
||||
## Project Overview
|
||||
|
||||
Flask 2.x Proof-of-Concept to demonstrate fine-grained, dynamic RBAC and multi-tenancy using **Zitadel** as OIDC IdP. Authentication is fully delegated to Zitadel; authorization and project assignments are handled locally via SQLite.
|
||||
|
||||
The full specification is in [claude-context.md](claude-context.md).
|
||||
|
||||
## Commands
|
||||
|
||||
### Local Development (venv)
|
||||
|
||||
```bash
|
||||
python3 -m venv venv
|
||||
source venv/bin/activate
|
||||
pip install -r requirements.txt
|
||||
cp .env.example .env # then fill in Zitadel credentials
|
||||
flask db-init # initialize SQLite schema
|
||||
flask seed-db # seed mock data (Firma Müller, 3 projects, sample notes)
|
||||
flask run
|
||||
```
|
||||
|
||||
### Docker / Production
|
||||
|
||||
```bash
|
||||
docker compose up --build # builds image from Dockerfile, reads .env
|
||||
docker compose down
|
||||
```
|
||||
|
||||
### Database CLI commands
|
||||
|
||||
```bash
|
||||
flask seed-db # wipes and re-seeds the SQLite database with test fixtures
|
||||
```
|
||||
|
||||
## Architecture
|
||||
|
||||
**Flat backend, rich local authorization:**
|
||||
|
||||
- **Zitadel (external)** — handles login, issues OIDC tokens carrying the user's global role claim (`Admin`, `Mitarbeiter`, or `Kunde`).
|
||||
- **`app/auth.py`** — Authlib OIDC client; extracts `sub`, role claims, and token scopes from the IdP response; logs token payload to stdout in development.
|
||||
- **`app/models.py`** — SQLAlchemy models for the local relational layer:
|
||||
- `User` (keyed on Zitadel `sub`)
|
||||
- `Client` (top-level company, e.g. "Firma Müller")
|
||||
- `Project` (belongs to one Client)
|
||||
- `ProjectMitarbeiterMapping` (N:M: employees ↔ projects)
|
||||
- `ProjectKundenMapping` (N:M: external users ↔ projects)
|
||||
- `Note` (timestamped text entry tied to a Project)
|
||||
- **`app/routes.py`** — all routing guards live here; unauthorized access always redirects to `login_error.html` (never raises HTTP errors).
|
||||
- **`app/config.py`** — reads `.env`; follows 12-Factor style.
|
||||
- **`app/database.py`** — SQLAlchemy engine/session setup.
|
||||
|
||||
## Role-Based Access (RBAC) Logic
|
||||
|
||||
| Role | Access |
|
||||
|---|---|
|
||||
| `Admin` | Full visibility; all clients, projects, users; global export |
|
||||
| `Mitarbeiter` | Only projects linked via `ProjectMitarbeiterMapping` |
|
||||
| `Kunde` | Only projects linked via `ProjectKundenMapping` for their client |
|
||||
|
||||
**Routing guard pattern:** Every protected route checks (1) Zitadel role from session, (2) local DB mapping for the requested resource. Any mismatch → redirect to `/error` (renders `login_error.html`). The error page has a JS back-button to support test flows.
|
||||
|
||||
## Environment Variables
|
||||
|
||||
See `.env.example`:
|
||||
|
||||
```
|
||||
FLASK_APP=app
|
||||
FLASK_ENV=development
|
||||
SECRET_KEY=...
|
||||
ZITADEL_CLIENT_ID=...
|
||||
ZITADEL_CLIENT_SECRET=...
|
||||
ZITADEL_DISCOVERY_URL=https://<instance>.zitadel.cloud/.well-known/openid-configuration
|
||||
DATABASE_URL=sqlite:///app.db
|
||||
```
|
||||
|
||||
## Docker Notes
|
||||
|
||||
- `Dockerfile` uses `python:3.11-slim`, runs app via `gunicorn`.
|
||||
- `docker-compose.yml` builds from source (no pre-built images), mounts a volume for the SQLite file, and reads `.env` directly.
|
||||
- Setting `pull_policy: always` (or equivalent) in the compose file ensures a base-image update triggers a rebuild.
|
||||
Reference in new issue
Block a user