diff --git a/src/Entities/Bases/AbstractProvider.php b/src/Entities/Bases/AbstractProvider.php index 9e63abde92dc28fc928e623ea3be29f2794de2fb..c4b66b672dafc44b29e24f04faafb5bef1356afa 100755 --- a/src/Entities/Bases/AbstractProvider.php +++ b/src/Entities/Bases/AbstractProvider.php @@ -18,23 +18,28 @@ abstract class AbstractProvider implements ProviderInterface $this->entityId = $this->resolveEntityId(); } - protected function resolveOptionallyLocalizedString(string $key, string $locale = 'en'): ?string - { - if (!isset($this->metadata[$key])) { + protected function resolveOptionallyLocalizedString( + string $key, + string $locale = self::DEFAULT_LOCALE, + array $metadataOverride = null + ): ?string { + $metadata = $metadataOverride ?? $this->metadata; + + if (!isset($metadata[$key])) { return null; } // Check for non-localized version. - if (is_string($this->metadata[$key])) { - return $this->metadata[$key]; + if (is_string($metadata[$key])) { + return $metadata[$key]; } if ( - is_array($this->metadata[$key]) && - !empty($this->metadata[$key][$locale]) && - is_string($this->metadata[$key][$locale]) + is_array($metadata[$key]) && + !empty($metadata[$key][$locale]) && + is_string($metadata[$key][$locale]) ) { - return $this->metadata[$key][$locale]; + return $metadata[$key][$locale]; } return null; @@ -50,8 +55,9 @@ abstract class AbstractProvider implements ProviderInterface return $this->entityId; } - abstract public function getName(string $locale = 'en'): ?string; - abstract public function getDescription(string $locale = 'en'): ?string; + abstract public function getName(string $locale = self::DEFAULT_LOCALE): ?string; + abstract public function getDescription(string $locale = self::DEFAULT_LOCALE): ?string; abstract protected function resolveEntityId(): string; abstract public function getProtocol(): AuthenticationProtocolInterface; + abstract protected function getProviderDescription(): string; } diff --git a/src/Entities/Interfaces/ProviderInterface.php b/src/Entities/Interfaces/ProviderInterface.php index c82a1792698873b1ba3e295addba031708832ca4..a5957a51fc49a2258d3ae76effb2a849d1dcc014 100755 --- a/src/Entities/Interfaces/ProviderInterface.php +++ b/src/Entities/Interfaces/ProviderInterface.php @@ -9,9 +9,11 @@ use SimpleSAML\Module\accounting\Entities\Bases\AbstractPayload; interface ProviderInterface { + public const DEFAULT_LOCALE = 'en'; + public function getMetadata(): array; - public function getName(string $locale = 'en'): ?string; + public function getName(string $locale = self::DEFAULT_LOCALE): ?string; public function getEntityId(): string; - public function getDescription(string $locale = 'en'): ?string; + public function getDescription(string $locale = self::DEFAULT_LOCALE): ?string; public function getProtocol(): AuthenticationProtocolInterface; } diff --git a/src/Entities/Providers/Bases/AbstractSaml2Provider.php b/src/Entities/Providers/Bases/AbstractSaml2Provider.php new file mode 100644 index 0000000000000000000000000000000000000000..0a5fd987ce73f561c7a66451fe6233eda59e9a38 --- /dev/null +++ b/src/Entities/Providers/Bases/AbstractSaml2Provider.php @@ -0,0 +1,69 @@ +<?php + +namespace SimpleSAML\Module\accounting\Entities\Providers\Bases; + +use SimpleSAML\Module\accounting\Entities\Bases\AbstractProvider; +use SimpleSAML\Module\accounting\Entities\Interfaces\AuthenticationProtocolInterface; +use SimpleSAML\Module\accounting\Exceptions\MetadataException; +use SimpleSAML\Module\accounting\Entities\Authentication; + +abstract class AbstractSaml2Provider extends AbstractProvider +{ + public const METADATA_KEY_ENTITY_ID = 'entityid'; + public const METADATA_KEY_NAME = 'name'; + public const METADATA_KEY_DESCRIPTION = 'description'; + public const METADATA_KEY_UI_INFO = 'UIInfo'; + public const METADATA_KEY_UI_INFO_DESCRIPTION = 'Description'; + public const METADATA_KEY_UI_INFO_DISPLAY_NAME = 'DisplayName'; + + protected function getEntityInfoString(string $key, string $locale = self::DEFAULT_LOCALE): ?string + { + return $this->resolveOptionallyLocalizedString($key, $locale); + } + + protected function getEntityUiInfoString(string $key, string $locale = self::DEFAULT_LOCALE): ?string + { + if ( + isset($this->metadata[self::METADATA_KEY_UI_INFO]) && + is_array($this->metadata[self::METADATA_KEY_UI_INFO]) + ) { + return $this->resolveOptionallyLocalizedString( + $key, + $locale, + $this->metadata[self::METADATA_KEY_UI_INFO] + ); + } + + return null; + } + + public function getName(string $locale = self::DEFAULT_LOCALE): ?string + { + return $this->getEntityInfoString(self::METADATA_KEY_NAME, $locale) ?? + $this->getEntityUiInfoString(self::METADATA_KEY_UI_INFO_DISPLAY_NAME, $locale); + } + + public function getDescription(string $locale = self::DEFAULT_LOCALE): ?string + { + return $this->getEntityInfoString(self::METADATA_KEY_DESCRIPTION, $locale) ?? + $this->getEntityUiInfoString(self::METADATA_KEY_UI_INFO_DESCRIPTION, $locale); + } + + /** + * @throws MetadataException + */ + protected function resolveEntityId(): string + { + if (empty($entityId = $this->getEntityInfoString(self::METADATA_KEY_ENTITY_ID))) { + $message = sprintf('Provider metadata does not contain entity ID (%s).', $this->getProviderDescription()); + throw new MetadataException($message); + } + + return $entityId; + } + + public function getProtocol(): AuthenticationProtocolInterface + { + return new Authentication\Protocol\Saml2(); + } +} diff --git a/src/Entities/Providers/Identity/Oidc.php b/src/Entities/Providers/Identity/Oidc.php index c662f78753be98476d0c03d8086fb94a0dafa24b..9bc3784b9fd14184f5c9e9f70f1e7c0c34411f3a 100755 --- a/src/Entities/Providers/Identity/Oidc.php +++ b/src/Entities/Providers/Identity/Oidc.php @@ -43,4 +43,9 @@ class Oidc extends AbstractProvider implements IdentityProviderInterface { return new Authentication\Protocol\Oidc(); } + + protected function getProviderDescription(): string + { + return $this->getProtocol()->getDesignation() . ' OpenID Provider'; + } } diff --git a/src/Entities/Providers/Identity/Saml2.php b/src/Entities/Providers/Identity/Saml2.php index 04768636840af510618c96d26587f396b283afe4..8bef30d9a6a930bac920b202f27e8d3e90a13afa 100755 --- a/src/Entities/Providers/Identity/Saml2.php +++ b/src/Entities/Providers/Identity/Saml2.php @@ -5,44 +5,15 @@ declare(strict_types=1); namespace SimpleSAML\Module\accounting\Entities\Providers\Identity; use SimpleSAML\Module\accounting\Entities\Authentication; -use SimpleSAML\Module\accounting\Entities\Bases\AbstractProvider; use SimpleSAML\Module\accounting\Entities\Interfaces\AuthenticationProtocolInterface; use SimpleSAML\Module\accounting\Entities\Interfaces\IdentityProviderInterface; +use SimpleSAML\Module\accounting\Entities\Providers\Bases\AbstractSaml2Provider; use SimpleSAML\Module\accounting\Exceptions\MetadataException; -class Saml2 extends AbstractProvider implements IdentityProviderInterface +class Saml2 extends AbstractSaml2Provider implements IdentityProviderInterface { - public const METADATA_KEY_NAME = 'name'; - public const METADATA_KEY_ENTITY_ID = 'entityid'; - public const METADATA_KEY_DESCRIPTION = 'description'; - - public function getName(string $locale = 'en'): ?string - { - return $this->resolveOptionallyLocalizedString(self::METADATA_KEY_NAME, $locale); - } - - public function getDescription(string $locale = 'en'): ?string - { - return $this->resolveOptionallyLocalizedString(self::METADATA_KEY_DESCRIPTION, $locale); - } - - /** - * @throws MetadataException - */ - protected function resolveEntityId(): string - { - if ( - !empty($this->metadata[self::METADATA_KEY_ENTITY_ID]) && - is_string($this->metadata[self::METADATA_KEY_ENTITY_ID]) - ) { - return $this->metadata[self::METADATA_KEY_ENTITY_ID]; - } - - throw new MetadataException('Identity provider metadata does not contain entity ID.'); - } - - public function getProtocol(): AuthenticationProtocolInterface + protected function getProviderDescription(): string { - return new Authentication\Protocol\Saml2(); + return $this->getProtocol()->getDesignation() . ' Identity Provider'; } } diff --git a/src/Entities/Providers/Service/Oidc.php b/src/Entities/Providers/Service/Oidc.php index 5f5ff82477128169db5708b40932172d79b54a6d..c683718f5caddb8edd6018368c76ddbcb504b2bb 100755 --- a/src/Entities/Providers/Service/Oidc.php +++ b/src/Entities/Providers/Service/Oidc.php @@ -45,4 +45,9 @@ class Oidc extends AbstractProvider implements ServiceProviderInterface { return new Authentication\Protocol\Oidc(); } + + protected function getProviderDescription(): string + { + return $this->getProtocol()->getDesignation() . ' Relying Party'; + } } diff --git a/src/Entities/Providers/Service/Saml2.php b/src/Entities/Providers/Service/Saml2.php index d0dfd4ac065c2b22a7f3dcdcf82c14096981f40d..deeb30727e3c05b0446c315b726a73923321c9c1 100755 --- a/src/Entities/Providers/Service/Saml2.php +++ b/src/Entities/Providers/Service/Saml2.php @@ -4,45 +4,13 @@ declare(strict_types=1); namespace SimpleSAML\Module\accounting\Entities\Providers\Service; -use SimpleSAML\Module\accounting\Entities\Authentication; -use SimpleSAML\Module\accounting\Entities\Bases\AbstractProvider; -use SimpleSAML\Module\accounting\Entities\Interfaces\AuthenticationProtocolInterface; use SimpleSAML\Module\accounting\Entities\Interfaces\ServiceProviderInterface; -use SimpleSAML\Module\accounting\Exceptions\MetadataException; +use SimpleSAML\Module\accounting\Entities\Providers\Bases\AbstractSaml2Provider; -class Saml2 extends AbstractProvider implements ServiceProviderInterface +class Saml2 extends AbstractSaml2Provider implements ServiceProviderInterface { - public const METADATA_KEY_ENTITY_ID = 'entityid'; - public const METADATA_KEY_NAME = 'name'; - public const METADATA_KEY_DESCRIPTION = 'description'; - - public function getName(string $locale = 'en'): ?string - { - return $this->resolveOptionallyLocalizedString(self::METADATA_KEY_NAME, $locale); - } - - public function getDescription(string $locale = 'en'): ?string - { - return $this->resolveOptionallyLocalizedString(self::METADATA_KEY_DESCRIPTION, $locale); - } - - /** - * @throws MetadataException - */ - protected function resolveEntityId(): string - { - if ( - !empty($this->metadata[self::METADATA_KEY_ENTITY_ID]) && - is_string($this->metadata[self::METADATA_KEY_ENTITY_ID]) - ) { - return $this->metadata[self::METADATA_KEY_ENTITY_ID]; - } - - throw new MetadataException('Service provider metadata does not contain entity ID.'); - } - - public function getProtocol(): AuthenticationProtocolInterface + protected function getProviderDescription(): string { - return new Authentication\Protocol\Saml2(); + return $this->getProtocol()->getDesignation() . ' Service Provider'; } } diff --git a/tests/src/Entities/Bases/AbstractProviderTest.php b/tests/src/Entities/Bases/AbstractProviderTest.php index e8d8a2743b4492f6242c9ae8aa5b162bc8cead90..e85837943cde85b720ddbd8a28fb0048beadbb24 100755 --- a/tests/src/Entities/Bases/AbstractProviderTest.php +++ b/tests/src/Entities/Bases/AbstractProviderTest.php @@ -112,6 +112,11 @@ class AbstractProviderTest extends TestCase } }; } + + protected function getProviderDescription(): string + { + return 'provider description'; + } }; } } diff --git a/tests/src/Entities/Providers/Identity/Saml2Test.php b/tests/src/Entities/Providers/Identity/Saml2Test.php index 7c995952a1fee1d1a238a78853682c393d655c6f..5c4db09f39ab25ac6fabe0066dc9d6aa76e15e17 100755 --- a/tests/src/Entities/Providers/Identity/Saml2Test.php +++ b/tests/src/Entities/Providers/Identity/Saml2Test.php @@ -12,6 +12,8 @@ use SimpleSAML\Test\Module\accounting\Constants\StateArrays; /** * @covers \SimpleSAML\Module\accounting\Entities\Providers\Identity\Saml2 * @uses \SimpleSAML\Module\accounting\Entities\Bases\AbstractProvider + * @uses \SimpleSAML\Module\accounting\Entities\Providers\Bases\AbstractSaml2Provider + * @uses \SimpleSAML\Module\accounting\Entities\Authentication\Protocol\Saml2 */ class Saml2Test extends TestCase { diff --git a/tests/src/Entities/Providers/Service/Saml2Test.php b/tests/src/Entities/Providers/Service/Saml2Test.php index c4475d7089d65d70742a6b2b14d65b0860f72316..225c92ab25da2ff79911036270f30ce651c88f26 100755 --- a/tests/src/Entities/Providers/Service/Saml2Test.php +++ b/tests/src/Entities/Providers/Service/Saml2Test.php @@ -9,6 +9,8 @@ use SimpleSAML\Module\accounting\Exceptions\MetadataException; /** * @covers \SimpleSAML\Module\accounting\Entities\Providers\Service\Saml2 * @uses \SimpleSAML\Module\accounting\Entities\Bases\AbstractProvider + * @uses \SimpleSAML\Module\accounting\Entities\Providers\Bases\AbstractSaml2Provider + * @uses \SimpleSAML\Module\accounting\Entities\Authentication\Protocol\Saml2 */ class Saml2Test extends TestCase { diff --git a/tests/src/Helpers/ProviderResolverTest.php b/tests/src/Helpers/ProviderResolverTest.php index 3661701b49175bb33f0e00568a2dbbd82b0fe60c..1e7f3fe5e7bae7ce2df95c6355f2854496ab381f 100755 --- a/tests/src/Helpers/ProviderResolverTest.php +++ b/tests/src/Helpers/ProviderResolverTest.php @@ -21,6 +21,8 @@ use SimpleSAML\Test\Module\accounting\Constants\StateArrays; * @uses \SimpleSAML\Module\accounting\Entities\Providers\Identity\Oidc * @uses \SimpleSAML\Module\accounting\Entities\Providers\Service\Saml2 * @uses \SimpleSAML\Module\accounting\Entities\Providers\Service\Oidc + * @uses \SimpleSAML\Module\accounting\Entities\Providers\Bases\AbstractSaml2Provider + * @uses \SimpleSAML\Module\accounting\Entities\Authentication\Protocol\Saml2 */ class ProviderResolverTest extends TestCase {