Skip to content

Commit ff2af3f

Browse files
committed
feat(consent): implement consent hash versioning
1 parent f998ae5 commit ff2af3f

File tree

24 files changed

+344
-158
lines changed

24 files changed

+344
-158
lines changed

config/services/controllers/api.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ services:
1616
- '@security.token_storage'
1717
- '@security.access.decision_manager'
1818
- '@OpenConext\EngineBlockBundle\Configuration\FeatureConfiguration'
19-
- '@OpenConext\EngineBlock\Service\ConsentService'
19+
- '@OpenConext\EngineBlock\Service\Consent\ConsentService'
2020

2121
OpenConext\EngineBlockBundle\Controller\Api\DeprovisionController:
2222
arguments:

config/services/services.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -78,8 +78,10 @@ services:
7878
engineblock.service.consent.ConsentHashService:
7979
class: OpenConext\EngineBlock\Service\Consent\ConsentHashService
8080
public: false
81+
arguments:
82+
- '@OpenConext\EngineBlockBundle\Authentication\Repository\DbalConsentRepository'
8183

82-
OpenConext\EngineBlock\Service\ConsentService:
84+
OpenConext\EngineBlock\Service\Consent\ConsentService:
8385
arguments:
8486
- '@OpenConext\EngineBlockBundle\Authentication\Repository\DbalConsentRepository'
8587
- '@OpenConext\EngineBlock\Service\MetadataService'

database/DoctrineMigrations/Version20220503092351.php

Lines changed: 0 additions & 30 deletions
This file was deleted.

library/EngineBlock/Application/DiContainer.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ public function getAuthenticationLoopGuard()
165165
*/
166166
public function getConsentService()
167167
{
168-
return $this->container->get(\OpenConext\EngineBlock\Service\ConsentService::class);
168+
return $this->container->get(\OpenConext\EngineBlock\Service\Consent\ConsentService::class);
169169
}
170170

171171
/**

library/EngineBlock/Corto/Model/Consent.php

Lines changed: 35 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,9 @@
1616
* limitations under the License.
1717
*/
1818

