Skip to content

Commit 571d043

Browse files
Add SQS AddPermission operation (#1773)
* Add SQS AddPermission operation * Add missing SQS AddPermission test * Fix PHPCSFixer issue * Add to changelog * Fixup changelog * Fix order * Fixup composer
1 parent 1a3902d commit 571d043

File tree

7 files changed

+349
-1
lines changed

7 files changed

+349
-1
lines changed

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,10 @@
22

33
## NOT RELEASED
44

5+
### Added
6+
7+
- Add AddPermission endpoint
8+
59
### Changed
610

711
- Enable compiler optimization for the `sprintf` function.

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,7 @@
2828
},
2929
"extra": {
3030
"branch-alias": {
31-
"dev-master": "2.1-dev"
31+
"dev-master": "2.2-dev"
3232
}
3333
}
3434
}

src/Input/AddPermissionRequest.php

Lines changed: 218 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,218 @@
1+
<?php
2+
3+
namespace AsyncAws\Sqs\Input;
4+
5+
use AsyncAws\Core\Exception\InvalidArgument;
6+
use AsyncAws\Core\Input;
7+
use AsyncAws\Core\Request;
8+
use AsyncAws\Core\Stream\StreamFactory;
9+
10+
final class AddPermissionRequest extends Input
11+
{
12+
/**
13+
* The URL of the Amazon SQS queue to which permissions are added.
14+
*
15+
* Queue URLs and names are case-sensitive.
16+
*
17+
* @required
18+
*
19+
* @var string|null
20+
*/
21+
private $queueUrl;
22+
23+
/**
24+
* The unique identification of the permission you're setting (for example, `AliceSendMessage`). Maximum 80 characters.
25+
* Allowed characters include alphanumeric characters, hyphens (`-`), and underscores (`_`).
26+
*
27+
* @required
28+
*
29+
* @var string|null
30+
*/
31+
private $label;
32+
33+
/**
34+
* The Amazon Web Services account numbers of the principals [^1] who are to receive permission. For information about
35+
* locating the Amazon Web Services account identification, see Your Amazon Web Services Identifiers [^2] in the *Amazon
36+
* SQS Developer Guide*.
37+
*
38+
* [^1]: https://docs.aws.amazon.com/general/latest/gr/glos-chap.html#P
39+
* [^2]: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-making-api-requests.html#sqs-api-request-authentication
40+
*
41+
* @required
42+
*
43+
* @var string[]|null
44+
*/
45+
private $awsAccountIds;
46+
47+
/**
48+
* The action the client wants to allow for the specified principal. Valid values: the name of any action or `*`.
49+
*
50+
* For more information about these actions, see Overview of Managing Access Permissions to Your Amazon Simple Queue
51+
* Service Resource [^1] in the *Amazon SQS Developer Guide*.
52+
*
53+
* Specifying `SendMessage`, `DeleteMessage`, or `ChangeMessageVisibility` for `ActionName.n` also grants permissions
54+
* for the corresponding batch versions of those actions: `SendMessageBatch`, `DeleteMessageBatch`, and
55+
* `ChangeMessageVisibilityBatch`.
56+
*
57+
* [^1]: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-overview-of-managing-access.html
58+
*
59+
* @required
60+
*
61+
* @var string[]|null
62+
*/
63+
private $actions;
64+
65+
/**
66+
* @param array{
67+
* QueueUrl?: string,
68+
* Label?: string,
69+
* AWSAccountIds?: string[],
70+
* Actions?: string[],
71+
* '@region'?: string|null,
72+
* } $input
73+
*/
74+
public function __construct(array $input = [])
75+
{
76+
$this->queueUrl = $input['QueueUrl'] ?? null;
77+
$this->label = $input['Label'] ?? null;
78+
$this->awsAccountIds = $input['AWSAccountIds'] ?? null;
79+
$this->actions = $input['Actions'] ?? null;
80+
parent::__construct($input);
81+
}
82+
83+
/**
84+
* @param array{
85+
* QueueUrl?: string,
86+
* Label?: string,
87+
* AWSAccountIds?: string[],
88+
* Actions?: string[],
89+
* '@region'?: string|null,
90+
* }|AddPermissionRequest $input
91+
*/
92+
public static function create($input): self
93+
{
94+
return $input instanceof self ? $input : new self($input);
95+
}
96+
97+
/**
98+
* @return string[]
99+
*/
100+
public function getActions(): array
101+
{
102+
return $this->actions ?? [];
103+
}
104+
105+
/**
106+
* @return string[]
107+
*/
108+
public function getAwsAccountIds(): array
109+
{
110+
return $this->awsAccountIds ?? [];
111+
}
112+
113+
public function getLabel(): ?string
114+
{
115+
return $this->label;
116+
}
117+
118+
public function getQueueUrl(): ?string
119+
{
120+
return $this->queueUrl;
121+
}
122+
123+
/**
124+
* @internal
125+
*/
126+
public function request(): Request
127+
{
128+
// Prepare headers
129+
$headers = [
130+
'Content-Type' => 'application/x-amz-json-1.0',
131+
'X-Amz-Target' => 'AmazonSQS.AddPermission',
132+
'Accept' => 'application/json',
133+
];
134+
135+
// Prepare query
136+
$query = [];
137+
138+
// Prepare URI
139+
$uriString = '/';
140+
141+
// Prepare Body
142+
$bodyPayload = $this->requestBody();
143+
$body = empty($bodyPayload) ? '{}' : json_encode($bodyPayload, 4194304);
144+
145+
// Return the Request
146+
return new Request('POST', $uriString, $query, $headers, StreamFactory::create($body));
147+
}
148+
149+
/**
150+
* @param string[] $value
151+
*/
152+
public function setActions(array $value): self
153+
{
154+
$this->actions = $value;
155+
156+
return $this;
157+
}
158+
159+
/**
160+
* @param string[] $value
161+
*/
162+
public function setAwsAccountIds(array $value): self
163+
{
164+
$this->awsAccountIds = $value;
165+
166+
return $this;
167+
}
168+
169+
public function setLabel(?string $value): self
170+
{
171+
$this->label = $value;
172+
173+
return $this;
174+
}
175+
176+
public function setQueueUrl(?string $value): self
177+
{
178+
$this->queueUrl = $value;
179+
180+
return $this;
181+
}
182+
183+
private function requestBody(): array
184+
{
185+
$payload = [];
186+
if (null === $v = $this->queueUrl) {
187+
throw new InvalidArgument(\sprintf('Missing parameter "QueueUrl" for "%s". The value cannot be null.', __CLASS__));
188+
}
189+
$payload['QueueUrl'] = $v;
190+
if (null === $v = $this->label) {
191+
throw new InvalidArgument(\sprintf('Missing parameter "Label" for "%s". The value cannot be null.', __CLASS__));
192+
}
193+
$payload['Label'] = $v;
194+
if (null === $v = $this->awsAccountIds) {
195+
throw new InvalidArgument(\sprintf('Missing parameter "AWSAccountIds" for "%s". The value cannot be null.', __CLASS__));
196+
}
197+
198+
$index = -1;
199+
$payload['AWSAccountIds'] = [];
200+
foreach ($v as $listValue) {
201+
++$index;
202+
$payload['AWSAccountIds'][$index] = $listValue;
203+
}
204+
205+
if (null === $v = $this->actions) {
206+
throw new InvalidArgument(\sprintf('Missing parameter "Actions" for "%s". The value cannot be null.', __CLASS__));
207+
}
208+
209+
$index = -1;
210+
$payload['Actions'] = [];
211+
foreach ($v as $listValue) {
212+
++$index;
213+
$payload['Actions'][$index] = $listValue;
214+
}
215+
216+
return $payload;
217+
}
218+
}

