Skip to content

Add Keycloak-backed tests for email-claim precedence and fallback - #97

Open
NovrusShehaj wants to merge 1 commit into
mainfrom
chore/keycloak-tests
Open

Add Keycloak-backed tests for email-claim precedence and fallback#97
NovrusShehaj wants to merge 1 commit into
mainfrom
chore/keycloak-tests

Conversation

@NovrusShehaj

Copy link
Copy Markdown
Collaborator

Summary

Adds three integration tests that prove get_current_user's email-claim
precedence/fallback logic against real, Keycloak-issued tokens — not
mocked JWTs or a stubbed identity provider. Two new OIDC clients are added to
the existing testcontainers-backed Keycloak test realm, each shaped to
produce a specific email-claim configuration on its issued tokens, so the
three failure/precedence modes in get_current_user can each be exercised
against a token that actually has that shape.

What changed

  • backend/tests/fixtures/keycloak/realm.json — two new OIDC clients
    added to the biosim-test realm import:

    • biosim-test-client-namespaced-email — stamps both a hardcoded
      namespaced https://api.biosimulations.org/email claim and a plain
      email claim, to prove the namespaced claim wins.
    • biosim-test-client-no-email — stamps neither claim, to prove a missing
      email degrades to None rather than crashing.
  • backend/tests/fixtures/keycloak/container.pyNAMESPACED_EMAIL_CLIENT_ID
    and NO_EMAIL_CLIENT_ID constants for the two new clients.

  • backend/tests/fixtures/keycloak/client.py — two new fixtures,
    alice_token_namespaced_email and alice_token_no_email_claim, each
    fetching a real access token for Alice from one of the new clients via the
    existing fetch_keycloak_token() real direct-grant flow.

  • backend/tests/conftest.py — registers the two new fixtures.

  • backend/tests/common/test_auth0.py (new file) — three tests:

    • test_get_current_user_reads_namespaced_email_claim
    • test_get_current_user_falls_back_to_plain_email_claim
    • test_get_current_user_no_email_claim_at_all

    Each calls get_current_user directly with a real bearer token and asserts
    on user.email. Marked pytest.mark.integration_local.

  • backend/pyproject.toml — adds a [tool.basedpyright] section
    (pythonVersion, venvPath, venv, extraPaths). Editor/type-checker
    config, unrelated to the Keycloak test work but included in this commit.

Keycloak integration

No mocking of Keycloak, JWKS, or JWT verification is introduced or present.
The existing keycloak_auth_settings fixture (unchanged by this PR) points
the app's live Auth0Settings at the running testcontainers Keycloak
container via monkeypatch; the actual verification code in
common/auth/auth0.py (JWKS fetch, RS256 signature check, issuer/audience
check) runs unmodified against real tokens fetched from Keycloak's real
/protocol/openid-connect/token endpoint. Verified directly: running the new
tests shows live HTTP calls to the Keycloak container's token and JWKS
endpoints, e.g.:

POST http://localhost:<port>/realms/biosim-test/protocol/openid-connect/token "HTTP/1.1 200 OK"
GET  http://localhost:<port>/realms/biosim-test/protocol/openid-connect/certs "HTTP/1.1 200 OK"

Test coverage

3 new tests, all passing. Also re-ran the 8 pre-existing
tests/rbac_demo/test_keycloak_integration.py end-to-end RBAC tests (same
Keycloak realm, unaffected by this PR) to confirm no regression in the
broader Keycloak test path.

Testing

cd backend
uv run ruff check .                                                              # All checks passed
uv run mypy biosim_server tests                                                  # Success: no issues found in 124 source files
uv run python -m pytest tests/common/test_auth0.py tests/rbac_demo/test_keycloak_integration.py \
    -v -m integration_local                                                      # 11 passed

All commands run against a real Docker-based Keycloak testcontainers
instance (started for this verification); results observed directly, not
assumed.

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