Skip to content

chore(deps): upgrade itk-dev/openid-connect-bundle to 5.0#474

Merged
tuj merged 2 commits into
release/3.0.0from
feature/openid-connect-bundle-5
Jun 3, 2026
Merged

chore(deps): upgrade itk-dev/openid-connect-bundle to 5.0#474
tuj merged 2 commits into
release/3.0.0from
feature/openid-connect-bundle-5

Conversation

@turegjorup

@turegjorup turegjorup commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Summary

Upgrades itk-dev/openid-connect-bundle (and upstream itk-dev/openid-connect) from 4.x to 5.0, following both packages' UPGRADE-5.0.md guides, and closes a long-standing worker-exhaustion risk by bounding the OIDC HTTP calls with an explicit timeout.

1. Bundle 5.0 upgrade

The 5.0 release reworks the exception hierarchy around a marker interface: concrete exceptions now extend SPL types and implement OpenIdConnectExceptionInterface, and no longer extend the deprecated ItkOpenIdConnectException. As a result, the existing catch (ItkOpenIdConnectException ...) blocks would silently match nothing after the bump — so this is the one thing the upgrade can break.

  • composer.json / composer.lockitk-dev/openid-connect-bundle: ^5.0; resolves both OIDC packages to 5.0.0.
  • src/Controller/Api/AuthOidcController.php — the two getUrls() catch sites now catch OpenIdConnectExceptionInterface.
  • src/Security/AzureOidcAuthenticator.php — the authenticate() catch now uses OpenIdConnectExceptionInterface (which also covers InvalidProviderException).

Runtime behaviour is unchanged: 404 for an unknown provider, 500 for an OIDC failure, endSessionUrl: null when the end-session endpoint isn't configured, and OIDC failures during claim validation wrapped as CustomUserMessageAuthenticationException.

2. Explicit OIDC HTTP timeout (worker-exhaustion fix)

The bundle never set a Guzzle timeout, so calls to the IdP inherited Guzzle's default of 0wait indefinitely. A hung/slow IdP could pin a php-fpm worker. 5.0.0 does not fix this on its own; the http_client_options.timeout knob (added in 4.2.0, forwarded through league/oauth2-client to Guzzle) is opt-in with no default, and this project never set it.

  • config/packages/itkdev_openid_connect.yaml — set http_client_options.timeout on both providers.
  • .env — new OIDC_HTTP_TIMEOUT env var, default 5s (passes the env-coverage gate).
  • docs/configuration/openid-connect.md — documented the new var (the README delegates OIDC env-var docs to this file, so no README change needed).

Most exposed path: the un-cached token-exchange POST on every login callback is now bounded; the discovery-doc and JWKS fetches (cached 24h) are bounded too on cold cache / refresh. Verified %env(float:OIDC_HTTP_TIMEOUT)% resolves to float(5).

Tests

The exception-mapping branches were previously uncovered — nothing in the suite would have caught the silent-catch regression. Added:

  • AuthOidcControllerTest (3 new) — the getUrls() branches: null end-session URL (200), unknown provider (404), generic OIDC failure (500).
  • AzureOidcAuthenticatorTest (new file, 8 tests) — the previously untested authenticate() logic: internal/external user provisioning, group-claim → tenant-role mapping, multi-role accumulation for one tenant, tenant de-provisioning when claims shrink, and the unknown-role-suffix / missing-id-claim / unsupported-provider rejection paths.

task code-analysis clean; 14 OIDC tests / 40 assertions pass.

Follow-up (not in this PR)

While testing the tenant-role mapping I found a latent bug in AzureOidcAuthenticator::getTenantKeyWithRole(): it derives the tenant key with str_replace('Admin', '', $group) / str_replace('Redaktoer', ...), which strips every occurrence rather than the trailing suffix (e.g. AdminTeamAdminTeam instead of AdminTeam). Low likelihood (only bites tenant keys containing those substrings) but a real correctness bug in access-control code. Happy to fix it under a separate issue/PR with an anchored suffix removal.

🤖 Generated with Claude Code

turegjorup and others added 2 commits June 2, 2026 21:13
Bumps itk-dev/openid-connect-bundle (and upstream itk-dev/openid-connect)
from 4.x to 5.0. The 5.0 release reworks the exception hierarchy around a
marker interface: concrete exceptions no longer extend the now-deprecated
ItkOpenIdConnectException, so existing `catch (ItkOpenIdConnectException)`
blocks would silently match nothing.

Migrate the three OIDC catch sites in AuthOidcController and the one in
AzureOidcAuthenticator to catch OpenIdConnectExceptionInterface, the new
marker that both bundle- and library-thrown exceptions implement. Behaviour
(404 unknown provider, 500 OIDC failure, null end-session URL, wrapped auth
failure) is unchanged.

Add regression tests:
- AuthOidcControllerTest: the three getUrls() exception-mapping branches
  (null end-session URL, 404, 500) that the upgrade put at risk.
- AzureOidcAuthenticatorTest: the previously untested authenticate() logic
  — internal/external user provisioning, group-claim to tenant-role mapping,
  multi-role accumulation, tenant de-provisioning, and the
  unknown-suffix / missing-claim / unsupported-provider rejections.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
The bundle never set a Guzzle timeout, so calls to the IdP (discovery,
JWKS, and especially the un-cached token exchange on the login callback)
inherited Guzzle's default of 0 — wait indefinitely. A hung or slow IdP
could therefore tie up a php-fpm worker until the FPM request terminator
kicked in.

itk-dev/openid-connect-bundle 4.2+ exposes http_client_options.timeout
(forwarded through league/oauth2-client to Guzzle), but it is opt-in with
no default. Set it on both providers via a new OIDC_HTTP_TIMEOUT env var
(default 5s), documented in .env and docs/configuration/openid-connect.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@turegjorup turegjorup self-assigned this Jun 2, 2026
@tuj
tuj merged commit ffc34eb into release/3.0.0 Jun 3, 2026
25 checks passed
@tuj
tuj deleted the feature/openid-connect-bundle-5 branch June 3, 2026 07:59
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.

2 participants