Skip to content

Commit

Permalink
Adding Support For BYOK with community contribution (#782)
Browse files Browse the repository at this point in the history
### Contributing Changes

- Adjusted link typo on codeExchange method to the right url by
[GabrielBrittoDev](https://github.com/GabrielBrittoDev).
([#774](#774))

### Changes

Following endpoints have been added : 

- GET /api/v2/keys/encryption
- POST  /api/v2/keys/encryption
- GET  /api/v2/keys/encryption/{kid}
- DELETE  /api/v2/keys/encryption/{kid}
- POST  /api/v2/keys/encryption/{kid}
- POST  /api/v2/keys/encryption/{kid}/wrapping-key


### References

-
[/api/v2/keys/encryption](https://auth0.com/docs/api/management/v2/keys/get-encryption-keys)

-
[/api/v2/keys/encryption](https://auth0.com/docs/api/management/v2/keys/post-encryption)

-
[/api/v2/keys/encryption/{kid}](https://auth0.com/docs/api/management/v2/keys/get-encryption-key)

- [DELETE
/api/v2/keys/encryption/{kid}](https://auth0.com/docs/api/management/v2/keys/delete-encryption-key)

-
[/api/v2/keys/encryption/{kid}](https://auth0.com/docs/api/management/v2/keys/post-encryption-key)

-
[/api/v2/keys/encryption/{kid}/wrapping-key](https://auth0.com/docs/api/management/v2/keys/post-encryption-wrapping-key)

- JIRA -> [SDK-5121](https://auth0team.atlassian.net/browse/SDK-5121)

### Testing

- [x] This change adds unit test coverage

- [x] This change adds integration test coverage

- [x] This change has been tested on the latest version of the
platform/language or why not

### Contributor Checklist

- [x] I agree to adhere to the [Auth0 General Contribution
Guidelines](https://github.com/auth0/open-source-template/blob/master/GENERAL-CONTRIBUTING.md).
- [x] I agree to uphold the [Auth0 Code of
Conduct](https://github.com/auth0/open-source-template/blob/master/CODE-OF-CONDUCT.md).


[SDK-5121]:
https://auth0team.atlassian.net/browse/SDK-5121?atlOrigin=eyJpIjoiNWRkNTljNzYxNjVmNDY3MDlhMDU5Y2ZhYzA5YTRkZjUiLCJwIjoiZ2l0aHViLWNvbS1KU1cifQ
  • Loading branch information
kishore7snehil authored Nov 13, 2024
1 parent d70324d commit e7d9916
Show file tree
Hide file tree
Showing 4 changed files with 292 additions and 2 deletions.
108 changes: 108 additions & 0 deletions src/API/Management/Keys.php
Original file line number Diff line number Diff line change
Expand Up @@ -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;

/**
Expand All @@ -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<null|int|string> $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 {
Expand All @@ -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();
}
}
4 changes: 2 additions & 2 deletions src/Contract/API/AuthenticationInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
103 changes: 103 additions & 0 deletions src/Contract/API/Management/KeysInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -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<mixed> $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<mixed> $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-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`.
Expand All @@ -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-wrapping-key
*/
public function postEncryptionWrappingKey(
string $kId,
?RequestOptions $options = null,
): ResponseInterface;
}
79 changes: 79 additions & 0 deletions tests/Unit/API/Management/KeysTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -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);
});

0 comments on commit e7d9916

Please sign in to comment.