src/SqsClient.php

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@
3838
use AsyncAws\Sqs\Exception\RequestThrottledException;
3939
use AsyncAws\Sqs\Exception\TooManyEntriesInBatchRequestException;
4040
use AsyncAws\Sqs\Exception\UnsupportedOperationException;
41+
use AsyncAws\Sqs\Input\AddPermissionRequest;
4142
use AsyncAws\Sqs\Input\ChangeMessageVisibilityBatchRequest;
4243
use AsyncAws\Sqs\Input\ChangeMessageVisibilityRequest;
4344
use AsyncAws\Sqs\Input\CreateQueueRequest;
@@ -69,6 +70,63 @@
6970

7071
class SqsClient extends AbstractApi
7172
{
73+
/**
74+
* Adds a permission to a queue for a specific principal [^1]. This allows sharing access to the queue.
75+
*
76+
* When you create a queue, you have full control access rights for the queue. Only you, the owner of the queue, can
77+
* grant or deny permissions to the queue. For more information about these permissions, see Allow Developers to Write
78+
* Messages to a Shared Queue [^2] in the *Amazon SQS Developer Guide*.
79+
*
80+
* > - `AddPermission` generates a policy for you. You can use `SetQueueAttributes` to upload your policy. For more
81+
* > information, see Using Custom Policies with the Amazon SQS Access Policy Language [^3] in the *Amazon SQS
82+
* > Developer Guide*.
83+
* > - An Amazon SQS policy can have a maximum of seven actions per statement.
84+
* > - To remove the ability to change queue permissions, you must deny permission to the `AddPermission`,
85+
* > `RemovePermission`, and `SetQueueAttributes` actions in your IAM policy.
86+
* > - Amazon SQS `AddPermission` does not support adding a non-account principal.
87+
* >
88+
*
89+
* > Cross-account permissions don't apply to this action. For more information, see Grant cross-account permissions to
90+
* > a role and a username [^4] in the *Amazon SQS Developer Guide*.
91+
*
92+
* [^1]: https://docs.aws.amazon.com/general/latest/gr/glos-chap.html#P
93+
* [^2]: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-writing-an-sqs-policy.html#write-messages-to-shared-queue
94+
* [^3]: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-creating-custom-policies.html
95+
* [^4]: https://docs.aws.amazon.com/AWSSimpleQueueService/latest/SQSDeveloperGuide/sqs-customer-managed-policy-examples.html#grant-cross-account-permissions-to-role-and-user-name
96+
*
97+
* @see https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_AddPermission.html
98+
* @see https://docs.aws.amazon.com/aws-sdk-php/v3/api/api-sqs-2012-11-05.html#addpermission
99+
*
100+
* @param array{
101+
* QueueUrl: string,
102+
* Label: string,
103+
* AWSAccountIds: string[],
104+
* Actions: string[],
105+
* '@region'?: string|null,
106+
* }|AddPermissionRequest $input
107+
*
108+
* @throws OverLimitException
109+
* @throws RequestThrottledException
110+
* @throws QueueDoesNotExistException
111+
* @throws InvalidAddressException
112+
* @throws InvalidSecurityException
113+
* @throws UnsupportedOperationException
114+
*/
115+
public function addPermission($input): Result
116+
{
117+
$input = AddPermissionRequest::create($input);
118+
$response = $this->getResponse($input->request(), new RequestContext(['operation' => 'AddPermission', 'region' => $input->getRegion(), 'exceptionMapping' => [
119+
'OverLimit' => OverLimitException::class,
120+
'RequestThrottled' => RequestThrottledException::class,
121+
'QueueDoesNotExist' => QueueDoesNotExistException::class,
122+
'InvalidAddress' => InvalidAddressException::class,
123+
'InvalidSecurity' => InvalidSecurityException::class,
124+
'UnsupportedOperation' => UnsupportedOperationException::class,
125+
]]));
126+
127+
return new Result($response);
128+
}
129+
72130
/**
73131
* Changes the visibility timeout of a specified message in a queue to a new value. The default visibility timeout for a
74132
* message is 30 seconds. The minimum is 0 seconds. The maximum is 12 hours. For more information, see Visibility

tests/Integration/SqsClientTest.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
use AsyncAws\Core\Credentials\NullProvider;
66
use AsyncAws\Core\Test\TestCase;
77
use AsyncAws\Sqs\Enum\QueueAttributeName;
8+
use AsyncAws\Sqs\Input\AddPermissionRequest;
89
use AsyncAws\Sqs\Input\ChangeMessageVisibilityBatchRequest;
910
use AsyncAws\Sqs\Input\ChangeMessageVisibilityRequest;
1011
use AsyncAws\Sqs\Input\CreateQueueRequest;
@@ -25,6 +26,21 @@
2526

2627
class SqsClientTest extends TestCase
2728
{
29+
public function testAddPermission(): void
30+
{
31+
$client = $this->getClient();
32+
33+
$input = new AddPermissionRequest([
34+
'QueueUrl' => 'change me',
35+
'Label' => 'change me',
36+
'AWSAccountIds' => ['change me'],
37+
'Actions' => ['change me'],
38+
]);
39+
$result = $client->addPermission($input);
40+
41+
$result->resolve();
42+
}
43+
2844
public function testChangeMessageVisibility()
2945
{
3046
$sqs = $this->getClient();
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
<?php
2+
3+
namespace AsyncAws\Sqs\Tests\Unit\Input;
4+
5+
use AsyncAws\Core\Test\TestCase;
6+
use AsyncAws\Sqs\Input\AddPermissionRequest;
7+
8+
class AddPermissionRequestTest extends TestCase
9+
{
10+
public function testRequest(): void
11+
{
12+
$input = new AddPermissionRequest([
13+
'QueueUrl' => 'https://sqs.us-east-1.amazonaws.com/177715257436/MyQueue/',
14+
'Label' => 'MyLabel',
15+
'AWSAccountIds' => ['177715257436', '111111111111'],
16+
'Actions' => ['SendMessage', 'ReceiveMessage'],
17+
]);
18+
19+
// see https://docs.aws.amazon.com/AWSSimpleQueueService/latest/APIReference/API_AddPermission.html
20+
$expected = '
21+
POST / HTTP/1.0
22+
Content-Type: application/x-amz-json-1.0
23+
x-amz-target: AmazonSQS.AddPermission
24+
Accept: application/json
25+
26+
{
27+
"QueueUrl": "https://sqs.us-east-1.amazonaws.com/177715257436/MyQueue/",
28+
"Label": "MyLabel",
29+
"Actions": ["SendMessage", "ReceiveMessage"],
30+
"AWSAccountIds": ["177715257436", "111111111111"]
31+
}';
32+
33+
self::assertRequestEqualsHttpRequest($expected, $input->request());
34+
}
35+
}

0 commit comments

Comments
 (0)