Skip to content

[codex] Add WorkOS auth mode#26

Merged
jruszo merged 2 commits intomasterfrom
feature/workos-auth-mode
Apr 14, 2026
Merged

[codex] Add WorkOS auth mode#26
jruszo merged 2 commits intomasterfrom
feature/workos-auth-mode

Conversation

@jruszo
Copy link
Copy Markdown
Owner

@jruszo jruszo commented Apr 10, 2026

Summary

This PR adds a deployment-wide authentication switch so Datamingle can run in either local builtin auth mode or WorkOS mode.

What Changed

  • added AUTH_MODE=builtin|workos with WorkOS env validation and a dedicated WorkOS auth flow
  • added WorkOS authorize, callback, exchange, logout, and auth-config API endpoints
  • provisioned local Datamingle users on first WorkOS login and added Users.workos_user_id
  • updated the SPA login/logout/callback flow to support WorkOS while preserving builtin auth mode
  • removed legacy OIDC, LDAP, and CAS settings, routes, dependencies, and old OIDC backend code
  • updated the legacy server-rendered login flow so it follows the same builtin vs WorkOS switch
  • documented both auth modes and WorkOS setup in README.md

Why

The enterprise deployment model now needs a clear choice between local Datamingle auth and WorkOS-backed tenant auth. The previous code still exposed legacy OIDC/LDAP/CAS paths that no longer fit that direction.

Impact

  • deployments can explicitly choose local auth or WorkOS with one env flag
  • WorkOS mode disables local password login for both SPA and legacy login surfaces
  • Datamingle still keeps its own users, groups, and resource-group authorization model after WorkOS login

Validation

  • docker exec datamingle-app python manage.py test sql_api.test_workos_auth sql_api.tests.TestTokenAuth2FA sql.tests.TestUser
  • docker exec datamingle-app python manage.py makemigrations sql --check
  • cd frontend && npm run build
  • black --check .

Notes

Before running with AUTH_MODE=workos, rebuild the app container so the workos dependency from requirements.txt is installed.

Summary by CodeRabbit

  • New Features

    • Added WorkOS single sign-on integration as an alternative authentication method.
    • User profile avatars now display when available.
    • Configurable authentication mode: choose between built-in credentials or WorkOS.
  • Removed Features

    • Removed LDAP, OIDC, and CAS authentication methods.
  • Bug Fixes & Updates

    • WorkOS-managed user accounts have synchronized identity information; display name and email edits are disabled.
    • Sign-up disabled when using WorkOS mode.
    • Updated password change restriction for WorkOS users.

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented Apr 10, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: b42be200-b7ad-468d-a71f-53359da8eec9

📥 Commits

Reviewing files that changed from the base of the PR and between 81524c7 and 106bc58.

📒 Files selected for processing (33)
  • README.md
  • archery/settings.py
  • archery/urls.py
  • common/auth.py
  • common/authenticate/oidc_auth.py
  • common/authenticate/test_oidc_auth.py
  • common/authenticate/workos.py
  • common/middleware/check_login_middleware.py
  • common/templates/config.html
  • common/templates/login.html
  • frontend/src/App.vue
  • frontend/src/lib/api.ts
  • frontend/src/lib/system-settings.ts
  • frontend/src/router/index.ts
  • frontend/src/stores/auth.ts
  • frontend/src/views/LoginCallbackView.vue
  • frontend/src/views/LoginView.vue
  • frontend/src/views/ProfileView.vue
  • frontend/src/views/SettingsUserDetailView.vue
  • frontend/src/views/SettingsUsersView.vue
  • requirements.txt
  • sql/migrations/0007_users_workos_user_id.py
  • sql/migrations/0008_users_avatar_url.py
  • sql/models.py
  • sql/tests.py
  • sql/views.py
  • sql_api/api_auth.py
  • sql_api/api_settings.py
  • sql_api/api_user.py
  • sql_api/serializers.py
  • sql_api/test_workos_auth.py
  • sql_api/tests.py
  • sql_api/urls.py

📝 Walkthrough

Walkthrough

The PR replaces LDAP, OIDC, and CAS authentication systems with WorkOS-based authentication via a new AUTH_MODE setting (builtin or workos). It removes deprecated auth backends/endpoints, adds WorkOS OAuth integration including user provisioning, introduces new user fields (workos_user_id, avatar_url), and updates frontend login/profile views to accommodate WorkOS user management and avatar display.

Changes

