Skip to content

OpenConceptLab/ocl_online#535 | Percent-encode the query values in the Keycloak login, sign-up, reset and logout URLs - #946

Merged
snyaggarwal merged 1 commit into
masterfrom
ocl_online#535
Oct 19, 2026
Merged

snyaggarwal merged 1 commit into
masterfrom
ocl_online#535

Conversation

@snyaggarwal

Copy link
Copy Markdown
Contributor

Server-side part of OpenConceptLab/ocl_online#535.

Why

OpenIDAuthService built the Keycloak URLs with f-strings. The values come from request.query_params, which Django has already decoded, and went into the URL raw. A post_logout_redirect_uri or redirect_uri containing ?, & or # therefore split into extra parameters or, with #, lost everything after it on the redirect to Keycloak. That second hop contributed to the "Invalid redirect uri" page users hit after an expired session in the Mapper.

What changes

  • A new OpenIDAuthService.build_url(endpoint, params, code_challenge, code_challenge_method) encodes every value with urlencode(..., quote_via=quote).
  • get_login_redirect_url, get_registration_redirect_url, get_reset_password_redirect_url and get_logout_redirect_url use it. Parameter names and order are unchanged.
  • On the wire, values are now percent-encoded, for example redirect_uri=http%3A%2F%2Flocalhost%3A4000 and scope=openid%20profile%20email. Keycloak decodes them to the same strings.

No migrations, indexing or env var changes.

Verification

  • docker exec -e OIDC_SERVER_URL= -e OIDC_SERVER_INTERNAL_URL= oclapi2-api-1 python manage.py test core.services.auth core.users.tests --keepdb: 97 tests, OK.
    • The two exact-string tests now expect the encoded form, and the login test also covers the PKCE parameters.
    • The new test_redirect_urls_keep_query_values_whole passes a redirect_uri containing #, ? and &, plus & and # in state and nonce, through all four builders. It checks that each value reads back intact via parse_qs with no fragment.
    • The OIDC URLs are unset in that command because the auth tests expect empty endpoints. A container with OIDC_SERVER_URL set fails them before and after this change.
  • docker exec oclapi2-api-1 pylint core/services/auth/openid.py core/services/auth/tests.py: 10.00/10.
  • Not tested against a real Keycloak.

Companion PRs: OpenConceptLab/oclmap#109 and OpenConceptLab/oclweb3#67. Their values are already safe either way, so the three can be deployed in any order.

🤖 Generated with Claude Code

…e Keycloak login, sign-up, reset and logout URLs

OpenIDAuthService built these URLs with f-strings, putting the already-decoded
query values in raw. A post_logout_redirect_uri or redirect_uri carrying ?, &
or # split into extra params or lost its tail. A new build_url helper encodes
every value with urlencode(quote_via=quote), keeping the parameter names and
order.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

@snyaggarwal snyaggarwal left a comment

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: Approve

Issue complete: yes. Centralizing Keycloak URL construction with urlencode preserves redirect_uri, post_logout_redirect_uri, state, nonce, and PKCE values across the API-to-Keycloak hop, including embedded #, ? and & characters. Existing parameter order and endpoint selection remain intact.

Security blockers: none. Encoding the decoded query values removes parameter-splitting and fragment-loss behavior without weakening redirect validation.

Verification: the focused auth suite passed locally (7 tests), including the new round-trip encoding coverage; Snyk passes. GitHub Pylint was still pending at review time, so merge should remain gated on that check.

(snyaggarwal • ReviewAutomation/GPT-5)

@snyaggarwal
snyaggarwal merged commit 9c83650 into master Oct 19, 2026
3 checks passed
@snyaggarwal
snyaggarwal deleted the ocl_online#535 branch October 19, 2026 04:52
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