From e1c552e811ceef34fd477740896d4c0f2b416c6f Mon Sep 17 00:00:00 2001 From: Snehil Kishore Date: Wed, 13 Nov 2024 13:07:32 +0530 Subject: [PATCH 1/2] Adding Support For BYOK --- src/API/Management/Keys.php | 108 ++++++++++++++++++ src/Contract/API/Management/KeysInterface.php | 103 +++++++++++++++++ tests/Unit/API/Management/KeysTest.php | 79 +++++++++++++ 3 files changed, 290 insertions(+) diff --git a/src/API/Management/Keys.php b/src/API/Management/Keys.php index 2a9f9a01..593c9fb4 100644 --- a/src/API/Management/Keys.php +++ b/src/API/Management/Keys.php @@ -6,6 +6,7 @@ use Auth0\SDK\Contract\API\Management\KeysInterface; use Auth0\SDK\Utility\Request\RequestOptions; +use Auth0\SDK\Utility\Toolkit; use Psr\Http\Message\ResponseInterface; /** @@ -15,6 +16,96 @@ */ final class Keys extends ManagementEndpoint implements KeysInterface { + public function deleteEncryptionKey( + string $kId, + ?RequestOptions $options = null, + ): ResponseInterface { + [$kId] = Toolkit::filter([$kId])->string()->trim(); + + Toolkit::assert([ + [$kId, \Auth0\SDK\Exception\ArgumentException::missing('kId')], + ])->isString(); + + return $this->getHttpClient() + ->method('delete')->addPath(['keys', 'encryption', $kId]) + ->withOptions($options) + ->call(); + } + + public function getEncryptionKey( + string $kId, + ?RequestOptions $options = null, + ): ResponseInterface { + [$kId] = Toolkit::filter([$kId])->string()->trim(); + + Toolkit::assert([ + [$kId, \Auth0\SDK\Exception\ArgumentException::missing('kId')], + ])->isString(); + + return $this->getHttpClient() + ->method('get') + ->addPath(['keys', 'encryption', $kId]) + ->withOptions($options) + ->call(); + } + + public function getEncryptionKeys( + ?array $parameters = null, + ?RequestOptions $options = null, + ): ResponseInterface { + [$parameters] = Toolkit::filter([$parameters])->array()->trim(); + + /** @var array $parameters */ + + return $this->getHttpClient() + ->method('get') + ->addPath(['keys', 'encryption']) + ->withParams($parameters) + ->withOptions($options) + ->call(); + } + + public function postEncryption( + array $body, + ?RequestOptions $options = null, + ): ResponseInterface { + [$body] = Toolkit::filter([$body])->array()->trim(); + + Toolkit::assert([ + [$body, \Auth0\SDK\Exception\ArgumentException::missing('body')], + ])->isArray(); + + return $this->getHttpClient() + ->method('post') + ->addPath(['keys', 'encryption']) + ->withBody((object) $body) + ->withOptions($options) + ->call(); + } + + public function postEncryptionKey( + string $kId, + array $body, + ?RequestOptions $options = null, + ): ResponseInterface { + [$kId] = Toolkit::filter([$kId])->string()->trim(); + [$body] = Toolkit::filter([$body])->array()->trim(); + + Toolkit::assert([ + [$kId, \Auth0\SDK\Exception\ArgumentException::missing('kId')], + ])->isString(); + Toolkit::assert([ + [$body, \Auth0\SDK\Exception\ArgumentException::missing('body')], + ])->isArray(); + + return $this->getHttpClient() + ->method('post') + ->addPath(['keys', 'encryption', $kId]) + ->withBody((object) $body) + ->withOptions($options) + ->call(); + } + public function postEncryptionRekey( ?RequestOptions $options = null, ): ResponseInterface { @@ -24,4 +115,21 @@ public function postEncryptionRekey( ->withOptions($options) ->call(); } + + public function postEncryptionWrappingKey( + string $kId, + ?RequestOptions $options = null, + ): ResponseInterface { + [$kId] = Toolkit::filter([$kId])->string()->trim(); + + Toolkit::assert([ + [$kId, \Auth0\SDK\Exception\ArgumentException::missing('kId')], + ])->isString(); + + return $this->getHttpClient() + ->method('post') + ->addPath(['keys', 'encryption', $kId, 'wrapping-key']) + ->withOptions($options) + ->call(); + } } diff --git a/src/Contract/API/Management/KeysInterface.php b/src/Contract/API/Management/KeysInterface.php index 9727887d..78a680d1 100644 --- a/src/Contract/API/Management/KeysInterface.php +++ b/src/Contract/API/Management/KeysInterface.php @@ -9,6 +9,92 @@ interface KeysInterface { + /** + * Delete the custom provided encryption key with the given ID and move back to using native encryption key. + * Required scope: `delete:encryption_keys`. + * + * @param string $kId key (by it's ID) to query + * @param null|RequestOptions $options Optional. Additional request options to use, such as a field filtering or pagination. (Not all endpoints support these. See @see for supported options.) + * + * @throws \Auth0\SDK\Exception\ArgumentException when an invalid `grantId` is provided + * @throws \Auth0\SDK\Exception\NetworkException when the API request fails due to a network error + * + * @see https://auth0.com/docs/api/management/v2#!/keys/delete-encryption-key + */ + public function deleteEncryptionKey( + string $kId, + ?RequestOptions $options = null, + ): ResponseInterface; + + /** + * Retrieve details of the encryption key with the given ID.. + * Required scopes: `read:encryption_key`. + * + * @param string $kId key (by it's ID) to query + * @param null|RequestOptions $options Optional. Additional request options to use, such as a field filtering or pagination. (Not all endpoints support these. See @see for supported options.) + * + * @throws \Auth0\SDK\Exception\ArgumentException when an invalid `kId` is provided + * @throws \Auth0\SDK\Exception\NetworkException when the API request fails due to a network error + * + * @see https://auth0.com/docs/api/management/v2#!/keys/get-encryption-key + */ + public function getEncryptionKey( + string $kId, + ?RequestOptions $options = null, + ): ResponseInterface; + + /** + * Retrieve details of all the encryption keys associated with your tenant. + * Required scope: `read:encryption_keys`. + * + * @param null|int[]|null[]|string[] $parameters Optional. Additional query parameters to pass with the API request. See @see for supported options. + * @param null|RequestOptions $options Optional. Additional request options to use, such as a field filtering or pagination. (Not all endpoints support these. See @see for supported options.) + * + * @throws \Auth0\SDK\Exception\NetworkException when the API request fails due to a network error + * + * @see https://auth0.com/docs/api/management/v2#!/keys/get-encryption-keys + */ + public function getEncryptionKeys( + ?array $parameters = null, + ?RequestOptions $options = null, + ): ResponseInterface; + + /** + * Create the new, pre-activated encryption key, without the key material. + * Required scope: `create:encryption_keys`. + * + * @param array $body Additional body content to pass with the API request. See @see for supported options. + * @param null|RequestOptions $options Optional. Additional request options to use, such as a field filtering or pagination. (Not all endpoints support these. See @see for supported options.) + * + * @throws \Auth0\SDK\Exception\ArgumentException when an invalid `body` are provided + * @throws \Auth0\SDK\Exception\NetworkException when the API request fails due to a network error + * + * @see https://auth0.com/docs/api/management/v2#!/keys/post-encryption + */ + public function postEncryption( + array $body, + ?RequestOptions $options = null, + ): ResponseInterface; + + /** + * Import wrapped key material and activate encryption key. + * Required scope: `create:encryption_keys`. + * + * @param string $kId key (by it's ID) to query + * @param array $body Additional body content to pass with the API request. See @see for supported options. + * @param null|RequestOptions $options Optional. Additional request options to use, such as a field filtering or pagination. (Not all endpoints support these. See @see for supported options.) + * + * @throws \Auth0\SDK\Exception\ArgumentException when an invalid `body` are provided + * @throws \Auth0\SDK\Exception\NetworkException when the API request fails due to a network error + * + * @see https://auth0.com/docs/api/management/v2#!/keys/post-encryption-wrapping-key + */ + public function postEncryptionKey( + string $kId, + array $body, + ?RequestOptions $options = null, + ): ResponseInterface; + /** * Perform rekeying operation on the key hierarchy. * Required scope: `create:encryption_keys`, `update:encryption_keys`. @@ -22,4 +108,21 @@ interface KeysInterface public function postEncryptionRekey( ?RequestOptions $options = null, ): ResponseInterface; + + /** + * Create the public wrapping key to wrap your own encryption key material. + * Required scope: `create:encryption_keys`. + * + * @param string $kId key (by it's ID) to query + * @param null|RequestOptions $options Optional. Additional request options to use, such as a field filtering or pagination. (Not all endpoints support these. See @see for supported options.) + * + * @throws \Auth0\SDK\Exception\ArgumentException when an invalid `body` are provided + * @throws \Auth0\SDK\Exception\NetworkException when the API request fails due to a network error + * + * @see https://auth0.com/docs/api/management/v2#!/keys/post-encryption + */ + public function postEncryptionWrappingKey( + string $kId, + ?RequestOptions $options = null, + ): ResponseInterface; } diff --git a/tests/Unit/API/Management/KeysTest.php b/tests/Unit/API/Management/KeysTest.php index eaf4e0ce..aeed4dfe 100644 --- a/tests/Unit/API/Management/KeysTest.php +++ b/tests/Unit/API/Management/KeysTest.php @@ -24,6 +24,66 @@ $this->endpoint = $this->api->mock()->keys(); }); +test('getEncryptionKey() issues an appropriate request', function(): void { + $keyId = uniqid(); + + $this->endpoint->getEncryptionKey($keyId); + + expect($this->api->getRequestMethod())->toEqual('GET'); + expect($this->api->getRequestUrl())->toStartWith('https://' . $this->api->mock()->getConfiguration()->getDomain() . '/api/v2/keys/encryption/' . $keyId); +}); + +test('getEncryptionKeys() issues an appropriate request', function(): void { + $this->endpoint->getEncryptionKeys(); + + expect($this->api->getRequestMethod())->toEqual('GET'); + expect($this->api->getRequestUrl())->toEndWith('/api/v2/keys/encryption'); + expect($this->api->getRequestQuery())->toBeEmpty(); +}); + +test('postEncryption() issues an appropriate request', function(): void { + $type = 'environment-root-key'; + $mock = (object) [ + 'body' => [ + 'type' => $type + ] + ]; + + $this->endpoint->postEncryption($mock->body); + + expect($this->api->getRequestMethod())->toEqual('POST'); + expect($this->api->getRequestUrl())->toEndWith('/api/v2/keys/encryption'); + + $body = $this->api->getRequestBody(); + $this->assertArrayHasKey('type', $body);; + expect($body['type'])->toEqual($type); + + $body = $this->api->getRequestBodyAsString(); + expect($body)->toEqual(json_encode(['type' => $type])); +}); + +test('postEncryptionKey() issues an appropriate request', function(): void { + $keyId = uniqid(); + $wrappedKey = 'base64 encoded ciphertext of wrapped key'; + $mock = (object) [ + 'body' => [ + 'wrappedKey' => $wrappedKey + ] + ]; + + $this->endpoint->postEncryptionKey($keyId, $mock->body); + + expect($this->api->getRequestMethod())->toEqual('POST'); + expect($this->api->getRequestUrl())->toEndWith('/api/v2/keys/encryption/' . $keyId); + + $body = $this->api->getRequestBody(); + $this->assertArrayHasKey('wrappedKey', $body);; + expect($body['wrappedKey'])->toEqual($wrappedKey); + + $body = $this->api->getRequestBodyAsString(); + expect($body)->toEqual(json_encode(['wrappedKey' => $wrappedKey])); +}); + test('postEncryptionRekey() issues an appropriate request', function(): void { $this->endpoint->postEncryptionRekey(); @@ -47,3 +107,22 @@ ->call(); expect($response->getStatusCode())->toEqual(204); }); + +test('postEncryptionWrappingKey() issues an appropriate request', function(): void { + $keyId = uniqid(); + + $this->endpoint->postEncryptionWrappingKey($keyId); + + expect($this->api->getRequestMethod())->toEqual('POST'); + expect($this->api->getRequestUrl())->toEndWith('/api/v2/keys/encryption/' . $keyId . '/wrapping-key'); +}); + +test('deleteEncryptionKey() issues an appropriate request', function(): void { + $keyId = uniqid(); + + $this->endpoint->deleteEncryptionKey($keyId); + + expect($this->api->getRequestMethod())->toEqual('DELETE'); + expect($this->api->getRequestUrl())->toEndWith('/api/v2/keys/encryption/' . $keyId); +}); + From f03146ebf31d6d56cb3a9919f182953eb2ec20de Mon Sep 17 00:00:00 2001 From: Snehil Kishore Date: Wed, 13 Nov 2024 13:23:39 +0530 Subject: [PATCH 2/2] Typo Fix suggested by GabrielBrittoDev. (#774) --- src/Contract/API/AuthenticationInterface.php | 4 ++-- src/Contract/API/Management/KeysInterface.php | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Contract/API/AuthenticationInterface.php b/src/Contract/API/AuthenticationInterface.php index 14be13cf..7b6ba139 100644 --- a/src/Contract/API/AuthenticationInterface.php +++ b/src/Contract/API/AuthenticationInterface.php @@ -53,8 +53,8 @@ public function clientCredentials( * @throws ConfigurationException when a redirect uri is not configured * @throws NetworkException when the API request fails due to a network error * - * @see https://auth0.com/docs/api/authentication#authorization-code-flow45 - * @see https://auth0.com/docs/api/authentication#authorization-code-flow-with-pkce46 + * @see https://auth0.com/docs/api/authentication#authorization-code-flow + * @see https://auth0.com/docs/api/authentication#authorization-code-flow-with-pkce */ public function codeExchange( string $code, diff --git a/src/Contract/API/Management/KeysInterface.php b/src/Contract/API/Management/KeysInterface.php index 78a680d1..dfc4b6c4 100644 --- a/src/Contract/API/Management/KeysInterface.php +++ b/src/Contract/API/Management/KeysInterface.php @@ -87,7 +87,7 @@ public function postEncryption( * @throws \Auth0\SDK\Exception\ArgumentException when an invalid `body` are provided * @throws \Auth0\SDK\Exception\NetworkException when the API request fails due to a network error * - * @see https://auth0.com/docs/api/management/v2#!/keys/post-encryption-wrapping-key + * @see https://auth0.com/docs/api/management/v2#!/keys/post-encryption-key */ public function postEncryptionKey( string $kId, @@ -119,7 +119,7 @@ public function postEncryptionRekey( * @throws \Auth0\SDK\Exception\ArgumentException when an invalid `body` are provided * @throws \Auth0\SDK\Exception\NetworkException when the API request fails due to a network error * - * @see https://auth0.com/docs/api/management/v2#!/keys/post-encryption + * @see https://auth0.com/docs/api/management/v2#!/keys/post-encryption-wrapping-key */ public function postEncryptionWrappingKey( string $kId,