Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(ses): add constructs for email receiving #1971

Merged
merged 10 commits into from
Mar 16, 2019
Merged
Show file tree
Hide file tree
Changes from 4 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
121 changes: 121 additions & 0 deletions packages/@aws-cdk/aws-ses/README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,123 @@
## The CDK Construct Library for AWS Simple Email Service
This module is part of the [AWS Cloud Development Kit](https://github.com/awslabs/aws-cdk) project.

### Email receiving
Create a receipt rule set with rules and actions:
```ts
const bucket = new s3.Bucket(this, 'Bucket');
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could you please move this into a file named:

test/example.receiving.lit.ts

And add the requirement imports and Stack declaration around it?

You can mark the piece of code that is relevant for the example with:

/// !show
...code goes here
/// !hide

And at this location in the README add:

[example of setting up a receive rule](test/example.receiving.lit.ts)

This will make sure that the example actually compiles, and if we make breaking API changes, the compiler failure will force us to update the example code.


const topic = new sns.Topic(this, 'Topic');

const ruleSet = new ses.ReceiptRuleSet(this, 'RuleSet', {
rules: [
{
actions: [
new ses.ReceiptRuleAddHeaderAction({
name: 'X-Special-Header',
value: 'aws'
})
new ses.ReceiptRuleS3Action({
bucket,
objectKeyPrefix: 'emails/',
topic
})
],
recipients: ['hello@aws.com'],
},
{
actions: [
new ses.ReceiptRuleSnsAction({
topic
})
]
recipients: ['aws.com'],
}
]
});
```

Alternatively, rules can be added to a rule set:
```ts
const ruleSet = new ses.ReceiptRuleSet(this, 'RuleSet'):

const awsRule = ruleSet.addRule('Aws', {
recipients: ['aws.com']
});
```

And actions to rules:
```ts
awsRule.addAction(
new ses.ReceiptRuleSnsAction({
topic
});
);
```
When using `addRule`, the new rule is added after the last added rule unless `after` is specified.

[More actions](test/integ.receipt.ts)

#### Drop spams
A rule to drop spam can be added by setting `dropSpam` to `true`:

```ts
new ses.ReceiptRuleSet(this, 'RuleSet', {
dropSpam: true
});
```

This will add a rule at the top of the rule set with a Lambda action that stops processing messages that have at least one spam indicator. See [Lambda Function Examples](https://docs.aws.amazon.com/ses/latest/DeveloperGuide/receiving-email-action-lambda-example-functions.html).

### Import and export receipt rule set and receipt rules
Receipt rule sets and receipt rules can be exported:

```ts
const ruleSet = new ReceiptRuleSet(this, 'RuleSet');
const rule = ruleSet.addRule(this, 'Rule', {
recipients: ['hello@mydomain.com']
});

const ruleSetRef = ruleSet.export();
const ruleRef = rule.export();
```

And imported:
```ts
const importedRuleSet = ses.ReceiptRuleSet.import(this, 'ImportedRuleSet', ruleSetRef);

const importedRule = ses.ReceiptRule.import(this, 'ImportedRule', ruleRef);

const otherRule = ses.ReceiptRule.import(this, 'OtherRule', {
name: 'other-rule'
});

importedRuleSet.addRule('New', { // This rule as added after the imported rule
after: importedRule,
recipients: ['mydomain.com']
});

importedRuleSet.addRule('Extra', { // Added after the 'New' rule
recipients: ['extra.com']
});
```

### Receipt filter
Create a receipt filter:
```ts
new ses.ReceiptFilter(this, 'Filter', {
ip: '1.2.3.4/16' // Will be blocked
})
```

Without props, a block all (0.0.0.0/0) filter is created.

A white list filter is also available:
```ts
new ses.WhiteListReceiptFilter(this, 'WhiteList', {
ips: [
'10.0.0.0/16',
'1.2.3.4/16',
]
});
```
This will first create a block all filter and then create allow filters for the listed ip addresses.
5 changes: 5 additions & 0 deletions packages/@aws-cdk/aws-ses/lib/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,7 @@
export * from './receipt-rule-set';
export * from './receipt-rule';
export * from './receipt-rule-action';
export * from './receipt-filter';

// AWS::SES CloudFormation Resources:
export * from './ses.generated';
82 changes: 82 additions & 0 deletions packages/@aws-cdk/aws-ses/lib/receipt-filter.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,82 @@
import cdk = require('@aws-cdk/cdk');
import { CfnReceiptFilter } from './ses.generated';

export enum ReceiptFilterPolicy {
jogold marked this conversation as resolved.
Show resolved Hide resolved
/**
* Allow the ip address or range.
*/
Allow = 'Allow',

/**
* Block the ip address or range.
*/
Block = 'Block'
}

export interface ReceiptFilterProps {
jogold marked this conversation as resolved.
Show resolved Hide resolved
/**
* The name for the receipt filter.
*
* @default a CloudFormation generated name
*/
name?: string;

/**
* The ip address or range to filter.
*
* @default 0.0.0.0/0
*/
ip?: string;

/**
* The policy for the filter.
*
* @default Block
*/
policy?: ReceiptFilterPolicy;
}

/**
* A receipt filter. When instantiated without props, it creates a
* block all receipt filter.
*/
export class ReceiptFilter extends cdk.Construct {
constructor(scope: cdk.Construct, id: string, props?: ReceiptFilterProps) {
super(scope, id);

new CfnReceiptFilter(this, 'Resource', {
filter: {
ipFilter: {
cidr: (props && props.ip) || '0.0.0.0/0',
policy: (props && props.policy) || ReceiptFilterPolicy.Block
},
name: props ? props.name : undefined
}
});
}
}

export interface WhiteListReceiptFilterProps {
jogold marked this conversation as resolved.
Show resolved Hide resolved
/**
* A list of ip addresses or ranges to white list.
*/
ips: string[];
}

/**
* A white list receipt filter.
*/
export class WhiteListReceiptFilter extends cdk.Construct {
constructor(scope: cdk.Construct, id: string, props: WhiteListReceiptFilterProps) {
super(scope, id);

new ReceiptFilter(this, 'BlockAll');

props.ips.forEach(ip => {
new ReceiptFilter(this, `Allow${ip.replace(/[^\d]/g, '')}`, {
ip,
policy: ReceiptFilterPolicy.Allow
});
});
}
}
Loading