Skip to content

Commit 377626d

Browse files
authored
Merge pull request #1160 from OpenConext/feature/engin-api-remove-consent
Support removal of consent by collab person id and SP entity id
2 parents 617da7b + ac05ebe commit 377626d

File tree

24 files changed

+681
-75
lines changed

24 files changed

+681
-75
lines changed

app/config/config.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@ open_conext_engine_block:
1717
features:
1818
api.metadata_push: "%feature_api_metadata_push%"
1919
api.consent_listing: "%feature_api_consent_listing%"
20+
api.consent_remove: "%feature_api_consent_remove%"
2021
api.metadata_api: "%feature_api_metadata_api%"
2122
api.deprovision: "%feature_api_deprovision%"
2223
eb.encrypted_assertions: "%feature_eb_encrypted_assertions%"

app/config/parameters.yml.dist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,7 @@ parameters:
212212
feature_eb_encrypted_assertions_require_outer_signature: true
213213
feature_api_metadata_push: true
214214
feature_api_consent_listing: true
215+
feature_api_consent_remove: true
215216
feature_api_metadata_api: true
216217
feature_api_deprovision: true
217218
feature_run_all_manipulations_prior_to_consent: false
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
<?php declare(strict_types=1);
2+
3+
namespace OpenConext\EngineBlock\Doctrine\Migrations;
4+
5+
use Doctrine\DBAL\Schema\Schema;
6+
use Doctrine\Migrations\AbstractMigration;
7+
8+
/**
9+
* Auto-generated Migration: Please modify to your needs!
10+
*/
11+
final class Version20220425090852 extends AbstractMigration
12+
{
13+
public function up(Schema $schema) : void
14+
{
15+
// this up() migration is auto-generated, please modify it to your needs
16+
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
17+
18+
$this->addSql('ALTER TABLE consent DROP PRIMARY KEY');
19+
$this->addSql('ALTER TABLE consent ADD deleted_at DATETIME NOT NULL');
20+
$this->addSql('CREATE INDEX deleted_at ON consent (deleted_at)');
21+
$this->addSql('ALTER TABLE consent ADD PRIMARY KEY (hashed_user_id, service_id, deleted_at)');
22+
}
23+
24+
public function down(Schema $schema) : void
25+
{
26+
// this down() migration is auto-generated, please modify it to your needs
27+
$this->abortIf($this->connection->getDatabasePlatform()->getName() !== 'mysql', 'Migration can only be executed safely on \'mysql\'.');
28+
29+
$this->addSql('DROP INDEX deleted_at ON consent');
30+
$this->addSql('ALTER TABLE consent DROP PRIMARY KEY');
31+
$this->addSql('ALTER TABLE consent DROP deleted_at');
32+
$this->addSql('ALTER TABLE consent ADD PRIMARY KEY (hashed_user_id, service_id)');
33+
}
34+
}

library/EngineBlock/Corto/Model/Consent.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -149,8 +149,8 @@ private function _storeConsent(ServiceProvider $serviceProvider, $consentType)
149149
return false;
150150
}
151151

152-
$query = "INSERT INTO consent (hashed_user_id, service_id, attribute, consent_type, consent_date)
153-
VALUES (?, ?, ?, ?, NOW())
152+
$query = "INSERT INTO consent (hashed_user_id, service_id, attribute, consent_type, consent_date, deleted_at)
153+
VALUES (?, ?, ?, ?, NOW(), '0000-00-00 00:00:00')
154154
ON DUPLICATE KEY UPDATE attribute=VALUES(attribute), consent_type=VALUES(consent_type), consent_date=NOW()";
155155
$parameters = array(
156156
sha1($this->_getConsentUid()),
@@ -174,7 +174,6 @@ private function _storeConsent(ServiceProvider $serviceProvider, $consentType)
174174
EngineBlock_Exception::CODE_CRITICAL
175175
);
176176
}
177-
178177
return true;
179178
}
180179

