Skip to content

Commit

Permalink
feat(aws-sqs): Add grantXxx() methods (#1004)
Browse files Browse the repository at this point in the history
Add grantReceive and grantSend to a Queue allowing a user to be able to
directly grant permissions to an IAM Principal (Role, User etc.).

An additional grantConsume is here for combining three permissions
commonly used when consuming messages rather than just receiving to
provide the ability to set message visibility and delete entirely.
  • Loading branch information
leepa authored and rix0rrr committed Oct 24, 2018
1 parent 6c9075a commit 8c90350
Show file tree
Hide file tree
Showing 3 changed files with 161 additions and 1 deletion.
12 changes: 12 additions & 0 deletions packages/@aws-cdk/aws-sqs/lib/perms.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
export const QUEUE_GET_ACTIONS = [
"sqs:ReceiveMessage",
];

export const QUEUE_CONSUME_ACTIONS = [
"sqs:ChangeMessageVisibility",
"sqs:DeleteMessage",
];

export const QUEUE_PUT_ACTIONS = [
"sqs:SendMessage",
];
60 changes: 60 additions & 0 deletions packages/@aws-cdk/aws-sqs/lib/queue.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import iam = require('@aws-cdk/aws-iam');
import kms = require('@aws-cdk/aws-kms');
import cdk = require('@aws-cdk/cdk');
import perms = require('./perms');
import { QueueRef } from './queue-ref';
import { cloudformation } from './sqs.generated';
import { validateProps } from './validate-props';
Expand Down Expand Up @@ -275,6 +277,64 @@ export class Queue extends QueueRef {
}
}

/**
* Grant permissions to consume messages from a queue
*
* This will grant the following permissions:
*
* - sqs:ChangeMessageVisibility
* - sqs:DeleteMessage
* - sqs:ReceiveMessage
*
* @param identity Principal to grant consume rights to
*/
public grantConsumeMessages(identity?: iam.IPrincipal) {
this.grant(identity, perms.QUEUE_GET_ACTIONS.concat(perms.QUEUE_CONSUME_ACTIONS));
}

/**
* Grant access to receive messages from a queue to
* the given identity.
*
* This will grant sqs:ReceiveMessage
*
* @param identity Principal to grant receive rights to
*/
public grantReceiveMessages(identity?: iam.IPrincipal) {
this.grant(identity, perms.QUEUE_GET_ACTIONS);
}

/**
* Grant access to send messages to a queue to the
* given identity.
*
* This will grant sqs:SendMessage
*
* @param identity Principal to grant send rights to
*/
public grantSendMessages(identity?: iam.IPrincipal) {
this.grant(identity, perms.QUEUE_PUT_ACTIONS);
}

/**
* Grant the actions defined in queueActions
* to the identity Principal given.
*
* @param identity Principal to grant right to
* @param queueActions The actions to grant
*/
private grant(identity: iam.IPrincipal | undefined,
queueActions: string[]) {

if (!identity) {
return;
}

identity.addToPolicy(new iam.PolicyStatement()
.addResource(this.queueArn)
.addActions(...queueActions));
}

/**
* Look at the props, see if the FIFO props agree, and return the correct subset of props
*/
Expand Down
90 changes: 89 additions & 1 deletion packages/@aws-cdk/aws-sqs/test/test.sqs.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { expect, haveResource } from '@aws-cdk/assert';
import { ArnPrincipal, PolicyStatement } from '@aws-cdk/aws-iam';
import { ArnPrincipal, PolicyStatement, Role, ServicePrincipal } from '@aws-cdk/aws-iam';
import kms = require('@aws-cdk/aws-kms');
import s3 = require('@aws-cdk/aws-s3');
import { resolve, Stack } from '@aws-cdk/cdk';
Expand Down Expand Up @@ -113,6 +113,94 @@ export = {
test.done();
},

'iam': {
'grants permission to consume messages'(test: Test) {
const stack = new Stack();
const role = new Role(stack, 'Role', { assumedBy: new ServicePrincipal('lambda.amazonaws.com') });
const queue = new sqs.Queue(stack, 'Queue');
queue.grantConsumeMessages(role);

expect(stack).to(haveResource('AWS::IAM::Policy', {
"PolicyDocument": {
"Statement": [
{
"Action": [
"sqs:ReceiveMessage",
"sqs:ChangeMessageVisibility",
"sqs:DeleteMessage"
],
"Effect": "Allow",
"Resource": {
"Fn::GetAtt":
[
"Queue4A7E3555",
"Arn"
]
}
}
]
}
}));

test.done();
},

'grants permission to receive messages'(test: Test) {
const stack = new Stack();
const role = new Role(stack, 'Role', { assumedBy: new ServicePrincipal('lambda.amazonaws.com') });
const queue = new sqs.Queue(stack, 'Queue');
queue.grantReceiveMessages(role);

expect(stack).to(haveResource('AWS::IAM::Policy', {
"PolicyDocument": {
"Statement": [
{
"Action": "sqs:ReceiveMessage",
"Effect": "Allow",
"Resource": {
"Fn::GetAtt":
[
"Queue4A7E3555",
"Arn"
]
}
}
]
}
}));

test.done();
},

'grants permission to send messages'(test: Test) {
const stack = new Stack();
const role = new Role(stack, 'Role', { assumedBy: new ServicePrincipal('lambda.amazonaws.com') });
const queue = new sqs.Queue(stack, 'Queue');
queue.grantSendMessages(role);

expect(stack).to(haveResource('AWS::IAM::Policy', {
"PolicyDocument": {
"Statement": [
{
"Action": "sqs:SendMessage",
"Effect": "Allow",
"Resource": {
"Fn::GetAtt":
[
"Queue4A7E3555",
"Arn"
]
}
}
]
}
}));

test.done();
}

},

'queue encryption': {
'encryptionMasterKey can be set to a custom KMS key'(test: Test) {
const stack = new Stack();
Expand Down

0 comments on commit 8c90350

Please sign in to comment.