diff --git a/lib/SimpleSAML/Auth/Simple.php b/lib/SimpleSAML/Auth/Simple.php index 552550d33e7b433cb417df070918e5aca04e4145..0909d9790bb341a9fb9284418d52a94fe3dd7eca 100644 --- a/lib/SimpleSAML/Auth/Simple.php +++ b/lib/SimpleSAML/Auth/Simple.php @@ -26,8 +26,8 @@ class Simple */ protected string $authSource; - /** @var \SimpleSAML\Configuration */ - protected Configuration $app_config; + /** @var \SimpleSAML\Configuration|null */ + protected ?Configuration $app_config; /** @var \SimpleSAML\Session */ protected Session $session; @@ -46,8 +46,7 @@ class Simple $config = Configuration::getInstance(); } $this->authSource = $authSource; - /** @psalm-var \SimpleSAML\Configuration $this->app_config */ - $this->app_config = $config->getConfigItem('application'); + $this->app_config = $config->getOptionalConfigItem('application', null); if ($session === null) { $session = Session::getSessionFromRequest(); diff --git a/lib/SimpleSAML/Configuration.php b/lib/SimpleSAML/Configuration.php index fed916d882d6014837a868b0c406df85bc5f1253..71c4f0ea5b7713b1cadf4026771896e7a03fdfb3 100644 --- a/lib/SimpleSAML/Configuration.php +++ b/lib/SimpleSAML/Configuration.php @@ -972,41 +972,51 @@ class Configuration implements Utils\ClearableState /** * Retrieve an array as a \SimpleSAML\Configuration object. * - * This function will load the value of an option into a \SimpleSAML\Configuration object. The option must contain - * an array. + * This function will load the value of an option into a \SimpleSAML\Configuration object. + * The option must contain an array. * - * An exception will be thrown if this option isn't an array, or if this option isn't found, and no default value - * is given. + * An exception will be thrown if this option isn't an array, or if this option isn't found. * * @param string $name The name of the option. + * @return \SimpleSAML\Configuration The option with the given name, + * + * @throws \SimpleSAML\Assert\AssertionFailedException If the option is not an array. + */ + public function getConfigItem(string $name): Configuration + { + $ret = $this->getArray($name); + + return self::loadFromArray($ret, $this->location . '[' . var_export($name, true) . ']'); + } + + + + /** + * Retrieve an optional array as a \SimpleSAML\Configuration object. + * + * This function will load the optional value of an option into a \SimpleSAML\Configuration object. + * The option must contain an array. + * + * An exception will be thrown if this option isn't an array, or if this option isn't found. + * + * @param string $name The name of the option. * @param array|null $default A default value which will be used if the option isn't found. An empty Configuration - * object will be returned if this parameter isn't given and the option doesn't exist. - * This function will only return null if $default is set to null and the option - * doesn't exist. + * object will be returned if this parameter isn't given and the option doesn't exist. + * This function will only return null if $default is set to null and the option doesn't exist. * * @return \SimpleSAML\Configuration|null The option with the given name, - * or $default if the option isn't found and $default is specified. + * or $default, converted into a Configuration object. * - * @throws \Exception If the option is not an array. + * @throws \SimpleSAML\Assert\AssertionFailed\Exception If the option is not an array. */ - public function getConfigItem(string $name, $default = []): ?Configuration + public function getOptionalConfigItem(string $name, ?array $default): ?Configuration { - $ret = $this->getValue($name, $default); - - if ($ret === null) { - // the option wasn't found, or it is explicitly null - // do not instantiate a new Configuration instance, but just return null - return null; - } - - if (!is_array($ret)) { - throw new \Exception( - $this->location . ': The option ' . var_export($name, true) . - ' is not an array.' - ); + if (!$this->hasValue($name)) { + // the option wasn't found, or it matches the default value. In any case, return this value + return $default; } - return self::loadFromArray($ret, $this->location . '[' . var_export($name, true) . ']'); + return $this->getConfigItem($name); } diff --git a/lib/SimpleSAML/Module.php b/lib/SimpleSAML/Module.php index cc3c132cc67ad61c1f43d8bf1bdeb24a10b974ff..d956eaeb0e39c2b1345d45f2f7127ee22fba3d2e 100644 --- a/lib/SimpleSAML/Module.php +++ b/lib/SimpleSAML/Module.php @@ -299,9 +299,9 @@ class Module } /** @psalm-var \SimpleSAML\Configuration $assetConfig */ - $assetConfig = $config->getConfigItem('assets'); + $assetConfig = $config->getOptionalConfigItem('assets', null); /** @psalm-var \SimpleSAML\Configuration $cacheConfig */ - $cacheConfig = $assetConfig->getConfigItem('caching'); + $cacheConfig = $assetConfig ?: $assetOptionalConfig->getConfigItem('caching', null); $response = new BinaryFileResponse($path); $response->setCache([ // "public" allows response caching even if the request was authenticated, diff --git a/lib/SimpleSAML/Utils/HTTP.php b/lib/SimpleSAML/Utils/HTTP.php index 0bd1e351f6f38a56a9a8d9f1a4b95789830cbb59..25317d1c4b422f81a7ffed27d4809ed985dd0776 100644 --- a/lib/SimpleSAML/Utils/HTTP.php +++ b/lib/SimpleSAML/Utils/HTTP.php @@ -804,8 +804,8 @@ class HTTP */ /** @var \SimpleSAML\Configuration $appcfg */ - $appcfg = $cfg->getConfigItem('application'); - $appurl = $appcfg->getOptionalString('baseURL', null); + $appcfg = $cfg->getOptionalConfigItem('application', null); + $appurl = $appcfg ?: $appcfg->getOptionalString('baseURL', null); if (!empty($appurl)) { $protocol = parse_url($appurl, PHP_URL_SCHEME); $hostname = parse_url($appurl, PHP_URL_HOST); diff --git a/tests/lib/SimpleSAML/ConfigurationTest.php b/tests/lib/SimpleSAML/ConfigurationTest.php index 3a6f1aeda0318ef1f98f8b91a4f545c8772497f5..b13e0782333113758ff239a0874eca021334d17e 100644 --- a/tests/lib/SimpleSAML/ConfigurationTest.php +++ b/tests/lib/SimpleSAML/ConfigurationTest.php @@ -647,25 +647,30 @@ class ConfigurationTest extends ClearStateTestCase $c = Configuration::loadFromArray([ 'opt' => ['a' => 42], ]); - $this->assertNull($c->getConfigItem('missing_opt', null)); + $opt = $c->getConfigItem('opt'); - $notOpt = $c->getConfigItem('notOpt'); $this->assertInstanceOf(Configuration::class, $opt); - $this->assertInstanceOf(Configuration::class, $notOpt); - $this->assertEquals($opt->getValue('a'), 42); + + // Missing option + $this->expectException(AssertionFailedException::class); + $c->getConfigItem('missing_opt'); } /** - * Test \SimpleSAML\Configuration::getConfigItem() wrong option + * Test \SimpleSAML\Configuration::getOptionalConfigItem() */ - public function testGetConfigItemWrong(): void + public function testGetOptionalConfigItem(): void { - $this->expectException(Exception::class); $c = Configuration::loadFromArray([ - 'opt' => 'not_an_array', + 'opt' => ['a' => 42], ]); - $c->getConfigItem('opt'); + + $opt = $c->getOptionalConfigItem('opt', null); + $this->assertInstanceOf(Configuration::class, $opt); + + // Missing option + $this->assertNull($c->getOptionalConfigItem('missing_opt', null)); }