Secure your code as it's written. Use Snyk Code to scan source code in minutes - no build needed - and fix issues immediately.
private grant(identity: IIdentityResource, objectsKeyPattern: string, bucketActions: string[], keyActions: string[]) {
const resources = [
this.bucketArn,
this.arnForObjects(objectsKeyPattern)
];
identity.addToPolicy(new PolicyStatement()
.addResources(...resources)
.addActions(...bucketActions));
// grant key permissions if there's an associated key.
if (this.encryptionKey) {
// KMS permissions need to be granted both directions
identity.addToPolicy(new PolicyStatement()
.addResource(this.encryptionKey.keyArn)
.addActions(...keyActions));
this.encryptionKey.addToResourcePolicy(new PolicyStatement()
.addResource('*')
.addPrincipal(identity.principal)
.addActions(...keyActions));
}
}
private grant(identity: IIdentityResource, actions: { streamActions: string[], keyActions: string[] }) {
identity.addToPolicy(new PolicyStatement()
.addResource(this.streamArn)
.addActions(...actions.streamActions));
// grant key permissions if there's an associated key.
if (this.encryptionKey) {
identity.addToPolicy(new PolicyStatement()
.addResource(this.encryptionKey.keyArn)
.addActions(...actions.keyActions));
}
}
}
const subscriptionName = queue.name + 'Subscription';
if (this.tryFindChild(subscriptionName)) {
throw new Error(`A subscription between the topic ${this.name} and the queue ${queue.name} already exists`);
}
// we use the queue name as the subscription's. there's no meaning to subscribing
// the same queue twice on the same topic.
const sub = new Subscription(this, subscriptionName, {
topic: this,
endpoint: queue.queueArn,
protocol: SubscriptionProtocol.Sqs
});
// add a statement to the queue resource policy which allows this topic
// to send messages to the queue.
queue.addToResourcePolicy(new PolicyStatement()
.addResource(queue.queueArn)
.addAction('sqs:SendMessage')
.addServicePrincipal('sns.amazonaws.com')
.setCondition('ArnEquals', { 'aws:SourceArn': this.topicArn }));
return sub;
}
public logSubscriptionDestination(sourceLogGroup: logs.LogGroup): logs.LogSubscriptionDestination {
// Following example from https://docs.aws.amazon.com/AmazonCloudWatch/latest/logs/SubscriptionFilters.html#DestinationKinesisExample
if (!this.cloudWatchLogsRole) {
// Create a role to be assumed by CWL that can write to this stream and pass itself.
this.cloudWatchLogsRole = new Role(this, 'CloudWatchLogsCanPutRecords', {
assumedBy: new ServicePrincipal(new FnConcat('logs.', new AwsRegion(), '.amazonaws.com')),
});
this.cloudWatchLogsRole.addToPolicy(new PolicyStatement().addAction('kinesis:PutRecord').addResource(this.streamArn));
this.cloudWatchLogsRole.addToPolicy(new PolicyStatement().addAction('iam:PassRole').addResource(this.cloudWatchLogsRole.roleArn));
}
// We've now made it possible for CloudWatch events to write to us. In case the LogGroup is in a
// different account, we must add a Destination in between as well.
const sourceStack = Stack.find(sourceLogGroup);
const thisStack = Stack.find(this);
// Case considered: if both accounts are undefined, we can't make any assumptions. Better
// to assume we don't need to do anything special.
const sameAccount = sourceStack.env.account === thisStack.env.account;
if (!sameAccount) {
return this.crossAccountLogSubscriptionDestination(sourceLogGroup);
}
if (!sourceStack.env.account || !thisStack.env.account) {
throw new Error('SubscriptionFilter stack and Destination stack must either both have accounts defined, or both not have accounts');
}
// Take some effort to construct a unique ID for the destination that is unique to the
// combination of (stream, loggroup).
const uniqueId = new HashedAddressingScheme().allocateAddress([sourceLogGroup.path.replace('/', ''), sourceStack.env.account!]);
// The destination lives in the target account
const dest = new logs.CrossAccountDestination(this, `CWLDestination${uniqueId}`, {
targetArn: this.streamArn,
role: this.cloudWatchLogsRole!
});
dest.addToPolicy(new PolicyStatement()
.addAction('logs:PutSubscriptionFilter')
.addAwsAccountPrincipal(sourceStack.env.account)
.addAllResources());
return dest.logSubscriptionDestination(sourceLogGroup);
}
function createAssumeRolePolicy(principal: PolicyPrincipal) {
return new PolicyDocument()
.addStatement(new PolicyStatement()
.addPrincipal(principal)
.addAction(principal.assumeRoleAction));
}
public grantPublish(identity?: IIdentityResource) {
if (!identity) {
return;
}
identity.addToPolicy(new PolicyStatement()
.addResource(this.topicArn)
.addActions('sns:Publish'));
}