Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Adding Support For BYOK with community contribution #782

Merged
merged 2 commits into from
Nov 13, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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);
});

Loading