19+
use OpenConext\EngineBlock\Authentication\Value\ConsentHashQuery;
20+
use OpenConext\EngineBlock\Authentication\Value\ConsentStoreParameters;
21+
use OpenConext\EngineBlock\Authentication\Value\ConsentUpdateParameters;
1922
use OpenConext\EngineBlock\Authentication\Value\ConsentVersion;
2023
use OpenConext\EngineBlock\Metadata\Entity\ServiceProvider;
2124
use OpenConext\EngineBlock\Authentication\Value\ConsentType;
@@ -98,6 +101,9 @@ public function explicitConsentWasGivenFor(ServiceProvider $serviceProvider): bo
98101
*/
99102
public function upgradeAttributeHashFor(ServiceProvider $serviceProvider, string $consentType): void
100103
{
104+
if (!$this->_consentEnabled) {
105+
return;
106+
}
101107
$consentVersion = $this->_hasStoredConsent($serviceProvider, $consentType);
102108
if ($consentVersion->isUnstable()) {
103109
$this->_updateConsent($serviceProvider, $consentType);
@@ -157,39 +163,48 @@ private function _storeConsent(ServiceProvider $serviceProvider, $consentType):
157163
return false;
158164
}
159165

160-
$parameters = array(
161-
sha1($consentUuid),
162-
$serviceProvider->entityId,
163-
$this->_getStableAttributesHash($this->_responseAttributes),
164-
$consentType,
166+
$parameters = new ConsentStoreParameters(
167+
hashedUserId: sha1($consentUuid),
168+
serviceId: $serviceProvider->entityId,
169+
attributeStableHash: $this->_getStableAttributesHash($this->_responseAttributes),
170+
consentType: $consentType,
165171
);
166172

167173
return $this->_hashService->storeConsentHash($parameters);
168174
}
169175

170176
private function _updateConsent(ServiceProvider $serviceProvider, $consentType): bool
171177
{
172-
$parameters = array(
173-
$this->_getStableAttributesHash($this->_responseAttributes),
174-
$this->_getAttributesHash($this->_responseAttributes),
175-
sha1($this->_getConsentUid()),
176-
$serviceProvider->entityId,
177-
$consentType,
178+
$consentUid = $this->_getConsentUid();
179+
if (!is_string($consentUid)) {
180+
return false;
181+
}
182+
183+
$parameters = new ConsentUpdateParameters(
184+
attributeStableHash: $this->_getStableAttributesHash($this->_responseAttributes),
185+
attributeHash: $this->_getAttributesHash($this->_responseAttributes),
186+
hashedUserId: sha1($consentUid),
187+
serviceId: $serviceProvider->entityId,
188+
consentType: $consentType,
178189
);
179190

180191
return $this->_hashService->updateConsentHash($parameters);
181192
}
182193

183194
private function _hasStoredConsent(ServiceProvider $serviceProvider, $consentType): ConsentVersion
184195
{
185-
$consentUuid = sha1($this->_getConsentUid());
186-
$parameters = [
187-
$consentUuid,
188-
$serviceProvider->entityId,
189-
$this->_getAttributesHash($this->_responseAttributes),
190-
$this->_getStableAttributesHash($this->_responseAttributes),
191-
$consentType,
192-
];
193-
return $this->_hashService->retrieveConsentHash($parameters);
196+
$consentUid = $this->_getConsentUid();
197+
if (!is_string($consentUid)) {
198+
return ConsentVersion::notGiven();
199+
}
200+
201+
$query = new ConsentHashQuery(
202+
hashedUserId: sha1($consentUid),
203+
serviceId: $serviceProvider->entityId,
204+
attributeHash: $this->_getAttributesHash($this->_responseAttributes),
205+
attributeStableHash: $this->_getStableAttributesHash($this->_responseAttributes),
206+
consentType: $consentType,
207+
);
208+
return $this->_hashService->retrieveConsentHash($query);
194209
}
195210
}

library/EngineBlock/Corto/Model/Consent/Factory.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
* limitations under the License.
1717
*/
1818

19-
use OpenConext\EngineBlock\Service\Consent\ConsentHashService;
19+
use OpenConext\EngineBlock\Service\Consent\ConsentHashServiceInterface;
2020

2121
/**
2222
* @todo write a test
@@ -27,7 +27,7 @@ class EngineBlock_Corto_Model_Consent_Factory
2727
private $_filterCommandFactory;
2828

2929
/**
30-
* @var ConsentHashService
30+
* @var ConsentHashServiceInterface
3131
*/
3232
private $_hashService;
3333

@@ -36,7 +36,7 @@ class EngineBlock_Corto_Model_Consent_Factory
3636
*/
3737
public function __construct(
3838
EngineBlock_Corto_Filter_Command_Factory $filterCommandFactory,
39-
ConsentHashService $hashService
39+
ConsentHashServiceInterface $hashService
4040
) {
4141
$this->_filterCommandFactory = $filterCommandFactory;
4242
$this->_hashService = $hashService;

library/EngineBlock/Corto/Module/Service/ProcessConsent.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,8 +102,9 @@ public function serve($serviceName, Request $httpRequest)
102102

103103
if (!$consentRepository->explicitConsentWasGivenFor($serviceProvider)) {
104104
$consentRepository->giveExplicitConsentFor($destinationMetadata);
105+
} else {
106+
$consentRepository->upgradeAttributeHashFor($destinationMetadata, ConsentType::TYPE_EXPLICIT);
105107
}
106-
$consentRepository->upgradeAttributeHashFor($destinationMetadata, ConsentType::TYPE_EXPLICIT);
107108

108109
$response->setConsent(Constants::CONSENT_OBTAINED);
109110
$response->setDestination($response->getReturn());

library/EngineBlock/Corto/Module/Service/ProvideConsent.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,9 @@ public function serve($serviceName, Request $httpRequest)
149149
if ($this->isConsentDisabled($spMetadataChain, $identityProvider)) {
150150
if (!$consentRepository->implicitConsentWasGivenFor($serviceProviderMetadata)) {
151151
$consentRepository->giveImplicitConsentFor($serviceProviderMetadata);
152+
} else {
153+
$consentRepository->upgradeAttributeHashFor($serviceProviderMetadata, ConsentType::TYPE_IMPLICIT);
152154
}
153-
$consentRepository->upgradeAttributeHashFor($serviceProviderMetadata, ConsentType::TYPE_IMPLICIT);
154155

155156
$response->setConsent(Constants::CONSENT_INAPPLICABLE);
156157
$response->setDestination($response->getReturn());
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace OpenConext\EngineBlock\Doctrine\Migrations;
6+
7+
use Doctrine\DBAL\Schema\Schema;
8+
use Doctrine\Migrations\AbstractMigration;
9+
10+
/**
11+
* Change to the consent schema
12+
* 1. Added the `attribute_stable` column, string(80), nullable
13+
* 2. Changed the `attribute` column, has been made nullable
14+
*/
15+
final class Version20220503092351 extends AbstractMigration
16+
{
17+
public function getDescription(): string
18+
{
19+
return 'Add attribute_stable column to consent table and make attribute nullable';
20+
}
21+
22+
public function preUp(Schema $schema): void
23+
{
24+
$tables = $this->connection->createSchemaManager()->listTableNames();
25+
$tableExists = in_array('consent', $tables, true);
26+
27+
if (!$tableExists) {
28+
$this->skipIf(true, 'Table consent does not exist yet (fresh install, baseline will create it). Skipping.');
29+
return;
30+
}
31+
32+
$columnExists = (bool) $this->connection->fetchOne(
33+
"SELECT COUNT(*) FROM information_schema.COLUMNS
34+
WHERE TABLE_SCHEMA = DATABASE()
35+
AND TABLE_NAME = 'consent'
36+
AND COLUMN_NAME = 'attribute_stable'"
37+
);
38+
$this->skipIf(
39+
$columnExists,
40+
'Column attribute_stable already exists (fresh install via baseline). Skipping.'
41+
);
42+
}
43+
44+
public function up(Schema $schema): void
45+
{
46+
$this->addSql('ALTER TABLE consent ADD attribute_stable VARCHAR(80) DEFAULT NULL, CHANGE attribute attribute VARCHAR(80) DEFAULT NULL');
47+
}
48+
49+
public function down(Schema $schema): void
50+
{
51+
$this->addSql('ALTER TABLE consent DROP attribute_stable, CHANGE attribute attribute VARCHAR(80) CHARACTER SET utf8 NOT NULL COLLATE `utf8_unicode_ci`');
52+
}
53+
}

migrations/DoctrineMigrations/Version20260210000000.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,8 @@ public function up(Schema $schema): void
5353
`consent_date` datetime NOT NULL,
5454
`hashed_user_id` varchar(80) NOT NULL,
5555
`service_id` varchar(255) NOT NULL,
56-
`attribute` varchar(80) NOT NULL,
56+
`attribute` varchar(80) DEFAULT NULL,
57+
`attribute_stable` varchar(80) DEFAULT NULL,
5758
`consent_type` varchar(20) DEFAULT \'explicit\',
5859
`deleted_at` datetime NOT NULL DEFAULT \'0000-00-00 00:00:00\',
5960
PRIMARY KEY (`hashed_user_id`,`service_id`,`deleted_at`),

0 commit comments

Comments
 (0)