Last active
October 16, 2024 20:04
-
-
Save PhilETaylor/6efbdd007ac55098ee87b500bc7611be to your computer and use it in GitHub Desktop.
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
<?php | |
// Just a random example entity | |
// /vendor/philetaylor/base/src/Entity/Changelog.php | |
namespace Base\Entity; | |
use Base\Doctrine\Encryption\Types\Encrypted; | |
use Base\Repository\ChangelogRepository; | |
use DateTime; | |
use Doctrine\DBAL\Types\Types; | |
use Doctrine\ORM\Mapping as ORM; | |
use Knp\DoctrineBehaviors\Contract\Entity\BlameableInterface; | |
use Knp\DoctrineBehaviors\Contract\Entity\TimestampableInterface; | |
use Knp\DoctrineBehaviors\Contract\Entity\UuidableInterface; | |
use Knp\DoctrineBehaviors\Model\Blameable\BlameableTrait; | |
use Knp\DoctrineBehaviors\Model\Timestampable\TimestampableTrait; | |
use Knp\DoctrineBehaviors\Model\Uuidable\UuidableTrait; | |
/** | |
* Changelog. | |
*/ | |
#[ORM\Table(name: 'changelog')] | |
#[ORM\Index(name: 'posted', columns: ['posted'])] | |
#[ORM\Entity(repositoryClass: ChangelogRepository::class)] | |
class Changelog implements BlameableInterface, TimestampableInterface, UuidableInterface | |
{ | |
use BlameableTrait; | |
use TimestampableTrait; | |
use UuidableTrait; | |
#[ORM\Column(name: 'id', type: Types::INTEGER)] | |
#[ORM\Id] | |
#[ORM\GeneratedValue(strategy: 'IDENTITY')] | |
private ?int $id = null; | |
#[ORM\Column(name: 'posted', type: Types::DATETIME_MUTABLE)] | |
private ?DateTime $posted = null; | |
#[ORM\Column(name: 'type', type: Types::STRING, length: 255)] | |
private ?string $type = null; | |
#[ORM\Column(name: '`change`', type: Encrypted::ENCRYPTED)] | |
private ?string $change = null; | |
#[ORM\Column(name: 'published', type: Types::INTEGER)] | |
private ?int $published = null; | |
public function getId(): int | |
{ | |
return $this->id; | |
} | |
public function setId(int $id): void | |
{ | |
$this->id = $id; | |
} | |
public function getPosted(): DateTime | |
{ | |
return $this->posted; | |
} | |
public function setPosted(DateTime $posted): void | |
{ | |
$this->posted = $posted; | |
} | |
public function getType(): ?string | |
{ | |
return $this->type; | |
} | |
public function setType(string $type): void | |
{ | |
$this->type = $type; | |
} | |
public function getChange(): ?string | |
{ | |
return $this->change; | |
} | |
public function setChange(string $change): void | |
{ | |
$this->change = $change; | |
} | |
public function getPublished(): int | |
{ | |
return $this->published; | |
} | |
public function setPublished(int $published): void | |
{ | |
$this->published = $published; | |
} | |
} |
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
<?php | |
// /vendor/philetaylor/base/src/Doctrine/Encryption/Types/Encrypted.php | |
namespace Base\Doctrine\Encryption\Types; | |
use Attribute; | |
use Base\Doctrine\Encryption\HaliteEncryptor; | |
use Doctrine\DBAL\Platforms\AbstractPlatform; | |
use Doctrine\DBAL\Types\Type; | |
use Override; | |
#[Attribute] | |
class Encrypted extends Type | |
{ | |
final public const string ENCRYPTED = 'encrypted'; | |
/** | |
* The encryptor to use for encrypting and decrypting values. | |
* | |
* @var HaliteEncryptor | |
*/ | |
public static $encryptor; | |
#[Override] | |
public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform): string | |
{ | |
return $platform->getClobTypeDeclarationSQL($fieldDeclaration); | |
} | |
#[Override] | |
public function getName(): string | |
{ | |
return self::ENCRYPTED; | |
} | |
#[Override] | |
public function convertToDatabaseValue($value, AbstractPlatform $platform): ?string | |
{ | |
return $this->getEncryptor()->encrypt($value); | |
} | |
#[Override] | |
public function convertToPHPValue($value, AbstractPlatform $platform): ?string | |
{ | |
return $this->getEncryptor()->decrypt($value); | |
} | |
#[Override] | |
public function requiresSQLCommentHint(AbstractPlatform $platform): bool | |
{ | |
return true; | |
} | |
public function getEncryptor(): HaliteEncryptor | |
{ | |
if (self::$encryptor===null) { | |
self::$encryptor = new HaliteEncryptor(); | |
} | |
return self::$encryptor; | |
} | |
} |
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
<?php | |
// /vendor/philetaylor/base/src/Doctrine/Encryption/HaliteEncryptor.php | |
namespace Base\Doctrine\Encryption; | |
use ParagonIE\Halite\KeyFactory; | |
use ParagonIE\Halite\Symmetric\Crypto; | |
use ParagonIE\Halite\Symmetric\EncryptionKey; | |
use ParagonIE\HiddenString\HiddenString; | |
class HaliteEncryptor | |
{ | |
private readonly EncryptionKey $enc_key; | |
public function __construct() | |
{ | |
$this->enc_key = KeyFactory::loadEncryptionKey(__DIR__ . '/../../../../../../' . '.encryptionkeys/live_encryption_key_2018.key'); | |
} | |
public function encrypt(?string $data = null): ?string | |
{ | |
if ($data === '' || $data===null || $data === 'null') { | |
return null; | |
} | |
// if we are forcing a decrypt | |
if (str_ends_with($data, '<DONOTENCRYPT>')) { | |
return substr($data, 0, \strlen($data) - 14); | |
} | |
// already encrypted! | |
if (str_ends_with($data, '<Ha>')) { | |
return $data; | |
} | |
return Crypto::encrypt(new HiddenString($data), $this->enc_key) . '<Ha>'; | |
} | |
public function decrypt(?string $ciphertext = null): ?string | |
{ | |
if ($ciphertext === '' || $ciphertext===null || $ciphertext === 'null') { | |
return null; | |
} | |
if (str_ends_with($ciphertext, '<Ha>')) { | |
$plaintext = Crypto::decrypt(substr($ciphertext, 0, \strlen($ciphertext) - 4), $this->enc_key); | |
return $plaintext->getString(); | |
} | |
return $ciphertext ?: null; | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Also need to register the new type in your config files