-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
3b6277f
commit 5a239f6
Showing
60 changed files
with
2,234 additions
and
14 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
# Personal Data | ||
|
||
|
||
|
||
|
||
## Learn more |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Patchlevel\EventSourcing\Attribute; | ||
|
||
use Attribute; | ||
|
||
#[Attribute(Attribute::TARGET_PROPERTY)] | ||
final class DataSubjectId | ||
{ | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Patchlevel\EventSourcing\Attribute; | ||
|
||
use Attribute; | ||
|
||
#[Attribute(Attribute::TARGET_PROPERTY)] | ||
final class PersonalData | ||
{ | ||
public function __construct( | ||
public readonly mixed $fallback = null, | ||
) { | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Patchlevel\EventSourcing\Cryptography\Cipher; | ||
|
||
interface Cipher | ||
{ | ||
/** @throws EncryptionFailed */ | ||
public function encrypt(CipherKey $key, mixed $data): string; | ||
|
||
/** @throws DecryptionFailed */ | ||
public function decrypt(CipherKey $key, string $data): mixed; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,20 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Patchlevel\EventSourcing\Cryptography\Cipher; | ||
|
||
final class CipherKey | ||
{ | ||
/** | ||
* @param non-empty-string $key | ||
* @param non-empty-string $method | ||
* @param non-empty-string $iv | ||
*/ | ||
public function __construct( | ||
public readonly string $key, | ||
public readonly string $method, | ||
public readonly string $iv, | ||
) { | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Patchlevel\EventSourcing\Cryptography\Cipher; | ||
|
||
interface CipherKeyFactory | ||
{ | ||
/** @throws CreateCipherKeyFailed */ | ||
public function __invoke(): CipherKey; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Patchlevel\EventSourcing\Cryptography\Cipher; | ||
|
||
use RuntimeException; | ||
|
||
final class CreateCipherKeyFailed extends RuntimeException | ||
{ | ||
public function __construct() | ||
{ | ||
parent::__construct('Create cipher key failed.'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Patchlevel\EventSourcing\Cryptography\Cipher; | ||
|
||
use RuntimeException; | ||
|
||
final class DecryptionFailed extends RuntimeException | ||
{ | ||
public function __construct() | ||
{ | ||
parent::__construct('Decryption failed.'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Patchlevel\EventSourcing\Cryptography\Cipher; | ||
|
||
use RuntimeException; | ||
|
||
final class EncryptionFailed extends RuntimeException | ||
{ | ||
public function __construct() | ||
{ | ||
parent::__construct('Encryption failed.'); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,67 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Patchlevel\EventSourcing\Cryptography\Cipher; | ||
|
||
use JsonException; | ||
|
||
use function base64_decode; | ||
use function base64_encode; | ||
use function json_decode; | ||
use function json_encode; | ||
use function openssl_decrypt; | ||
use function openssl_encrypt; | ||
|
||
use const JSON_THROW_ON_ERROR; | ||
|
||
final class OpensslCipher implements Cipher | ||
{ | ||
public function encrypt(CipherKey $key, mixed $data): string | ||
{ | ||
$encryptedData = @openssl_encrypt( | ||
$this->dataEncode($data), | ||
$key->method, | ||
$key->key, | ||
0, | ||
$key->iv, | ||
); | ||
|
||
if ($encryptedData === false) { | ||
throw new EncryptionFailed(); | ||
} | ||
|
||
return base64_encode($encryptedData); | ||
} | ||
|
||
public function decrypt(CipherKey $key, string $data): mixed | ||
{ | ||
$data = @openssl_decrypt( | ||
base64_decode($data), | ||
$key->method, | ||
$key->key, | ||
0, | ||
$key->iv, | ||
); | ||
|
||
if ($data === false) { | ||
throw new DecryptionFailed(); | ||
} | ||
|
||
try { | ||
return $this->dataDecode($data); | ||
} catch (JsonException) { | ||
throw new DecryptionFailed(); | ||
} | ||
} | ||
|
||
private function dataEncode(mixed $data): string | ||
{ | ||
return json_encode($data, JSON_THROW_ON_ERROR); | ||
} | ||
|
||
private function dataDecode(string $data): mixed | ||
{ | ||
return json_decode($data, true, 512, JSON_THROW_ON_ERROR); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
<?php | ||
|
||
declare(strict_types=1); | ||
|
||
namespace Patchlevel\EventSourcing\Cryptography\Cipher; | ||
|
||
use function openssl_cipher_iv_length; | ||
use function openssl_random_pseudo_bytes; | ||
|
||
final class OpensslCipherKeyFactory implements CipherKeyFactory | ||
{ | ||
public const DEFAULT_LENGTH = 32; | ||
|
||
public const DEFAULT_METHOD = 'aes128'; | ||
|
||
/** | ||
* @param positive-int $length | ||
* @param non-empty-string $method | ||
*/ | ||
public function __construct( | ||
private readonly int $length = self::DEFAULT_LENGTH, | ||
private readonly string $method = self::DEFAULT_METHOD, | ||
) { | ||
} | ||
|
||
public function __invoke(): CipherKey | ||
{ | ||
$ivLength = @openssl_cipher_iv_length($this->method); | ||
|
||
if ($ivLength === false) { | ||
throw new CreateCipherKeyFailed(); | ||
} | ||
|
||
return new CipherKey( | ||
openssl_random_pseudo_bytes($this->length), | ||
$this->method, | ||
openssl_random_pseudo_bytes($ivLength), | ||
); | ||
} | ||
} |
Oops, something went wrong.