From b589a2585c7d74ce61f9bc8ec8fbd9e0cea5adfd Mon Sep 17 00:00:00 2001 From: Juha Jantunen Date: Mon, 30 Mar 2020 19:22:18 +0400 Subject: [PATCH] Add setters for Key-classes, fix composer.json, CI-tweaks (#6) * Add setters for Key-classes, fix composer.json, CI-tweaks - Add setters for KeyInterface and implementing classes - Fix composer.json according to schema for publishing in Packagist - Add check for composer.json validity to Travis config - Add check for php-cs-fixer to Travis config --- .travis.yml | 2 ++ CONTRIBUTING.md | 6 ++-- README.md | 2 +- composer.json | 21 ++++++++---- src/Key/AbstractKey.php | 63 ++++++++++++++++++++++++++++------- src/Key/KeyInterface.php | 53 +++++++++++++++++++++++++++++ src/Key/Rsa.php | 26 ++++++++++++++- tests/Key/AbstractKeyTest.php | 23 +++++++++++++ tests/Key/RsaTest.php | 14 ++++++++ 9 files changed, 187 insertions(+), 23 deletions(-) diff --git a/.travis.yml b/.travis.yml index fafce43..7f6b382 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,9 @@ before_script: - composer install script: + - composer validate - phpunit + - ./vendor/bin/php-cs-fixer fix -v --diff --dry-run --config .php_cs.php after_success: - bash <(curl -s https://codecov.io/bash) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1c2d14b..de24daa 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -20,7 +20,7 @@ Basic steps: 1. Clone it locally 1. Install dependencies with Composer ```bash - composer install + $ composer install ``` 1. Create a branch on your fork 1. Commit & push @@ -31,11 +31,11 @@ Some guidelines: 1. Before committing make sure to format the code accordingly: ```bash - make php-cs-fixer-fix + $ make php-cs-fixer-fix ``` 1. Also make sure the tests pass successfully and you have sufficient coverage ```bash - make test-unit + $ make test-unit ``` ### Git Commit Messages diff --git a/README.md b/README.md index e9f0fbe..0cd50c3 100644 --- a/README.md +++ b/README.md @@ -16,7 +16,7 @@ See [JSON Web Key RFC](https://tools.ietf.org/html/rfc7517) for reference. This library requires PHP version 7.2 or higher and can be installed with composer: ```bash -composer require strobotti/php-jwk +$ composer require strobotti/php-jwk ``` ## Example usage diff --git a/composer.json b/composer.json index 36b189a..466a747 100644 --- a/composer.json +++ b/composer.json @@ -1,11 +1,14 @@ { "name": "strobotti/php-jwk", "description": "A small PHP library to handle JWKs (Json Web Keys)", + "type": "library", + "keywords": ["jwk", "jwks"], "homepage": "https://github.com/Strobotti/php-jwk", "authors": [ { "name": "Juha Jantunen", "email": "juha@strobotti.com", + "homepage": "https://www.strobotti.com", "role": "Developer" } ], @@ -18,16 +21,22 @@ }, "autoload": { "psr-4": { - "Strobotti\\JWK\\": "src" - }, - "autoload-dev": { - "psr-4": { - "Strobotti\\JWK\\Tests\\": "tests/" - } + "Strobotti\\JWK\\": "src/" + } + }, + "autoload-dev": { + "psr-4": { + "Strobotti\\JWK\\Tests\\": "tests/" } }, "require-dev": { "phpunit/phpunit": "^8.0", "friendsofphp/php-cs-fixer": "^2.16" + }, + "scripts": { + "test": "./vendor/bin/phpunit" + }, + "scripts-descriptions": { + "test": "Run all tests" } } diff --git a/src/Key/AbstractKey.php b/src/Key/AbstractKey.php index 9ba9d2d..dfa890d 100644 --- a/src/Key/AbstractKey.php +++ b/src/Key/AbstractKey.php @@ -23,14 +23,14 @@ abstract class AbstractKey implements KeyInterface /** * The key ID. * - * @var string + * @var null|string */ private $kid; /** * The public key use. * - * @var string + * @var null|string */ private $use; @@ -51,6 +51,19 @@ public function __toString() return \json_encode($this->jsonSerialize(), JSON_PRETTY_PRINT); } + /** + * {@inheritdoc} + * + * @since 1.0.0 Protected setter + * @since 1.2.0 Public setter + */ + public function setKeyType(string $kty): KeyInterface + { + $this->kty = $kty; + + return $this; + } + /** * {@inheritdoc} * @@ -61,6 +74,18 @@ public function getKeyType(): string return $this->kty; } + /** + * {@inheritdoc} + * + * @since 1.2.0 + */ + public function setKeyId(?string $kid): KeyInterface + { + $this->kid = $kid; + + return $this; + } + /** * {@inheritdoc} * @@ -71,6 +96,18 @@ public function getKeyId(): ?string return $this->kid; } + /** + * {@inheritdoc} + * + * @since 1.2.0 + */ + public function setPublicKeyUse(?string $use): KeyInterface + { + $this->use = $use; + + return $this; + } + /** * {@inheritdoc} * @@ -81,6 +118,18 @@ public function getPublicKeyUse(): ?string return $this->use; } + /** + * {@inheritdoc} + * + * @since 1.2.0 + */ + public function setAlgorithm(string $alg): KeyInterface + { + $this->alg = $alg; + + return $this; + } + /** * {@inheritdoc} * @@ -140,14 +189,4 @@ public static function createFromJSON(string $json, KeyInterface $prototype = nu return $instance; } - - /** - * @since 1.0.0 - */ - protected function setKeyType(string $kty): self - { - $this->kty = $kty; - - return $this; - } } diff --git a/src/Key/KeyInterface.php b/src/Key/KeyInterface.php index 716f163..0c890cf 100644 --- a/src/Key/KeyInterface.php +++ b/src/Key/KeyInterface.php @@ -15,8 +15,23 @@ */ interface KeyInterface extends \JsonSerializable { + /** + * @since 1.0.0 + */ public const KEY_TYPE_RSA = 'RSA'; + + /** + * @since 1.0.0 + * + * @todo Model currently not implemented + */ public const KEY_TYPE_OKP = 'OKP'; + + /** + * @since 1.0.0 + * + * @todo Model currently not implemented + */ public const KEY_TYPE_EC = 'EC'; public const PUBLIC_KEY_USE_SIGNATURE = 'sig'; @@ -33,6 +48,17 @@ interface KeyInterface extends \JsonSerializable */ public function __toString(); + /** + * Sets the key type, ie. the value for the `kty` field. + * + * See the KEY_TYPE_* constants for reference. + * + * @return KeyInterface + * + * @since 1.2.0 + */ + public function setKeyType(string $kty): self; + /** * Gets the key type, ie. the value of the `kty` field. * @@ -40,6 +66,15 @@ public function __toString(); */ public function getKeyType(): string; + /** + * Sets the key id, ie. the value of the `kid` field. + * + * @return KeyInterface + * + * @since 1.2.0 + */ + public function setKeyId(?string $kid): self; + /** * Gets the key id, ie. the value of the `kid` field. * @@ -47,6 +82,15 @@ public function getKeyType(): string; */ public function getKeyId(): ?string; + /** + * Sets the public key use, ie. the value of the `use` field. + * + * @return KeyInterface + * + * @since 1.2.0 + */ + public function setPublicKeyUse(?string $use): self; + /** * Gets the public key use, ie. the value of the `use` field. * @@ -54,6 +98,15 @@ public function getKeyId(): ?string; */ public function getPublicKeyUse(): ?string; + /** + * Sets the cryptographic algorithm used to sign the key, ie. the value of the `alg` field. + * + * @return KeyInterface + * + * @since 1.2.0 + */ + public function setAlgorithm(string $alg): self; + /** * Gets the cryptographic algorithm used to sign the key, ie. the value of the `alg` field. * diff --git a/src/Key/Rsa.php b/src/Key/Rsa.php index c2b149b..89c9ac2 100644 --- a/src/Key/Rsa.php +++ b/src/Key/Rsa.php @@ -35,6 +35,18 @@ public function __construct() $this->setKeyType(KeyInterface::KEY_TYPE_RSA); } + /** + * Sets the exponent for the RSA public key, ie. the `e` field. + * + * @since 1.2.0 + */ + public function setExponent(string $e): self + { + $this->e = $e; + + return $this; + } + /** * Returns the exponent for the RSA public key. * @@ -46,7 +58,19 @@ public function getExponent(): string } /** - * Returns the modulus for the RSA public key. + * Sets the modulus for the RSA public key, ie. the `n` field. + * + * @since 1.2.0 + */ + public function setModulus(string $n): KeyInterface + { + $this->n = $n; + + return $this; + } + + /** + * Returns the modulus for the RSA public key, ie. the `n`field. * * @since 1.0.0 */ diff --git a/tests/Key/AbstractKeyTest.php b/tests/Key/AbstractKeyTest.php index 93fff55..f3a61f5 100644 --- a/tests/Key/AbstractKeyTest.php +++ b/tests/Key/AbstractKeyTest.php @@ -6,6 +6,7 @@ use PHPUnit\Framework\TestCase; use Strobotti\JWK\Key\AbstractKey; +use Strobotti\JWK\Key\KeyInterface; /** * @internal @@ -27,6 +28,28 @@ public function testCreateFromJSON(): void static::assertSame($json, "{$key}"); } + + public function testSettersAndGetters(): void + { + $key = new AbstractKeyTest__AbstractKey__Mock(); + $key->setAlgorithm(KeyInterface::ALGORITHM_RS256) + ->setPublicKeyUse(KeyInterface::PUBLIC_KEY_USE_SIGNATURE) + ->setKeyType(KeyInterface::KEY_TYPE_RSA) + ->setKeyId('asdf') + ; + + static::assertSame(KeyInterface::ALGORITHM_RS256, $key->getAlgorithm()); + static::assertSame(KeyInterface::PUBLIC_KEY_USE_SIGNATURE, $key->getPublicKeyUse()); + static::assertSame(KeyInterface::KEY_TYPE_RSA, $key->getKeyType()); + static::assertSame('asdf', $key->getKeyId()); + + // Test nullable fields + $key->setKeyId(null); + $key->setPublicKeyUse(null); + + static::assertNull($key->getKeyId()); + static::assertNull($key->getPublicKeyUse()); + } } final class AbstractKeyTest__AbstractKey__Mock extends AbstractKey diff --git a/tests/Key/RsaTest.php b/tests/Key/RsaTest.php index 1b065a0..1382f7c 100644 --- a/tests/Key/RsaTest.php +++ b/tests/Key/RsaTest.php @@ -69,4 +69,18 @@ public function testToString(): void static::assertSame($json, "{$key}"); } + + public function testSettersAndGetters(): void + { + $e = 'AQAB'; + $n = 'iGaLqP6y-SJCCBq5Hv6pGDbG_SQ11MNjH7rWHcCFYz4hGwHC4lcSurTlV8u3avoVNM8jXevG1Iu1SY11qInqUvjJur--hghr1b56OPJu6H1iKulSxGjEIyDP6c5BdE1uwprYyr4IO9th8fOwCPygjLFrh44XEGbDIFeImwvBAGOhmMB2AD1n1KviyNsH0bEB7phQtiLk-ILjv1bORSRl8AK677-1T8isGfHKXGZ_ZGtStDe7Lu0Ihp8zoUt59kx2o9uWpROkzF56ypresiIl4WprClRCjz8x6cPZXU2qNWhu71TQvUFwvIvbkE1oYaJMb0jcOTmBRZA2QuYw-zHLwQ'; + + $key = new Rsa(); + $key->setExponent($e) + ->setModulus($n) + ; + + static::assertSame($e, $key->getExponent()); + static::assertSame($n, $key->getModulus()); + } }