Skip to content

Commit

Permalink
AP-5187 Ability to define many sqs prefixes. (#207)
Browse files Browse the repository at this point in the history
  • Loading branch information
kamilwylegala authored Sep 10, 2024
1 parent 5a4f0ad commit e733ec2
Show file tree
Hide file tree
Showing 3 changed files with 59 additions and 13 deletions.
2 changes: 1 addition & 1 deletion packages/sns/lib/sns/AbstractSnsService.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export type SNSTopicConfig = {
}

export type ExtraSNSCreationParams = {
queueUrlsWithSubscribePermissionsPrefix?: string
queueUrlsWithSubscribePermissionsPrefix?: string | readonly string[]
allowedSourceOwner?: string
}

Expand Down
29 changes: 27 additions & 2 deletions packages/sns/lib/utils/snsAttributeUtils.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,32 @@ describe('snsAttributeUtils', () => {
})

expect(resolvedPolicy).toBe(
`{"Version":"2012-10-17","Id":"__default_policy_ID","Statement":[{"Sid":"AllowSQSSubscription","Effect":"Allow","Principal":{"AWS":"*"},"Action":["sns:Subscribe"],"Resource":"arn:aws:sns:eu-central-1:632374391739:test-sns-some-service","Condition":{"StringEquals":{"AWS:SourceOwner": "111111111111"},"StringLike":{"sns:Endpoint":"arn:aws:sqs:eu-central-1:632374391739:test-sqs-*"}}}]}`,
`{"Version":"2012-10-17","Id":"__default_policy_ID","Statement":[{"Sid":"AllowSQSSubscription","Effect":"Allow","Principal":{"AWS":"*"},"Action":["sns:Subscribe"],"Resource":"arn:aws:sns:eu-central-1:632374391739:test-sns-some-service","Condition":{"StringEquals":{"AWS:SourceOwner":"111111111111"},"StringLike":{"sns:Endpoint":"arn:aws:sqs:eu-central-1:632374391739:test-sqs-*"}}}]}`,
)
})

it('resolves policy for array of sns:endpoints', () => {
const resolvedPolicy = generateTopicSubscriptionPolicy({
topicArn: 'arn:aws:sns:eu-central-1:632374391739:test-sns-some-service',
allowedSqsQueueUrlPrefix: [
'arn:aws:sqs:eu-central-1:632374391739:test1-sqs-*',
'arn:aws:sqs:eu-central-1:632374391739:test2-sqs-*',
],
})

expect(resolvedPolicy).toBe(
`{"Version":"2012-10-17","Id":"__default_policy_ID","Statement":[{"Sid":"AllowSQSSubscription","Effect":"Allow","Principal":{"AWS":"*"},"Action":["sns:Subscribe"],"Resource":"arn:aws:sns:eu-central-1:632374391739:test-sns-some-service","Condition":{"StringLike":{"sns:Endpoint":["arn:aws:sqs:eu-central-1:632374391739:test1-sqs-*","arn:aws:sqs:eu-central-1:632374391739:test2-sqs-*"]}}}]}`,
)
})

it('resolves policy without condition for sns:endpoint if provided array is empty', () => {
const resolvedPolicy = generateTopicSubscriptionPolicy({
topicArn: 'arn:aws:sns:eu-central-1:632374391739:test-sns-some-service',
allowedSqsQueueUrlPrefix: [],
})

expect(resolvedPolicy).toBe(
`{"Version":"2012-10-17","Id":"__default_policy_ID","Statement":[{"Sid":"AllowSQSSubscription","Effect":"Allow","Principal":{"AWS":"*"},"Action":["sns:Subscribe"],"Resource":"arn:aws:sns:eu-central-1:632374391739:test-sns-some-service","Condition":{}}]}`,
)
})

Expand All @@ -27,7 +52,7 @@ describe('snsAttributeUtils', () => {
})

expect(resolvedPolicy).toBe(
`{"Version":"2012-10-17","Id":"__default_policy_ID","Statement":[{"Sid":"AllowSQSSubscription","Effect":"Allow","Principal":{"AWS":"*"},"Action":["sns:Subscribe"],"Resource":"arn:aws:sns:eu-central-1:632374391739:test-sns-some-service","Condition":{"StringEquals":{"AWS:SourceOwner": "111111111111"}}}]}`,
`{"Version":"2012-10-17","Id":"__default_policy_ID","Statement":[{"Sid":"AllowSQSSubscription","Effect":"Allow","Principal":{"AWS":"*"},"Action":["sns:Subscribe"],"Resource":"arn:aws:sns:eu-central-1:632374391739:test-sns-some-service","Condition":{"StringEquals":{"AWS:SourceOwner":"111111111111"}}}]}`,
)
})

Expand Down
41 changes: 31 additions & 10 deletions packages/sns/lib/utils/snsAttributeUtils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,42 @@ const POLICY_VERSION = '2012-10-17'

export type TopicSubscriptionPolicyParams = {
topicArn: string
allowedSqsQueueUrlPrefix?: string
allowedSqsQueueUrlPrefix?: string | readonly string[]
allowedSourceOwner?: string
}

export function generateTopicSubscriptionPolicy(params: TopicSubscriptionPolicyParams) {
const sourceOwnerFragment = params.allowedSourceOwner
? `"StringEquals":{"AWS:SourceOwner": "${params.allowedSourceOwner}"}`
: ''
const supportedSqsQueueUrlPrefixFragment = params.allowedSqsQueueUrlPrefix
? `"StringLike":{"sns:Endpoint":"${params.allowedSqsQueueUrlPrefix}"}`
: ''
const commaFragment =
sourceOwnerFragment.length > 0 && supportedSqsQueueUrlPrefixFragment.length > 0 ? ',' : ''
const policyObject = {
Version: POLICY_VERSION,
Id: '__default_policy_ID',
Statement: [
{
Sid: 'AllowSQSSubscription',
Effect: 'Allow',
Principal: {
AWS: '*',
},
Action: ['sns:Subscribe'],
Resource: params.topicArn,
Condition: {},
},
],
}

if (params.allowedSourceOwner) {
// @ts-ignore
policyObject.Statement[0].Condition.StringEquals = {
'AWS:SourceOwner': params.allowedSourceOwner,
}
}
if (params.allowedSqsQueueUrlPrefix?.length && params.allowedSqsQueueUrlPrefix.length > 0) {
// @ts-ignore
policyObject.Statement[0].Condition.StringLike = {
'sns:Endpoint': params.allowedSqsQueueUrlPrefix,
}
}

return `{"Version":"${POLICY_VERSION}","Id":"__default_policy_ID","Statement":[{"Sid":"AllowSQSSubscription","Effect":"Allow","Principal":{"AWS":"*"},"Action":["sns:Subscribe"],"Resource":"${params.topicArn}","Condition":{${sourceOwnerFragment}${commaFragment}${supportedSqsQueueUrlPrefixFragment}}}]}`
return JSON.stringify(policyObject)
}

export function generateFilterAttributes(
Expand Down

0 comments on commit e733ec2

Please sign in to comment.