Feature: integrate Hanko auth login #538
Conversation
…xport-tool into feature/login-hanko
emi420
left a comment
There was a problem hiding this comment.
Hi @andrea-chirillano ! I did my review before moving the PR to "Ready to review" so it's easier for other people to review it.
Thanks!
There was a problem hiding this comment.
Hi @andrea-chirillano ! please remove this file, the branch feature/login_hanko will be deleted once merged so this file will not be used after that.
There was a problem hiding this comment.
Hi, the branch is necessary because that branch depends on the staging environment https://export.testlogin.hotosm.org/v3/
|
|
||
| if not all: | ||
| queryset = queryset.filter(Q(user_id=user.id)) | ||
|
|
There was a problem hiding this comment.
Why this change? it adds additional filters, could we revert it?
There was a problem hiding this comment.
I also realized they were unnecessary, and I've already reverted those changes.
There was a problem hiding this comment.
Please remove this file, it's only for testing on export.testlogin.hotosm.org and will not be used after the PR
There was a problem hiding this comment.
I added it to gitignore
There was a problem hiding this comment.
This file is for development right? if that's the case, please add a comment about it and move it to a docker folder
There was a problem hiding this comment.
I added it to gitignore and move that Dockerfile into a docker folder.
…xport-tool into feature/login-hanko
|
Thanks - I just saw this PR from the message on slack! I have no idea how Export Tool is deployed in production, nor how we can test this PR for now, but once it's marked as ready for review, I can look into those things with dk 😄 |
its in a single ec2 instance in our aws ! Ideally we can swamp a quick stage server for export tool in a tiny instance ! I am happy to review once PR is ready ! |
|
Is it a systemd service or something, running the Python / Django server? I can't see any containerisation in the repo |
|
Ah I literally just saw this dir! https://github.com/hotosm/osm-export-tool/tree/main/ops/systemd Assuming a few services all run in parallel, managed by systemd |
|
We have a testing deployment: |
|
Yes systemd services, export tool isn't containerized yet ! Yarn builds the frontend ! |
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
AUTH_PROVIDERsetting (legacy|hanko) — default islegacy, existing deployments are unaffectedHankoAuthenticationDRF backend added toDEFAULT_AUTHENTICATION_CLASSES(takes priority, falls back to token/OAuth2)hotosm-authweb component (<hotosm-auth>) rendered in NavBar viaHankoAuthButton.js<hotosm/tool-menu>web component added to the layout (loaded from jsDelivr, fixed version)hotosm-auth[django])print()calls replaced withloggingthroughoutapi/views.pyis_superuser(legacy) andADMIN_EMAILSenv var (Hanko)New API Endpoints
/api/auth/me//api/v1/auth/status//api/v1/auth/onboarding//api/admin//api/v1/hotosm_auth_django)Legacy OAuth routes (
/osm/,/o/,/authorized) are only registered whenAUTH_PROVIDER=legacy.New Dependencies
hotosm-auth[django]==0.2.12tzdata@hotosm/hanko-auth@0.5.2@hotosm/tool-menu@0.2.6Required Environment Variables
Backend — required (Hanko mode)
AUTH_PROVIDERhankohankoto enable SSO. Default:legacyHANKO_API_URLhttps://login.hotosm.orgCOOKIE_SECRET<shared-secret>Backend — recommended
HANKO_PUBLIC_URLHANKO_API_URLCOOKIE_DOMAIN.hotosm.orgfor cross-subdomain SSOCOOKIE_SECUREnot DEBUGtruein productionADMIN_EMAILS""is_superuserin Hanko modeRAW_DATA_API_PUBLIC_URLRAW_DATA_API_URLBackend — optional (OSM connection & JWT)
These are read directly from the environment by the
hotosm-authlibrary.OSM_CLIENT_ID/OSM_CLIENT_SECRET/api/v1/auth/osm/login/). If unset, onboarding redirects users to the login service to connect OSMOSM_REDIRECT_URIJWT_AUDIENCENoneaudclaimJWT_ISSUERHANKO_API_URLCOOKIE_SAMESITElaxFrontend (injected via Django template into
window.*)AUTH_PROVIDERHANKO_URLhanko-urlto<hotosm-auth>Database Migrations
When
AUTH_PROVIDER=hanko, thehotosm_auth_djangoapp is added toINSTALLED_APPSand contributes one migration (0001_initial):hanko_user_mappingstable (maps Hanko user IDs ↔ Django user IDs, scoped byapp_name)CREATE TABLE IF NOT EXISTS— idempotent, safe to re-runpython manage.py migrate(orpython manage.py migrate hotosm_auth_django)No migrations are added to the export-tool's own apps (
api,jobs,tasks,ui). Rolling back toAUTH_PROVIDER=legacyneeds no reverse migration — the table is harmless if left in place. Explicit rollback:python manage.py migrate hotosm_auth_django zero.How It Works
Legacy mode (default)
AUTH_PROVIDER=legacy— no changes, continues using OSM OAuth withaccess-tokenheader.Hanko mode
login.hotosm.orgHankoAuthenticationDRF backend validates the JWT cookie viahotosm_auth_djangoGET /api/v1/auth/status/returnsneeds_onboarding: true→ onboarding flow startsOnboarding account matching
For "I already have an account", existing users are matched by priority:
social_auth_usersocialauth(find_legacy_user_by_osm_id)auth_user.email(find_legacy_user_by_email, lowestidwins)If neither matches, the user is redirected back to the login service with an error and no DB rows are created.
Test Plan
AUTH_PROVIDER=legacyGET /api/v1/auth/status/returns correctauthenticatedandneeds_onboardingvaluesPOST /api/v1/exports/) works with Hanko JWT cookiehotosm_auth_djangoapp migrations apply correctly whenAUTH_PROVIDER=hankoBackward Compatibility
legacy— no action required for existing deploymentshankowhen ready by setting the environment variables aboveDeployment
The deploy is done manually via SSH. There is no automated pipeline — after the PR is merged, someone with server access must connect and deploy by hand.
Dependency & Django Version Update
Django has been upgraded from 3.2 → 4.2 LTS and several dependencies have been
updated to their latest compatible versions. These changes are required for two reasons:
Django 4.2. Running tests against Django 3.2 will result in failures.
patches. Upgrading to the 4.2 LTS branch ensures continued security support.
Collateral Fixes (not Hanko, but required)
A few changes in this PR are not part of the SSO feature itself, but were necessary to make the branch run, build under Docker, or pass tests. Listed here so reviewers aren't surprised by non-Hanko diffs:
userinfo=fromGalaxy(...)callstasks/task_runners.pyosm-export-tool-python==2.0.10does not accept auserinfoargument —mainraisesTypeErroron every export runor→andin thelast_run_statusguardtasks/task_runners.py!= "SUBMITTED" or != "RUNNING"is alwaysTrue, so a new run was created even when one was alreadySUBMITTED/RUNNING, allowing duplicate parallel runs. The matchingelsebranch was unreachable dead codetasks/task_runners.py,core/settings/project.pylocalhost; in a containerized setup it runs in a separate container. Defaults tolocalhost, so non-Docker setups are unaffectedFeatureSelection.example()→SIMPLE_FEATURE_SELECTIONconstantconftest.py(new) +api/tests/test_views.py,jobs/tests/test_models.py,tasks/tests/test_models.pyfrom feature_selection.feature_selection import FeatureSelectionraisesModuleNotFoundError— the affected test files inmaincannot even be collected[tool:pytest]configsetup.cfgDJANGO_SETTINGS_MODULEso the test suite can be run withpytest