Cohort / File(s) Summary
Configuration & Dependencies
README.md, requirements.txt
Documented new AUTH_MODE setting and WorkOS setup; replaced django-auth-ldap, mozilla-django-oidc, django-cas-ng with workos==5.45.0.
Settings & Auth Modes
archery/settings.py
Removed LDAP/OIDC/CAS configuration blocks; introduced AUTH_MODE (builtin/workos), WorkOS credentials, and validation; set AUTHENTICATION_BACKENDS and LOGIN_REDIRECT_URL unconditionally.
Removed Auth Backends
common/authenticate/oidc_auth.py, common/authenticate/test_oidc_auth.py
Deleted entire OIDC authentication backend implementation and its test suite (80+ and 162 lines respectively).
New WorkOS Integration
common/authenticate/workos.py, sql_api/api_auth.py, sql_api/test_workos_auth.py, sql_api/urls.py
Added WorkOS client wrapper, OAuth flow handlers (authorize/callback/exchange/logout), user provisioning logic with role mapping, and comprehensive test suite covering all WorkOS flows.
Login & Auth Flow
common/auth.py, common/middleware/check_login_middleware.py, archery/urls.py, sql/views.py
Disabled password/signup in WorkOS mode; removed CAS/OIDC URL routes and ignored paths; updated login context to expose auth_mode.
Frontend Login & Callback
frontend/src/views/LoginView.vue, frontend/src/views/LoginCallbackView.vue, frontend/src/router/index.ts
Conditionally show WorkOS button or username/password form based on auth_mode; added callback view to exchange WorkOS code for session tokens; added /login/callback route.
Frontend Auth Store & API
frontend/src/stores/auth.ts, frontend/src/lib/api.ts
Added authMode state and loadAuthConfig() action; extended API with AuthMode/AuthConfig types and exchangeWorkosCode(), fetchAuthConfig() functions.
Frontend User Profile
frontend/src/views/ProfileView.vue, frontend/src/views/SettingsUserDetailView.vue, frontend/src/views/SettingsUsersView.vue, frontend/src/App.vue
Added avatar display with fallback to initials; disabled password/profile edits for WorkOS-managed users; conditionally render identity vs. display-name sections; updated logout to handle WorkOS redirect.
Backend User Model & Serializers
sql/models.py, sql/migrations/0007_users_workos_user_id.py, sql/migrations/0008_users_avatar_url.py, sql_api/serializers.py, sql_api/api_user.py
Added workos_user_id (unique, indexed) and avatar_url fields; added is_workos_managed computed field; enforced immutability of email/display and disabled password changes for WorkOS users.
System Settings
common/templates/config.html, frontend/src/lib/system-settings.ts, sql_api/api_settings.py
Removed oidc_btn_name system setting from UI, configuration schema, and settings API.
Tests
sql/tests.py, sql_api/tests.py
Added WorkOS mode tests verifying login page and disabled password/signup endpoints; updated user list assertion to include is_workos_managed field.

Sequence Diagram(s)

sequenceDiagram
    participant User as User Browser
    participant Frontend as Frontend (SPA)
    participant Backend as Backend API
    participant WorkOS as WorkOS
    participant DB as Database

    User->>Frontend: Click "Continue with WorkOS"
    Frontend->>Backend: GET /api/auth/workos/authorize/
    Backend->>Backend: Generate state, create secure cookie
    Backend->>WorkOS: Redirect to WorkOS consent screen
    Backend-->>Frontend: 302 redirect to WorkOS
    User->>WorkOS: Log in / authorize

    WorkOS->>Backend: Redirect to /api/auth/workos/callback/?code=...&state=...
    Backend->>Backend: Validate state cookie
    Backend->>WorkOS: Exchange code for user info
    WorkOS-->>Backend: Return user + access_token

    Backend->>Backend: Decode JWT token for session_id
    Backend->>DB: Query/provision user by email
    Backend->>DB: Update workos_user_id, avatar_url
    Backend->>DB: Assign groups & roles by email
    Backend->>Backend: Store exchange code in Redis
    Backend-->>Frontend: 302 redirect to /login/callback?code=...

    User->>Frontend: Redirect received
    Frontend->>Backend: POST /api/auth/workos/exchange/ with code
    Backend->>Backend: Retrieve & validate exchange code from Redis
    Backend->>DB: Load user record
    Backend->>Backend: Issue local JWT pair (access + refresh)
    Backend-->>Frontend: Return { access, refresh }

    Frontend->>Frontend: Store tokens, load user profile
    Frontend->>Backend: GET /api/v1/me/
    Backend-->>Frontend: Return user + is_workos_managed, avatar_url
    Frontend->>User: Display authenticated dashboard
Loading
sequenceDiagram
    participant User as User Browser
    participant Frontend as Frontend (SPA)
    participant Backend as Backend API
    participant WorkOS as WorkOS

    User->>Frontend: Click Logout
    Frontend->>Backend: GET /api/auth/workos/logout/
    Backend->>Backend: Check if WorkOS session cookie present
    alt Session cookie exists
        Backend->>WorkOS: Get logout URL for session_id
        WorkOS-->>Backend: Return logout URL
        Backend-->>Frontend: 302 redirect to WorkOS logout URL
        User->>WorkOS: Log out
        WorkOS-->>Frontend: Redirect to /login
    else No session cookie
        Backend-->>Frontend: 302 redirect to /login
    end
    Frontend->>Frontend: Clear local tokens
    User->>Frontend: Display login page
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Poem

🐰 WorkOS hops into the warren,
OIDC, LDAP must now depart-en,
Avatar-adorned users now shine,
Builtin or WorkOS—a choice divine!
Let this auth tale finally settle,
Our security now second-to-metal! 🔐

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feature/workos-auth-mode

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@jruszo jruszo marked this pull request as ready for review April 14, 2026 09:08
@jruszo jruszo merged commit 4733125 into master Apr 14, 2026
7 checks passed
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.

1 participant