From 7a5ef2feb460d0019f3b5d1b7c9b6dba8d83e697 Mon Sep 17 00:00:00 2001 From: Jarkko Lehtoranta Date: Thu, 7 Mar 2024 12:57:38 +0200 Subject: [PATCH] feat(idps): Allow to filter idps based on trusted domains Signed-off-by: Jarkko Lehtoranta --- appinfo/app.php | 4 ++-- lib/Controller/SAMLController.php | 2 +- lib/SAMLSettings.php | 12 +++++++++++- lib/Settings/Admin.php | 4 ++++ 4 files changed, 18 insertions(+), 4 deletions(-) diff --git a/appinfo/app.php b/appinfo/app.php index f238ba3a5..e05761533 100644 --- a/appinfo/app.php +++ b/appinfo/app.php @@ -111,7 +111,7 @@ } $multipleUserBackEnds = $samlSettings->allowMultipleUserBackEnds(); -$configuredIdps = $samlSettings->getListOfIdps(); +$configuredIdps = $samlSettings->getListOfIdps($request); $showLoginOptions = ($multipleUserBackEnds || count($configuredIdps) > 1) && $type === 'saml'; if ($redirectSituation === true && $showLoginOptions) { @@ -152,7 +152,7 @@ [ 'requesttoken' => $csrfToken->getEncryptedValue(), 'originalUrl' => $originalUrl, - 'idp' => array_keys($configuredIdps)[0] ?? '', + 'idp' => array_key_first($configuredIdps) ?? '', ] ); header('Location: '.$targetUrl); diff --git a/lib/Controller/SAMLController.php b/lib/Controller/SAMLController.php index 984cc6603..e4beb8c96 100644 --- a/lib/Controller/SAMLController.php +++ b/lib/Controller/SAMLController.php @@ -592,7 +592,7 @@ public function selectUserBackEnd(string $redirectUrl): Http\TemplateResponse { */ private function getIdps(string $redirectUrl): array { $result = []; - $idps = $this->samlSettings->getListOfIdps(); + $idps = $this->samlSettings->getListOfIdps($this->request); foreach ($idps as $idpId => $displayName) { $result[] = [ 'url' => $this->getSSOUrl($redirectUrl, (string)$idpId), diff --git a/lib/SAMLSettings.php b/lib/SAMLSettings.php index 7eb464be9..535630b46 100644 --- a/lib/SAMLSettings.php +++ b/lib/SAMLSettings.php @@ -25,6 +25,7 @@ class SAMLSettings { // IdP-specific keys public const IDP_CONFIG_KEYS = [ 'general-idp0_display_name', + 'general-custom_hosts', 'general-uid_mapping', 'idp-entityId', 'idp-singleLogoutService.responseUrl', @@ -95,11 +96,20 @@ public function __construct( * @return array * @throws Exception */ - public function getListOfIdps(): array { + public function getListOfIdps(?\OCP\IRequest $request = null): array { + $serverHost = !is_null($request) ? $request->getServerHost() : null; + $this->ensureConfigurationsLoaded(); $result = []; foreach ($this->configurations as $configID => $config) { + // Filter configs which don't match the trusted host in the request + if (!empty($serverHost)) { + $customHosts = key_exists('general-custom_hosts', $config) ? array_map('trim', explode(',', $config['general-custom_hosts'])) : []; + if (!in_array($serverHost, $customHosts)) { + continue; + } + } // no fancy array_* method, because there might be thousands $result[$configID] = $config['general-idp0_display_name'] ?? ''; } diff --git a/lib/Settings/Admin.php b/lib/Settings/Admin.php index 12e0079e8..0e706c2f3 100644 --- a/lib/Settings/Admin.php +++ b/lib/Settings/Admin.php @@ -81,6 +81,10 @@ public function getForm() { 'type' => 'line', 'required' => true, ], + 'custom_hosts' => [ + 'text' => $this->l10n->t('Hostnames associated with this provider (e.g. nextcloud.a.com, nextcloud.b.com).'), + 'type' => 'line', + ], 'require_provisioned_account' => [ 'text' => $this->l10n->t('Only allow authentication if an account exists on some other backend (e.g. LDAP).'), 'type' => 'checkbox',