Skip to content

fix: graceful handling when user_saml is enabled but no IdP is configured#1138

Merged
CarlSchwan merged 2 commits into
nextcloud:masterfrom
IONOS-Productivity:fix/unconfigured-saml-crash
Jun 18, 2026
Merged

fix: graceful handling when user_saml is enabled but no IdP is configured#1138
CarlSchwan merged 2 commits into
nextcloud:masterfrom
IONOS-Productivity:fix/unconfigured-saml-crash

Conversation

@printminion-co

@printminion-co printminion-co commented Jun 10, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Fixes a 500 TypeError that occurs when user_saml is active (type=saml) but no IdP has been configured
  • Redirects to the existing genericError page with a translatable user-readable message instead of crashing
  • Adds occ saml:config:validate for one-shot admin/support diagnostics (exit 0/1/2)

Reproduction

  1. Install/enable the user_saml app
  2. occ config:app:set user_saml type --value saml
  3. Do not add any IdP via the admin panel
  4. Open the Nextcloud login page → 500 TypeError

Root Cause

The crash is a two-step interaction within the same request:

  1. Application.php beforeware calls $samlSettings->getListOfIdps()ensureConfigurationsLoaded(-1) loads from DB → DB is empty → sets configurationsLoadedState = LOADED_ALL
  2. SAMLController::login(1) calls getOneLoginSettingsArray(1)ensureConfigurationsLoaded(1) returns early (already LOADED_ALL) → $this->configurations[1] is never set → remains null
  3. Line 156 calls array_key_exists('sp-entityId', $this->configurations[$idp])array_key_exists() on null throws a TypeError

Every other field access in getOneLoginSettingsArray() uses the safe ?? '' null-coalesce pattern; line 156 was the one outlier using array_key_exists().

Changes

lib/SAMLSettings.php

  • Replace the array_key_exists() call with ?? '' (consistent with all other lines in the method)
  • Add an early guard after ensureConfigurationsLoaded() that throws InvalidArgumentException when the requested IdP is absent from $configurations, converting a cryptic null-pointer into a clear, actionable message

lib/Controller/SAMLController.php

  • Catch InvalidArgumentException from getOneLoginSettingsArray() in login() and redirect to the existing genericError page with a translatable user-readable message, instead of letting the exception propagate as a 500

occ saml:config:validate (new command)

Gives support teams and administrators a single command to diagnose the SAML configuration state without reading raw database rows:

$ occ saml:config:validate
Type: saml
  IdP #1 (My IdP): MISSING idp-entityId, idp-singleSignOnService.url

Exit codes:

Code Meaning
0 All configured IdPs pass required-field validation
1 type not set — app is not active
2 Active but one or more required fields are missing

Validated fields per IdP: idp-entityId, idp-singleSignOnService.url, general-uid_mapping.

New files: lib/Command/ConfigValidate.php, tests/unit/Command/ConfigValidateTest.php, + one line in appinfo/info.xml.

Tests

  • tests/unit/SAMLSettingsTest.php (new): reproduces the exact LOADED_ALL bug scenario; also covers the simple not-in-DB case, happy path, and sp-entityId fallback to metadata URL
  • tests/unit/Controller/SAMLControllerTest.php: adds testLoginWithUnconfiguredIdpRedirectsToGenericError() — verifies the controller redirects to genericError when getOneLoginSettingsArray() throws InvalidArgumentException
  • tests/unit/Command/ConfigValidateTest.php (new): covers all four exit-code paths (type not set, no IdPs, OK, missing fields)

After This Fix

  • /login — shows the normal Nextcloud login page (no crash; admins can still log in to fix the configuration)
  • /apps/user_saml/saml/login?idp=1 — redirects to the existing genericError page with a readable message: "SAML authentication is not configured. Please ask your administrator to complete the SAML setup in the admin panel."
  • data/nextcloud.log — no array_key_exists(): Argument #2 must be of type array, null given

@printminion-co printminion-co marked this pull request as ready for review June 10, 2026 13:49
Comment thread lib/Controller/SAMLController.php Outdated
@printminion-co printminion-co marked this pull request as draft June 11, 2026 07:33
@printminion-co printminion-co force-pushed the fix/unconfigured-saml-crash branch 2 times, most recently from 570b38e to 261d821 Compare June 11, 2026 07:46
When user_saml is enabled (type=saml) but no IdP exists in the database,
navigating to the login page caused a TypeError:

  array_key_exists(): Argument #2 ($array) must be of type array,
  null given in SAMLSettings.php line 147

Root cause: Application.php beforeware calls getListOfIdps() which sets
LOADED_ALL on SAMLSettings. When SAMLController::login() then calls
getOneLoginSettingsArray(1), ensureConfigurationsLoaded(1) returns early
due to LOADED_ALL, leaving $this->configurations[1] undefined (null).
The array_key_exists() call on null then throws a TypeError.

Two fixes in SAMLSettings::getOneLoginSettingsArray():
- Replace the lone array_key_exists() call (line 156) with ?? '' to be
  consistent with every other field access in the method.
- Add an early guard that throws InvalidArgumentException when the
  requested IdP is not in $configurations, converting a cryptic
  null-pointer into a clear error message.

SAMLController::login() catches InvalidArgumentException and redirects
to the existing genericError page with a translatable user-readable
message instead of letting the exception propagate as a 500.

Tests added:
- SAMLSettingsTest: reproduces the exact LOADED_ALL bug scenario, tests
  the simple not-in-db case, happy path, and sp-entityId fallback.
- SAMLControllerTest: verifies the controller redirects to genericError
  when getOneLoginSettingsArray() throws InvalidArgumentException.

Signed-off-by: Misha M.-Kupriyanov <kupriyanov@strato.de>
Adds a new occ command that support teams and administrators can run to
get an immediate diagnosis of the user_saml configuration state:

  occ saml:config:validate

Exit codes:
  0 — all configured IdPs pass required-field validation
  1 — SAML type not set (app is not active)
  2 — active but one or more required fields are missing

The command checks for the three fields required for a working SAML
login: idp-entityId, idp-singleSignOnService.url, general-uid_mapping.

Useful for support diagnostics and CI/monitoring health checks.

Signed-off-by: Misha M.-Kupriyanov <kupriyanov@strato.de>
@printminion-co printminion-co force-pushed the fix/unconfigured-saml-crash branch from 261d821 to 61d9a6e Compare June 11, 2026 08:05
@printminion-co printminion-co marked this pull request as ready for review June 11, 2026 08:05
@artonge artonge requested a review from CarlSchwan June 16, 2026 08:56
@CarlSchwan CarlSchwan merged commit e373abf into nextcloud:master Jun 18, 2026
57 checks passed
@github-actions

Copy link
Copy Markdown

Hello there,
Thank you so much for taking the time and effort to create a pull request to our Nextcloud project.

We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process.

Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6

Thank you for contributing to Nextcloud and we hope to hear from you soon!

(If you believe you should not receive this message, you can add yourself to the blocklist.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants