From ad0c0afa927da6d9b41086a683cae51d0d8a774d Mon Sep 17 00:00:00 2001 From: Michiel Kodde Date: Mon, 20 Sep 2021 14:38:54 +0200 Subject: [PATCH 1/7] Explicitly install NPM on the phpfpm containers --- docker/php-fpm/Dockerfile-php72 | 11 ++++++++--- docker/php-fpm/Dockerfile-php74 | 9 +++++++-- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/docker/php-fpm/Dockerfile-php72 b/docker/php-fpm/Dockerfile-php72 index 111a6e613d..cf11edb531 100644 --- a/docker/php-fpm/Dockerfile-php72 +++ b/docker/php-fpm/Dockerfile-php72 @@ -1,4 +1,4 @@ -FROM php:7.2.33-fpm +FROM php:7.2-fpm ARG NPM_UID=1000 ARG NPM_GID=1000 @@ -6,11 +6,16 @@ ARG NPM_GID=1000 # Copy phpfpm config COPY docker/php-fpm/app.ini /usr/local/etc/php/conf.d/ +# Yank the node and npm binaries from the official Node docker container +COPY --from=node:10 /usr/local/lib/node_modules /usr/local/lib/node_modules +COPY --from=node:10 /usr/local/bin/node /usr/local/bin/node +RUN ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm +RUN npm install -g npx + # Install dependencies -RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - RUN apt-get update && apt-get install -y \ git \ - nodejs \ + python \ zip \ chromium \ libpng-dev \ diff --git a/docker/php-fpm/Dockerfile-php74 b/docker/php-fpm/Dockerfile-php74 index 9e9a685e75..010712a54d 100644 --- a/docker/php-fpm/Dockerfile-php74 +++ b/docker/php-fpm/Dockerfile-php74 @@ -6,11 +6,16 @@ ARG NPM_GID=1000 # Copy phpfpm config COPY docker/php-fpm/app.ini /usr/local/etc/php/conf.d/ +# Yank the node and npm binaries from the official Node docker container +COPY --from=node:10 /usr/local/lib/node_modules /usr/local/lib/node_modules +COPY --from=node:10 /usr/local/bin/node /usr/local/bin/node +RUN ln -s /usr/local/lib/node_modules/npm/bin/npm-cli.js /usr/local/bin/npm +RUN npm install -g npx + # Install dependencies -RUN curl -sL https://deb.nodesource.com/setup_10.x | bash - RUN apt-get update && apt-get install -y \ git \ - nodejs \ + python \ zip \ chromium \ libpng-dev \ From a604d51b6fd86293b663e4223e57616cb1a45c4b Mon Sep 17 00:00:00 2001 From: Michiel Kodde Date: Tue, 28 Sep 2021 13:52:31 +0200 Subject: [PATCH 2/7] Upgrade OpenConext Monitor Bundle to 2.1.0 --- composer.json | 6 ++-- composer.lock | 81 +++++++++++++++++++++++---------------------------- 2 files changed, 39 insertions(+), 48 deletions(-) diff --git a/composer.json b/composer.json index 5f47b5b2e3..9447b41939 100644 --- a/composer.json +++ b/composer.json @@ -15,6 +15,7 @@ "ext-dom": "*", "ext-json": "*", "ext-mbstring": "*", + "ext-openssl": "*", "beberlei/assert": "^2.6", "composer/package-versions-deprecated": "^1.11", "doctrine/doctrine-bundle": "^1.11", @@ -23,7 +24,7 @@ "guzzlehttp/guzzle": "^6.3", "incenteev/composer-parameter-handler": "~2.0", "monolog/monolog": "~1.13", - "openconext/monitor-bundle": "^1.0", + "openconext/monitor-bundle": "^2.1", "openconext/saml-value-object": "^1.3", "pimple/pimple": "~2.1", "ramsey/uuid": "^3.3.0", @@ -37,8 +38,7 @@ "symfony/swiftmailer-bundle": "^2.6", "symfony/symfony": "3.4.*", "twig/extensions": "^1.5", - "twig/twig": "^1.35", - "ext-openssl": "*" + "twig/twig": "^1.35" }, "require-dev": { "behat/behat": "~3.0", diff --git a/composer.lock b/composer.lock index 43f2c0fd05..a00ed50717 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "6d49a0b8f8cbc4af9238fbe996ee3860", + "content-hash": "af5f601b52804c7c98eddf961386401b", "packages": [ { "name": "beberlei/assert", @@ -750,6 +750,7 @@ "cache", "caching" ], + "abandoned": true, "time": "2019-11-29T11:22:01+00:00" }, { @@ -1989,22 +1990,22 @@ }, { "name": "openconext/monitor-bundle", - "version": "1.0.5", + "version": "2.1.0", "source": { "type": "git", "url": "https://github.com/OpenConext/Monitor-bundle.git", - "reference": "0c1fe3abfb68e5c315ccf651fa4a23b98d6ad2e0" + "reference": "f06e967b702bc5d78d85c39ba4a90219af152a67" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/OpenConext/Monitor-bundle/zipball/0c1fe3abfb68e5c315ccf651fa4a23b98d6ad2e0", - "reference": "0c1fe3abfb68e5c315ccf651fa4a23b98d6ad2e0", + "url": "https://api.github.com/repos/OpenConext/Monitor-bundle/zipball/f06e967b702bc5d78d85c39ba4a90219af152a67", + "reference": "f06e967b702bc5d78d85c39ba4a90219af152a67", "shasum": "" }, "require": { "php": ">=5.4,<8.0-dev", - "symfony/dependency-injection": ">=2.7,<4", - "symfony/framework-bundle": ">=2.7,<4", + "symfony/dependency-injection": ">=3.4,<5", + "symfony/framework-bundle": ">=3.4,<5", "webmozart/assert": "^1.2" }, "require-dev": { @@ -2029,7 +2030,7 @@ "license": [ "Apache-2.0" ], - "description": "A Symfony 3 bundle that facilitates health and info endpoints to a Symfony application. The bundle is backwards compatible with Symfony 2 projects.", + "description": "A Symfony 4 bundle that facilitates health and info endpoints to a Symfony application. The bundle is backwards compatible with Symfony 2 projects.", "keywords": [ "OpenConext", "health", @@ -2037,7 +2038,7 @@ "stepup", "surfnet" ], - "time": "2018-09-12T13:38:01+00:00" + "time": "2021-09-28T11:09:57+00:00" }, { "name": "openconext/saml-value-object", @@ -2123,11 +2124,6 @@ "pseudorandom", "random" ], - "support": { - "email": "info@paragonie.com", - "issues": "https://github.com/paragonie/random_compat/issues", - "source": "https://github.com/paragonie/random_compat" - }, "time": "2018-07-02T15:55:56+00:00" }, { @@ -2220,9 +2216,6 @@ "psr", "psr-6" ], - "support": { - "source": "https://github.com/php-fig/cache/tree/master" - }, "time": "2016-08-06T20:24:11+00:00" }, { @@ -2370,9 +2363,6 @@ "psr-13", "rest" ], - "support": { - "source": "https://github.com/php-fig/link/tree/master" - }, "time": "2016-10-28T16:06:13+00:00" }, { @@ -2471,9 +2461,6 @@ "psr-16", "simple-cache" ], - "support": { - "source": "https://github.com/php-fig/simple-cache/tree/master" - }, "time": "2017-10-23T01:57:42+00:00" }, { @@ -2860,6 +2847,7 @@ } ], "description": "A security checker for your composer.lock", + "abandoned": "https://github.com/fabpot/local-php-security-checker", "time": "2019-06-08T06:46:26+00:00" }, { @@ -3404,16 +3392,16 @@ }, { "name": "symfony/polyfill-ctype", - "version": "v1.22.1", + "version": "v1.23.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-ctype.git", - "reference": "c6c942b1ac76c82448322025e084cadc56048b4e" + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/c6c942b1ac76c82448322025e084cadc56048b4e", - "reference": "c6c942b1ac76c82448322025e084cadc56048b4e", + "url": "https://api.github.com/repos/symfony/polyfill-ctype/zipball/46cd95797e9df938fdd2b03693b5fca5e64b01ce", + "reference": "46cd95797e9df938fdd2b03693b5fca5e64b01ce", "shasum": "" }, "require": { @@ -3425,7 +3413,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "1.22-dev" + "dev-main": "1.23-dev" }, "thanks": { "name": "symfony/polyfill", @@ -3462,9 +3450,6 @@ "polyfill", "portable" ], - "support": { - "source": "https://github.com/symfony/polyfill-ctype/tree/v1.22.1" - }, "funding": [ { "url": "https://symfony.com/sponsor", @@ -3479,7 +3464,7 @@ "type": "tidelift" } ], - "time": "2021-01-07T16:49:33+00:00" + "time": "2021-02-19T12:13:01+00:00" }, { "name": "symfony/polyfill-intl-icu", @@ -4325,6 +4310,7 @@ "i18n", "text" ], + "abandoned": true, "time": "2018-12-05T18:34:18+00:00" }, { @@ -4407,29 +4393,33 @@ }, { "name": "webmozart/assert", - "version": "1.5.0", + "version": "1.10.0", "source": { "type": "git", - "url": "https://github.com/webmozart/assert.git", - "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4" + "url": "https://github.com/webmozarts/assert.git", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/88e6d84706d09a236046d686bbea96f07b3a34f4", - "reference": "88e6d84706d09a236046d686bbea96f07b3a34f4", + "url": "https://api.github.com/repos/webmozarts/assert/zipball/6964c76c7804814a842473e0c8fd15bab0f18e25", + "reference": "6964c76c7804814a842473e0c8fd15bab0f18e25", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0", + "php": "^7.2 || ^8.0", "symfony/polyfill-ctype": "^1.8" }, + "conflict": { + "phpstan/phpstan": "<0.12.20", + "vimeo/psalm": "<4.6.1 || 4.6.2" + }, "require-dev": { - "phpunit/phpunit": "^4.8.36 || ^7.5.13" + "phpunit/phpunit": "^8.5.13" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.10-dev" } }, "autoload": { @@ -4453,7 +4443,7 @@ "check", "validate" ], - "time": "2019-08-24T08:43:50+00:00" + "time": "2021-03-09T10:59:23+00:00" }, { "name": "zendframework/zend-code", @@ -5768,12 +5758,12 @@ "version": "v3.1.6", "source": { "type": "git", - "url": "https://github.com/mlively/Phake.git", + "url": "https://github.com/phake/Phake.git", "reference": "3848901ed8e236534ae684dd5cf0f3bfc4c8a24c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/mlively/Phake/zipball/3848901ed8e236534ae684dd5cf0f3bfc4c8a24c", + "url": "https://api.github.com/repos/phake/Phake/zipball/3848901ed8e236534ae684dd5cf0f3bfc4c8a24c", "reference": "3848901ed8e236534ae684dd5cf0f3bfc4c8a24c", "shasum": "" }, @@ -7353,11 +7343,12 @@ "php": "7.2", "ext-dom": "*", "ext-json": "*", - "ext-mbstring": "*" + "ext-mbstring": "*", + "ext-openssl": "*" }, "platform-dev": [], "platform-overrides": { "php": "7.2" }, - "plugin-api-version": "2.0.0" + "plugin-api-version": "1.1.0" } From 83db13127f0f9a92574061bae041c1d1e4f55e1d Mon Sep 17 00:00:00 2001 From: Michiel Kodde Date: Wed, 29 Sep 2021 11:28:30 +0200 Subject: [PATCH 3/7] Update CHANGELOG.md --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index be6580361e..f2db89aea5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,10 @@ We will continue to post relevant release notes on the GitHub release page. More More information about our release strategy can be found in the [Development Guidelines](https://github.com/OpenConext/OpenConext-engineblock/wiki/Development-Guidelines#release-notes) on the EngineBlock wiki. +## 6.6.5 +**Feature** + - Upgrade the Monitor bundle, exposing opcache statistics to the info endpoint #1163 + ## 6.6.4 **Features** - allow control over the RequestedAttribute list added to the proxy SP metadata From c17c0a18e32344286af91430b55fb467a510d03f Mon Sep 17 00:00:00 2001 From: Stephan Kok Date: Mon, 11 Oct 2021 15:16:13 +0200 Subject: [PATCH 4/7] Check if there is a valid authentication in the AuthenticationState --- .../Module/Service/AssertionConsumer.php | 3 +- .../Corto/Module/Service/ProcessConsent.php | 7 +-- .../Corto/Module/Service/ProvideConsent.php | 9 ++-- .../AuthenticationProcedure.php | 37 ++++++++++---- .../AuthenticationProcedureMap.php | 25 ++++++++-- .../Authentication/AuthenticationState.php | 42 ++++++++++++---- .../AuthenticationStateInterface.php | 14 ++++-- .../Module/Service/ProcessConsentTest.php | 1 + .../Module/Service/ProvideConsentTest.php | 15 +++--- .../AuthenticationStateTest.php | 48 ++++++++++++++++++- 10 files changed, 154 insertions(+), 47 deletions(-) diff --git a/library/EngineBlock/Corto/Module/Service/AssertionConsumer.php b/library/EngineBlock/Corto/Module/Service/AssertionConsumer.php index ec7098982b..27da43b268 100644 --- a/library/EngineBlock/Corto/Module/Service/AssertionConsumer.php +++ b/library/EngineBlock/Corto/Module/Service/AssertionConsumer.php @@ -66,7 +66,8 @@ public function __construct( ProcessingStateHelperInterface $processingStateHelper, StepupGatewayCallOutHelper $stepupGatewayCallOutHelper, ServiceProviderFactory $serviceProviderFactory - ) { + ) + { $this->_server = $server; $this->_xmlConverter = $xmlConverter; $this->_session = $session; diff --git a/library/EngineBlock/Corto/Module/Service/ProcessConsent.php b/library/EngineBlock/Corto/Module/Service/ProcessConsent.php index 056260c10b..97cf0300b6 100644 --- a/library/EngineBlock/Corto/Module/Service/ProcessConsent.php +++ b/library/EngineBlock/Corto/Module/Service/ProcessConsent.php @@ -26,12 +26,12 @@ class EngineBlock_Corto_Module_Service_ProcessConsent implements EngineBlock_Corto_Module_Service_ServiceInterface { /** - * @var \EngineBlock_Corto_ProxyServer + * @var EngineBlock_Corto_ProxyServer */ protected $_server; /** - * @var \EngineBlock_Corto_XmlToArray + * @var EngineBlock_Corto_XmlToArray */ protected $_xmlConverter; @@ -63,7 +63,8 @@ public function __construct( EngineBlock_Corto_Model_Consent_Factory $consentFactory, AuthenticationStateHelperInterface $stateHelper, ProcessingStateHelperInterface $processingStateHelper - ) { + ) + { $this->_server = $server; $this->_xmlConverter = $xmlConverter; $this->_consentFactory = $consentFactory; diff --git a/library/EngineBlock/Corto/Module/Service/ProvideConsent.php b/library/EngineBlock/Corto/Module/Service/ProvideConsent.php index d1a481abe5..3fed23d19d 100644 --- a/library/EngineBlock/Corto/Module/Service/ProvideConsent.php +++ b/library/EngineBlock/Corto/Module/Service/ProvideConsent.php @@ -33,7 +33,7 @@ class EngineBlock_Corto_Module_Service_ProvideConsent implements EngineBlock_Corto_Module_Service_ServiceInterface { - /** @var \EngineBlock_Corto_ProxyServer */ + /** @var EngineBlock_Corto_ProxyServer */ private $_server; /** * @var EngineBlock_Corto_XmlToArray @@ -41,10 +41,10 @@ class EngineBlock_Corto_Module_Service_ProvideConsent private $_xmlConverter; /** @var EngineBlock_Corto_Model_Consent_Factory */ - private $_consentFactory; + private $_consentFactory; /** @var ConsentServiceInterface */ - private $_consentService; + private $_consentService; /** @var AuthenticationStateHelperInterface */ private $_authenticationStateHelper; @@ -67,7 +67,8 @@ public function __construct( AuthenticationStateHelperInterface $authStateHelper, Environment $twig, ProcessingStateHelperInterface $processingStateHelper - ) { + ) + { $this->_server = $server; $this->_xmlConverter = $xmlConverter; $this->_consentFactory = $consentFactory; diff --git a/src/OpenConext/EngineBlockBundle/Authentication/AuthenticationProcedure.php b/src/OpenConext/EngineBlockBundle/Authentication/AuthenticationProcedure.php index c5e37d0573..bf0cb1505b 100644 --- a/src/OpenConext/EngineBlockBundle/Authentication/AuthenticationProcedure.php +++ b/src/OpenConext/EngineBlockBundle/Authentication/AuthenticationProcedure.php @@ -47,7 +47,7 @@ private function __construct(Entity $serviceProvider) * @param Entity $serviceProvider * @return AuthenticationProcedure */ - public static function onBehalfOf(Entity $serviceProvider) + public static function onBehalfOf(Entity $serviceProvider): AuthenticationProcedure { return new self($serviceProvider); } @@ -55,7 +55,7 @@ public static function onBehalfOf(Entity $serviceProvider) /** * @param Entity $identityProvider */ - public function authenticatedAt(Entity $identityProvider) + public function authenticatedAt(Entity $identityProvider): void { $this->identityProvider = $identityProvider; } @@ -63,25 +63,32 @@ public function authenticatedAt(Entity $identityProvider) /** * @param DateTimeInterface $dateTime */ - public function completeOn(DateTimeInterface $dateTime) + public function completeOn(DateTimeInterface $dateTime): void { $this->dateOfCompletion = $dateTime; } /** + * Validates if the authentication has been completed with any Identity Provider + * * @return bool */ - public function hasBeenAuthenticated() + public function hasBeenAuthenticated(): bool { - return $this->identityProvider === null; + return $this->identityProvider !== null; } /** + * Validates if the authentication has been completed with the passed Identity Provider + * * @param Entity $identityProvider * @return bool */ - public function hasBeenAuthenticatedAt(Entity $identityProvider) + public function hasBeenAuthenticatedAt(Entity $identityProvider): bool { + if ($this->identityProvider === null) { + return false; + } return $this->identityProvider->equals($identityProvider); } @@ -89,7 +96,7 @@ public function hasBeenAuthenticatedAt(Entity $identityProvider) * @param Entity $serviceProvider * @return bool */ - public function isOnBehalfOf(Entity $serviceProvider) + public function isOnBehalfOf(Entity $serviceProvider): bool { return $this->serviceProvider->equals($serviceProvider); } @@ -98,7 +105,7 @@ public function isOnBehalfOf(Entity $serviceProvider) * @param DateTimeInterface $date * @return bool */ - public function isCompletedAfter(DateTimeInterface $date) + public function isCompletedAfter(DateTimeInterface $date): bool { if ($this->dateOfCompletion === null) { return false; @@ -107,11 +114,21 @@ public function isCompletedAfter(DateTimeInterface $date) return $this->dateOfCompletion > $date; } + /** + * We assume that the authentication procedure has been (successfully) finished if a dateOfCompletion is set. + * + * @return bool + */ + public function isCompleted(): bool + { + return $this->dateOfCompletion !== null; + } + /** * @param AuthenticationProcedure $other * @return bool */ - public function equals(AuthenticationProcedure $other) + public function equals(AuthenticationProcedure $other): bool { $isSameServiceProvider = $this->serviceProvider->equals($other->serviceProvider); @@ -123,7 +140,7 @@ public function equals(AuthenticationProcedure $other) $isSameIdentityProvider = $this->identityProvider->equals($other->identityProvider); } - $isSameDateOfCompletion = $this->dateOfCompletion == $other->dateOfCompletion; + $isSameDateOfCompletion = $this->dateOfCompletion === $other->dateOfCompletion; return $isSameServiceProvider && $isSameIdentityProvider && $isSameDateOfCompletion; } diff --git a/src/OpenConext/EngineBlockBundle/Authentication/AuthenticationProcedureMap.php b/src/OpenConext/EngineBlockBundle/Authentication/AuthenticationProcedureMap.php index cbcbfe3aa4..c13f2867a3 100644 --- a/src/OpenConext/EngineBlockBundle/Authentication/AuthenticationProcedureMap.php +++ b/src/OpenConext/EngineBlockBundle/Authentication/AuthenticationProcedureMap.php @@ -43,7 +43,7 @@ public function __construct(array $authenticationProcedures = []) * @param AuthenticationProcedure $authenticationProcedure * @return AuthenticationProcedureMap */ - public function add($requestId, AuthenticationProcedure $authenticationProcedure) + public function add($requestId, AuthenticationProcedure $authenticationProcedure): AuthenticationProcedureMap { $newAuthenticationProcedures = $this->authenticationProcedures; $newAuthenticationProcedures[$requestId] = $authenticationProcedure; @@ -56,7 +56,7 @@ public function add($requestId, AuthenticationProcedure $authenticationProcedure * @return AuthenticationProcedure|null * @throws AssertionFailedException */ - public function find($requestId) + public function find($requestId): ?AuthenticationProcedure { Assertion::string($requestId, 'The requestId must be a string (XML ID) value'); if (isset($this->authenticationProcedures[$requestId])) { @@ -69,7 +69,7 @@ public function find($requestId) * @param Entity $entity * @return AuthenticationProcedureMap */ - public function filterOnBehalfOf(Entity $entity) + public function filterOnBehalfOf(Entity $entity): AuthenticationProcedureMap { $filterMethod = function (AuthenticationProcedure $authenticationProcedure) use ($entity) { return $authenticationProcedure->isOnBehalfOf($entity); @@ -82,7 +82,7 @@ public function filterOnBehalfOf(Entity $entity) * @param DateTimeInterface $startDate * @return AuthenticationProcedureMap */ - public function filterProceduresCompletedAfter(DateTimeInterface $startDate) + public function filterProceduresCompletedAfter(DateTimeInterface $startDate): AuthenticationProcedureMap { $filterMethod = function (AuthenticationProcedure $authenticationProcedure) use ($startDate) { return $authenticationProcedure->isCompletedAfter($startDate); @@ -95,7 +95,7 @@ public function filterProceduresCompletedAfter(DateTimeInterface $startDate) * @param AuthenticationProcedure $other * @return bool */ - public function contains(AuthenticationProcedure $other) + public function contains(AuthenticationProcedure $other): bool { foreach ($this->authenticationProcedures as $authenticationProcedure) { if ($authenticationProcedure->equals($other)) { @@ -110,4 +110,19 @@ public function count() { return count($this->authenticationProcedures); } + + /** + * Validates if any of the authenticationProcedures has been authenticated and completed + * + * @return bool + */ + public function hasBeenAuthenticated(): bool + { + foreach ($this->authenticationProcedures as $authenticationProcedure) { + if ($authenticationProcedure->hasBeenAuthenticated() && $authenticationProcedure->isCompleted()) { + return true; + } + } + return false; + } } diff --git a/src/OpenConext/EngineBlockBundle/Authentication/AuthenticationState.php b/src/OpenConext/EngineBlockBundle/Authentication/AuthenticationState.php index 7543dc832a..eb5aba1a98 100644 --- a/src/OpenConext/EngineBlockBundle/Authentication/AuthenticationState.php +++ b/src/OpenConext/EngineBlockBundle/Authentication/AuthenticationState.php @@ -40,16 +40,16 @@ final class AuthenticationState implements AuthenticationStateInterface public function __construct(AuthenticationLoopGuardInterface $authenticationLoopGuard) { $this->authenticationProcedures = new AuthenticationProcedureMap; - $this->authenticationLoopGuard = $authenticationLoopGuard; + $this->authenticationLoopGuard = $authenticationLoopGuard; } /** - * @param $requestId + * @param string $requestId * @param Entity $serviceProvider * @return void * @throws AssertionFailedException */ - public function startAuthenticationOnBehalfOf($requestId, Entity $serviceProvider) + public function startAuthenticationOnBehalfOf(string $requestId, Entity $serviceProvider): void { Assertion::string($requestId, 'The requestId must be a string (XML ID) value'); $currentAuthenticationProcedure = AuthenticationProcedure::onBehalfOf($serviceProvider); @@ -78,12 +78,14 @@ public function startAuthenticationOnBehalfOf($requestId, Entity $serviceProvide } /** + * Validates if an request can be found in session and sets the Identity Provider in the authentication Procedure + * * @param string $requestId * @param Entity $identityProvider * @return void * @throws AssertionFailedException */ - public function authenticatedAt($requestId, Entity $identityProvider) + public function authenticatedAt(string $requestId, Entity $identityProvider): void { Assertion::string($requestId, 'The requestId must be a string (XML ID) value'); @@ -92,7 +94,8 @@ public function authenticatedAt($requestId, Entity $identityProvider) if ($currentRequest === null) { throw new LogicException( sprintf( - 'The requested authentication procedure with requestId "%s" couldn\'t be found in the session storage.', + 'The requested authentication procedure with requestId "%s" couldn\'t be found in the ' . + 'session storage.', $requestId ) ); @@ -102,32 +105,51 @@ public function authenticatedAt($requestId, Entity $identityProvider) } /** + * Completes the authentication procedure and sets the completion time + * * @param string $requestId * @return void * @throws AssertionFailedException */ - public function completeCurrentProcedure($requestId) + public function completeCurrentProcedure(string $requestId): void { Assertion::string($requestId, 'The requestId must be a string (XML ID) value'); $currentRequest = $this->authenticationProcedures->find($requestId); if ($currentRequest === null) { throw new LogicException( sprintf( - 'The requested authentication procedure with requestId "%s" couldn\'t be found in the session storage in order to complete.', + 'The requested authentication procedure with requestId "%s" couldn\'t be found in the ' . + 'session storage in order to complete.', $requestId ) ); } - if ($currentRequest->hasBeenAuthenticated()) { + if (!$currentRequest->hasBeenAuthenticated()) { throw new LogicException( sprintf( - 'The requested authentication procedure with requestId "%s" has already been authenticated.', + 'The requested authentication procedure with requestId "%s" has not been authenticated.', $requestId ) ); } - $currentRequest->completeOn(new DateTimeImmutable); + $currentRequest->completeOn(new DateTimeImmutable()); + } + + /** + * Validates if the current session contains at least one authentication procedure that has been + * authenticated and completed + * + * @return bool + * @throws LogicException + */ + public function isAuthenticated(): bool + { + if ($this->authenticationProcedures === null) { + throw new LogicException('The requested authentication procedure couldn\'t be found in the ' . + 'session storage in order to complete.'); + } + return $this->authenticationProcedures->hasBeenAuthenticated(); } } diff --git a/src/OpenConext/EngineBlockBundle/Authentication/AuthenticationStateInterface.php b/src/OpenConext/EngineBlockBundle/Authentication/AuthenticationStateInterface.php index 4e97da53fd..894be0a854 100644 --- a/src/OpenConext/EngineBlockBundle/Authentication/AuthenticationStateInterface.php +++ b/src/OpenConext/EngineBlockBundle/Authentication/AuthenticationStateInterface.php @@ -27,18 +27,22 @@ interface AuthenticationStateInterface * @param Entity $serviceProvider * @return void */ - public function startAuthenticationOnBehalfOf($requestId, Entity $serviceProvider); + public function startAuthenticationOnBehalfOf(string $requestId, Entity $serviceProvider): void; /** * @param string $requestId - * @param Entity $identityProvider * @return void */ - public function authenticatedAt($requestId, Entity $identityProvider); + public function authenticatedAt(string $requestId, Entity $identityProvider): void; /** - * @param $requestId + * @param string $requestId * @return void */ - public function completeCurrentProcedure($requestId); + public function completeCurrentProcedure(string $requestId): void; + + /** + * @return bool + */ + public function isAuthenticated(): bool; } diff --git a/tests/library/EngineBlock/Test/Corto/Module/Service/ProcessConsentTest.php b/tests/library/EngineBlock/Test/Corto/Module/Service/ProcessConsentTest.php index 0d16b46bfc..9debea8d05 100644 --- a/tests/library/EngineBlock/Test/Corto/Module/Service/ProcessConsentTest.php +++ b/tests/library/EngineBlock/Test/Corto/Module/Service/ProcessConsentTest.php @@ -268,6 +268,7 @@ private function mockSspResponse() $sspResponse->setAssertions(array($assertion)); $sspResponse = new EngineBlock_Saml2_ResponseAnnotationDecorator($sspResponse); + $sspResponse->setOriginalIssuer("https://idp.example.edu"); return $sspResponse; } diff --git a/tests/library/EngineBlock/Test/Corto/Module/Service/ProvideConsentTest.php b/tests/library/EngineBlock/Test/Corto/Module/Service/ProvideConsentTest.php index 462187affc..806a5cdaaa 100644 --- a/tests/library/EngineBlock/Test/Corto/Module/Service/ProvideConsentTest.php +++ b/tests/library/EngineBlock/Test/Corto/Module/Service/ProvideConsentTest.php @@ -83,17 +83,18 @@ class EngineBlock_Test_Corto_Module_Service_ProvideConsentTest extends TestCase */ private $sessionMock; - public function setup() { - $diContainer = EngineBlock_ApplicationSingleton::getInstance()->getDiContainer(); + public function setup() + { + $diContainer = EngineBlock_ApplicationSingleton::getInstance()->getDiContainer(); $this->sspResponseMock = $this->mockSspResponse(); - $this->proxyServerMock = $this->mockProxyServer(); - $this->xmlConverterMock = $this->mockXmlConverter($diContainer->getXmlConverter()); + $this->proxyServerMock = $this->mockProxyServer(); + $this->xmlConverterMock = $this->mockXmlConverter($diContainer->getXmlConverter()); $this->consentFactoryMock = $diContainer->getConsentFactory(); - $this->consentMock = $this->mockConsent(); - $this->consentService = $this->mockConsentService(); + $this->consentMock = $this->mockConsent(); + $this->consentService = $this->mockConsentService(); $this->authStateHelperMock = $this->mockAuthStateHelper(); - $this->twig = $this->mockTwig(); + $this->twig = $this->mockTwig(); $this->processingStateHelperMock = $this->mockProcessingStateHelper(); $this->httpRequestMock = $this->mockHttpRequest(); } diff --git a/tests/unit/OpenConext/EngineBlockBundle/Authentication/AuthenticationStateTest.php b/tests/unit/OpenConext/EngineBlockBundle/Authentication/AuthenticationStateTest.php index a105fe3663..f6a04ceeae 100644 --- a/tests/unit/OpenConext/EngineBlockBundle/Authentication/AuthenticationStateTest.php +++ b/tests/unit/OpenConext/EngineBlockBundle/Authentication/AuthenticationStateTest.php @@ -80,9 +80,53 @@ public function an_authentication_procedure_cannot_be_completed_if_it_has_not_be $authenticationState = new AuthenticationState($authenticationLoopGuard); $authenticationState->startAuthenticationOnBehalfOf($requestId, $serviceProvider); - $this->expectException(LogicException::class); - $this->expectExceptionMessage('The requested authentication procedure with requestId "_00000000-0000-0000-0000-000000000000" has already been authenticated.'); + $this->expectExceptionMessage('The requested authentication procedure with requestId "_00000000-0000-0000-0000-000000000000" has not been authenticated.'); + $authenticationState->completeCurrentProcedure($requestId); + } + + /** + * @test + * @group Authentication + */ + public function an_authentication_procedure_can_be_completed_multiple_times() + { + $authenticationLoopGuard = new AuthenticationLoopGuard(5, 30); + $serviceProvider = new Entity(new EntityId('https://my-service-provider.example'), EntityType::SP()); + $identityProvider = new Entity(new EntityId('https://my-service-provider.example'), EntityType::IdP()); + + $requestId = '_00000000-0000-0000-0000-000000000000'; + + $authenticationState = new AuthenticationState($authenticationLoopGuard); + $authenticationState->startAuthenticationOnBehalfOf($requestId, $serviceProvider); + $authenticationState->authenticatedAt($requestId, $identityProvider); + $authenticationState->completeCurrentProcedure($requestId); $authenticationState->completeCurrentProcedure($requestId); + + self::assertTrue($authenticationState->isAuthenticated()); + } + + /** + * @test + * @group Authentication + */ + public function an_authentication_procedure_is_not_authenticated_before_consent() + { + $authenticationLoopGuard = new AuthenticationLoopGuard(5, 30); + + $serviceProvider = new Entity(new EntityId('https://my-service-provider.example'), EntityType::SP()); + $identityProvider = new Entity(new EntityId('https://my-service-provider.example'), EntityType::IdP()); + + $requestId = '_00000000-0000-0000-0000-000000000000'; + + $authenticationState = new AuthenticationState($authenticationLoopGuard); + $authenticationState->startAuthenticationOnBehalfOf($requestId, $serviceProvider); + $authenticationState->authenticatedAt($requestId, $identityProvider); + + self::assertFalse($authenticationState->isAuthenticated()); + + $authenticationState->completeCurrentProcedure($requestId); + + self::assertTrue($authenticationState->isAuthenticated()); } } From a481f96823c4dec5b43149f8025c1f92e6820491 Mon Sep 17 00:00:00 2001 From: Thomas Beekman Date: Tue, 19 Oct 2021 10:31:31 +0200 Subject: [PATCH 5/7] Add "consent disable" feature --- app/config/config.yml | 1 + app/config/parameters.yml.dist | 1 + library/EngineBlock/Corto/Model/Consent.php | 47 ++++++------ .../Corto/Model/Consent/Factory.php | 4 +- .../TestFeatureConfiguration.php | 1 + .../Test/Corto/Model/ConsentTest.php | 75 +++++++++++++++++++ 6 files changed, 104 insertions(+), 25 deletions(-) create mode 100644 tests/library/EngineBlock/Test/Corto/Model/ConsentTest.php diff --git a/app/config/config.yml b/app/config/config.yml index f67961f640..b9e68ccd16 100644 --- a/app/config/config.yml +++ b/app/config/config.yml @@ -24,6 +24,7 @@ open_conext_engine_block: eb.run_all_manipulations_prior_to_consent: "%feature_run_all_manipulations_prior_to_consent%" eb.block_user_on_violation: "%feature_block_user_on_violation%" eb.enable_sso_notification: "%feature_enable_sso_notification%" + eb.feature_disable_consent: "%feature_disable_consent%" swiftmailer: transport: "%mailer_transport%" diff --git a/app/config/parameters.yml.dist b/app/config/parameters.yml.dist index 6ee8f5dbd8..8482749a37 100644 --- a/app/config/parameters.yml.dist +++ b/app/config/parameters.yml.dist @@ -216,6 +216,7 @@ parameters: feature_api_deprovision: true feature_run_all_manipulations_prior_to_consent: false feature_block_user_on_violation: false + feature_disable_consent: false ########################################################################################## ## PROFILE SETTINGS diff --git a/library/EngineBlock/Corto/Model/Consent.php b/library/EngineBlock/Corto/Model/Consent.php index e9a31d5bd0..2ea9894268 100644 --- a/library/EngineBlock/Corto/Model/Consent.php +++ b/library/EngineBlock/Corto/Model/Consent.php @@ -52,6 +52,13 @@ class EngineBlock_Corto_Model_Consent */ private $_amPriorToConsentEnabled; + /** + * A reflection of the eb.feature_disable_consent feature flag + * + * @var bool + */ + private $_consentDisabled; + /** * @param string $tableName * @param bool $mustStoreValues @@ -59,6 +66,7 @@ class EngineBlock_Corto_Model_Consent * @param array $responseAttributes * @param EngineBlock_Database_ConnectionFactory $databaseConnectionFactory * @param bool $amPriorToConsentEnabled Is the run_all_manipulations_prior_to_consent feature enabled or not + * @param bool $consentDisabled Is the feature_disable_consent feature enabled or not */ public function __construct( $tableName, @@ -66,7 +74,8 @@ public function __construct( EngineBlock_Saml2_ResponseAnnotationDecorator $response, array $responseAttributes, EngineBlock_Database_ConnectionFactory $databaseConnectionFactory, - $amPriorToConsentEnabled + $amPriorToConsentEnabled, + $consentDisabled ) { $this->_tableName = $tableName; @@ -75,41 +84,31 @@ public function __construct( $this->_responseAttributes = $responseAttributes; $this->_databaseConnectionFactory = $databaseConnectionFactory; $this->_amPriorToConsentEnabled = $amPriorToConsentEnabled; + $this->_consentDisabled = $consentDisabled; } - public function explicitConsentWasGivenFor(ServiceProvider $serviceProvider) { - return $this->_hasStoredConsent($serviceProvider, ConsentType::TYPE_EXPLICIT); + public function explicitConsentWasGivenFor(ServiceProvider $serviceProvider) + { + return $this->_consentDisabled || + $this->_hasStoredConsent($serviceProvider, ConsentType::TYPE_EXPLICIT); } - public function implicitConsentWasGivenFor(ServiceProvider $serviceProvider) { - return $this->_hasStoredConsent($serviceProvider, ConsentType::TYPE_IMPLICIT); + public function implicitConsentWasGivenFor(ServiceProvider $serviceProvider) + { + return $this->_consentDisabled || + $this->_hasStoredConsent($serviceProvider, ConsentType::TYPE_IMPLICIT); } public function giveExplicitConsentFor(ServiceProvider $serviceProvider) { - return $this->_storeConsent($serviceProvider, ConsentType::TYPE_EXPLICIT); + return $this->_consentDisabled || + $this->_storeConsent($serviceProvider, ConsentType::TYPE_EXPLICIT); } public function giveImplicitConsentFor(ServiceProvider $serviceProvider) { - return $this->_storeConsent($serviceProvider, ConsentType::TYPE_IMPLICIT); - } - - public function countTotalConsent() - { - $dbh = $this->_getConsentDatabaseConnection(); - $hashedUserId = sha1($this->_getConsentUid()); - $query = "SELECT COUNT(*) FROM consent where hashed_user_id = ?"; - $parameters = array($hashedUserId); - $statement = $dbh->prepare($query); - if (!$statement) { - throw new EngineBlock_Exception( - "Unable to create a prepared statement to count consent?!", EngineBlock_Exception::CODE_ALERT - ); - } - /** @var $statement PDOStatement */ - $statement->execute($parameters); - return (int)$statement->fetchColumn(); + return $this->_consentDisabled || + $this->_storeConsent($serviceProvider, ConsentType::TYPE_IMPLICIT); } /** diff --git a/library/EngineBlock/Corto/Model/Consent/Factory.php b/library/EngineBlock/Corto/Model/Consent/Factory.php index 8ff4fe6b74..caf198886a 100644 --- a/library/EngineBlock/Corto/Model/Consent/Factory.php +++ b/library/EngineBlock/Corto/Model/Consent/Factory.php @@ -61,6 +61,7 @@ public function create( ->getFeatureConfiguration(); $amPriorToConsent = $featureConfiguration->isEnabled('eb.run_all_manipulations_prior_to_consent'); + $consentDisabled = $featureConfiguration->isEnabled('eb.feature_disable_consent'); return new EngineBlock_Corto_Model_Consent( $proxyServer->getConfig('ConsentDbTable', 'consent'), @@ -68,7 +69,8 @@ public function create( $response, $attributes, $this->_databaseConnectionFactory, - $amPriorToConsent + $amPriorToConsent, + $consentDisabled ); } } diff --git a/src/OpenConext/EngineBlockBundle/Configuration/TestFeatureConfiguration.php b/src/OpenConext/EngineBlockBundle/Configuration/TestFeatureConfiguration.php index f6682eafe8..c82ea753a7 100644 --- a/src/OpenConext/EngineBlockBundle/Configuration/TestFeatureConfiguration.php +++ b/src/OpenConext/EngineBlockBundle/Configuration/TestFeatureConfiguration.php @@ -42,6 +42,7 @@ public function __construct() $this->setFeature(new Feature('eb.encrypted_assertions', true)); $this->setFeature(new Feature('eb.encrypted_assertions_require_outer_signature', true)); $this->setFeature(new Feature('eb.enable_sso_notification', false)); + $this->setFeature(new Feature('eb.feature_disable_consent', false)); } public function setFeature(Feature $feature): void diff --git a/tests/library/EngineBlock/Test/Corto/Model/ConsentTest.php b/tests/library/EngineBlock/Test/Corto/Model/ConsentTest.php new file mode 100644 index 0000000000..a4d816bcf9 --- /dev/null +++ b/tests/library/EngineBlock/Test/Corto/Model/ConsentTest.php @@ -0,0 +1,75 @@ +mockedDatabaseConnection = Phake::mock('EngineBlock_Database_ConnectionFactory'); + $mockedResponse = Phake::mock('EngineBlock_Saml2_ResponseAnnotationDecorator'); + + $this->consentDisabled = new EngineBlock_Corto_Model_Consent( + "consent", + true, + $mockedResponse, + [], + $this->mockedDatabaseConnection, + false, + true + ); + + $this->consent = new EngineBlock_Corto_Model_Consent( + "consent", + true, + $mockedResponse, + [], + $this->mockedDatabaseConnection, + false, + false + ); + } + + public function testConsentDisabledDoesNotWriteToDatabase() + { + $serviceProvider = new ServiceProvider("service-provider-entity-id"); + $this->consentDisabled->explicitConsentWasGivenFor($serviceProvider); + $this->consentDisabled->implicitConsentWasGivenFor($serviceProvider); + $this->consentDisabled->giveExplicitConsentFor($serviceProvider); + $this->consentDisabled->giveImplicitConsentFor($serviceProvider); + + Phake::verify($this->mockedDatabaseConnection, Phake::times(0))->create(); + } + + public function testConsentWriteToDatabase() + { + $serviceProvider = new ServiceProvider("service-provider-entity-id"); + $this->consent->explicitConsentWasGivenFor($serviceProvider); + $this->consent->implicitConsentWasGivenFor($serviceProvider); + $this->consent->giveExplicitConsentFor($serviceProvider); + $this->consent->giveImplicitConsentFor($serviceProvider); + + Phake::verify($this->mockedDatabaseConnection, Phake::times(4))->create(); + } +} From 68f3d6497fa083d6c532b05e12a4f9e54862659c Mon Sep 17 00:00:00 2001 From: Thomas Beekman Date: Tue, 19 Oct 2021 15:18:35 +0200 Subject: [PATCH 6/7] Add "consent disable" feature - refactored feature_disable_consent into feature_enable_consent --- app/config/config.yml | 2 +- app/config/parameters.yml.dist | 2 +- library/EngineBlock/Corto/Model/Consent.php | 18 +++++++++--------- .../Corto/Model/Consent/Factory.php | 4 ++-- .../Configuration/TestFeatureConfiguration.php | 2 +- .../Test/Corto/Model/ConsentTest.php | 4 ++-- 6 files changed, 16 insertions(+), 16 deletions(-) diff --git a/app/config/config.yml b/app/config/config.yml index b9e68ccd16..439fd60b0c 100644 --- a/app/config/config.yml +++ b/app/config/config.yml @@ -24,7 +24,7 @@ open_conext_engine_block: eb.run_all_manipulations_prior_to_consent: "%feature_run_all_manipulations_prior_to_consent%" eb.block_user_on_violation: "%feature_block_user_on_violation%" eb.enable_sso_notification: "%feature_enable_sso_notification%" - eb.feature_disable_consent: "%feature_disable_consent%" + eb.feature_enable_consent: "%feature_enable_consent%" swiftmailer: transport: "%mailer_transport%" diff --git a/app/config/parameters.yml.dist b/app/config/parameters.yml.dist index 8482749a37..782b789282 100644 --- a/app/config/parameters.yml.dist +++ b/app/config/parameters.yml.dist @@ -216,7 +216,7 @@ parameters: feature_api_deprovision: true feature_run_all_manipulations_prior_to_consent: false feature_block_user_on_violation: false - feature_disable_consent: false + feature_enable_consent: true ########################################################################################## ## PROFILE SETTINGS diff --git a/library/EngineBlock/Corto/Model/Consent.php b/library/EngineBlock/Corto/Model/Consent.php index 2ea9894268..c3f0cee4a3 100644 --- a/library/EngineBlock/Corto/Model/Consent.php +++ b/library/EngineBlock/Corto/Model/Consent.php @@ -53,11 +53,11 @@ class EngineBlock_Corto_Model_Consent private $_amPriorToConsentEnabled; /** - * A reflection of the eb.feature_disable_consent feature flag + * A reflection of the eb.feature_enable_consent feature flag * * @var bool */ - private $_consentDisabled; + private $_consentEnabled; /** * @param string $tableName @@ -66,7 +66,7 @@ class EngineBlock_Corto_Model_Consent * @param array $responseAttributes * @param EngineBlock_Database_ConnectionFactory $databaseConnectionFactory * @param bool $amPriorToConsentEnabled Is the run_all_manipulations_prior_to_consent feature enabled or not - * @param bool $consentDisabled Is the feature_disable_consent feature enabled or not + * @param bool $consentEnabled Is the feature_enable_consent feature enabled or not */ public function __construct( $tableName, @@ -75,7 +75,7 @@ public function __construct( array $responseAttributes, EngineBlock_Database_ConnectionFactory $databaseConnectionFactory, $amPriorToConsentEnabled, - $consentDisabled + $consentEnabled ) { $this->_tableName = $tableName; @@ -84,30 +84,30 @@ public function __construct( $this->_responseAttributes = $responseAttributes; $this->_databaseConnectionFactory = $databaseConnectionFactory; $this->_amPriorToConsentEnabled = $amPriorToConsentEnabled; - $this->_consentDisabled = $consentDisabled; + $this->_consentEnabled = $consentEnabled; } public function explicitConsentWasGivenFor(ServiceProvider $serviceProvider) { - return $this->_consentDisabled || + return !$this->_consentEnabled || $this->_hasStoredConsent($serviceProvider, ConsentType::TYPE_EXPLICIT); } public function implicitConsentWasGivenFor(ServiceProvider $serviceProvider) { - return $this->_consentDisabled || + return !$this->_consentEnabled || $this->_hasStoredConsent($serviceProvider, ConsentType::TYPE_IMPLICIT); } public function giveExplicitConsentFor(ServiceProvider $serviceProvider) { - return $this->_consentDisabled || + return !$this->_consentEnabled || $this->_storeConsent($serviceProvider, ConsentType::TYPE_EXPLICIT); } public function giveImplicitConsentFor(ServiceProvider $serviceProvider) { - return $this->_consentDisabled || + return !$this->_consentEnabled || $this->_storeConsent($serviceProvider, ConsentType::TYPE_IMPLICIT); } diff --git a/library/EngineBlock/Corto/Model/Consent/Factory.php b/library/EngineBlock/Corto/Model/Consent/Factory.php index caf198886a..80be173e81 100644 --- a/library/EngineBlock/Corto/Model/Consent/Factory.php +++ b/library/EngineBlock/Corto/Model/Consent/Factory.php @@ -61,7 +61,7 @@ public function create( ->getFeatureConfiguration(); $amPriorToConsent = $featureConfiguration->isEnabled('eb.run_all_manipulations_prior_to_consent'); - $consentDisabled = $featureConfiguration->isEnabled('eb.feature_disable_consent'); + $consentEnabled = $featureConfiguration->isEnabled('eb.feature_enable_consent'); return new EngineBlock_Corto_Model_Consent( $proxyServer->getConfig('ConsentDbTable', 'consent'), @@ -70,7 +70,7 @@ public function create( $attributes, $this->_databaseConnectionFactory, $amPriorToConsent, - $consentDisabled + $consentEnabled ); } } diff --git a/src/OpenConext/EngineBlockBundle/Configuration/TestFeatureConfiguration.php b/src/OpenConext/EngineBlockBundle/Configuration/TestFeatureConfiguration.php index c82ea753a7..198d705c87 100644 --- a/src/OpenConext/EngineBlockBundle/Configuration/TestFeatureConfiguration.php +++ b/src/OpenConext/EngineBlockBundle/Configuration/TestFeatureConfiguration.php @@ -42,7 +42,7 @@ public function __construct() $this->setFeature(new Feature('eb.encrypted_assertions', true)); $this->setFeature(new Feature('eb.encrypted_assertions_require_outer_signature', true)); $this->setFeature(new Feature('eb.enable_sso_notification', false)); - $this->setFeature(new Feature('eb.feature_disable_consent', false)); + $this->setFeature(new Feature('eb.feature_enable_consent', true)); } public function setFeature(Feature $feature): void diff --git a/tests/library/EngineBlock/Test/Corto/Model/ConsentTest.php b/tests/library/EngineBlock/Test/Corto/Model/ConsentTest.php index a4d816bcf9..38a2bfaaea 100644 --- a/tests/library/EngineBlock/Test/Corto/Model/ConsentTest.php +++ b/tests/library/EngineBlock/Test/Corto/Model/ConsentTest.php @@ -37,7 +37,7 @@ public function setup() [], $this->mockedDatabaseConnection, false, - true + false ); $this->consent = new EngineBlock_Corto_Model_Consent( @@ -47,7 +47,7 @@ public function setup() [], $this->mockedDatabaseConnection, false, - false + true ); } From fa79f9febf807adadece9a2123ed287bb163b21e Mon Sep 17 00:00:00 2001 From: Thijs Kinkhorst Date: Wed, 20 Oct 2021 15:10:44 +0200 Subject: [PATCH 7/7] Add behat test for consent enabled feature toggle --- .../Features/Consent.feature | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/OpenConext/EngineBlockFunctionalTestingBundle/Features/Consent.feature b/src/OpenConext/EngineBlockFunctionalTestingBundle/Features/Consent.feature index 10f47ea396..2480712c07 100644 --- a/src/OpenConext/EngineBlockFunctionalTestingBundle/Features/Consent.feature +++ b/src/OpenConext/EngineBlockFunctionalTestingBundle/Features/Consent.feature @@ -2,7 +2,7 @@ Feature: In order to make an informed decision about what information I'm sharing with SPs As a user - I want to send see what information the SP requires + I want to see what information the SP requires Background: Given an EngineBlock instance on "vm.openconext.org" @@ -69,7 +69,7 @@ Feature: And I pass through the IdP Then the response should contain "Dummy-SP will receive" - Scenario: The user is can read why the service providers requires an attribute + Scenario: The user can read why the service provider requires an attribute Given I log in at "Dummy-SP" And I pass through EngineBlock And I pass through the IdP @@ -79,7 +79,7 @@ Feature: And the response should contain "Motivation for affiliation" And the response should contain "Motivation for orcid" - Scenario: The user presented with an institution provided consent text + Scenario: The user is presented with an institution provided consent text Given I log in at "Dummy-SP" And the IdP "Dummy-IdP" provides a consent message "Institutional privacy message" for SP "Dummy-SP" And I pass through EngineBlock @@ -115,3 +115,11 @@ Feature: And I pass through the IdP Then the response should contain "urn:collab:person:engine-test-stand.openconext.org:test" Then the response should not contain "The identifier for this service is generated by" + + Scenario: The user is not asked for consent when the consent feature toggle is disabled + Given feature "eb.feature_enable_consent" is disabled + And I log in at "Dummy-SP" + And I pass through EngineBlock + And I pass through the IdP + And I pass through EngineBlock + Then the url should match "functional-testing/Dummy-SP/acs"