feat: add Keycloak OIDC integration#3340
Draft
boehlke wants to merge 18 commits intoOpenSlides:mainfrom
Draft
Conversation
63ce527 to
2e97848
Compare
- OIDC token validator with JWKS verification - Keycloak admin client factory for Admin API operations - oidc-provision and who-am-i endpoints - Redis session invalidation for OIDC backchannel logout - Auth adapter extensions for OIDC token validation - PostgreSQL schema updates for keycloak_id column Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Sync user CRUD operations to Keycloak via Admin API (keycloak_sync_mixin) - Save Keycloak account action for user provisioning - Migration 0101: migrate existing users to Keycloak with Argon2 password hashes - Migration 0102: add keycloak_id to user view Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Backchannel logout tests - User migration tests (Argon2 hash import) - User sync tests (CRUD operations to Keycloak) - Update existing system tests for Keycloak-aware base classes Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Swap migration order so keycloak_id column (0101) is added before the Keycloak user sync (0102) which depends on it. Migration 0101 now only adds the column to user_t via ALTER TABLE. The user view uses SELECT * and picks up new columns automatically, so no view replacement is needed. Also regenerates schema_relational.sql to include keycloak_id for fresh database installs, and updates module references in application.py and tests. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Apply Black, isort, pyupgrade formatting to all OIDC files - Fix flake8 errors: remove unused imports (Optional, os), fix f-string without placeholders, fix E402 import ordering - Fix mypy errors: add proper type annotations to test fixtures, fix implicit Optional parameters, update RouteFunction type alias to use RouteResponse, add type narrowing in base_view, fix test_presenter missing user_id argument - All CI linting checks (black, isort, flake8, mypy, pyupgrade) now pass Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Point meta submodule to ec0bc10 (the actual HEAD of feature/keycloak-oidc on kryptance/openslides-meta), replacing the orphaned commit 761c67d that was force-pushed away. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Add null checks for fetchone() results before indexing (3 sites) - Change get_user() return type to dict[str, Any] | None - Use column name instead of int index for DictRow in application.py Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
…l.sql The generated schema_relational.sql was missing the keycloak_id column in user_t, which was added to models.yml but the SQL wasn't regenerated. This caused the auth-service's PostgreSQL queries to fail with "column keycloak_id does not exist". Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
… sync data_manipulation() from migration 0102 sets both migration 101 and 102 to FINALIZATION_REQUIRED. The previous code only reset migration 101, leaving migration 102 stuck in FINALIZATION_REQUIRED state. This caused "Missing 1 migrations to apply" errors on every backend API request when OIDC mode was enabled with a fresh database. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Move user provisioning logic from BaseView._authenticate_oidc() to oidc-provision route in ActionView. This ensures provisioning only happens during the OIDC redirect flow, not on every authenticated request. Changes: - ActionView.oidc_provision_route(): Full provisioning flow with token validation, user info fetch, and user creation/update - BaseView._authenticate_oidc(): Simplified to only authenticate and lookup existing users (removed provisioning logic) - BaseView._provision_oidc_user(): Removed
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Import is_session_invalidated from base_view where it is defined, not from oidc_validator where it does not exist.
In OIDC mode, the Traefik plugin manages the session. The provision endpoint only needs to provision the user and redirect - no OpenSlides auth token is needed.
Returns the remaining seconds until the access token expires, allowing the client to proactively refresh before expiry.
ed32294 to
ec071dc
Compare
ec071dc to
81db2fb
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
oidc-provisionandwho-am-iendpoints for OIDC session managementkeycloak_idto user viewContext
This is the largest PR in the Keycloak OIDC integration series. Structured as 3 commits:
Related PRs:
🤖 Generated with Claude Code