From 93cc4c102a8c4c2e6482c95b10f6287f0e38870c Mon Sep 17 00:00:00 2001 From: Steven Brookes Date: Tue, 1 Oct 2024 08:40:07 +0100 Subject: [PATCH 1/7] Add SQS AddPermission operation --- manifest.json | 1 + .../Sqs/src/Input/AddPermissionRequest.php | 218 ++++++++++++++++++ src/Service/Sqs/src/SqsClient.php | 58 +++++ .../Sqs/tests/Integration/SqsClientTest.php | 16 ++ .../Unit/Input/AddPermissionRequestTest.php | 33 +++ src/Service/Sqs/tests/Unit/SqsClientTest.php | 17 ++ 6 files changed, 343 insertions(+) create mode 100644 src/Service/Sqs/src/Input/AddPermissionRequest.php create mode 100644 src/Service/Sqs/tests/Unit/Input/AddPermissionRequestTest.php diff --git a/manifest.json b/manifest.json index c54cd670f..d436126bb 100644 --- a/manifest.json +++ b/manifest.json @@ -623,6 +623,7 @@ "example": "https://raw.githubusercontent.com/aws/aws-sdk-php/${LATEST}/src/data/sqs/2012-11-05/examples-1.json", "api-reference": "https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference", "methods": [ + "AddPermission", "ChangeMessageVisibility", "ChangeMessageVisibilityBatch", "CreateQueue", diff --git a/src/Service/Sqs/src/Input/AddPermissionRequest.php b/src/Service/Sqs/src/Input/AddPermissionRequest.php new file mode 100644 index 000000000..66dea9b3d --- /dev/null +++ b/src/Service/Sqs/src/Input/AddPermissionRequest.php @@ -0,0 +1,218 @@ +queueUrl = $input['QueueUrl'] ?? null; + $this->label = $input['Label'] ?? null; + $this->awsAccountIds = $input['AWSAccountIds'] ?? null; + $this->actions = $input['Actions'] ?? null; + parent::__construct($input); + } + + /** + * @param array{ + * QueueUrl?: string, + * Label?: string, + * AWSAccountIds?: string[], + * Actions?: string[], + * '@region'?: string|null, + * }|AddPermissionRequest $input + */ + public static function create($input): self + { + return $input instanceof self ? $input : new self($input); + } + + /** + * @return string[] + */ + public function getActions(): array + { + return $this->actions ?? []; + } + + /** + * @return string[] + */ + public function getAwsAccountIds(): array + { + return $this->awsAccountIds ?? []; + } + + public function getLabel(): ?string + { + return $this->label; + } + + public function getQueueUrl(): ?string + { + return $this->queueUrl; + } + + /** + * @internal + */ + public function request(): Request + { + // Prepare headers + $headers = [ + 'Content-Type' => 'application/x-amz-json-1.0', + 'X-Amz-Target' => 'AmazonSQS.AddPermission', + 'Accept' => 'application/json', + ]; + + // Prepare query + $query = []; + + // Prepare URI + $uriString = '/'; + + // Prepare Body + $bodyPayload = $this->requestBody(); + $body = empty($bodyPayload) ? '{}' : json_encode($bodyPayload, 4194304); + + // Return the Request + return new Request('POST', $uriString, $query, $headers, StreamFactory::create($body)); + } + + /** + * @param string[] $value + */ + public function setActions(array $value): self + { + $this->actions = $value; + + return $this; + } + + /** + * @param string[] $value + */ + public function setAwsAccountIds(array $value): self + { + $this->awsAccountIds = $value; + + return $this; + } + + public function setLabel(?string $value): self + { + $this->label = $value; + + return $this; + } + + public function setQueueUrl(?string $value): self + { + $this->queueUrl = $value; + + return $this; + } + + private function requestBody(): array + { + $payload = []; + if (null === $v = $this->queueUrl) { + throw new InvalidArgument(\sprintf('Missing parameter "QueueUrl" for "%s". The value cannot be null.', __CLASS__)); + } + $payload['QueueUrl'] = $v; + if (null === $v = $this->label) { + throw new InvalidArgument(\sprintf('Missing parameter "Label" for "%s". The value cannot be null.', __CLASS__)); + } + $payload['Label'] = $v; + if (null === $v = $this->awsAccountIds) { + throw new InvalidArgument(\sprintf('Missing parameter "AWSAccountIds" for "%s". The value cannot be null.', __CLASS__)); + } + + $index = -1; + $payload['AWSAccountIds'] = []; + foreach ($v as $listValue) { + ++$index; + $payload['AWSAccountIds'][$index] = $listValue; + } + + if (null === $v = $this->actions) { + throw new InvalidArgument(\sprintf('Missing parameter "Actions" for "%s". The value cannot be null.', __CLASS__)); + } + + $index = -1; + $payload['Actions'] = []; + foreach ($v as $listValue) { + ++$index; + $payload['Actions'][$index] = $listValue; + } + + return $payload; + } +} diff --git a/src/Service/Sqs/src/SqsClient.php b/src/Service/Sqs/src/SqsClient.php index 2d9306995..aa839f67e 100644 --- a/src/Service/Sqs/src/SqsClient.php +++ b/src/Service/Sqs/src/SqsClient.php @@ -38,6 +38,7 @@ use AsyncAws\Sqs\Exception\RequestThrottledException; use AsyncAws\Sqs\Exception\TooManyEntriesInBatchRequestException; use AsyncAws\Sqs\Exception\UnsupportedOperationException; +use AsyncAws\Sqs\Input\AddPermissionRequest; use AsyncAws\Sqs\Input\ChangeMessageVisibilityBatchRequest; use AsyncAws\Sqs\Input\ChangeMessageVisibilityRequest; use AsyncAws\Sqs\Input\CreateQueueRequest; @@ -69,6 +70,63 @@ class SqsClient extends AbstractApi { + /** + * Adds a permission to a queue for a specific principal [^1]. This allows sharing access to the queue. + * + * When you create a queue, you have full control access rights for the queue. Only you, the owner of the queue, can + * grant or deny permissions to the queue. For more information about these permissions, see Allow Developers to Write + * Messages to a Shared Queue [^2] in the *Amazon SQS Developer Guide*. + * + * > - `AddPermission` generates a policy for you. You can use `SetQueueAttributes` to upload your policy. For more + * > information, see Using Custom Policies with the Amazon SQS Access Policy Language [^3] in the *Amazon SQS + * > Developer Guide*. + * > - An Amazon SQS policy can have a maximum of seven actions per statement. + * > - To remove the ability to change queue permissions, you must deny permission to the `AddPermission`, + * > `RemovePermission`, and `SetQueueAttributes` actions in your IAM policy. + * > - Amazon SQS `AddPermission` does not support adding a non-account principal. + * > + * + * > Cross-account permissions don't apply to this action. For more information, see Grant cross-account permissions to + * > a role and a username [^4] in the *Amazon SQS Developer Guide*. + * + * [^1]: https://docs.aws.amazon.com/general/latest/gr/glos-chap.html#P + * [^2]: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-writing-an-sqs-policy.html#write-messages-to-shared-queue + * [^3]: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-creating-custom-policies.html + * [^4]: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-customer-managed-policy-examples.html#grant-cross-account-permissions-to-role-and-user-name + * + * @see https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_AddPermission.html + * @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sqs-2012-11-05.html#addpermission + * + * @param array{ + * QueueUrl: string, + * Label: string, + * AWSAccountIds: string[], + * Actions: string[], + * '@region'?: string|null, + * }|AddPermissionRequest $input + * + * @throws OverLimitException + * @throws RequestThrottledException + * @throws QueueDoesNotExistException + * @throws InvalidAddressException + * @throws InvalidSecurityException + * @throws UnsupportedOperationException + */ + public function addPermission($input): Result + { + $input = AddPermissionRequest::create($input); + $response = $this->getResponse($input->request(), new RequestContext(['operation' => 'AddPermission', 'region' => $input->getRegion(), 'exceptionMapping' => [ + 'OverLimit' => OverLimitException::class, + 'RequestThrottled' => RequestThrottledException::class, + 'QueueDoesNotExist' => QueueDoesNotExistException::class, + 'InvalidAddress' => InvalidAddressException::class, + 'InvalidSecurity' => InvalidSecurityException::class, + 'UnsupportedOperation' => UnsupportedOperationException::class, + ]])); + + return new Result($response); + } + /** * Changes the visibility timeout of a specified message in a queue to a new value. The default visibility timeout for a * message is 30 seconds. The minimum is 0 seconds. The maximum is 12 hours. For more information, see Visibility diff --git a/src/Service/Sqs/tests/Integration/SqsClientTest.php b/src/Service/Sqs/tests/Integration/SqsClientTest.php index bbdb0f961..0857a4675 100644 --- a/src/Service/Sqs/tests/Integration/SqsClientTest.php +++ b/src/Service/Sqs/tests/Integration/SqsClientTest.php @@ -5,6 +5,7 @@ use AsyncAws\Core\Credentials\NullProvider; use AsyncAws\Core\Test\TestCase; use AsyncAws\Sqs\Enum\QueueAttributeName; +use AsyncAws\Sqs\Input\AddPermissionRequest; use AsyncAws\Sqs\Input\ChangeMessageVisibilityBatchRequest; use AsyncAws\Sqs\Input\ChangeMessageVisibilityRequest; use AsyncAws\Sqs\Input\CreateQueueRequest; @@ -25,6 +26,21 @@ class SqsClientTest extends TestCase { + public function testAddPermission(): void + { + $client = $this->getClient(); + + $input = new AddPermissionRequest([ + 'QueueUrl' => 'change me', + 'Label' => 'change me', + 'AWSAccountIds' => ['change me'], + 'Actions' => ['change me'], + ]); + $result = $client->addPermission($input); + + $result->resolve(); + } + public function testChangeMessageVisibility() { $sqs = $this->getClient(); diff --git a/src/Service/Sqs/tests/Unit/Input/AddPermissionRequestTest.php b/src/Service/Sqs/tests/Unit/Input/AddPermissionRequestTest.php new file mode 100644 index 000000000..c4222e423 --- /dev/null +++ b/src/Service/Sqs/tests/Unit/Input/AddPermissionRequestTest.php @@ -0,0 +1,33 @@ + 'change me', + 'Label' => 'change me', + 'AWSAccountIds' => ['change me'], + 'Actions' => ['change me'], + ]); + + // see https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_AddPermission.html + $expected = ' + POST / HTTP/1.0 + Content-Type: application/x-amz-json-1.0 + + { + "change": "it" + } + '; + + self::assertRequestEqualsHttpRequest($expected, $input->request()); + } +} diff --git a/src/Service/Sqs/tests/Unit/SqsClientTest.php b/src/Service/Sqs/tests/Unit/SqsClientTest.php index 475fae95f..d16c93d3b 100644 --- a/src/Service/Sqs/tests/Unit/SqsClientTest.php +++ b/src/Service/Sqs/tests/Unit/SqsClientTest.php @@ -5,6 +5,7 @@ use AsyncAws\Core\Credentials\NullProvider; use AsyncAws\Core\Result; use AsyncAws\Core\Test\TestCase; +use AsyncAws\Sqs\Input\AddPermissionRequest; use AsyncAws\Sqs\Input\ChangeMessageVisibilityBatchRequest; use AsyncAws\Sqs\Input\ChangeMessageVisibilityRequest; use AsyncAws\Sqs\Input\CreateQueueRequest; @@ -35,6 +36,22 @@ class SqsClientTest extends TestCase { + public function testAddPermission(): void + { + $client = new SqsClient([], new NullProvider(), new MockHttpClient()); + + $input = new AddPermissionRequest([ + 'QueueUrl' => 'change me', + 'Label' => 'change me', + 'AWSAccountIds' => ['change me'], + 'Actions' => ['change me'], + ]); + $result = $client->addPermission($input); + + self::assertInstanceOf(Result::class, $result); + self::assertFalse($result->info()['resolved']); + } + public function testChangeMessageVisibility(): void { $client = new SqsClient([], new NullProvider(), new MockHttpClient()); From 98c79d871fb656667e298afa23c7ddae5d41f07b Mon Sep 17 00:00:00 2001 From: Steven Brookes Date: Tue, 1 Oct 2024 09:43:17 +0100 Subject: [PATCH 2/7] Add missing SQS AddPermission test --- .../Unit/Input/AddPermissionRequestTest.php | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/src/Service/Sqs/tests/Unit/Input/AddPermissionRequestTest.php b/src/Service/Sqs/tests/Unit/Input/AddPermissionRequestTest.php index c4222e423..8e3253746 100644 --- a/src/Service/Sqs/tests/Unit/Input/AddPermissionRequestTest.php +++ b/src/Service/Sqs/tests/Unit/Input/AddPermissionRequestTest.php @@ -9,24 +9,26 @@ class AddPermissionRequestTest extends TestCase { public function testRequest(): void { - self::fail('Not implemented'); - $input = new AddPermissionRequest([ - 'QueueUrl' => 'change me', - 'Label' => 'change me', - 'AWSAccountIds' => ['change me'], - 'Actions' => ['change me'], + 'QueueUrl' => 'https://sqs.us-east-1.amazonaws.com/177715257436/MyQueue/', + 'Label' => 'MyLabel', + 'AWSAccountIds' => ["177715257436", "111111111111"], + 'Actions' => ["SendMessage", "ReceiveMessage"], ]); // see https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_AddPermission.html $expected = ' POST / HTTP/1.0 Content-Type: application/x-amz-json-1.0 + x-amz-target: AmazonSQS.AddPermission + Accept: application/json { - "change": "it" - } - '; + "QueueUrl": "https://sqs.us-east-1.amazonaws.com/177715257436/MyQueue/", + "Label": "MyLabel", + "Actions": ["SendMessage", "ReceiveMessage"], + "AWSAccountIds": ["177715257436", "111111111111"] + }'; self::assertRequestEqualsHttpRequest($expected, $input->request()); } From 9b7d15aa65ee89c6e7317224043942248dc47cb3 Mon Sep 17 00:00:00 2001 From: Steven Brookes Date: Tue, 1 Oct 2024 09:52:50 +0100 Subject: [PATCH 3/7] Fix PHPCSFixer issue --- src/Service/Sqs/tests/Unit/Input/AddPermissionRequestTest.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Service/Sqs/tests/Unit/Input/AddPermissionRequestTest.php b/src/Service/Sqs/tests/Unit/Input/AddPermissionRequestTest.php index 8e3253746..3f7f842c6 100644 --- a/src/Service/Sqs/tests/Unit/Input/AddPermissionRequestTest.php +++ b/src/Service/Sqs/tests/Unit/Input/AddPermissionRequestTest.php @@ -12,8 +12,8 @@ public function testRequest(): void $input = new AddPermissionRequest([ 'QueueUrl' => 'https://sqs.us-east-1.amazonaws.com/177715257436/MyQueue/', 'Label' => 'MyLabel', - 'AWSAccountIds' => ["177715257436", "111111111111"], - 'Actions' => ["SendMessage", "ReceiveMessage"], + 'AWSAccountIds' => ['177715257436', '111111111111'], + 'Actions' => ['SendMessage', 'ReceiveMessage'], ]); // see https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_AddPermission.html From 4a4636c41f0b2c512eef3a233038fa9730e24cb5 Mon Sep 17 00:00:00 2001 From: Steven Brookes Date: Tue, 1 Oct 2024 14:16:43 +0100 Subject: [PATCH 4/7] Add to changelog --- src/Service/Sqs/CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/src/Service/Sqs/CHANGELOG.md b/src/Service/Sqs/CHANGELOG.md index 6ce5ca371..5c6aeea8c 100644 --- a/src/Service/Sqs/CHANGELOG.md +++ b/src/Service/Sqs/CHANGELOG.md @@ -5,6 +5,7 @@ ### Changed - Enable compiler optimization for the `sprintf` function. +- Add AddPermission endpoint ## 2.1.1 From 339070e5f19ec3efe042214b30e88334be7bb6e9 Mon Sep 17 00:00:00 2001 From: Steven Brookes Date: Tue, 1 Oct 2024 15:03:43 +0100 Subject: [PATCH 5/7] Fixup changelog --- src/Service/Sqs/CHANGELOG.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Service/Sqs/CHANGELOG.md b/src/Service/Sqs/CHANGELOG.md index 5c6aeea8c..21ae61954 100644 --- a/src/Service/Sqs/CHANGELOG.md +++ b/src/Service/Sqs/CHANGELOG.md @@ -5,6 +5,9 @@ ### Changed - Enable compiler optimization for the `sprintf` function. + +### Added + - Add AddPermission endpoint ## 2.1.1 From 9c07d902b9032671b6e39baa07e62d61b7c16d2c Mon Sep 17 00:00:00 2001 From: Steven Brookes Date: Tue, 1 Oct 2024 16:01:47 +0100 Subject: [PATCH 6/7] Fix order --- src/Service/Sqs/CHANGELOG.md | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/Service/Sqs/CHANGELOG.md b/src/Service/Sqs/CHANGELOG.md index 21ae61954..a9660961d 100644 --- a/src/Service/Sqs/CHANGELOG.md +++ b/src/Service/Sqs/CHANGELOG.md @@ -2,14 +2,14 @@ ## NOT RELEASED -### Changed - -- Enable compiler optimization for the `sprintf` function. - ### Added - Add AddPermission endpoint +### Changed + +- Enable compiler optimization for the `sprintf` function. + ## 2.1.1 ### Changed From 57fe32c6fd8a6d23948705abdc392ad7f2599b66 Mon Sep 17 00:00:00 2001 From: Steven Brookes Date: Thu, 3 Oct 2024 09:33:15 +0100 Subject: [PATCH 7/7] Fixup composer --- src/Service/Sqs/composer.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Service/Sqs/composer.json b/src/Service/Sqs/composer.json index 871fafccb..6ae2ad18c 100644 --- a/src/Service/Sqs/composer.json +++ b/src/Service/Sqs/composer.json @@ -28,7 +28,7 @@ }, "extra": { "branch-alias": { - "dev-master": "2.1-dev" + "dev-master": "2.2-dev" } } }