Skip to content

Commit

Permalink
Add Cryptex
Browse files Browse the repository at this point in the history
  • Loading branch information
paulbalandan committed Jan 6, 2025
1 parent 67b5a89 commit 9b9209e
Show file tree
Hide file tree
Showing 4 changed files with 187 additions and 0 deletions.
57 changes: 57 additions & 0 deletions src/Nexus/Encryption/Cryptex.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
<?php

declare(strict_types=1);

/**
* This file is part of the Nexus framework.
*
* (c) John Paul E. Balandan, CPA <[email protected]>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace Nexus\Encryption;

use Nexus\Encryption\Exception\InvalidEncodingVariantException;

final readonly class Cryptex
{
/**
* Version tag in the form 'v' + major + minor + patch.
*
* Note: Increment only the major and minor versions when making updates.
*/
public const string HEADER_VERSION = "\x76\x01\x00\x00";

/**
* Length of the version header.
*/
public const int HEADER_VERSION_SIZE = 4;

public const int ENCODE_NONE = 0;
public const int ENCODE_BASE64_ORIGINAL = 1;
public const int ENCODE_BASE64_ORIGINAL_NO_PADDING = 2;
public const int ENCODE_BASE64_URL_SAFE = 3;
public const int ENCODE_BASE64_URL_SAFE_NO_PADDING = 4;
public const int ENCODE_HEX = 5;

/**
* Gets the encoder. If `self::ENCODE_NONE` is chosen, any subsequent encode
* and decode operations will just return the strings as-is.
*
* @throws InvalidEncodingVariantException
*/
public static function encoder(int $variant = self::ENCODE_HEX): Encoding\EncoderInterface
{
return match ($variant) {
self::ENCODE_NONE => new Encoding\NullEncoder(),
self::ENCODE_BASE64_ORIGINAL => new Encoding\Base64OriginalEncoder(),
self::ENCODE_BASE64_ORIGINAL_NO_PADDING => new Encoding\Base64OriginalNoPaddingEncoder(),
self::ENCODE_BASE64_URL_SAFE => new Encoding\Base64UrlSafeEncoder(),
self::ENCODE_BASE64_URL_SAFE_NO_PADDING => new Encoding\Base64UrlSafeNoPaddingEncoder(),
self::ENCODE_HEX => new Encoding\HexEncoder(),
default => throw new InvalidEncodingVariantException(),
};
}
}
22 changes: 22 additions & 0 deletions src/Nexus/Encryption/Exception/InvalidEncodingVariantException.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?php

declare(strict_types=1);

/**
* This file is part of the Nexus framework.
*
* (c) John Paul E. Balandan, CPA <[email protected]>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace Nexus\Encryption\Exception;

final class InvalidEncodingVariantException extends \RuntimeException
{
public function __construct()
{
parent::__construct('Unknown variant for encoder.');
}
}
71 changes: 71 additions & 0 deletions tests/Encryption/CryptexTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php

declare(strict_types=1);

/**
* This file is part of the Nexus framework.
*
* (c) John Paul E. Balandan, CPA <[email protected]>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace Nexus\Tests\Encryption;

use Nexus\Encryption\Cryptex;
use Nexus\Encryption\Encoding\Base64OriginalEncoder;
use Nexus\Encryption\Encoding\Base64OriginalNoPaddingEncoder;
use Nexus\Encryption\Encoding\Base64UrlSafeEncoder;
use Nexus\Encryption\Encoding\Base64UrlSafeNoPaddingEncoder;
use Nexus\Encryption\Encoding\EncoderInterface;
use Nexus\Encryption\Encoding\HexEncoder;
use Nexus\Encryption\Encoding\NullEncoder;
use Nexus\Encryption\Exception\InvalidEncodingVariantException;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\TestCase;

/**
* @internal
*/
#[CoversClass(Cryptex::class)]
#[Group('unit-test')]
final class CryptexTest extends TestCase
{
public function testInvalidVariantThrows(): void
{
$this->expectException(InvalidEncodingVariantException::class);
$this->expectExceptionMessage('Unknown variant for encoder.');

Cryptex::encoder(10);
}

/**
* @param class-string<EncoderInterface> $expectedEncoder
*/
#[DataProvider('provideEncoderCases')]
public function testEncoder(int $variant, string $expectedEncoder): void
{
self::assertInstanceOf($expectedEncoder, Cryptex::encoder($variant));
}

/**
* @return iterable<string, array{int, class-string<EncoderInterface>}>
*/
public static function provideEncoderCases(): iterable
{
yield 'base64 original' => [Cryptex::ENCODE_BASE64_ORIGINAL, Base64OriginalEncoder::class];

yield 'base 64 original no padding' => [Cryptex::ENCODE_BASE64_ORIGINAL_NO_PADDING, Base64OriginalNoPaddingEncoder::class];

yield 'base 64 URL safe' => [Cryptex::ENCODE_BASE64_URL_SAFE, Base64UrlSafeEncoder::class];

yield 'base 64 URL safe no padding' => [Cryptex::ENCODE_BASE64_URL_SAFE_NO_PADDING, Base64UrlSafeNoPaddingEncoder::class];

yield 'hex' => [Cryptex::ENCODE_HEX, HexEncoder::class];

yield 'none' => [Cryptex::ENCODE_NONE, NullEncoder::class];
}
}
37 changes: 37 additions & 0 deletions tests/Encryption/Exception/InvalidEncodingVariantExceptionTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

/**
* This file is part of the Nexus framework.
*
* (c) John Paul E. Balandan, CPA <[email protected]>
*
* For the full copyright and license information, please view
* the LICENSE file that was distributed with this source code.
*/

namespace Nexus\Tests\Encryption\Exception;

use Nexus\Encryption\Cryptex;
use Nexus\Encryption\Exception\InvalidEncodingVariantException;
use PHPUnit\Framework\Attributes\CoversClass;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\TestCase;

/**
* @internal
*/
#[CoversClass(InvalidEncodingVariantException::class)]
#[Group('unit-test')]
final class InvalidEncodingVariantExceptionTest extends TestCase
{
public function testMessage(): void
{
try {
Cryptex::encoder(10);
} catch (InvalidEncodingVariantException $e) {
self::assertSame('Unknown variant for encoder.', $e->getMessage());
}
}
}

0 comments on commit 9b9209e

Please sign in to comment.