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..d683c31853 --- /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..cb8da488f1 --- /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..97cecdc7f9 --- /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..1b356459ab 100644 --- a/src/OpenConext/EngineBlock/Metadata/MetadataRepository/DoctrineMetadataPushRepository.php +++ b/src/OpenConext/EngineBlock/Metadata/MetadataRepository/DoctrineMetadataPushRepository.php @@ -25,7 +25,9 @@ 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; class DoctrineMetadataPushRepository @@ -45,9 +47,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 faced 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 faced 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 faced out + */ + const ROLES_TABLE_NAME_EB6 = 'sso_provider_roles_eb6'; + const FIELD_VALUE = 0; const FIELD_TYPE = 1; @@ -58,6 +87,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 faced out + */ + $this->spMetadataUpdated = $entityManager->getClassMetadata(ServiceProviderEb6::class); + $this->idpMetadataUpdated = $entityManager->getClassMetadata(IdentityProviderEb6::class); } /** @@ -133,11 +171,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 faced 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 faced out + */ + $this->deleteRolesByEntityId(array_values($spsToBeRemoved), $this->spMetadata); $result->removedServiceProviders = array_values($spsToBeRemoved); } }); @@ -150,7 +202,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 faced 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 +228,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 faced 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 +262,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 faced 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 +294,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 faced 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 faced 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 +337,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 faced 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); + } +}