Skip to content

Feature: integrate Hanko auth login#537

Closed
andrea-chirillano wants to merge 64 commits intomainfrom
login-hanko
Closed

Feature: integrate Hanko auth login#537
andrea-chirillano wants to merge 64 commits intomainfrom
login-hanko

Conversation

@andrea-chirillano
Copy link
Copy Markdown
Collaborator

@andrea-chirillano andrea-chirillano commented Mar 18, 2026

This pull request requires in-depth review before merging.

This PR includes changes to the backend (Django), frontend (React/JS), infrastructure (Docker, nginx), and tests. Review carefully before approving.


Add Hanko SSO Authentication

Integrates Hanko SSO as an alternative to legacy OSM OAuth, enabling single sign-on across the HOT ecosystem via login.hotosm.org.

Key changes

  • New AUTH_PROVIDER setting (legacy | hanko) — default is legacy, existing deployments are unaffected
  • HankoAuthentication DRF backend added to DEFAULT_AUTHENTICATION_CLASSES (takes priority, falls back to token/OAuth2)
  • Onboarding flow to link existing OSM accounts or create new ones for first-time Hanko users
  • hotosm-auth web component (<hotosm-auth>) rendered in NavBar via HankoAuthButton.js
  • <hotosm/tool-menu> web component added to the layout (loaded from jsDelivr, fixed version)
  • Django upgraded from 3.2 → 4.2 LTS (required by hotosm-auth[django])
  • print() calls replaced with logging throughout api/views.py
  • Responsive navbar collapse added (mobile support)
  • Admin authorization now supports both modes: is_superuser (legacy) and ADMIN_EMAILS env var (Hanko)

New API Endpoints

Endpoint Method Description
/api/auth/me/ GET Current user info
/api/v1/auth/status/ GET Auth status + onboarding flag
/api/v1/auth/onboarding/ GET Callback from login service after OSM link
/api/admin/ Hanko→Django user mapping (admin panel)
/api/v1/ Hanko OSM OAuth routes (from hotosm_auth_django)

Legacy OAuth routes (/osm/, /o/, /authorized) are only registered when AUTH_PROVIDER=legacy.


New Dependencies

Package Location Notes
hotosm-auth[django]==0.2.10 Backend (PyPI) Hanko middleware, helpers, OSM views
tzdata Backend (PyPI) Required on minimal images (Python 3.9+)
@hotosm/hanko-auth@0.5.2 Frontend (jsDelivr CDN) Login web component
@hotosm/tool-menu@0.2.6 Frontend (jsDelivr CDN) HOT ecosystem nav menu

Required Environment Variables

Backend

Variable Required Example Description
AUTH_PROVIDER Yes hanko Set to hanko to enable SSO. Default: legacy
HANKO_API_URL Yes (Hanko) https://login.hotosm.org Hanko service URL
HANKO_PUBLIC_URL No same as above Public URL (defaults to HANKO_API_URL)
COOKIE_SECRET Yes (Hanko) <shared-secret> Must match the login service — coordinate with login team
COOKIE_DOMAIN Yes (Hanko) .hotosm.org Cookie domain — use .hotosm.org for cross-subdomain SSO
COOKIE_SECURE No true Defaults to not DEBUG
ADMIN_EMAILS No admin@hotosm.org Comma-separated list; replaces is_superuser in Hanko mode
RAW_DATA_API_PUBLIC_URL No https://api.rawdata.hotosm.org Public URL for frontend (falls back to RAW_DATA_API_URL)

Frontend (injected via Django template into window.*)

Variable Required Description
AUTH_PROVIDER Yes Must match backend
HANKO_URL Yes (Hanko) Hanko public URL — passed as hanko-url to <hotosm-auth>

How It Works

Legacy mode (default)

AUTH_PROVIDER=legacy — no changes, continues using OSM OAuth with access-token header.

Hanko mode

  1. User clicks login → redirected to login.hotosm.org
  2. Hanko sets a JWT cookie after authentication
  3. HankoAuthentication DRF backend validates the JWT cookie via hotosm_auth_django
  4. If a Django↔Hanko mapping exists → user is authenticated
  5. If no mapping → GET /api/v1/auth/status/ returns needs_onboarding: true → onboarding flow starts
  6. Onboarding: user chooses to link an existing OSM account (recovers data) or create a new one

Test Plan

  • Legacy auth continues working with AUTH_PROVIDER=legacy
  • Hanko login/logout flow works end-to-end
  • New user onboarding creates a Django account
  • Existing user onboarding recovers account via OSM link
  • GET /api/v1/auth/status/ returns correct authenticated and needs_onboarding values
  • Navbar shows correct user state in both modes
  • Protected routes redirect to login when unauthenticated
  • Worker dashboard access control works in both modes
  • Export creation (POST /api/v1/exports/) works with Hanko JWT cookie
  • Django 4.2 migration runs cleanly — no regressions from 3.2 upgrade
  • hotosm_auth_django app migrations apply correctly when AUTH_PROVIDER=hanko

Backward Compatibility

  • Default is legacy — no action required for existing deployments
  • Existing OSM OAuth users continue working unchanged
  • Switch to hanko when ready by setting the environment variables above

@warmijusti warmijusti marked this pull request as draft March 19, 2026 15:33
@andrea-chirillano andrea-chirillano deleted the login-hanko branch March 26, 2026 23:46
@andrea-chirillano andrea-chirillano restored the login-hanko branch March 27, 2026 17:20
@andrea-chirillano andrea-chirillano deleted the login-hanko branch March 27, 2026 17:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants