From ab9ee518ccb6a32ecf14fdeefd0ecdc84e242119 Mon Sep 17 00:00:00 2001 From: Stephan Kok Date: Mon, 13 Sep 2021 17:52:40 +0200 Subject: [PATCH 1/3] Introduce sso_provider_roles_eb6 to prepare for custom doctrine types --- app/config/config.yml | 10 + .../Version20211019150744.php | 28 ++ .../Metadata/Entity/AbstractRoleEb6.php | 395 +++++++++++++++++ .../Metadata/Entity/IdentityProviderEb6.php | 279 ++++++++++++ .../Metadata/Entity/ServiceProviderEb6.php | 409 ++++++++++++++++++ .../DoctrineMetadataPushRepository.php | 174 +++++++- .../Type/AttributeReleasePolicyType.php | 81 ++++ .../Doctrine/Type/CertificateArrayType.php | 109 +++++ .../Doctrine/Type/ContactPersonArrayType.php | 111 +++++ .../Doctrine/Type/IndexedServiceArrayType.php | 110 +++++ .../Doctrine/Type/LogoType.php | 94 ++++ .../Doctrine/Type/OrganizationType.php | 92 ++++ .../Type/RequestedAttributeArrayType.php | 109 +++++ .../Doctrine/Type/ServiceArrayType.php | 108 +++++ .../Doctrine/Type/ServiceType.php | 91 ++++ .../Doctrine/Type/ShibMdScopeArrayType.php | 108 +++++ .../Type/AttributeReleasePolicyTypeTest.php | 147 +++++++ .../Type/CertificateArrayTypeTest.php | 142 ++++++ .../Type/ContactPersonArrayTypeTest.php | 145 +++++++ .../Type/IndexedServiceArrayTypeTest.php | 137 ++++++ .../Doctrine/Type/LogoTypeTest.php | 137 ++++++ .../Doctrine/Type/OrganizationTypeTest.php | 137 ++++++ .../Type/RequestedAttributeArrayTypeTest.php | 137 ++++++ .../Doctrine/Type/ServiceArrayTypeTest.php | 137 ++++++ .../Doctrine/Type/ServiceTypeTest.php | 152 +++++++ .../Type/ShibMdScopeArrayTypeTest.php | 142 ++++++ 26 files changed, 3707 insertions(+), 14 deletions(-) create mode 100644 database/DoctrineMigrations/Version20211019150744.php create mode 100644 src/OpenConext/EngineBlock/Metadata/Entity/AbstractRoleEb6.php create mode 100644 src/OpenConext/EngineBlock/Metadata/Entity/IdentityProviderEb6.php create mode 100644 src/OpenConext/EngineBlock/Metadata/Entity/ServiceProviderEb6.php create mode 100644 src/OpenConext/EngineBlockBundle/Doctrine/Type/AttributeReleasePolicyType.php create mode 100644 src/OpenConext/EngineBlockBundle/Doctrine/Type/CertificateArrayType.php create mode 100644 src/OpenConext/EngineBlockBundle/Doctrine/Type/ContactPersonArrayType.php create mode 100644 src/OpenConext/EngineBlockBundle/Doctrine/Type/IndexedServiceArrayType.php create mode 100644 src/OpenConext/EngineBlockBundle/Doctrine/Type/LogoType.php create mode 100644 src/OpenConext/EngineBlockBundle/Doctrine/Type/OrganizationType.php create mode 100644 src/OpenConext/EngineBlockBundle/Doctrine/Type/RequestedAttributeArrayType.php create mode 100644 src/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceArrayType.php create mode 100644 src/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceType.php create mode 100644 src/OpenConext/EngineBlockBundle/Doctrine/Type/ShibMdScopeArrayType.php create mode 100644 tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/AttributeReleasePolicyTypeTest.php create mode 100644 tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/CertificateArrayTypeTest.php create mode 100644 tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/ContactPersonArrayTypeTest.php create mode 100644 tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/IndexedServiceArrayTypeTest.php create mode 100644 tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/LogoTypeTest.php create mode 100644 tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/OrganizationTypeTest.php create mode 100644 tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/RequestedAttributeArrayTypeTest.php create mode 100644 tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceArrayTypeTest.php create mode 100644 tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceTypeTest.php create mode 100644 tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/ShibMdScopeArrayTypeTest.php diff --git a/app/config/config.yml b/app/config/config.yml index f67961f640..8dfe211113 100644 --- a/app/config/config.yml +++ b/app/config/config.yml @@ -95,9 +95,19 @@ doctrine: mapping_types: enum: string types: + engineblock_attribute_release_policy: OpenConext\EngineBlockBundle\Doctrine\Type\AttributeReleasePolicyType + engineblock_certificate_array: OpenConext\EngineBlockBundle\Doctrine\Type\CertificateArrayType engineblock_collab_person_id: OpenConext\EngineBlockBundle\Doctrine\Type\CollabPersonIdType engineblock_collab_person_uuid: OpenConext\EngineBlockBundle\Doctrine\Type\CollabPersonUuidType + engineblock_contact_person_array: OpenConext\EngineBlockBundle\Doctrine\Type\ContactPersonArrayType + engineblock_indexed_service_array: OpenConext\EngineBlockBundle\Doctrine\Type\IndexedServiceArrayType + engineblock_logo: OpenConext\EngineBlockBundle\Doctrine\Type\LogoType engineblock_metadata_coins: OpenConext\EngineBlockBundle\Doctrine\Type\MetadataCoinType + engineblock_organization: OpenConext\EngineBlockBundle\Doctrine\Type\OrganizationType + engineblock_requested_attribute_array: OpenConext\EngineBlockBundle\Doctrine\Type\RequestedAttributeArrayType + engineblock_service: OpenConext\EngineBlockBundle\Doctrine\Type\ServiceType + engineblock_service_array: OpenConext\EngineBlockBundle\Doctrine\Type\ServiceArrayType + engineblock_shib_md_scope_array: OpenConext\EngineBlockBundle\Doctrine\Type\ShibMdScopeArrayType orm: auto_generate_proxy_classes: "%kernel.debug%" proxy_dir: '%kernel.cache_dir%/doctrine/orm/Proxies' diff --git a/database/DoctrineMigrations/Version20211019150744.php b/database/DoctrineMigrations/Version20211019150744.php new file mode 100644 index 0000000000..9625c8ee24 --- /dev/null +++ b/database/DoctrineMigrations/Version20211019150744.php @@ -0,0 +1,28 @@ +abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.'); + + $this->addSql('CREATE TABLE sso_provider_roles_eb6 (id INT AUTO_INCREMENT NOT NULL, entity_id VARCHAR(255) NOT NULL, name_nl VARCHAR(255) DEFAULT NULL, name_en VARCHAR(255) DEFAULT NULL, name_pt VARCHAR(255) DEFAULT NULL, description_nl VARCHAR(255) DEFAULT NULL, description_en VARCHAR(255) DEFAULT NULL, description_pt VARCHAR(255) DEFAULT NULL, display_name_nl VARCHAR(255) DEFAULT NULL, display_name_en VARCHAR(255) DEFAULT NULL, display_name_pt VARCHAR(255) DEFAULT NULL, logo LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:engineblock_logo)\', organization_nl_name LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:engineblock_organization)\', organization_en_name LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:engineblock_organization)\', organization_pt_name LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:engineblock_organization)\', keywords_nl VARCHAR(255) DEFAULT NULL, keywords_en VARCHAR(255) DEFAULT NULL, keywords_pt VARCHAR(255) DEFAULT NULL, certificates LONGTEXT NOT NULL COMMENT \'(DC2Type:engineblock_certificate_array)\', workflow_state VARCHAR(255) NOT NULL, contact_persons LONGTEXT NOT NULL COMMENT \'(DC2Type:engineblock_contact_person_array)\', name_id_format VARCHAR(255) DEFAULT NULL, name_id_formats LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:json)\', single_logout_service LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:engineblock_service)\', requests_must_be_signed TINYINT(1) NOT NULL, manipulation LONGTEXT DEFAULT NULL, coins LONGTEXT NOT NULL COMMENT \'(DC2Type:engineblock_metadata_coins)\', type VARCHAR(255) NOT NULL, attribute_release_policy LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:engineblock_attribute_release_policy)\', assertion_consumer_services LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:engineblock_indexed_service_array)\', allowed_idp_entity_ids LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:json)\', allow_all TINYINT(1) DEFAULT NULL, requested_attributes LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:engineblock_requested_attribute_array)\', support_url_en VARCHAR(255) DEFAULT NULL, support_url_nl VARCHAR(255) DEFAULT NULL, support_url_pt VARCHAR(255) DEFAULT NULL, enabled_in_wayf TINYINT(1) DEFAULT NULL, single_sign_on_services LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:engineblock_service_array)\', consent_settings LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:json_array)\', shib_md_scopes LONGTEXT DEFAULT NULL COMMENT \'(DC2Type:engineblock_shib_md_scope_array)\', INDEX idx_sso_provider_roles_eb6_type (type), INDEX idx_sso_provider_roles_eb6_entity_id (entity_id), UNIQUE INDEX idx_sso_provider_roles_eb6_entity_id_type (type, entity_id), PRIMARY KEY(id)) DEFAULT CHARACTER SET UTF8 COLLATE `UTF8_unicode_ci` ENGINE = InnoDB'); + } + + public function down(Schema $schema) : void + { + // this down() migration is auto-generated, please modify it to your needs + $this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.'); + + $this->addSql('DROP TABLE sso_provider_roles_eb6'); + } +} diff --git a/src/OpenConext/EngineBlock/Metadata/Entity/AbstractRoleEb6.php b/src/OpenConext/EngineBlock/Metadata/Entity/AbstractRoleEb6.php new file mode 100644 index 0000000000..287dab541d --- /dev/null +++ b/src/OpenConext/EngineBlock/Metadata/Entity/AbstractRoleEb6.php @@ -0,0 +1,395 @@ +certificates = $certificates; + $this->contactPersons = $contactPersons; + $this->descriptionEn = $descriptionEn; + $this->descriptionNl = $descriptionNl; + $this->descriptionPt = $descriptionPt; + $this->displayNameEn = $displayNameEn; + $this->displayNameNl = $displayNameNl; + $this->displayNamePt = $displayNamePt; + $this->entityId = $entityId; + $this->keywordsEn = $keywordsEn; + $this->keywordsNl = $keywordsNl; + $this->keywordsPt = $keywordsPt; + $this->logo = $logo; + $this->nameEn = $nameEn; + $this->nameNl = $nameNl; + $this->namePt = $namePt; + $this->nameIdFormat = $nameIdFormat; + $this->supportedNameIdFormats = $supportedNameIdFormats; + $this->organizationEn = $organizationEn; + $this->organizationNl = $organizationNl; + $this->organizationPt = $organizationPt; + $this->requestsMustBeSigned = $requestsMustBeSigned; + $this->singleLogoutService = $singleLogoutService; + $this->workflowState = $workflowState; + $this->manipulation = $manipulation; + } + + /** + * @param VisitorInterface $visitor + * @return null|AbstractRole + */ + abstract public function accept(VisitorInterface $visitor); + + /** + * @return string + */ + public function getManipulation() + { + return $this->manipulation; + } + + /** + * @return $this + */ + public function toggleWorkflowState() + { + if ($this->workflowState === static::WORKFLOW_STATE_PROD) { + $this->workflowState = static::WORKFLOW_STATE_TEST; + return $this; + } + + if ($this->workflowState === static::WORKFLOW_STATE_TEST) { + $this->workflowState = static::WORKFLOW_STATE_PROD; + return $this; + } + + throw new RuntimeException('Unknown workflow state'); + } + + /** + * @return Coins + */ + public function getCoins() + { + return $this->coins; + } +} diff --git a/src/OpenConext/EngineBlock/Metadata/Entity/IdentityProviderEb6.php b/src/OpenConext/EngineBlock/Metadata/Entity/IdentityProviderEb6.php new file mode 100644 index 0000000000..cda9ba436a --- /dev/null +++ b/src/OpenConext/EngineBlock/Metadata/Entity/IdentityProviderEb6.php @@ -0,0 +1,279 @@ +enabledInWayf = $enabledInWayf; + $this->shibMdScopes = $shibMdScopes; + $this->singleSignOnServices = $singleSignOnServices; + $this->consentSettings = $consentSettings; + + $this->coins = Coins::createForIdentityProvider( + $guestQualifier, + $schacHomeOrganization, + $hidden, + $stepupConnections, + $disableScoping, + $additionalLogging, + $signatureMethod, + $mfaEntities + ); + } + + /** + * {@inheritdoc} + */ + public function accept(VisitorInterface $visitor) + { + $visitor->visitIdentityProvider($this); + } + + /** + * @param string $preferredLocale + * @return string + */ + public function getDisplayName($preferredLocale = '') + { + $idpName = ''; + if ($preferredLocale === 'nl') { + $idpName = $this->nameNl; + } elseif ($preferredLocale === 'en') { + $idpName = $this->nameEn; + } elseif ($preferredLocale === 'pt') { + $idpName = $this->namePt; + } + if (empty($idpName)) { + $idpName = $this->entityId; + } + return $idpName; + } + + /** + * @param ConsentSettings $settings + * @return IdentityProvider + */ + public function setConsentSettings(ConsentSettings $settings) + { + $this->consentSettings = $settings; + + return $this; + } + + /** + * @return ConsentSettings + */ + public function getConsentSettings() + { + if (!$this->consentSettings instanceof ConsentSettings) { + $this->setConsentSettings( + new ConsentSettings( + (array)$this->consentSettings + ) + ); + } + + return $this->consentSettings; + } +} diff --git a/src/OpenConext/EngineBlock/Metadata/Entity/ServiceProviderEb6.php b/src/OpenConext/EngineBlock/Metadata/Entity/ServiceProviderEb6.php new file mode 100644 index 0000000000..847a4dd95d --- /dev/null +++ b/src/OpenConext/EngineBlock/Metadata/Entity/ServiceProviderEb6.php @@ -0,0 +1,409 @@ +attributeReleasePolicy = $attributeReleasePolicy; + $this->allowedIdpEntityIds = $allowedIdpEntityIds; + $this->allowAll = $allowAll; + $this->assertionConsumerServices = $assertionConsumerServices; + $this->requestedAttributes = $requestedAttributes; + $this->supportUrlEn = $supportUrlEn; + $this->supportUrlNl = $supportUrlNl; + $this->supportUrlPt = $supportUrlPt; + + $this->coins = Coins::createForServiceProvider( + $isConsentRequired, + $isTransparentIssuer, + $isTrustedProxy, + $displayUnconnectedIdpsWayf, + $termsOfServiceUrl, + $skipDenormalization, + $policyEnforcementDecisionRequired, + $requesteridRequired, + $signResponse, + $stepupAllowNoToken, + $stepupRequireLoa, + $disableScoping, + $additionalLogging, + $signatureMethod + ); + } + + /** + * This is a factory method to convert the immutable ServiceProviderEntityInterface to the legacy domain entity. + * + * @param ServiceProviderEntityInterface $serviceProvider + * @return ServiceProvider + */ + public static function fromServiceProviderEntity(ServiceProviderEntityInterface $serviceProvider): ServiceProvider + { + $entity = new self($serviceProvider->getEntityId()); + $entity->id = $serviceProvider->getId(); + $entity->entityId = $serviceProvider->getEntityId(); + $entity->nameNl = $serviceProvider->getName('nl'); + $entity->nameEn = $serviceProvider->getName('en'); + $entity->namePt = $serviceProvider->getName('pt'); + $entity->descriptionNl = $serviceProvider->getDescription('nl'); + $entity->descriptionEn = $serviceProvider->getDescription('en'); + $entity->descriptionPt = $serviceProvider->getDescription('pt'); + $entity->displayNameNl = $serviceProvider->getDisplayName('nl'); + $entity->displayNameEn = $serviceProvider->getDisplayName('en'); + $entity->displayNamePt = $serviceProvider->getDisplayName('pt'); + $entity->logo = $serviceProvider->getLogo(); + $entity->organizationNl = $serviceProvider->getOrganization('nl'); + $entity->organizationEn = $serviceProvider->getOrganization('en'); + $entity->organizationPt = $serviceProvider->getOrganization('pt'); + $entity->keywordsNl = $serviceProvider->getKeywords('nl'); + $entity->keywordsEn = $serviceProvider->getKeywords('en'); + $entity->keywordsPt = $serviceProvider->getKeywords('pt'); + $entity->certificates = $serviceProvider->getCertificates(); + $entity->workflowState = $serviceProvider->getWorkflowState(); + $entity->contactPersons = $serviceProvider->getContactPersons(); + $entity->nameIdFormat = $serviceProvider->getNameIdFormat(); + $entity->supportedNameIdFormats = $serviceProvider->getSupportedNameIdFormats(); + $entity->singleLogoutService = $serviceProvider->getSingleLogoutService(); + $entity->requestsMustBeSigned = $serviceProvider->isRequestsMustBeSigned(); + $entity->manipulation = $serviceProvider->getManipulation(); + $entity->coins = $serviceProvider->getCoins(); + $entity->attributeReleasePolicy = $serviceProvider->getAttributeReleasePolicy(); + $entity->assertionConsumerServices = $serviceProvider->getAssertionConsumerServices(); + $entity->allowedIdpEntityIds = $serviceProvider->getAllowedIdpEntityIds(); + $entity->allowAll = $serviceProvider->isAllowAll(); + $entity->requestedAttributes = $serviceProvider->getRequestedAttributes(); + $entity->supportUrlNl = $serviceProvider->getSupportUrl('nl'); + $entity->supportUrlEn = $serviceProvider->getSupportUrl('en'); + $entity->supportUrlPt = $serviceProvider->getSupportUrl('pt'); + + return $entity; + } + + /** + * {@inheritdoc} + */ + public function accept(VisitorInterface $visitor) + { + $visitor->visitServiceProvider($this); + } + + /** + * @return null|AttributeReleasePolicy + */ + public function getAttributeReleasePolicy() + { + return $this->attributeReleasePolicy; + } + + /** + * @param string $idpEntityId + * @return bool + */ + public function isAllowed($idpEntityId) + { + return $this->allowAll || in_array($idpEntityId, $this->allowedIdpEntityIds); + } + + /** + * Algorithm for display name is: + * 1. Display name in preferred locale + * 2. Name in preferred locale + * 3. Display name in English + * 4. Name in English + * 5. EntityID (should never happen) + */ + public function getDisplayName(string $preferredLocale = 'en'): string + { + $preferredName = 'displayName' . ucfirst($preferredLocale); + $fallback = 'name' . ucfirst($preferredLocale); + $spName = !empty($this->$preferredName) ? $this->$preferredName : $this->$fallback; + + if ($preferredLocale !== 'en' & empty($spName)) { + $spName = !empty($this->displayNameEn) ? $this->displayNameEn : $this->nameEn; + } + + if (empty($spName)) { + $spName = $this->entityId; + } + + return $spName; + } + + /** + * Algorithm for organization name is + * 1. Organization display name in preferred locale + * 2. Organization name in preferred locale + * 3. English organization display name + * 4. English organization name + * 5. Empty string (will be set to the locale-specific variant of 'unknown' in the template) + */ + public function getOrganizationName(string $preferredLocale = 'en'): string + { + $orgLocale = 'organization' . ucfirst($preferredLocale); + // Load the preferred locale org. display name, falling back on org. name + $orgName = !empty($this->$orgLocale->displayName) + ? $this->$orgLocale->displayName + : $this->$orgLocale->name; + + // Fallback to EN naming preferences when the preferred locale was not set or yielded no value + if (($preferredLocale !== 'en' && empty($orgName)) || empty($orgName)) { + $orgName = !empty($this->organizationEn->displayName) ? $this->organizationEn->displayName : $this->organizationEn->name; + } + + // Show empty string when no translation was found (virtually impossible) + if (empty($orgName)) { + $orgName = ''; + } + + return $orgName; + } + + /** + * @return bool + */ + public function isAttributeAggregationRequired() + { + if (is_null($this->attributeReleasePolicy)) { + return false; + } + + $rules = $this->attributeReleasePolicy->getRulesWithSourceSpecification(); + + return count($rules) > 0; + } +} diff --git a/src/OpenConext/EngineBlock/Metadata/MetadataRepository/DoctrineMetadataPushRepository.php b/src/OpenConext/EngineBlock/Metadata/MetadataRepository/DoctrineMetadataPushRepository.php index 8308b62e4f..bf280f3348 100644 --- a/src/OpenConext/EngineBlock/Metadata/MetadataRepository/DoctrineMetadataPushRepository.php +++ b/src/OpenConext/EngineBlock/Metadata/MetadataRepository/DoctrineMetadataPushRepository.php @@ -25,9 +25,19 @@ use Doctrine\ORM\Mapping\ClassMetadata; use OpenConext\EngineBlock\Metadata\Entity\AbstractRole; use OpenConext\EngineBlock\Metadata\Entity\IdentityProvider; +use OpenConext\EngineBlock\Metadata\Entity\IdentityProviderEb6; use OpenConext\EngineBlock\Metadata\Entity\ServiceProvider; +use OpenConext\EngineBlock\Metadata\Entity\ServiceProviderEb6; use RuntimeException; +/** + * This class has added to temporary extra objects to push to both sso_provider_roles_eb5 + * and sso_provider_roles_eb6 + * + * TODO: Remove this suppression after sso_provider_roles_eb5 has been phased out + * + * @SuppressWarnings(PHPMD.CouplingBetweenObjects) + */ class DoctrineMetadataPushRepository { /** @@ -45,9 +55,36 @@ class DoctrineMetadataPushRepository */ private $idpMetadata; + /** + * This field has been added to temporary push to both sso_provider_roles_eb5 + * and sso_provider_roles_eb6 + * + * TODO: Remove this code after sso_provider_roles_eb5 has been phased out + * + * @var ClassMetadata + */ + private $spMetadataUpdated; + + /** + * This field has been added to temporary push to both sso_provider_roles_eb5 + * and sso_provider_roles_eb6 + * + * TODO: Remove this code after sso_provider_roles_eb5 has been phased out + * + * @var ClassMetadata + */ + private $idpMetadataUpdated; const ROLES_TABLE_NAME = 'sso_provider_roles_eb5'; + /** + * This field has been added to temporary push to both sso_provider_roles_eb5 + * and sso_provider_roles_eb6 + * + * TODO: Remove this code after sso_provider_roles_eb5 has been phased out + */ + const ROLES_TABLE_NAME_EB6 = 'sso_provider_roles_eb6'; + const FIELD_VALUE = 0; const FIELD_TYPE = 1; @@ -58,6 +95,15 @@ public function __construct( $this->spMetadata = $entityManager->getClassMetadata(ServiceProvider::class); $this->idpMetadata = $entityManager->getClassMetadata(IdentityProvider::class); + + /** + * This code below has been added to temporary push to both sso_provider_roles_eb5 + * and sso_provider_roles_eb6 + * + * TODO: Remove this code after sso_provider_roles_eb5 has been phased out + */ + $this->spMetadataUpdated = $entityManager->getClassMetadata(ServiceProviderEb6::class); + $this->idpMetadataUpdated = $entityManager->getClassMetadata(IdentityProviderEb6::class); } /** @@ -133,11 +179,25 @@ public function synchronize(array $roles) if ($idpsToBeRemoved) { $this->deleteRolesByIds(array_keys($idpsToBeRemoved), $this->idpMetadata); + /** + * This call {deleteRolesByEntityId} has been added to temporary push to both sso_provider_roles_eb5 + * and sso_provider_roles_eb6 + * + * TODO: Remove this code after sso_provider_roles_eb5 has been phased out + */ + $this->deleteRolesByEntityId(array_values($idpsToBeRemoved), $this->idpMetadata); $result->removedIdentityProviders = array_values($idpsToBeRemoved); } if ($spsToBeRemoved) { $this->deleteRolesByIds(array_keys($spsToBeRemoved), $this->spMetadata); + /** + * This call {deleteRolesByEntityId} has been added to temporary push to both sso_provider_roles_eb5 + * and sso_provider_roles_eb6 + * + * TODO: Remove this code after sso_provider_roles_eb5 has been phased out + */ + $this->deleteRolesByEntityId(array_values($spsToBeRemoved), $this->spMetadata); $result->removedServiceProviders = array_values($spsToBeRemoved); } }); @@ -150,7 +210,21 @@ private function insertRole(AbstractRole $role, ClassMetadata $metadata) $query = $this->connection->createQueryBuilder() ->insert(self::ROLES_TABLE_NAME); - $normalized = $this->addInsertQueryParameters($role, $query, $metadata); + $normalized = $this->addInsertQueryParameters($role, $query, $metadata, false); + + $stmt = $this->connection->prepare($query->getSQL()); + $this->bindParameters($normalized, $stmt); + $stmt->execute(); + + /** + * This code below has been added to temporary push to both sso_provider_roles_eb5 and sso_provider_roles_eb6 + * + * TODO: Remove this code after sso_provider_roles_eb5 has been phased out + */ + $query = $this->connection->createQueryBuilder() + ->insert(self::ROLES_TABLE_NAME_EB6); + + $normalized = $this->addInsertQueryParameters($role, $query, $metadata, true); $stmt = $this->connection->prepare($query->getSQL()); $this->bindParameters($normalized, $stmt); @@ -162,7 +236,21 @@ private function updateRole(AbstractRole $role, ClassMetadata $metadata) $query = $this->connection->createQueryBuilder() ->update(self::ROLES_TABLE_NAME); - $normalized = $this->addUpdateQueryParameters($role, $query, $metadata); + $normalized = $this->addUpdateQueryParameters($role, $query, $metadata, false); + + $stmt = $this->connection->prepare($query->getSQL()); + $this->bindParameters($normalized, $stmt); + $stmt->execute(); + + /** + * This code below has been added to temporary push to both sso_provider_roles_eb5 and sso_provider_roles_eb6 + * + * TODO: Remove this code after sso_provider_roles_eb5 has been phased out + */ + $query = $this->connection->createQueryBuilder() + ->update(self::ROLES_TABLE_NAME_EB6); + + $normalized = $this->addUpdateQueryParameters($role, $query, $metadata, true); $stmt = $this->connection->prepare($query->getSQL()); $this->bindParameters($normalized, $stmt); @@ -182,6 +270,22 @@ private function deleteRolesByIds(array $roles, ClassMetadata $metadata) return $result; } + /** + * This function has been added to temporary push to both sso_provider_roles_eb5 and sso_provider_roles_eb6 + * + * TODO: Remove this code after sso_provider_roles_eb5 has been phased out + */ + private function deleteRolesByEntityId(array $entityIds, ClassMetadata $metadata) + { + $query = $this->connection->createQueryBuilder() + ->delete(self::ROLES_TABLE_NAME_EB6) + ->where('entity_id IN (:entity_ids)') + ->setParameter('entity_ids', $entityIds, Connection::PARAM_STR_ARRAY); + + $this->addDiscriminatorQuery($query, $metadata); + return $query->execute(); + } + private function findAllRoleEntityIds(ClassMetadata $metadata) { $query = $this->connection->createQueryBuilder() @@ -198,18 +302,30 @@ private function findAllRoleEntityIds(ClassMetadata $metadata) return $results; } - private function addInsertQueryParameters(AbstractRole $role, QueryBuilder $query, ClassMetadata $metadata) + /** + * The code {$isInsertForDuplicateTable} has been added to temporary push to both sso_provider_roles_eb5 + * and sso_provider_roles_eb6 + * + * TODO: Remove this code after sso_provider_roles_eb5 has been phased out + */ + private function addInsertQueryParameters(AbstractRole $role, QueryBuilder $query, ClassMetadata $metadata, bool $isInsertForDuplicateTable) { - $normalized = $this->normalizeData($role, $metadata); + $normalized = $this->normalizeData($role, $metadata, $isInsertForDuplicateTable); foreach (array_keys($normalized) as $id) { $query->setValue($id, ":$id"); } return $normalized; } - private function addUpdateQueryParameters(AbstractRole $role, QueryBuilder $query, ClassMetadata $metadata) + /** + * The code {$isUpdateForDuplicateTable} has been added to temporary push to both sso_provider_roles_eb5 + * and sso_provider_roles_eb6 + * + * TODO: Remove this code after sso_provider_roles_eb5 has been phased out + */ + private function addUpdateQueryParameters(AbstractRole $role, QueryBuilder $query, ClassMetadata $metadata, bool $isUpdateForDuplicateTable) { - $normalized = $this->normalizeData($role, $metadata); + $normalized = $this->normalizeData($role, $metadata, $isUpdateForDuplicateTable); foreach (array_keys($normalized) as $id) { $query->set($id, ":$id"); } @@ -229,18 +345,48 @@ private function bindParameters($normalized, Statement $statement) private function addDiscriminatorQuery(QueryBuilder $queryBuilder, ClassMetadata $metadata) { - $queryBuilder->andWhere(sprintf('%s = :%s', $metadata->discriminatorColumn['fieldName'], $metadata->discriminatorColumn['name'])) - ->setParameter($metadata->discriminatorColumn['name'], $metadata->discriminatorValue, $metadata->discriminatorColumn['type']); + $queryBuilder->andWhere( + sprintf('%s = :%s', $metadata->discriminatorColumn['fieldName'], $metadata->discriminatorColumn['name']) + )->setParameter( + $metadata->discriminatorColumn['name'], + $metadata->discriminatorValue, + $metadata->discriminatorColumn['type'] + ); } - private function normalizeData(AbstractRole $role, ClassMetadata $metadata) + private function normalizeData(AbstractRole $role, ClassMetadata $metadata, bool $isNormalizeForDuplicateTable) { $result = []; - foreach ($metadata->fieldMappings as $id => $columnInfo) { - $result[$columnInfo['columnName']] = [ - self::FIELD_VALUE => $metadata->reflFields[$id]->getValue($role), - self::FIELD_TYPE => $columnInfo['type'], - ]; + /** + * The code {$isNormalizeForDuplicateTable} has been added to temporary push to both sso_provider_roles_eb5 + * and sso_provider_roles_eb6 + * + * TODO: Remove this code after sso_provider_roles_eb5 has been phased out + */ + if ($isNormalizeForDuplicateTable) { + if ($role instanceof IdentityProvider) { + foreach ($metadata->fieldMappings as $id => $columnInfo) { + $result[$columnInfo['columnName']] = [ + self::FIELD_VALUE => $metadata->reflFields[$id]->getValue($role), + self::FIELD_TYPE => $this->idpMetadataUpdated->fieldMappings[$id]['type'], + ]; + } + } + if ($role instanceof ServiceProvider) { + foreach ($metadata->fieldMappings as $id => $columnInfo) { + $result[$columnInfo['columnName']] = [ + self::FIELD_VALUE => $metadata->reflFields[$id]->getValue($role), + self::FIELD_TYPE => $this->spMetadataUpdated->fieldMappings[$id]['type'], + ]; + } + } + } else { + foreach ($metadata->fieldMappings as $id => $columnInfo) { + $result[$columnInfo['columnName']] = [ + self::FIELD_VALUE => $metadata->reflFields[$id]->getValue($role), + self::FIELD_TYPE => $columnInfo['type'], + ]; + } } // The primary id field is autogenerated and should not be added to the SQL statement. diff --git a/src/OpenConext/EngineBlockBundle/Doctrine/Type/AttributeReleasePolicyType.php b/src/OpenConext/EngineBlockBundle/Doctrine/Type/AttributeReleasePolicyType.php new file mode 100644 index 0000000000..547d8c549e --- /dev/null +++ b/src/OpenConext/EngineBlockBundle/Doctrine/Type/AttributeReleasePolicyType.php @@ -0,0 +1,81 @@ +getJsonTypeDeclarationSQL($fieldDeclaration); + } + + /** + * @throws ConversionException + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string + { + if (is_null($value)) { + return null; + } + + if (!$value instanceof AttributeReleasePolicy) { + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + ["null", AttributeReleasePolicy::class] + ); + } + + return json_encode($value->getAttributeRules()); + } + + public function convertToPHPValue($value, AbstractPlatform $platform) + { + if (is_null($value)) { + return $value; + } + + try { + $arp = new AttributeReleasePolicy(json_decode($value, true)); + } catch (InvalidArgumentException | TypeError $e) { + // get nice standard message, so we can throw it keeping the exception chain + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + AttributeReleasePolicy::class + ); + } + + return $arp; + } + + public function getName() + { + return self::NAME; + } +} diff --git a/src/OpenConext/EngineBlockBundle/Doctrine/Type/CertificateArrayType.php b/src/OpenConext/EngineBlockBundle/Doctrine/Type/CertificateArrayType.php new file mode 100644 index 0000000000..32c8f4a93c --- /dev/null +++ b/src/OpenConext/EngineBlockBundle/Doctrine/Type/CertificateArrayType.php @@ -0,0 +1,109 @@ +getJsonTypeDeclarationSQL($fieldDeclaration); + } + + /** + * @throws ConversionException + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string + { + if (is_null($value)) { + return null; + } + + if (!is_array($value)) { + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + ["null", "array"] + ); + } + + $certificates = []; + foreach ($value as $certificate) { + if (!$certificate instanceof X509CertificateLazyProxy) { + throw ConversionException::conversionFailedInvalidType( + $certificate, + $this->getName(), + [X509CertificateLazyProxy::class] + ); + } + array_push($certificates, $certificate->toCertData()); + } + + return json_encode($certificates); + } + + /** + * @throws ConversionException + */ + public function convertToPHPValue($value, AbstractPlatform $platform): ?array + { + if (is_null($value)) { + return null; + } + + try { + $certificates = []; + $decoded = json_decode($value, true); + + if (!is_array($decoded)) { + throw ConversionException::conversionFailedFormat( + $decoded, + $this->getName(), + "array" + ); + } + + foreach ($decoded as $metaData) { + array_push($certificates, new X509CertificateLazyProxy(new X509CertificateFactory(), $metaData)); + } + } catch (InvalidArgumentException $e) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + X509CertificateLazyProxy::class + ); + } + + return $certificates; + } + + public function getName(): string + { + return self::NAME; + } +} diff --git a/src/OpenConext/EngineBlockBundle/Doctrine/Type/ContactPersonArrayType.php b/src/OpenConext/EngineBlockBundle/Doctrine/Type/ContactPersonArrayType.php new file mode 100644 index 0000000000..5613125870 --- /dev/null +++ b/src/OpenConext/EngineBlockBundle/Doctrine/Type/ContactPersonArrayType.php @@ -0,0 +1,111 @@ +getJsonTypeDeclarationSQL($fieldDeclaration); + } + + /** + * @throws ConversionException + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string + { + if (is_null($value)) { + return null; + } + + if (!is_array($value)) { + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + ["null", "array"] + ); + } + + foreach ($value as $contactPerson) { + if (!$contactPerson instanceof ContactPerson) { + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + [ContactPerson::class] + ); + } + } + + return json_encode($value); + } + + /** + * @throws ConversionException + */ + public function convertToPHPValue($value, AbstractPlatform $platform): ?array + { + if (is_null($value)) { + return null; + } + + try { + $decoded = json_decode($value, true); + + if (!is_array($decoded)) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + "array" + ); + } + + $contactPersons = []; + foreach ($decoded as $contactPerson) { + array_push($contactPersons, ContactPerson::from( + $contactPerson["contactType"], + $contactPerson["givenName"], + $contactPerson["surName"], + $contactPerson["emailAddress"], + $contactPerson["telephoneNumber"] + )); + } + } catch (InvalidArgumentException $e) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + ContactPerson::class + ); + } + + return $contactPersons; + } + + public function getName(): string + { + return self::NAME; + } +} diff --git a/src/OpenConext/EngineBlockBundle/Doctrine/Type/IndexedServiceArrayType.php b/src/OpenConext/EngineBlockBundle/Doctrine/Type/IndexedServiceArrayType.php new file mode 100644 index 0000000000..58d00e5b19 --- /dev/null +++ b/src/OpenConext/EngineBlockBundle/Doctrine/Type/IndexedServiceArrayType.php @@ -0,0 +1,110 @@ +getJsonTypeDeclarationSQL($fieldDeclaration); + } + + /** + * @throws ConversionException + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string + { + if (is_null($value)) { + return null; + } + + if (!is_array($value)) { + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + ["null", "array"] + ); + } + + foreach ($value as $indexService) { + if (!$indexService instanceof IndexedService) { + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + [IndexedService::class] + ); + } + } + + return json_encode($value); + } + + /** + * @throws ConversionException + */ + public function convertToPHPValue($value, AbstractPlatform $platform): ?array + { + if (is_null($value)) { + return null; + } + + try { + $decoded = json_decode($value, true); + + if (!is_array($decoded)) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + "array" + ); + } + + $indexedServices = []; + foreach ($decoded as $indexedService) { + array_push($indexedServices, new IndexedService( + $indexedService["location"], + $indexedService["binding"], + $indexedService["serviceIndex"], + $indexedService["isDefault"] + )); + } + } catch (InvalidArgumentException $e) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + IndexedService::class + ); + } + + return $indexedServices; + } + + public function getName(): string + { + return self::NAME; + } +} diff --git a/src/OpenConext/EngineBlockBundle/Doctrine/Type/LogoType.php b/src/OpenConext/EngineBlockBundle/Doctrine/Type/LogoType.php new file mode 100644 index 0000000000..b629492901 --- /dev/null +++ b/src/OpenConext/EngineBlockBundle/Doctrine/Type/LogoType.php @@ -0,0 +1,94 @@ +getJsonTypeDeclarationSQL($fieldDeclaration); + } + + /** + * @throws ConversionException + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string + { + if (is_null($value)) { + return null; + } + + if (!$value instanceof Logo) { + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + ["null", Logo::class] + ); + } + + return json_encode($value); + } + + /** + * @throws ConversionException + */ + public function convertToPHPValue($value, AbstractPlatform $platform): ?Logo + { + if (is_null($value)) { + return null; + } + + try { + $decoded = json_decode($value, true); + + if (!is_array($decoded)) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + "array" + ); + } + + $logo = new Logo($decoded["url"]); + $logo->height = $decoded["height"]; + $logo->width = $decoded["width"]; + } catch (InvalidArgumentException $e) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + Logo::class + ); + } + + return $logo; + } + + public function getName(): string + { + return self::NAME; + } +} diff --git a/src/OpenConext/EngineBlockBundle/Doctrine/Type/OrganizationType.php b/src/OpenConext/EngineBlockBundle/Doctrine/Type/OrganizationType.php new file mode 100644 index 0000000000..7a6a3c231b --- /dev/null +++ b/src/OpenConext/EngineBlockBundle/Doctrine/Type/OrganizationType.php @@ -0,0 +1,92 @@ +getJsonTypeDeclarationSQL($fieldDeclaration); + } + + /** + * @throws ConversionException + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string + { + if (is_null($value)) { + return null; + } + + if (!$value instanceof Organization) { + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + ["null", Organization::class] + ); + } + + return json_encode($value); + } + + /** + * @throws ConversionException + */ + public function convertToPHPValue($value, AbstractPlatform $platform): ?Organization + { + if (is_null($value)) { + return null; + } + + try { + $decoded = json_decode($value, true); + + if (!is_array($decoded)) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + "array" + ); + } + + $organization = new Organization($decoded["name"], $decoded["displayName"], $decoded["url"]); + } catch (InvalidArgumentException $e) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + Organization::class + ); + } + + return $organization; + } + + public function getName(): string + { + return self::NAME; + } +} diff --git a/src/OpenConext/EngineBlockBundle/Doctrine/Type/RequestedAttributeArrayType.php b/src/OpenConext/EngineBlockBundle/Doctrine/Type/RequestedAttributeArrayType.php new file mode 100644 index 0000000000..629a21f348 --- /dev/null +++ b/src/OpenConext/EngineBlockBundle/Doctrine/Type/RequestedAttributeArrayType.php @@ -0,0 +1,109 @@ +getJsonTypeDeclarationSQL($fieldDeclaration); + } + + /** + * @throws ConversionException + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string + { + if (is_null($value)) { + return null; + } + + if (!is_array($value)) { + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + ["null", "array"] + ); + } + + foreach ($value as $requestedAttribute) { + if (!$requestedAttribute instanceof RequestedAttribute) { + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + [RequestedAttribute::class] + ); + } + } + + return json_encode($value); + } + + /** + * @throws ConversionException + */ + public function convertToPHPValue($value, AbstractPlatform $platform): ?array + { + if (is_null($value)) { + return null; + } + + try { + $decoded = json_decode($value, true); + + if (!is_array($decoded)) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + "array" + ); + } + + $requestedAttributes = []; + foreach ($decoded as $requestedAttribute) { + array_push($requestedAttributes, new RequestedAttribute( + $requestedAttribute["name"], + $requestedAttribute["required"], + $requestedAttribute["nameFormat"] + )); + } + } catch (InvalidArgumentException $e) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + RequestedAttribute::class + ); + } + + return $requestedAttributes; + } + + public function getName(): string + { + return self::NAME; + } +} diff --git a/src/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceArrayType.php b/src/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceArrayType.php new file mode 100644 index 0000000000..b9ee0c7a6d --- /dev/null +++ b/src/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceArrayType.php @@ -0,0 +1,108 @@ +getJsonTypeDeclarationSQL($fieldDeclaration); + } + + /** + * @throws ConversionException + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string + { + if (is_null($value)) { + return null; + } + + if (!is_array($value)) { + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + ["null", "array"] + ); + } + + foreach ($value as $service) { + if (!$service instanceof Service) { + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + [Service::class] + ); + } + } + + return json_encode($value); + } + + /** + * @throws ConversionException + */ + public function convertToPHPValue($value, AbstractPlatform $platform): ?array + { + if (is_null($value)) { + return null; + } + + try { + $decoded = json_decode($value, true); + + if (!is_array($decoded)) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + "array" + ); + } + + $services = []; + foreach ($decoded as $service) { + array_push($services, new Service( + $service["location"], + $service["binding"] + )); + } + } catch (InvalidArgumentException $e) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + Service::class + ); + } + + return $services; + } + + public function getName(): string + { + return self::NAME; + } +} diff --git a/src/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceType.php b/src/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceType.php new file mode 100644 index 0000000000..e015d2c332 --- /dev/null +++ b/src/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceType.php @@ -0,0 +1,91 @@ +getJsonTypeDeclarationSQL($fieldDeclaration); + } + + /** + * @throws ConversionException + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string + { + if (is_null($value)) { + return null; + } + + if (!$value instanceof Service) { + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + ["null", Service::class] + ); + } + + return json_encode($value); + } + + /** + * @throws ConversionException + */ + public function convertToPHPValue($value, AbstractPlatform $platform): ?Service + { + if (is_null($value)) { + return null; + } + + try { + $decoded = json_decode($value, true); + + if (!is_array($decoded)) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + "array" + ); + } + $service = new Service($decoded["location"], $decoded["binding"]); + } catch (InvalidArgumentException $e) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + Service::class + ); + } + + return $service; + } + + public function getName(): string + { + return self::NAME; + } +} diff --git a/src/OpenConext/EngineBlockBundle/Doctrine/Type/ShibMdScopeArrayType.php b/src/OpenConext/EngineBlockBundle/Doctrine/Type/ShibMdScopeArrayType.php new file mode 100644 index 0000000000..dc08a8f35c --- /dev/null +++ b/src/OpenConext/EngineBlockBundle/Doctrine/Type/ShibMdScopeArrayType.php @@ -0,0 +1,108 @@ +getJsonTypeDeclarationSQL($fieldDeclaration); + } + + /** + * @throws ConversionException + */ + public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string + { + if (is_null($value)) { + return null; + } + + if (!is_array($value)) { + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + ["null", "array"] + ); + } + + foreach ($value as $shibMdScope) { + if (!$shibMdScope instanceof ShibMdScope) { + throw ConversionException::conversionFailedInvalidType( + $value, + $this->getName(), + [ShibMdScope::class] + ); + } + } + + return json_encode($value); + } + + /** + * @throws ConversionException + */ + public function convertToPHPValue($value, AbstractPlatform $platform): ?array + { + if (is_null($value)) { + return null; + } + + try { + $decoded = json_decode($value, true); + + if (!is_array($decoded)) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + "array" + ); + } + + $shibMdScopes = []; + foreach ($decoded as $shibMdScope) { + $result = new ShibMdScope(); + $result->allowed = $shibMdScope["allowed"]; + $result->regexp = $shibMdScope["regexp"]; + array_push($shibMdScopes, $result); + } + } catch (InvalidArgumentException $e) { + throw ConversionException::conversionFailedFormat( + $value, + $this->getName(), + ShibMdScope::class + ); + } + + return $shibMdScopes; + } + + public function getName(): string + { + return self::NAME; + } +} diff --git a/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/AttributeReleasePolicyTypeTest.php b/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/AttributeReleasePolicyTypeTest.php new file mode 100644 index 0000000000..ca1601332c --- /dev/null +++ b/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/AttributeReleasePolicyTypeTest.php @@ -0,0 +1,147 @@ +platform = new MySqlPlatform(); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function a_null_value_remains_null_in_to_sql_conversion() + { + $arpType = Type::getType(AttributeReleasePolicyType::NAME); + + $value = $arpType->convertToDatabaseValue(null, $this->platform); + + $this->assertNull($value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function attribute_release_policy_converted_to_json() + { + $arpType = Type::getType(AttributeReleasePolicyType::NAME); + $arp = array(); + $arp["uid"] = ["value" => "*", "motiviation" => ""]; + $arp["givenName"] = ["value" => "*", "motiviation" => ""]; + $arp["attribute"] = ["value" => "*", "motiviation" => ""]; + $attributeReleasePolicy = new AttributeReleasePolicy($arp); + + $value = $arpType->convertToDatabaseValue($attributeReleasePolicy, $this->platform); + + $this->assertEquals(json_encode($attributeReleasePolicy->getAttributeRules()), $value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function a_null_value_is_converted_to_null() + { + $arpType = Type::getType(AttributeReleasePolicyType::NAME); + + $value = $arpType->convertToPHPValue(null, $this->platform); + + $this->assertNull($value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function saved_object_equals_result() + { + $arpType = Type::getType(AttributeReleasePolicyType::NAME); + + $arp = array(); + $arp["uid"] = ["value" => "*", "motiviation" => ""]; + $arp["givenName"] = ["value" => "*", "motiviation" => ""]; + $arp["attribute"] = ["value" => "*", "motiviation" => ""]; + $attributeReleasePolicy = new AttributeReleasePolicy($arp); + + $value = $arpType->convertToPHPValue($arpType->convertToDatabaseValue($attributeReleasePolicy, $this->platform), + $this->platform); + + $this->assertEquals($attributeReleasePolicy, $value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function an_invalid_php_value_causes_an_exception_upon_conversion() + { + $arpType = Type::getType(AttributeReleasePolicyType::NAME); + + $this->expectException(ConversionException::class); + $arpType->convertToDatabaseValue(false, $this->platform); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function an_invalid_database_value_causes_an_exception_upon_conversion() + { + $arpType = Type::getType(AttributeReleasePolicyType::NAME); + + $this->expectException(ConversionException::class); + $arpType->convertToPHPValue(false, $this->platform); + } +} diff --git a/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/CertificateArrayTypeTest.php b/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/CertificateArrayTypeTest.php new file mode 100644 index 0000000000..d3c3db6ad4 --- /dev/null +++ b/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/CertificateArrayTypeTest.php @@ -0,0 +1,142 @@ +platform = new MySqlPlatform(); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function a_null_value_remains_null_in_to_sql_conversion() + { + $certType = Type::getType(CertificateArrayType::NAME); + + $value = $certType->convertToDatabaseValue(null, $this->platform); + + $this->assertNull($value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function certificate_array_type_converted_to_json() + { + $certType = Type::getType(CertificateArrayType::NAME); + $certificateArray = [new X509CertificateLazyProxy(new X509CertificateFactory(), $this->certData)]; + + $value = $certType->convertToDatabaseValue($certificateArray, $this->platform); + + $this->assertEquals(json_encode([$certificateArray[0]->toCertData()]), $value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function a_null_value_is_converted_to_null() + { + $certType = Type::getType(CertificateArrayType::NAME); + + $value = $certType->convertToPHPValue(null, $this->platform); + + $this->assertNull($value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function saved_object_equals_result() + { + $certType = Type::getType(CertificateArrayType::NAME); + + $certificateArray = [new X509CertificateLazyProxy(new X509CertificateFactory(), $this->certData)]; + + $value = $certType->convertToPHPValue($certType->convertToDatabaseValue($certificateArray, $this->platform), + $this->platform); + + $this->assertEquals($certificateArray[0]->toCertData(), $value[0]->toCertData()); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function an_invalid_php_value_causes_an_exception_upon_conversion() + { + $certType = Type::getType(CertificateArrayType::NAME); + + $this->expectException(ConversionException::class); + $certType->convertToDatabaseValue(false, $this->platform); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function an_invalid_database_value_causes_an_exception_upon_conversion() + { + $certType = Type::getType(CertificateArrayType::NAME); + + $this->expectException(ConversionException::class); + $certType->convertToPHPValue(false, $this->platform); + } +} diff --git a/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/ContactPersonArrayTypeTest.php b/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/ContactPersonArrayTypeTest.php new file mode 100644 index 0000000000..ebf879fd62 --- /dev/null +++ b/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/ContactPersonArrayTypeTest.php @@ -0,0 +1,145 @@ +platform = new MySqlPlatform(); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function a_null_value_remains_null_in_to_sql_conversion() + { + $contactPersonType = Type::getType(ContactPersonArrayType::NAME); + + $value = $contactPersonType->convertToDatabaseValue(null, $this->platform); + + $this->assertNull($value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function contact_person_array_type_converted_to_json() + { + $contactPersonType = Type::getType(ContactPersonArrayType::NAME); + $contactPerson = [new ContactPerson("support")]; + $contactPerson[0]->givenName = "givenName"; + $contactPerson[0]->telephoneNumber = "telephoneNumber"; + $contactPerson[0]->surName = "surName"; + $contactPerson[0]->emailAddress = "emailAddress"; + + $value = $contactPersonType->convertToDatabaseValue($contactPerson, $this->platform); + + $this->assertEquals(json_encode($contactPerson), $value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function a_null_value_is_converted_to_null() + { + $contactPersonType = Type::getType(ContactPersonArrayType::NAME); + + $value = $contactPersonType->convertToPHPValue(null, $this->platform); + + $this->assertNull($value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function saved_object_equals_result() + { + $contactPersonType = Type::getType(ContactPersonArrayType::NAME); + $contactPerson = [new ContactPerson("support")]; + $contactPerson[0]->givenName = "givenName"; + $contactPerson[0]->telephoneNumber = "telephoneNumber"; + $contactPerson[0]->surName = "surName"; + $contactPerson[0]->emailAddress = "emailAddress"; + + $value = $contactPersonType->convertToPHPValue($contactPersonType->convertToDatabaseValue($contactPerson, $this->platform), + $this->platform); + + $this->assertEquals($contactPerson, $value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function an_invalid_php_value_causes_an_exception_upon_conversion() + { + $contactPersonType = Type::getType(ContactPersonArrayType::NAME); + + $this->expectException(ConversionException::class); + $contactPersonType->convertToDatabaseValue(false, $this->platform); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function an_invalid_database_value_causes_an_exception_upon_conversion() + { + $contactPersonType = Type::getType(ContactPersonArrayType::NAME); + + $this->expectException(ConversionException::class); + $contactPersonType->convertToPHPValue(false, $this->platform); + } +} diff --git a/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/IndexedServiceArrayTypeTest.php b/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/IndexedServiceArrayTypeTest.php new file mode 100644 index 0000000000..5fb215c630 --- /dev/null +++ b/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/IndexedServiceArrayTypeTest.php @@ -0,0 +1,137 @@ +platform = new MySqlPlatform(); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function a_null_value_remains_null_in_to_sql_conversion() + { + $indexedServiceArrayType = Type::getType(IndexedServiceArrayType::NAME); + + $value = $indexedServiceArrayType->convertToDatabaseValue(null, $this->platform); + + $this->assertNull($value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function indexed_service_array_type_converted_to_json() + { + $indexedServiceArrayType = Type::getType(IndexedServiceArrayType::NAME); + $serviceIndex = [new IndexedService("location", "binding", 0)]; + $value = $indexedServiceArrayType->convertToDatabaseValue($serviceIndex, $this->platform); + + $this->assertEquals(json_encode($serviceIndex), $value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function a_null_value_is_converted_to_null() + { + $indexedServiceArrayType = Type::getType(IndexedServiceArrayType::NAME); + + $value = $indexedServiceArrayType->convertToPHPValue(null, $this->platform); + + $this->assertNull($value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function saved_object_equals_result() + { + $indexedServiceArrayType = Type::getType(IndexedServiceArrayType::NAME); + $serviceIndex = [new IndexedService("location", "binding", 0)]; + + $value = $indexedServiceArrayType->convertToPHPValue($indexedServiceArrayType->convertToDatabaseValue($serviceIndex, $this->platform), + $this->platform); + + $this->assertEquals($serviceIndex, $value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function an_invalid_php_value_causes_an_exception_upon_conversion() + { + $indexedServiceArrayType = Type::getType(IndexedServiceArrayType::NAME); + + $this->expectException(ConversionException::class); + $indexedServiceArrayType->convertToDatabaseValue(false, $this->platform); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function an_invalid_database_value_causes_an_exception_upon_conversion() + { + $indexedServiceArrayType = Type::getType(IndexedServiceArrayType::NAME); + + $this->expectException(ConversionException::class); + $indexedServiceArrayType->convertToPHPValue(false, $this->platform); + } +} diff --git a/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/LogoTypeTest.php b/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/LogoTypeTest.php new file mode 100644 index 0000000000..8b58430e8f --- /dev/null +++ b/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/LogoTypeTest.php @@ -0,0 +1,137 @@ +platform = new MySqlPlatform(); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function a_null_value_remains_null_in_to_sql_conversion() + { + $logoType = Type::getType(LogoType::NAME); + + $value = $logoType->convertToDatabaseValue(null, $this->platform); + + $this->assertNull($value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function logo_type_converted_to_json() + { + $logoType = Type::getType(LogoType::NAME); + $logo = new Logo("location"); + $value = $logoType->convertToDatabaseValue($logo, $this->platform); + + $this->assertEquals(json_encode($logo), $value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function a_null_value_is_converted_to_null() + { + $logoType = Type::getType(LogoType::NAME); + + $value = $logoType->convertToPHPValue(null, $this->platform); + + $this->assertNull($value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function saved_object_equals_result() + { + $logoType = Type::getType(LogoType::NAME); + $logo = new Logo("location"); + + $value = $logoType->convertToPHPValue($logoType->convertToDatabaseValue($logo, $this->platform), + $this->platform); + + $this->assertEquals($logo, $value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function an_invalid_php_value_causes_an_exception_upon_conversion() + { + $logoType = Type::getType(LogoType::NAME); + + $this->expectException(ConversionException::class); + $logoType->convertToDatabaseValue(false, $this->platform); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function an_invalid_database_value_causes_an_exception_upon_conversion() + { + $logoType = Type::getType(LogoType::NAME); + + $this->expectException(ConversionException::class); + $logoType->convertToPHPValue(false, $this->platform); + } +} diff --git a/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/OrganizationTypeTest.php b/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/OrganizationTypeTest.php new file mode 100644 index 0000000000..a33b166d95 --- /dev/null +++ b/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/OrganizationTypeTest.php @@ -0,0 +1,137 @@ +platform = new MySqlPlatform(); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function a_null_value_remains_null_in_to_sql_conversion() + { + $organizationType = Type::getType(OrganizationType::NAME); + + $value = $organizationType->convertToDatabaseValue(null, $this->platform); + + $this->assertNull($value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function organization_type_converted_to_json() + { + $organizationType = Type::getType(OrganizationType::NAME); + $organization = new Organization("name", "displayName", "url"); + $value = $organizationType->convertToDatabaseValue($organization, $this->platform); + + $this->assertEquals(json_encode($organization), $value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function a_null_value_is_converted_to_null() + { + $organizationType = Type::getType(OrganizationType::NAME); + + $value = $organizationType->convertToPHPValue(null, $this->platform); + + $this->assertNull($value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function saved_object_equals_result() + { + $organizationType = Type::getType(OrganizationType::NAME); + $organization = new Organization("name", "displayName", "url"); + + $value = $organizationType->convertToPHPValue($organizationType->convertToDatabaseValue($organization, $this->platform), + $this->platform); + + $this->assertEquals($organization, $value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function an_invalid_php_value_causes_an_exception_upon_conversion() + { + $organizationType = Type::getType(OrganizationType::NAME); + + $this->expectException(ConversionException::class); + $organizationType->convertToDatabaseValue(false, $this->platform); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function an_invalid_database_value_causes_an_exception_upon_conversion() + { + $organizationType = Type::getType(OrganizationType::NAME); + + $this->expectException(ConversionException::class); + $organizationType->convertToPHPValue(false, $this->platform); + } +} diff --git a/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/RequestedAttributeArrayTypeTest.php b/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/RequestedAttributeArrayTypeTest.php new file mode 100644 index 0000000000..37ed5aa82c --- /dev/null +++ b/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/RequestedAttributeArrayTypeTest.php @@ -0,0 +1,137 @@ +platform = new MySqlPlatform(); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function a_null_value_remains_null_in_to_sql_conversion() + { + $requestedAttributeArrayType = Type::getType(RequestedAttributeArrayType::NAME); + + $value = $requestedAttributeArrayType->convertToDatabaseValue(null, $this->platform); + + $this->assertNull($value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function requested_attribute_array_type_converted_to_json() + { + $requestedAttributeArrayType = Type::getType(RequestedAttributeArrayType::NAME); + $requestedAttribute = [new RequestedAttribute("name")]; + $value = $requestedAttributeArrayType->convertToDatabaseValue($requestedAttribute, $this->platform); + + $this->assertEquals(json_encode($requestedAttribute), $value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function a_null_value_is_converted_to_null() + { + $requestedAttributeArrayType = Type::getType(RequestedAttributeArrayType::NAME); + + $value = $requestedAttributeArrayType->convertToPHPValue(null, $this->platform); + + $this->assertNull($value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function saved_object_equals_result() + { + $requestedAttributeArrayType = Type::getType(RequestedAttributeArrayType::NAME); + $requestedAttribute = [new RequestedAttribute("name")]; + + $value = $requestedAttributeArrayType->convertToPHPValue($requestedAttributeArrayType->convertToDatabaseValue($requestedAttribute, $this->platform), + $this->platform); + + $this->assertEquals($requestedAttribute, $value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function an_invalid_php_value_causes_an_exception_upon_conversion() + { + $requestedAttributeArrayType = Type::getType(RequestedAttributeArrayType::NAME); + + $this->expectException(ConversionException::class); + $requestedAttributeArrayType->convertToDatabaseValue(false, $this->platform); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function an_invalid_database_value_causes_an_exception_upon_conversion() + { + $requestedAttributeArrayType = Type::getType(RequestedAttributeArrayType::NAME); + + $this->expectException(ConversionException::class); + $requestedAttributeArrayType->convertToPHPValue(false, $this->platform); + } +} diff --git a/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceArrayTypeTest.php b/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceArrayTypeTest.php new file mode 100644 index 0000000000..c22a3712aa --- /dev/null +++ b/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceArrayTypeTest.php @@ -0,0 +1,137 @@ +platform = new MySqlPlatform(); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function a_null_value_remains_null_in_to_sql_conversion() + { + $serviceArrayType = Type::getType(ServiceArrayType::NAME); + + $value = $serviceArrayType->convertToDatabaseValue(null, $this->platform); + + $this->assertNull($value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function service_array_type_converted_to_json() + { + $serviceArrayType = Type::getType(ServiceArrayType::NAME); + $serviceArray = [new Service("location", "binding")]; + $value = $serviceArrayType->convertToDatabaseValue($serviceArray, $this->platform); + + $this->assertEquals(json_encode($serviceArray), $value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function a_null_value_is_converted_to_null() + { + $serviceArrayType = Type::getType(ServiceArrayType::NAME); + + $value = $serviceArrayType->convertToPHPValue(null, $this->platform); + + $this->assertNull($value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function saved_object_equals_result() + { + $serviceArrayType = Type::getType(ServiceArrayType::NAME); + $serviceArray = [new Service("location", "binding")]; + + $value = $serviceArrayType->convertToPHPValue($serviceArrayType->convertToDatabaseValue($serviceArray, $this->platform), + $this->platform); + + $this->assertEquals($serviceArray, $value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function an_invalid_php_value_causes_an_exception_upon_conversion() + { + $serviceArrayType = Type::getType(ServiceArrayType::NAME); + + $this->expectException(ConversionException::class); + $serviceArrayType->convertToDatabaseValue(false, $this->platform); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function an_invalid_database_value_causes_an_exception_upon_conversion() + { + $serviceArrayType = Type::getType(ServiceArrayType::NAME); + + $this->expectException(ConversionException::class); + $serviceArrayType->convertToPHPValue(false, $this->platform); + } +} diff --git a/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceTypeTest.php b/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceTypeTest.php new file mode 100644 index 0000000000..594a70c3ad --- /dev/null +++ b/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceTypeTest.php @@ -0,0 +1,152 @@ +platform = new MySqlPlatform(); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function a_null_value_remains_null_in_to_sql_conversion() + { + $serviceType = Type::getType(ServiceType::NAME); + + $value = $serviceType->convertToDatabaseValue(null, $this->platform); + + $this->assertNull($value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function service_converted_to_json() + { + $serviceType = Type::getType(ServiceType::NAME); + $service = new Service("location", "binding"); + + $value = $serviceType->convertToDatabaseValue($service, $this->platform); + + $this->assertEquals(json_encode($service), $value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function a_null_value_is_converted_to_null() + { + $serviceType = Type::getType(ServiceType::NAME); + + $value = $serviceType->convertToPHPValue(null, $this->platform); + + $this->assertNull($value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function saved_object_equals_result() + { + $serviceType = Type::getType(ServiceType::NAME); + $serviceComplete = new Service("location", "binding"); + $serviceLocation = new Service("location", null); + $serviceBinding = new Service(null, "binding"); + + + $valueComplete = $serviceType->convertToPHPValue( + $serviceType->convertToDatabaseValue($serviceComplete, $this->platform), + $this->platform); + $valueLocation = $serviceType->convertToPHPValue( + $serviceType->convertToDatabaseValue($serviceLocation, $this->platform), + $this->platform); + $valueBinding = $serviceType->convertToPHPValue( + $serviceType->convertToDatabaseValue($serviceBinding, $this->platform), + $this->platform); + + + $this->assertEquals($serviceComplete, $valueComplete); + $this->assertEquals($serviceLocation, $valueLocation); + $this->assertEquals($serviceBinding, $valueBinding); + $this->assertNotEquals($valueBinding, $valueLocation); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function an_invalid_php_value_causes_an_exception_upon_conversion() + { + $serviceType = Type::getType(ServiceType::NAME); + + $this->expectException(ConversionException::class); + $serviceType->convertToDatabaseValue(false, $this->platform); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function an_invalid_database_value_causes_an_exception_upon_conversion() + { + $serviceType = Type::getType(ServiceType::NAME); + + $this->expectException(ConversionException::class); + $serviceType->convertToPHPValue(false, $this->platform); + } +} diff --git a/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/ShibMdScopeArrayTypeTest.php b/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/ShibMdScopeArrayTypeTest.php new file mode 100644 index 0000000000..ea67fb29a3 --- /dev/null +++ b/tests/unit/OpenConext/EngineBlockBundle/Doctrine/Type/ShibMdScopeArrayTypeTest.php @@ -0,0 +1,142 @@ +platform = new MySqlPlatform(); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function a_null_value_remains_null_in_to_sql_conversion() + { + $shibMdScopeArrayType = Type::getType(ShibMdScopeArrayType::NAME); + + $value = $shibMdScopeArrayType->convertToDatabaseValue(null, $this->platform); + + $this->assertNull($value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function shib_md_scope_array_type_converted_to_json() + { + $shibMdScopeArrayType = Type::getType(ShibMdScopeArrayType::NAME); + $shibMdScopeArray = [new ShibMdScope()]; + $shibMdScopeArray[0]->regexp = true; + $shibMdScopeArray[0]->allowed = "query"; + + $value = $shibMdScopeArrayType->convertToDatabaseValue($shibMdScopeArray, $this->platform); + + $this->assertEquals(json_encode($shibMdScopeArray), $value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function a_null_value_is_converted_to_null() + { + $shibMdScopeArrayType = Type::getType(ShibMdScopeArrayType::NAME); + + $value = $shibMdScopeArrayType->convertToPHPValue(null, $this->platform); + + $this->assertNull($value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function saved_object_equals_result() + { + $shibMdScopeArrayType = Type::getType(ShibMdScopeArrayType::NAME); + $shibMdScopeArray = [new ShibMdScope()]; + $shibMdScopeArray[0]->regexp = true; + $shibMdScopeArray[0]->allowed = "query"; + + $value = $shibMdScopeArrayType->convertToPHPValue($shibMdScopeArrayType->convertToDatabaseValue($shibMdScopeArray, $this->platform), + $this->platform); + + $this->assertEquals($shibMdScopeArray, $value); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function an_invalid_php_value_causes_an_exception_upon_conversion() + { + $shibMdScopeArrayType = Type::getType(ShibMdScopeArrayType::NAME); + + $this->expectException(ConversionException::class); + $shibMdScopeArrayType->convertToDatabaseValue(false, $this->platform); + } + + /** + * @test + * @group EngineBlockBundle + * @group Doctrine + */ + public function an_invalid_database_value_causes_an_exception_upon_conversion() + { + $shibMdScopeArrayType = Type::getType(ShibMdScopeArrayType::NAME); + + $this->expectException(ConversionException::class); + $shibMdScopeArrayType->convertToPHPValue(false, $this->platform); + } +} From d4237ffceaf44ab969accb82d786047b6c7a52c5 Mon Sep 17 00:00:00 2001 From: Stephan Kok Date: Thu, 21 Oct 2021 13:41:11 +0200 Subject: [PATCH 2/3] Introduce sso_provider_roles_eb6 to prepare for custom doctrine types - Update tests to delete sso_provider_roles_eb6 as well --- .../Fixtures/ServiceRegistryFixture.php | 23 +++++++++++++++++++ ...ttributeReleasePolicyControllerApiTest.php | 9 ++++++++ .../Api/ConnectionsControllerTest.php | 9 ++++++++ .../Controller/Api/ConsentControllerTest.php | 9 ++++++++ 4 files changed, 50 insertions(+) diff --git a/src/OpenConext/EngineBlockFunctionalTestingBundle/Fixtures/ServiceRegistryFixture.php b/src/OpenConext/EngineBlockFunctionalTestingBundle/Fixtures/ServiceRegistryFixture.php index c754c16697..f5afb52280 100644 --- a/src/OpenConext/EngineBlockFunctionalTestingBundle/Fixtures/ServiceRegistryFixture.php +++ b/src/OpenConext/EngineBlockFunctionalTestingBundle/Fixtures/ServiceRegistryFixture.php @@ -116,6 +116,12 @@ public function save() $this->entityManager->flush(); } + /** + * This call duplicate database call has been added to temporary push to both sso_provider_roles_eb5 + * and sso_provider_roles_eb6 + * + * TODO: Remove this code after sso_provider_roles_eb5 has been phased out + */ public function reset() { $queryBuilder = $this->entityManager->getConnection()->createQueryBuilder(); @@ -123,9 +129,19 @@ public function reset() ->delete('sso_provider_roles_eb5') ->execute(); + $this->entityManager->getConnection()->createQueryBuilder() + ->delete('sso_provider_roles_eb6') + ->execute(); + return $this; } + /** + * This call duplicate database call has been added to temporary push to both sso_provider_roles_eb5 + * and sso_provider_roles_eb6 + * + * TODO: Remove this code after sso_provider_roles_eb5 has been phased out + */ public function remove($entityId, $role) { $queryBuilder = $this->entityManager->getConnection()->createQueryBuilder(); @@ -136,6 +152,13 @@ public function remove($entityId, $role) ->setParameter('entityId', $entityId) ->setParameter('type', $role) ->execute(); + $this->entityManager->getConnection()->createQueryBuilder() + ->delete('sso_provider_roles_eb6', 'roles') + ->where('roles.entity_id = :entityId') + ->andWhere('roles.type = :type') + ->setParameter('entityId', $entityId) + ->setParameter('type', $role) + ->execute(); return $this; } diff --git a/tests/functional/OpenConext/EngineBlockBundle/Controller/Api/AttributeReleasePolicyControllerApiTest.php b/tests/functional/OpenConext/EngineBlockBundle/Controller/Api/AttributeReleasePolicyControllerApiTest.php index ac2bb4c5df..7f15034b58 100644 --- a/tests/functional/OpenConext/EngineBlockBundle/Controller/Api/AttributeReleasePolicyControllerApiTest.php +++ b/tests/functional/OpenConext/EngineBlockBundle/Controller/Api/AttributeReleasePolicyControllerApiTest.php @@ -478,11 +478,20 @@ private function addServiceProviderFixture(ServiceProvider $serviceProvider) $em->flush(); } + /** + * This call {->delete('sso_provider_roles_eb5')} has been added to temporary push to both sso_provider_roles_eb5 + * and sso_provider_roles_eb6 + * + * TODO: Remove this code after sso_provider_roles_eb5 has been phased out + */ private function clearMetadataFixtures() { $queryBuilder = $this->getContainer()->get('doctrine')->getConnection()->createQueryBuilder(); $queryBuilder ->delete('sso_provider_roles_eb5') ->execute(); + $this->getContainer()->get('doctrine')->getConnection()->createQueryBuilder() + ->delete('sso_provider_roles_eb6') + ->execute(); } } diff --git a/tests/functional/OpenConext/EngineBlockBundle/Controller/Api/ConnectionsControllerTest.php b/tests/functional/OpenConext/EngineBlockBundle/Controller/Api/ConnectionsControllerTest.php index 3c94e203ad..cc7a0aea12 100644 --- a/tests/functional/OpenConext/EngineBlockBundle/Controller/Api/ConnectionsControllerTest.php +++ b/tests/functional/OpenConext/EngineBlockBundle/Controller/Api/ConnectionsControllerTest.php @@ -394,12 +394,21 @@ private function disableMetadataPushApiFeatureFor(Client $client) $client->getContainer()->set('engineblock.features', $featureToggles); } + /** + * This call {->delete('sso_provider_roles_eb5')} has been added to temporary push to both sso_provider_roles_eb5 + * and sso_provider_roles_eb6 + * + * TODO: Remove this code after sso_provider_roles_eb5 has been phased out + */ private function clearMetadataFixtures() { $queryBuilder = $this->getContainer()->get('doctrine')->getConnection()->createQueryBuilder(); $queryBuilder ->delete('sso_provider_roles_eb5') ->execute(); + $this->getContainer()->get('doctrine')->getConnection()->createQueryBuilder() + ->delete('sso_provider_roles_eb6') + ->execute(); } /** diff --git a/tests/functional/OpenConext/EngineBlockBundle/Controller/Api/ConsentControllerTest.php b/tests/functional/OpenConext/EngineBlockBundle/Controller/Api/ConsentControllerTest.php index 529a2ad62a..b5562fc06c 100644 --- a/tests/functional/OpenConext/EngineBlockBundle/Controller/Api/ConsentControllerTest.php +++ b/tests/functional/OpenConext/EngineBlockBundle/Controller/Api/ConsentControllerTest.php @@ -297,12 +297,21 @@ private function addServiceProviderFixture(ServiceProvider $serviceProvider) $em->flush(); } + /** + * This call {->delete('sso_provider_roles_eb5')} has been added to temporary push to both sso_provider_roles_eb5 + * and sso_provider_roles_eb6 + * + * TODO: Remove this code after sso_provider_roles_eb5 has been phased out + */ private function clearMetadataFixtures() { $queryBuilder = $this->getContainer()->get('doctrine')->getConnection()->createQueryBuilder(); $queryBuilder ->delete('sso_provider_roles_eb5') ->execute(); + $this->getContainer()->get('doctrine')->getConnection()->createQueryBuilder() + ->delete('sso_provider_roles_eb6') + ->execute(); } private function clearConsentFixtures() From 8d8ac230e90400098b96b914b3685810a28bf299 Mon Sep 17 00:00:00 2001 From: Stephan Kok Date: Tue, 7 Dec 2021 17:01:44 +0100 Subject: [PATCH 3/3] Introduce Static constructors --- .../Metadata/AttributeReleasePolicy.php | 10 +++++ .../EngineBlock/Metadata/ContactPerson.php | 39 ++++++++++++++++--- .../EngineBlock/Metadata/IndexedService.php | 14 +++++++ src/OpenConext/EngineBlock/Metadata/Logo.php | 21 ++++++++-- .../EngineBlock/Metadata/Organization.php | 10 +++++ .../Metadata/RequestedAttribute.php | 10 +++++ .../EngineBlock/Metadata/Service.php | 10 +++++ .../EngineBlock/Metadata/ShibMdScope.php | 21 ++++++++++ .../Type/AttributeReleasePolicyType.php | 12 +++++- .../Doctrine/Type/ContactPersonArrayType.php | 16 ++++---- .../Doctrine/Type/IndexedServiceArrayType.php | 15 ++++--- .../Doctrine/Type/LogoType.php | 4 +- .../Doctrine/Type/OrganizationType.php | 2 +- .../Type/RequestedAttributeArrayType.php | 14 ++++--- .../Doctrine/Type/ServiceArrayType.php | 13 +++++-- .../Doctrine/Type/ServiceType.php | 2 +- .../Doctrine/Type/ShibMdScopeArrayType.php | 13 +++++-- 17 files changed, 184 insertions(+), 42 deletions(-) diff --git a/src/OpenConext/EngineBlock/Metadata/AttributeReleasePolicy.php b/src/OpenConext/EngineBlock/Metadata/AttributeReleasePolicy.php index 250d0af450..6ad04de7d7 100644 --- a/src/OpenConext/EngineBlock/Metadata/AttributeReleasePolicy.php +++ b/src/OpenConext/EngineBlock/Metadata/AttributeReleasePolicy.php @@ -235,4 +235,14 @@ public function getAttributeRules() { return $this->attributeRules; } + + /** + * A convenience static constructor for the AttributeReleasePolicy. + * @param array $attributeReleasePolicy + * @return AttributeReleasePolicy + */ + public static function fromArray(array $attributeReleasePolicy): AttributeReleasePolicy + { + return new self($attributeReleasePolicy); + } } diff --git a/src/OpenConext/EngineBlock/Metadata/ContactPerson.php b/src/OpenConext/EngineBlock/Metadata/ContactPerson.php index 9f49cd4871..c44bedf092 100644 --- a/src/OpenConext/EngineBlock/Metadata/ContactPerson.php +++ b/src/OpenConext/EngineBlock/Metadata/ContactPerson.php @@ -25,17 +25,30 @@ class ContactPerson { public $contactType; - public $emailAddress = ''; - public $telephoneNumber = ''; - public $givenName = ''; - public $surName = ''; + public $emailAddress; + public $telephoneNumber; + public $givenName; + public $surName; /** * @param $contactType + * @param string $emailAddress + * @param string $telephoneNumber + * @param string $givenName + * @param string $surName */ - public function __construct($contactType) - { + public function __construct( + $contactType, + string $emailAddress = '', + string $telephoneNumber = '', + string $givenName = '', + string $surName = '' + ) { $this->contactType = $contactType; + $this->emailAddress = $emailAddress; + $this->telephoneNumber = $telephoneNumber; + $this->givenName = $givenName; + $this->surName = $surName; } /** @@ -61,4 +74,18 @@ public static function from( $contact->telephoneNumber = $telephoneNumber; return $contact; } + + /** + * A convenience static constructor for the contact person. + * @param array $contactPerson + * @return ContactPerson + */ + public static function fromArray(array $contactPerson): ContactPerson + { + return new self($contactPerson["contactType"], + $contactPerson["emailAddress"], + $contactPerson["telephoneNumber"], + $contactPerson["givenName"], + $contactPerson["surName"]); + } } diff --git a/src/OpenConext/EngineBlock/Metadata/IndexedService.php b/src/OpenConext/EngineBlock/Metadata/IndexedService.php index b254c7cc99..c1a39c02e4 100644 --- a/src/OpenConext/EngineBlock/Metadata/IndexedService.php +++ b/src/OpenConext/EngineBlock/Metadata/IndexedService.php @@ -49,4 +49,18 @@ public function __construct($location, $binding, $serviceIndex, $isDefault = nul parent::__construct($location, $binding); } + + /** + * A convenience static constructor for the IndexedService. + * @param array $indexedService + * @return IndexedService + */ + public static function indexedServiceFromArray(array $indexedService): IndexedService + { + return new self($indexedService["location"], + $indexedService["binding"], + $indexedService["serviceIndex"], + $indexedService["isDefault"] + ); + } } diff --git a/src/OpenConext/EngineBlock/Metadata/Logo.php b/src/OpenConext/EngineBlock/Metadata/Logo.php index 99e38b5531..931a5f8c4b 100644 --- a/src/OpenConext/EngineBlock/Metadata/Logo.php +++ b/src/OpenConext/EngineBlock/Metadata/Logo.php @@ -24,15 +24,28 @@ */ class Logo { - public $height = null; - public $width = null; - public $url = null; + public $height; + public $width; + public $url; /** * @param string $url */ - public function __construct($url) + public function __construct($url, $height = null, $width = null) { $this->url = $url; + $this->height = $height; + $this->width = $width; + } + + + /** + * A convenience static constructor for the Logo. + * @param array $logo + * @return Logo + */ + public static function fromArray(array $logo): Logo + { + return new self($logo["url"], $logo["height"], $logo["width"]); } } diff --git a/src/OpenConext/EngineBlock/Metadata/Organization.php b/src/OpenConext/EngineBlock/Metadata/Organization.php index a9073cdb0c..5105c59181 100644 --- a/src/OpenConext/EngineBlock/Metadata/Organization.php +++ b/src/OpenConext/EngineBlock/Metadata/Organization.php @@ -35,4 +35,14 @@ public function __construct($name, $displayName, $url) $this->name = $name; $this->url = $url; } + + /** + * A convenience static constructor for the Organization. + * @param array $organization + * @return Organization + */ + public static function fromArray(array $organization): Organization + { + return new self($organization["name"], $organization["displayName"], $organization["url"]); + } } diff --git a/src/OpenConext/EngineBlock/Metadata/RequestedAttribute.php b/src/OpenConext/EngineBlock/Metadata/RequestedAttribute.php index fb7abf5c78..7b94dab08f 100644 --- a/src/OpenConext/EngineBlock/Metadata/RequestedAttribute.php +++ b/src/OpenConext/EngineBlock/Metadata/RequestedAttribute.php @@ -52,4 +52,14 @@ public function __construct($name, $isRequired = false, $nameFormat = self::NAME $this->nameFormat = $nameFormat; $this->required = $isRequired; } + + /** + * A convenience static constructor for the RequestedAttribute. + * @param array $requestedAttribute + * @return RequestedAttribute + */ + public static function fromArray(array $requestedAttribute): RequestedAttribute + { + return new self($requestedAttribute["name"], $requestedAttribute["required"], $requestedAttribute["nameFormat"]); + } } diff --git a/src/OpenConext/EngineBlock/Metadata/Service.php b/src/OpenConext/EngineBlock/Metadata/Service.php index 400bb5da12..1bdf2fe79a 100644 --- a/src/OpenConext/EngineBlock/Metadata/Service.php +++ b/src/OpenConext/EngineBlock/Metadata/Service.php @@ -43,4 +43,14 @@ public function __construct($location, $binding) $this->binding = $binding; $this->location = $location; } + + /** + * A convenience static constructor for the Service. + * @param array $service + * @return Service + */ + public static function fromArray(array $service): Service + { + return new self($service["location"], $service["binding"]); + } } diff --git a/src/OpenConext/EngineBlock/Metadata/ShibMdScope.php b/src/OpenConext/EngineBlock/Metadata/ShibMdScope.php index e1c5402ab1..5abfeb2320 100644 --- a/src/OpenConext/EngineBlock/Metadata/ShibMdScope.php +++ b/src/OpenConext/EngineBlock/Metadata/ShibMdScope.php @@ -33,4 +33,25 @@ class ShibMdScope * @var string */ public $regexp; + + /** + * @param string|null $allowed + * @param string|null $regexp + */ + public function __construct(string $allowed = null, string $regexp = null) + { + $this->allowed = $allowed; + $this->regexp = $regexp; + } + + + /** + * A convenience static constructor for the ShibMdScope. + * @param array $shibMdScope + * @return ShibMdScope + */ + public static function fromArray(array $shibMdScope): ShibMdScope + { + return new self($shibMdScope["allowed"], $shibMdScope["regexp"]); + } } diff --git a/src/OpenConext/EngineBlockBundle/Doctrine/Type/AttributeReleasePolicyType.php b/src/OpenConext/EngineBlockBundle/Doctrine/Type/AttributeReleasePolicyType.php index 547d8c549e..964fb5e619 100644 --- a/src/OpenConext/EngineBlockBundle/Doctrine/Type/AttributeReleasePolicyType.php +++ b/src/OpenConext/EngineBlockBundle/Doctrine/Type/AttributeReleasePolicyType.php @@ -61,7 +61,17 @@ public function convertToPHPValue($value, AbstractPlatform $platform) } try { - $arp = new AttributeReleasePolicy(json_decode($value, true)); + $decoded = json_decode($value, true); + + if (!is_array($decoded)) { + throw ConversionException::conversionFailedFormat( + $decoded, + $this->getName(), + "array" + ); + } + + $arp = AttributeReleasePolicy::fromArray($decoded); } catch (InvalidArgumentException | TypeError $e) { // get nice standard message, so we can throw it keeping the exception chain throw ConversionException::conversionFailedFormat( diff --git a/src/OpenConext/EngineBlockBundle/Doctrine/Type/ContactPersonArrayType.php b/src/OpenConext/EngineBlockBundle/Doctrine/Type/ContactPersonArrayType.php index 5613125870..af8a7c8524 100644 --- a/src/OpenConext/EngineBlockBundle/Doctrine/Type/ContactPersonArrayType.php +++ b/src/OpenConext/EngineBlockBundle/Doctrine/Type/ContactPersonArrayType.php @@ -85,13 +85,15 @@ public function convertToPHPValue($value, AbstractPlatform $platform): ?array $contactPersons = []; foreach ($decoded as $contactPerson) { - array_push($contactPersons, ContactPerson::from( - $contactPerson["contactType"], - $contactPerson["givenName"], - $contactPerson["surName"], - $contactPerson["emailAddress"], - $contactPerson["telephoneNumber"] - )); + if (!is_array($contactPerson)) { + throw ConversionException::conversionFailedFormat( + $contactPerson, + $this->getName(), + "array" + ); + } + + array_push($contactPersons, ContactPerson::fromArray($contactPerson)); } } catch (InvalidArgumentException $e) { throw ConversionException::conversionFailedFormat( diff --git a/src/OpenConext/EngineBlockBundle/Doctrine/Type/IndexedServiceArrayType.php b/src/OpenConext/EngineBlockBundle/Doctrine/Type/IndexedServiceArrayType.php index 58d00e5b19..fc9274539a 100644 --- a/src/OpenConext/EngineBlockBundle/Doctrine/Type/IndexedServiceArrayType.php +++ b/src/OpenConext/EngineBlockBundle/Doctrine/Type/IndexedServiceArrayType.php @@ -85,12 +85,15 @@ public function convertToPHPValue($value, AbstractPlatform $platform): ?array $indexedServices = []; foreach ($decoded as $indexedService) { - array_push($indexedServices, new IndexedService( - $indexedService["location"], - $indexedService["binding"], - $indexedService["serviceIndex"], - $indexedService["isDefault"] - )); + if (!is_array($indexedService)) { + throw ConversionException::conversionFailedFormat( + $indexedService, + $this->getName(), + "array" + ); + } + + array_push($indexedServices, IndexedService::indexedServiceFromArray($indexedService)); } } catch (InvalidArgumentException $e) { throw ConversionException::conversionFailedFormat( diff --git a/src/OpenConext/EngineBlockBundle/Doctrine/Type/LogoType.php b/src/OpenConext/EngineBlockBundle/Doctrine/Type/LogoType.php index b629492901..d3874ade62 100644 --- a/src/OpenConext/EngineBlockBundle/Doctrine/Type/LogoType.php +++ b/src/OpenConext/EngineBlockBundle/Doctrine/Type/LogoType.php @@ -73,9 +73,7 @@ public function convertToPHPValue($value, AbstractPlatform $platform): ?Logo ); } - $logo = new Logo($decoded["url"]); - $logo->height = $decoded["height"]; - $logo->width = $decoded["width"]; + $logo = Logo::fromArray($decoded); } catch (InvalidArgumentException $e) { throw ConversionException::conversionFailedFormat( $value, diff --git a/src/OpenConext/EngineBlockBundle/Doctrine/Type/OrganizationType.php b/src/OpenConext/EngineBlockBundle/Doctrine/Type/OrganizationType.php index 7a6a3c231b..f7739a7a6a 100644 --- a/src/OpenConext/EngineBlockBundle/Doctrine/Type/OrganizationType.php +++ b/src/OpenConext/EngineBlockBundle/Doctrine/Type/OrganizationType.php @@ -73,7 +73,7 @@ public function convertToPHPValue($value, AbstractPlatform $platform): ?Organiza ); } - $organization = new Organization($decoded["name"], $decoded["displayName"], $decoded["url"]); + $organization = Organization::fromArray($decoded); } catch (InvalidArgumentException $e) { throw ConversionException::conversionFailedFormat( $value, diff --git a/src/OpenConext/EngineBlockBundle/Doctrine/Type/RequestedAttributeArrayType.php b/src/OpenConext/EngineBlockBundle/Doctrine/Type/RequestedAttributeArrayType.php index 629a21f348..039bfc7e93 100644 --- a/src/OpenConext/EngineBlockBundle/Doctrine/Type/RequestedAttributeArrayType.php +++ b/src/OpenConext/EngineBlockBundle/Doctrine/Type/RequestedAttributeArrayType.php @@ -85,11 +85,15 @@ public function convertToPHPValue($value, AbstractPlatform $platform): ?array $requestedAttributes = []; foreach ($decoded as $requestedAttribute) { - array_push($requestedAttributes, new RequestedAttribute( - $requestedAttribute["name"], - $requestedAttribute["required"], - $requestedAttribute["nameFormat"] - )); + if (!is_array($requestedAttribute)) { + throw ConversionException::conversionFailedFormat( + $requestedAttribute, + $this->getName(), + "array" + ); + } + + array_push($requestedAttributes, RequestedAttribute::fromArray($requestedAttribute)); } } catch (InvalidArgumentException $e) { throw ConversionException::conversionFailedFormat( diff --git a/src/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceArrayType.php b/src/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceArrayType.php index b9ee0c7a6d..930d121b5b 100644 --- a/src/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceArrayType.php +++ b/src/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceArrayType.php @@ -85,10 +85,15 @@ public function convertToPHPValue($value, AbstractPlatform $platform): ?array $services = []; foreach ($decoded as $service) { - array_push($services, new Service( - $service["location"], - $service["binding"] - )); + if (!is_array($service)) { + throw ConversionException::conversionFailedFormat( + $service, + $this->getName(), + "array" + ); + } + + array_push($services, Service::fromArray($service)); } } catch (InvalidArgumentException $e) { throw ConversionException::conversionFailedFormat( diff --git a/src/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceType.php b/src/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceType.php index e015d2c332..796aa990a4 100644 --- a/src/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceType.php +++ b/src/OpenConext/EngineBlockBundle/Doctrine/Type/ServiceType.php @@ -72,7 +72,7 @@ public function convertToPHPValue($value, AbstractPlatform $platform): ?Service "array" ); } - $service = new Service($decoded["location"], $decoded["binding"]); + $service = Service::fromArray($decoded); } catch (InvalidArgumentException $e) { throw ConversionException::conversionFailedFormat( $value, diff --git a/src/OpenConext/EngineBlockBundle/Doctrine/Type/ShibMdScopeArrayType.php b/src/OpenConext/EngineBlockBundle/Doctrine/Type/ShibMdScopeArrayType.php index dc08a8f35c..f207aa1598 100644 --- a/src/OpenConext/EngineBlockBundle/Doctrine/Type/ShibMdScopeArrayType.php +++ b/src/OpenConext/EngineBlockBundle/Doctrine/Type/ShibMdScopeArrayType.php @@ -85,10 +85,15 @@ public function convertToPHPValue($value, AbstractPlatform $platform): ?array $shibMdScopes = []; foreach ($decoded as $shibMdScope) { - $result = new ShibMdScope(); - $result->allowed = $shibMdScope["allowed"]; - $result->regexp = $shibMdScope["regexp"]; - array_push($shibMdScopes, $result); + if (!is_array($shibMdScope)) { + throw ConversionException::conversionFailedFormat( + $shibMdScope, + $this->getName(), + "array" + ); + } + + array_push($shibMdScopes, ShibMdScope::fromArray($shibMdScope)); } } catch (InvalidArgumentException $e) { throw ConversionException::conversionFailedFormat(