Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 5 additions & 5 deletions .pre-commit-config.yaml
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
repos:
# Versioning: Commit messages & changelog
- repo: https://github.com/commitizen-tools/commitizen
rev: v4.13.10
rev: v4.16.5
hooks:
- id: commitizen
stages: [commit-msg]

# Lint / autoformat: Python code
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: "v0.15.12"
rev: "v0.16.0"
hooks:
- id: ruff
files: ^(?:backend|auth-libs/python)/.*\.py$
Expand All @@ -18,7 +18,7 @@ repos:

# Deps: ensure Python uv lockfile is up to date
- repo: https://github.com/astral-sh/uv-pre-commit
rev: 0.11.7
rev: 0.11.32
hooks:
- id: uv-lock
files: ^backend/pyproject\.toml$
Expand All @@ -37,7 +37,7 @@ repos:

# Lint: code cognitive complexity
- repo: https://github.com/rohaquinlop/complexipy-pre-commit
rev: v5.1.0
rev: v6.2.0
hooks:
- id: complexipy
files: ^(?:backend|auth-libs/python)/.*\.py$
Expand Down Expand Up @@ -84,7 +84,7 @@ repos:

# Lint: Markdown
- repo: https://github.com/igorshubovych/markdownlint-cli
rev: v0.48.0
rev: v0.49.1
hooks:
- id: markdownlint
args:
Expand Down
4 changes: 2 additions & 2 deletions docs/src/admin.md
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ app.include_router(admin_router, prefix="/api")
This creates:

| Method | Path | Description |
|--------|------|-------------|
| -------- | ------ | ------------- |
| `GET` | `/api/admin/mappings` | List mappings (paginated) |
| `POST` | `/api/admin/mappings` | Create a mapping |
| `GET` | `/api/admin/mappings/{hanko_user_id}` | Get one mapping |
Expand Down Expand Up @@ -157,7 +157,7 @@ These map to the app keys used in the proxy: `drone-tm`, `fair`, `umap`.
## Proxy Endpoints (Login Backend)

| Method | Path | Description |
|--------|------|-------------|
| -------- | ------ | ------------- |
| `GET` | `/api/admin/check` | Check if current user is admin |
| `GET` | `/api/admin/apps` | List configured apps |
| `GET` | `/api/admin/{app}/mappings` | List mappings for an app (enriched with Hanko emails) |
Expand Down
4 changes: 2 additions & 2 deletions docs/src/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ app = Litestar(route_handlers=[*route_handlers, me], dependencies=deps)
## Reference

| Document | Description |
|----------|-------------|
| ---------- | ------------- |
| [**Overview**](overview.md) | Auth flow, JWT validation, user mapping, env vars |
| [**Python Libraries**](python-libs.md) | `hotosm_auth`, `hotosm_auth_fastapi`, `hotosm_auth_django` |
| [**Web Component**](web-component.md) | `<hotosm-auth>` Lit element — attributes, events, modes |
Expand All @@ -138,7 +138,7 @@ app = Litestar(route_handlers=[*route_handlers, me], dependencies=deps)
## Implementations

| Project | Stack | Documentation |
|---------|-------|---------------|
| --------- | ------- | --------------- |
| Portal | FastAPI + React | [Implementation](projects/portal.md) |
| ChatMap | FastAPI + React | [Implementation](projects/chatmap.md) |
| Drone-TM | FastAPI + React | [Implementation](projects/drone-tm.md) |
Expand Down
4 changes: 2 additions & 2 deletions docs/src/integration-guide.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ Step by step guide to integrate `hotosm-auth` in your project.
## Quick Links

