Skip to content

Commit 86efe5f

Browse files
committed
Rename PersonalData to SensitiveData. This makes clear that the usage can be broader then only personal data from users.
Add missing doc entry for multiple `DataSubjectId`'s.
1 parent e7314e5 commit 86efe5f

22 files changed

Lines changed: 203 additions & 189 deletions

README.md

Lines changed: 38 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -528,7 +528,7 @@ There are two events: `PostExtract` and `PreHydrate`.
528528
For this functionality we use the [symfony/event-dispatcher](https://symfony.com/doc/current/components/event_dispatcher.html).
529529

530530
```php
531-
use Patchlevel\Hydrator\Cryptography\PersonalDataPayloadCryptographer;
531+
use Patchlevel\Hydrator\Cryptography\SensitiveDataPayloadCryptographer;
532532
use Patchlevel\Hydrator\Cryptography\Store\CipherKeyStore;
533533
use Patchlevel\Hydrator\Metadata\Event\EventMetadataFactory;
534534
use Patchlevel\Hydrator\MetadataHydrator;
@@ -557,8 +557,8 @@ $hydrator = new MetadataHydrator(eventDispatcher: $eventDispatcher);
557557

558558
### Cryptography
559559

560-
The library also offers the possibility to encrypt and decrypt personal data.
561-
For this purpose, a key is created for each subject ID, which is used to encrypt the personal data.
560+
The library also offers the possibility to encrypt and decrypt sensitive data, e.g. personal data of customers.
561+
For this purpose, a key is created for each subject ID, which is used to encrypt the sensitive data.
562562

563563
#### DataSubjectId
564564

@@ -579,42 +579,62 @@ final class EmailChanged
579579

580580
> [!WARNING]
581581
> The `DataSubjectId` must be a string. You can use a normalizer to convert it to a string.
582-
> The Subject ID cannot be personal data.
582+
> The Subject ID cannot be sensitive data.
583583
584-
#### PersonalData
584+
First we need to define what the subject id is.
585585

586-
Next, we need to specify which fields we want to encrypt.
586+
```php
587+
use Patchlevel\Hydrator\Attribute\DataSubjectId;
588+
589+
final class EmailChanged
590+
{
591+
public function __construct(
592+
#[DataSubjectId(name: 'profile')]
593+
public readonly string $profileId,
594+
) {
595+
}
596+
}
597+
```
598+
599+
You can also use multiple data subject id's in one event by defining the name of the subject id's.
587600

588601
```php
589602
use Patchlevel\Hydrator\Attribute\DataSubjectId;
590-
use Patchlevel\Hydrator\Attribute\PersonalData;
603+
use Patchlevel\Hydrator\Attribute\SensitiveData;
591604

592605
final class DTO
593606
{
594607
public function __construct(
595-
#[DataSubjectId]
596-
public readonly string $profileId,
597-
#[PersonalData]
598-
public readonly string|null $email,
608+
#[DataSubjectId(name: 'profile1')]
609+
public readonly string $profile1Id,
610+
#[SensitiveData(subjectIdName: 'profile1')]
611+
public readonly string|null $email1,
612+
#[DataSubjectId(name: 'profile2')]
613+
public readonly string $profile2Id,
614+
#[SensitiveData(subjectIdName: 'profile2')]
615+
public readonly string|null $email2,
599616
) {
600617
}
601618
}
602619
```
603620

621+
> [!NOTE]
622+
> The default name of `DataSubjectId` is `default`.
623+
604624
If the information could not be decrypted, then a fallback value is inserted.
605625
The default fallback value is `null`.
606626
You can change this by setting the `fallback` parameter.
607627
In this case `unknown` is added:
608628

609629
```php
610-
use Patchlevel\Hydrator\Attribute\PersonalData;
630+
use Patchlevel\Hydrator\Attribute\SensitiveData;
611631

612632
final class DTO
613633
{
614634
public function __construct(
615635
#[DataSubjectId]
616636
public readonly string $profileId,
617-
#[PersonalData(fallback: 'unknown')]
637+
#[SensitiveData(fallback: 'unknown')]
618638
public readonly string $name,
619639
) {
620640
}
@@ -625,16 +645,16 @@ You can also use a callable as a fallback.
625645

626646
```php
627647
use Patchlevel\Hydrator\Attribute\DataSubjectId;
628-
use Patchlevel\Hydrator\Attribute\PersonalData;
648+
use Patchlevel\Hydrator\Attribute\SensitiveData;
629649

630650
final class ProfileCreated
631651
{
632652
public function __construct(
633653
#[DataSubjectId]
634654
public readonly string $profileId,
635-
#[PersonalData(fallback: 'deleted profile')]
655+
#[SensitiveData(fallback: 'deleted profile')]
636656
public readonly string $name,
637-
#[PersonalData(fallbackCallable: [self::class, 'anonymizedEmail'])]
657+
#[SensitiveData(fallbackCallable: [self::class, 'anonymizedEmail'])]
638658
public readonly string $email,
639659
) {
640660
}
@@ -655,13 +675,13 @@ final class ProfileCreated
655675
Here we show you how to configure the cryptography.
656676

657677
```php
658-
use Patchlevel\Hydrator\Cryptography\PersonalDataPayloadCryptographer;
678+
use Patchlevel\Hydrator\Cryptography\SensitiveDataPayloadCryptographer;
659679
use Patchlevel\Hydrator\Cryptography\Store\CipherKeyStore;
660680
use Patchlevel\Hydrator\Metadata\Event\EventMetadataFactory;
661681
use Patchlevel\Hydrator\MetadataHydrator;
662682

663683
$cipherKeyStore = new InMemoryCipherKeyStore();
664-
$cryptographer = PersonalDataPayloadCryptographer::createWithDefaultSettings($cipherKeyStore);
684+
$cryptographer = SensitiveDataPayloadCryptographer::createWithDefaultSettings($cipherKeyStore);
665685
$hydrator = new MetadataHydrator(cryptographer: $cryptographer);
666686
```
667687

baseline.xml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
<?xml version="1.0" encoding="UTF-8"?>
22
<files psalm-version="6.12.0@cf420941d061a57050b6c468ef2c778faf40aee2">
3-
<file src="src/Attribute/PersonalData.php">
3+
<file src="src/Attribute/SensitiveData.php">
44
<MixedPropertyTypeCoercion>
55
<code><![CDATA[$fallbackCallable]]></code>
66
</MixedPropertyTypeCoercion>
@@ -17,7 +17,7 @@
1717
<code><![CDATA[list<string>]]></code>
1818
</MoreSpecificReturnType>
1919
</file>
20-
<file src="src/Cryptography/PersonalDataPayloadCryptographer.php">
20+
<file src="src/Cryptography/SensitiveDataPayloadCryptographer.php">
2121
<MixedArgument>
2222
<code><![CDATA[$rawData]]></code>
2323
</MixedArgument>
@@ -41,7 +41,7 @@
4141
</file>
4242
<file src="src/Metadata/PropertyMetadata.php">
4343
<RiskyTruthyFalsyComparison>
44-
<code><![CDATA[$this->personalDataFallbackCallable]]></code>
44+
<code><![CDATA[$this->sensitiveDataFallbackCallable]]></code>
4545
</RiskyTruthyFalsyComparison>
4646
</file>
4747
<file src="src/MetadataHydrator.php">

phpstan-baseline.neon

Lines changed: 1 addition & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ parameters:
1616
message: '#^Parameter \#2 \$data of method Patchlevel\\Hydrator\\Cryptography\\Cipher\\Cipher\:\:decrypt\(\) expects string, mixed given\.$#'
1717
identifier: argument.type
1818
count: 1
19-
path: src/Cryptography/PersonalDataPayloadCryptographer.php
19+
path: src/Cryptography/SensitiveDataPayloadCryptographer.php
2020

2121
-
2222
message: '#^Method Patchlevel\\Hydrator\\Guesser\\BuiltInGuesser\:\:guess\(\) has parameter \$type with generic class Symfony\\Component\\TypeInfo\\Type\\ObjectType but does not specify its types\: T$#'
@@ -54,12 +54,6 @@ parameters:
5454
count: 1
5555
path: src/Metadata/AttributeMetadataFactory.php
5656

57-
-
58-
message: '#^Method Patchlevel\\Hydrator\\Metadata\\AttributeMetadataFactory\:\:getPersonalData\(\) should return array\{bool, mixed, \(callable\(string, mixed\)\: mixed\)\|null\} but returns array\{false, null\}\.$#'
59-
identifier: return.type
60-
count: 1
61-
path: src/Metadata/AttributeMetadataFactory.php
62-
6357
-
6458
message: '#^Parameter \#1 \$class of method Patchlevel\\Hydrator\\Metadata\\AttributeMetadataFactory\:\:findNormalizerOnClass\(\) expects class\-string, string given\.$#'
6559
identifier: argument.type

src/Attribute/DataSubjectId.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
final class DataSubjectId
1111
{
1212
public function __construct(
13-
public readonly string $identifier = 'default',
13+
public readonly string $name = 'default',
1414
) {
1515
}
1616
}
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,15 @@
88
use InvalidArgumentException;
99

1010
#[Attribute(Attribute::TARGET_PROPERTY)]
11-
final class PersonalData
11+
final class SensitiveData
1212
{
1313
/** @var (callable(string, mixed):mixed)|null */
1414
public readonly mixed $fallbackCallable;
1515

1616
public function __construct(
1717
public readonly mixed $fallback = null,
1818
callable|null $fallbackCallable = null,
19-
public readonly string $identifier = 'default',
19+
public readonly string $subjectIdName = 'default',
2020
) {
2121
$this->fallbackCallable = $fallbackCallable;
2222

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88

99
use function sprintf;
1010

11-
final class NotPersonalData extends RuntimeException
11+
final class NotSensitiveData extends RuntimeException
1212
{
1313
/** @param class-string $class */
1414
public function __construct(string $class, string $fieldName)
1515
{
16-
parent::__construct(sprintf('Trying to get subject id for %s::%s which is not marked as personal data.', $class, $fieldName));
16+
parent::__construct(sprintf('Trying to get subject id for %s::%s which is not marked as sensitive data.', $class, $fieldName));
1717
}
1818
}

src/Cryptography/PersonalDataPayloadCryptographer.php renamed to src/Cryptography/SensitiveDataPayloadCryptographer.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
use function is_int;
1919
use function is_string;
2020

21-
final class PersonalDataPayloadCryptographer implements PayloadCryptographer
21+
final class SensitiveDataPayloadCryptographer implements PayloadCryptographer
2222
{
2323
public function __construct(
2424
private readonly CipherKeyStore $cipherKeyStore,
@@ -37,7 +37,7 @@ public function __construct(
3737
public function encrypt(ClassMetadata $metadata, array $data): array
3838
{
3939
foreach ($metadata->properties() as $propertyMetadata) {
40-
if (!$propertyMetadata->isPersonalData()) {
40+
if (!$propertyMetadata->isSensitiveData()) {
4141
continue;
4242
}
4343

@@ -77,7 +77,7 @@ public function encrypt(ClassMetadata $metadata, array $data): array
7777
public function decrypt(ClassMetadata $metadata, array $data): array
7878
{
7979
foreach ($metadata->properties() as $propertyMetadata) {
80-
if (!$propertyMetadata->isPersonalData()) {
80+
if (!$propertyMetadata->isSensitiveData()) {
8181
continue;
8282
}
8383

@@ -119,17 +119,17 @@ public function decrypt(ClassMetadata $metadata, array $data): array
119119
/** @param array<string, mixed> $data */
120120
private function subjectId(PropertyMetadata $propertyMetadata, ClassMetadata $metadata, array $data): string
121121
{
122-
if (!$propertyMetadata->isPersonalData()) {
123-
throw new NotPersonalData($metadata->className(), $propertyMetadata->propertyName());
122+
if (!$propertyMetadata->isSensitiveData()) {
123+
throw new NotSensitiveData($metadata->className(), $propertyMetadata->propertyName());
124124
}
125125

126-
$personalDataIdentifier = $propertyMetadata->personalDataIdentifier();
126+
$sensitiveDataSubjectIdName = $propertyMetadata->sensitiveDataSubjectIdName();
127127

128-
if (!$metadata->hasSubjectIdIdentifier($personalDataIdentifier)) {
128+
if (!$metadata->hasSubjectIdIdentifier($sensitiveDataSubjectIdName)) {
129129
throw new MissingSubjectId($metadata->className(), $propertyMetadata->propertyName());
130130
}
131131

132-
$fieldName = $metadata->getSubjectIdFieldName($personalDataIdentifier);
132+
$fieldName = $metadata->getSubjectIdFieldName($sensitiveDataSubjectIdName);
133133

134134
if (!array_key_exists($fieldName, $data)) {
135135
throw new MissingSubjectId($metadata->className(), $fieldName);
@@ -150,10 +150,10 @@ private function subjectId(PropertyMetadata $propertyMetadata, ClassMetadata $me
150150

151151
private function fallback(PropertyMetadata $propertyMetadata, string $subjectId, mixed $rawData): mixed
152152
{
153-
$callback = $propertyMetadata->personalDataFallbackCallback();
153+
$callback = $propertyMetadata->sensitiveDataFallbackCallable();
154154

155155
if (!$callback) {
156-
return $propertyMetadata->personalDataFallback();
156+
return $propertyMetadata->sensitiveDataFallback();
157157
}
158158

159159
return $callback($subjectId, $rawData);

src/Metadata/AttributeMetadataFactory.php

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,9 @@
88
use Patchlevel\Hydrator\Attribute\Ignore;
99
use Patchlevel\Hydrator\Attribute\Lazy;
1010
use Patchlevel\Hydrator\Attribute\NormalizedName;
11-
use Patchlevel\Hydrator\Attribute\PersonalData;
1211
use Patchlevel\Hydrator\Attribute\PostHydrate;
1312
use Patchlevel\Hydrator\Attribute\PreExtract;
13+
use Patchlevel\Hydrator\Attribute\SensitiveData;
1414
use Patchlevel\Hydrator\Guesser\BuiltInGuesser;
1515
use Patchlevel\Hydrator\Guesser\Guesser;
1616
use Patchlevel\Hydrator\Normalizer\ArrayNormalizer;
@@ -156,7 +156,7 @@ private function getPropertyMetadataList(ReflectionClass $reflectionClass): arra
156156
$fieldName,
157157
$this->getNormalizer($reflectionProperty),
158158
$this->getSubjectId($reflectionProperty),
159-
...$this->getPersonalData($reflectionProperty),
159+
...$this->getSensitiveData($reflectionProperty),
160160
);
161161
}
162162

@@ -291,41 +291,41 @@ private function getSubjectId(ReflectionProperty $reflectionProperty): string|nu
291291
return null;
292292
}
293293

294-
return $attributeReflectionList[0]->newInstance()->identifier;
294+
return $attributeReflectionList[0]->newInstance()->name;
295295
}
296296

297297
/** @return array{string|null, mixed, (callable(string, mixed):mixed)|null} */
298-
private function getPersonalData(ReflectionProperty $reflectionProperty): array
298+
private function getSensitiveData(ReflectionProperty $reflectionProperty): array
299299
{
300-
$attributeReflectionList = $reflectionProperty->getAttributes(PersonalData::class);
300+
$attributeReflectionList = $reflectionProperty->getAttributes(SensitiveData::class);
301301

302302
if ($attributeReflectionList === []) {
303303
return [null, null, null];
304304
}
305305

306306
$attribute = $attributeReflectionList[0]->newInstance();
307307

308-
return [$attribute->identifier, $attribute->fallback, $attribute->fallbackCallable];
308+
return [$attribute->subjectIdName, $attribute->fallback, $attribute->fallbackCallable];
309309
}
310310

311311
private function validate(ClassMetadata $metadata): void
312312
{
313313
$subjectIds = [];
314314

315315
foreach ($metadata->properties() as $property) {
316-
if ($property->isPersonalData() && $property->isSubjectId()) {
317-
throw new SubjectIdAndPersonalDataConflict($metadata->className(), $property->propertyName());
316+
if ($property->isSensitiveData() && $property->isSubjectId()) {
317+
throw new SubjectIdAndSensitiveDataConflict($metadata->className(), $property->propertyName());
318318
}
319319

320-
if ($property->isPersonalData() && !$metadata->hasSubjectIdIdentifier($property->personalDataIdentifier())) {
320+
if ($property->isSensitiveData() && !$metadata->hasSubjectIdIdentifier($property->sensitiveDataSubjectIdName())) {
321321
throw new MissingDataSubjectId($metadata->className());
322322
}
323323

324324
if (!$property->isSubjectId()) {
325325
continue;
326326
}
327327

328-
$subjectIdIdentifier = $property->subjectIdIdentifier();
328+
$subjectIdIdentifier = $property->subjectIdName();
329329

330330
if (array_key_exists($subjectIdIdentifier, $subjectIds)) {
331331
throw new DuplicateSubjectIdIdentifier(

src/Metadata/ClassMetadata.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ public function propertyForField(string $name): PropertyMetadata
8383
public function hasSubjectIdIdentifier(string $subjectIdIdentifier): bool
8484
{
8585
foreach ($this->properties as $property) {
86-
if ($property->subjectIdIdentifier() === $subjectIdIdentifier) {
86+
if ($property->subjectIdName() === $subjectIdIdentifier) {
8787
return true;
8888
}
8989
}
@@ -94,7 +94,7 @@ public function hasSubjectIdIdentifier(string $subjectIdIdentifier): bool
9494
public function getSubjectIdFieldName(string $subjectIdIdentifier): string
9595
{
9696
foreach ($this->properties as $property) {
97-
if ($property->subjectIdIdentifier() === $subjectIdIdentifier) {
97+
if ($property->subjectIdName() === $subjectIdIdentifier) {
9898
return $property->fieldName();
9999
}
100100
}

0 commit comments

Comments
 (0)