@@ -188,7 +187,15 @@ private function _hasStoredConsent(ServiceProvider $serviceProvider, $consentTyp
188187

189188
$attributesHash = $this->_getAttributesHash($this->_responseAttributes);
190189

191-
$query = "SELECT * FROM {$this->_tableName} WHERE hashed_user_id = ? AND service_id = ? AND attribute = ? AND consent_type = ?";
190+
$query = "
191+
SELECT *
192+
FROM {$this->_tableName}
193+
WHERE hashed_user_id = ?
194+
AND service_id = ?
195+
AND attribute = ?
196+
AND consent_type = ?
197+
AND deleted_at IS NULL
198+
";
192199
$hashedUserId = sha1($this->_getConsentUid());
193200
$parameters = array(
194201
$hashedUserId,

library/EngineBlock/User.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,8 @@ public function getConsent()
5959
{
6060
$pdo = $this->_getDatabaseConnection();
6161
$query = 'SELECT service_id FROM consent
62-
WHERE hashed_user_id = ?';
62+
WHERE hashed_user_id = ?
63+
AND deleted_at IS NULL';
6364
$parameters = array(
6465
sha1($this->getUid())
6566
);

src/OpenConext/EngineBlock/Authentication/Repository/ConsentRepository.php

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,4 +35,6 @@ public function findAllFor($userId);
3535
* @return Consent[]
3636
*/
3737
public function deleteAllFor($userId);
38+
39+
public function deleteOneFor(string $userId, string $serviceProviderEntityId): bool;
3840
}

src/OpenConext/EngineBlock/Service/ConsentService.php

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,11 @@
2323
use OpenConext\EngineBlock\Authentication\Dto\ConsentList;
2424
use OpenConext\EngineBlock\Authentication\Model\Consent as ConsentEntity;
2525
use OpenConext\EngineBlock\Authentication\Repository\ConsentRepository;
26+
use OpenConext\EngineBlock\Authentication\Value\CollabPersonId;
2627
use OpenConext\EngineBlock\Exception\RuntimeException;
2728
use OpenConext\Value\Saml\EntityId;
2829
use Psr\Log\LoggerInterface;
30+
use function sprintf;
2931

3032
final class ConsentService implements ConsentServiceInterface
3133
{
@@ -46,7 +48,7 @@ final class ConsentService implements ConsentServiceInterface
4648

4749
public function __construct(
4850
ConsentRepository $consentRepository,
49-
MetadataService $metadataService,
51+
MetadataServiceInterface $metadataService,
5052
LoggerInterface $logger
5153
) {
5254
$this->consentRepository = $consentRepository;
@@ -92,6 +94,24 @@ public function countAllFor($userId)
9294
return count($consents);
9395
}
9496

97+
public function deleteOneConsentFor(CollabPersonId $id, string $serviceProviderEntityId): bool
98+
{
99+
$collabPersonId = $id->getCollabPersonId();
100+
try {
101+
return $this->consentRepository->deleteOneFor($collabPersonId, $serviceProviderEntityId);
102+
} catch (Exception $e) {
103+
throw new RuntimeException(
104+
sprintf(
105+
'An exception occurred while removing consent for a service provider("%s") and user ("%s").',
106+
$serviceProviderEntityId,
107+
$collabPersonId
108+
),
109+
0,
110+
$e
111+
);
112+
}
113+
}
114+
95115
/**
96116
* @param ConsentEntity $consent
97117
* @return Consent|null

src/OpenConext/EngineBlock/Service/ConsentServiceInterface.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
namespace OpenConext\EngineBlock\Service;
2020

2121
use OpenConext\EngineBlock\Authentication\Dto\ConsentList;
22+
use OpenConext\EngineBlock\Authentication\Value\CollabPersonId;
2223

2324
interface ConsentServiceInterface
2425
{
@@ -33,4 +34,6 @@ public function findAllFor($userId);
3334
* @return int
3435
*/
3536
public function countAllFor($userId);
37+
38+
public function deleteOneConsentFor(CollabPersonId $id, string $serviceProviderEntityId): bool;
3639
}

src/OpenConext/EngineBlock/Service/DeprovisionService.php

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,12 +18,15 @@
1818

1919
namespace OpenConext\EngineBlock\Service;
2020

21+
use Exception;
2122
use OpenConext\EngineBlock\Authentication\Model\User;
2223
use OpenConext\EngineBlock\Authentication\Repository\ConsentRepository;
2324
use OpenConext\EngineBlock\Authentication\Repository\UserDirectory;
2425
use OpenConext\EngineBlock\Authentication\Value\CollabPersonId;
26+
use OpenConext\EngineBlock\Exception\RuntimeException;
2527
use OpenConext\EngineBlockBundle\Authentication\Repository\SamlPersistentIdRepository;
2628
use OpenConext\EngineBlockBundle\Authentication\Repository\ServiceProviderUuidRepository;
29+
use function sprintf;
2730

2831
final class DeprovisionService implements DeprovisionServiceInterface
2932
{

src/OpenConext/EngineBlock/Service/MetadataService.php

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@
2525
use OpenConext\EngineBlock\Metadata\MetadataRepository\MetadataRepositoryInterface;
2626
use OpenConext\Value\Saml\EntityId;
2727

28-
final class MetadataService
28+
final class MetadataService implements MetadataServiceInterface
2929
{
3030
/**
3131
* @var MetadataRepositoryInterface
@@ -37,11 +37,7 @@ public function __construct(MetadataRepositoryInterface $metadataRepository)
3737
$this->metadataRepository = $metadataRepository;
3838
}
3939

40-
/**
41-
* @param EntityId $entityId
42-
* @return null|IdentityProvider
43-
*/
44-
public function findIdentityProvider(EntityId $entityId)
40+
public function findIdentityProvider(EntityId $entityId): ?IdentityProvider
4541
{
4642
try {
4743
$identityProvider = $this->metadataRepository->fetchIdentityProviderByEntityId($entityId->getEntityId());
@@ -52,11 +48,7 @@ public function findIdentityProvider(EntityId $entityId)
5248
return $identityProvider;
5349
}
5450

55-
/**
56-
* @param EntityId $entityId
57-
* @return null|ServiceProvider
58-
*/
59-
public function findServiceProvider(EntityId $entityId)
51+
public function findServiceProvider(EntityId $entityId): ?ServiceProvider
6052
{
6153
try {
6254
$serviceProvider = $this->metadataRepository->fetchServiceProviderByEntityId($entityId->getEntityId());
@@ -67,11 +59,7 @@ public function findServiceProvider(EntityId $entityId)
6759
return $serviceProvider;
6860
}
6961

70-
/**
71-
* @param EntityId $entityId
72-
* @return null|AttributeReleasePolicy
73-
*/
74-
public function findArpForServiceProviderByEntityId(EntityId $entityId)
62+
public function findArpForServiceProviderByEntityId(EntityId $entityId): ?AttributeReleasePolicy
7563
{
7664
$serviceProvider = $this->findServiceProvider($entityId);
7765

0 commit comments

Comments
 (0)