| Framework | Without Legacy Auth | With Legacy Auth |
|-----------|---------------------|------------------|
| ----------- | --------------------- | ------------------ |
| **FastAPI** | [Simple](#fastapi-simple-integration) | [With Mapping](#fastapi-integration-with-mapping) |
| **Django** | [Simple](#django-simple-integration) | [With Mapping](#django-integration-with-mapping) |
| **Litestar** | [Simple](#litestar-simple-integration) | [With Mapping](#litestar-integration-with-mapping) |
Expand Down Expand Up @@ -434,7 +434,7 @@ VITE_HANKO_URL=https://login.hotosm.org
## Checklist

| Step | FastAPI Simple | FastAPI+Mapping | Django Simple | Django+Mapping | Litestar Simple | Litestar+Mapping |
|------|----------------|-----------------|---------------|----------------|-----------------|------------------|
| ------ | ---------------- | ----------------- | --------------- | ---------------- | ----------------- | ------------------ |
| Dependency | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| Init | init_auth | init_auth | middleware | middleware | setup_auth() | setup_auth() |
| Protect routes | CurrentUser | Override login_required | request.hotosm | BaseAuthentication | AuthContext | Custom dep |
Expand Down
4 changes: 2 additions & 2 deletions docs/src/overview.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
- **User Mapping**: Maps Hanko users to app-specific user IDs

| Component | Purpose |
|-----------|---------|
| ----------- | --------- |
| `hotosm_auth` | Core Python package (JWT, config, crypto) |
| `hotosm_auth_fastapi` | FastAPI integration (dependencies, routes) |
| `hotosm_auth_django` | Django integration (middleware, decorators) |
Expand Down Expand Up @@ -155,7 +155,7 @@ VITE_AUTH_PROVIDER=hanko # "legacy" or "hanko"
### Variables by Project

| Variable | Portal | ChatMap | Drone-TM | fAIr | uMap | Login |
|----------|--------|---------|----------|------|------|-------|
| ---------- | -------- | --------- | ---------- | ------ | ------ | ------- |
| **Backend** |
| `HANKO_API_URL` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
| `COOKIE_SECRET` | ✅ | ✅ | ✅ | ✅ | ✅ | ✅ |
Expand Down
2 changes: 1 addition & 1 deletion docs/src/projects/chatmap.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
## Overview

| Aspect | Detail |
|--------|--------|
| -------- | -------- |
| Framework | FastAPI |
| Type | Simple (no mapping) |
| OSM | Not used |
Expand Down
4 changes: 2 additions & 2 deletions docs/src/projects/drone-tm.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
## Overview

| Aspect | Detail |
|--------|--------|
| -------- | -------- |
| Framework | FastAPI |
| Frontend | React SPA (Vite) |
| Legacy Auth | Google OAuth |
Expand Down Expand Up @@ -298,7 +298,7 @@ VITE_FRONTEND_URL=https://drone.hotosm.org
## Auth Flow

| Step | What happens |
|------|-------------|
| ------ | ------------- |
| 1. Sign In | User clicks role button (Project Creator / Drone Pilot) |
| 2. Redirect | `window.location.href` to `{HANKO_URL}/app?return_to={returnUrl}` |
| 3. Login service | User authenticates at login.hotosm.org, gets JWT cookie |
Expand Down
4 changes: 2 additions & 2 deletions docs/src/projects/fair.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
## Overview

| Aspect | Detail |
|--------|--------|
| -------- | -------- |
| Framework | Django (DRF) |
| Frontend | React SPA (Vite) |
| Legacy Auth | OSM OAuth (`osm-login-python`) |
Expand Down Expand Up @@ -290,7 +290,7 @@ VITE_BASE_API_URL=https://fair.hotosm.org/api/v1/
## Auth Flow

| Step | What happens |
|------|-------------|
| ------ | ------------- |
| 1. Login | Web component redirects to login service |
| 2. Auth | User authenticates, gets session cookie |
| 3. Return | Web component fires `hanko-login` event |
Expand Down
4 changes: 2 additions & 2 deletions docs/src/projects/portal.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
## Overview

| Aspect | Detail |
|--------|--------|
| -------- | -------- |
| Framework | FastAPI |
| Type | Simple (no mapping) |
| OSM Required | Optional |
Expand Down Expand Up @@ -137,7 +137,7 @@ VITE_HANKO_URL=https://login.hotosm.org
### Available Dependencies (FastAPI)

| Dependency | Type | Error if missing |
|------------|------|------------------|
| ------------ | ------ | ------------------ |
| `CurrentUser` | `HankoUser` | 401 Unauthorized |
| `CurrentUserOptional` | `Optional[HankoUser]` | None (no error) |
| `OSMConnectionRequired` | `OSMConnection` | 403 Forbidden |
Expand Down
4 changes: 2 additions & 2 deletions docs/src/projects/umap.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
## Overview

| Aspect | Detail |
|--------|--------|
| -------- | -------- |
| Framework | Django (umap-project) |
| Frontend | Django templates (no SPA) + web component via CDN |
| Legacy Auth | OSM OAuth via `django-social-auth` |
Expand Down Expand Up @@ -327,7 +327,7 @@ No frontend-specific env vars — everything comes from Django context processor
## Auth Flow

| Step | What happens |
|------|-------------|
| ------ | ------------- |
| 1. Login | Web component redirects to login service (`HANKO_PUBLIC_URL`) |
| 2. Auth | User authenticates at login.hotosm.org, gets JWT cookie |
| 3. Return | Login service redirects to `SITE_URL` |
Expand Down
4 changes: 2 additions & 2 deletions docs/src/python-libs.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@ async def edit(osm: OSMConnectionRequired):
### Dependencies

| Dependency | Type | Raises |
|------------|------|--------|
| ------------ | ------ | -------- |
| `CurrentUser` | `HankoUser` | 401 |
| `CurrentUserOptional` | `Optional[HankoUser]` | - |
| `OSMConnectionDep` | `Optional[OSMConnection]` | - |
Expand Down Expand Up @@ -403,7 +403,7 @@ async def public(optional_auth: OptionalAuthContext) -> dict:
### Dependencies

| Dependency | Type | Raises |
|------------|------|--------|
| ------------ | ------ | -------- |
| `AuthContext` | `AuthContext` (`.user`, `.osm`) | 401 |
| `OptionalAuthContext` | `OptionalAuthContext` | - |
| `AdminUser` | `HankoUser` | 403 |
Expand Down
6 changes: 3 additions & 3 deletions docs/src/web-component.md
Original file line number Diff line number Diff line change
Expand Up @@ -72,15 +72,15 @@ export function AuthButton({ hankoUrl, onLogin }) {
### Core

| Attribute | Type | Default | Description |
|-----------|------|---------|-------------|
| ----------- | ------ | --------- | ------------- |
| `hanko-url` | string | `window.location.origin` | Login service URL (login.hotosm.org) for Hanko authentication |
| `base-path` | string | `""` | Base URL for OSM OAuth endpoints. Usually same as `hanko-url` since login service hosts both Hanko and OSM auth |
| `auth-path` | string | `/api/auth/osm` | OSM auth endpoints path (appended to `base-path`) |

### Behavior

| Attribute | Type | Default | Description |
|-----------|------|---------|-------------|
| ----------- | ------ | --------- | ------------- |
| `osm-required` | boolean | `false` | Require OSM connection |
| `osm-scopes` | string | `"read_prefs"` | Space-separated OSM scopes |
| `auto-connect` | boolean | `false` | Auto-redirect to OSM OAuth |
Expand Down Expand Up @@ -112,7 +112,7 @@ export function AuthButton({ hankoUrl, onLogin }) {
## Events

| Event | Detail | When |
|-------|--------|------|
| ------- | -------- | ------ |
| `hanko-login` | `{ user: HankoUser }` | User logged in |
| `osm-connected` | `{ osmData: OSMData }` | OSM account linked |
| `osm-skipped` | `{}` | User skipped OSM connection |
Expand Down