Skip to content

Commit

Permalink
Merge branch 'master' into pmc-fix-12583-invalid-user-data-ecs-windows
Browse files Browse the repository at this point in the history
  • Loading branch information
SoManyHs authored Jan 20, 2021
2 parents 5484956 + d126fcc commit 8d083ff
Show file tree
Hide file tree
Showing 29 changed files with 1,275 additions and 430 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -238,4 +238,9 @@ export enum PredefinedMetric {
* @see https://docs.aws.amazon.com/lambda/latest/dg/monitoring-metrics.html#monitoring-metrics-concurrency
*/
LAMBDA_PROVISIONED_CONCURRENCY_UTILIZATION = 'LambdaProvisionedConcurrencyUtilization',
/**
* KAFKA_BROKER_STORAGE_UTILIZATION
* @see https://docs.aws.amazon.com/autoscaling/application/APIReference/API_PredefinedMetricSpecification.html
*/
KAFKA_BROKER_STORAGE_UTILIZATION = 'KafkaBrokerStorageUtilization',
}
2 changes: 1 addition & 1 deletion packages/@aws-cdk/aws-codepipeline-actions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,7 @@ CodePipeline can use a BitBucket Git repository as a source:
**Note**: you have to manually connect CodePipeline through the AWS Console with your BitBucket account.
This is a one-time operation for a given AWS account in a given region.
The simplest way to do that is to either start creating a new CodePipeline,
or edit na existing one, while being logged in to BitBucket.
or edit an existing one, while being logged in to BitBucket.
Choose BitBucket as the source,
and grant CodePipeline permissions to your BitBucket account.
Copy & paste the Connection ARN that you get in the console,
Expand Down
24 changes: 24 additions & 0 deletions packages/@aws-cdk/aws-cognito/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -572,6 +572,30 @@ pool.addClient('app-client', {
});
```

Clients can (and should) be allowed to read and write relevant user attributes only. Usually every client can be allowed to read the `given_name`
attribute but not every client should be allowed to set the `email_verified` attribute.
The same criteria applies for both standard and custom attributes, more info is available at
[Attribute Permissions and Scopes](https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-attributes.html#user-pool-settings-attribute-permissions-and-scopes).
The default behaviour is to allow read and write permissions on all attributes. The following code shows how this can be configured for a client.

```ts
const pool = new cognito.UserPool(this, 'Pool');

const clientWriteAttributes = (new ClientAttributes())
.withStandardAttributes({name: true, email: true})
.withCustomAttributes(['favouritePizza']);

const clientReadAttributes = clientWriteAttributes
.withStandardAttributes({emailVerified: true})
.withCustomAttributes(['pointsEarned']);

pool.addClient('app-client', {
// ...
readAttributes: clientReadAttributes,
writeAttributes: clientWriteAttributes,
});
```

### Resource Servers

A resource server is a server for access-protected resources. It handles authenticated requests from an app that has an
Expand Down
2 changes: 2 additions & 0 deletions packages/@aws-cdk/aws-cognito/lib/private/attr-names.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,6 @@ export const StandardAttributeNames = {
timezone: 'zoneinfo',
lastUpdateTime: 'updated_at',
website: 'website',
emailVerified: 'email_verified',
phoneNumberVerified: 'phone_number_verified',
};
200 changes: 200 additions & 0 deletions packages/@aws-cdk/aws-cognito/lib/user-pool-attr.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import { Token } from '@aws-cdk/core';
import { StandardAttributeNames } from './private/attr-names';

/**
* The set of standard attributes that can be marked as required or mutable.
Expand Down Expand Up @@ -107,6 +108,18 @@ export interface StandardAttributes {
* @default - see the defaults under `StandardAttribute`
*/
readonly website?: StandardAttribute;

/**
* Whether the email address has been verified.
* @default - see the defaults under `StandardAttribute`
*/
readonly emailVerified?: StandardAttribute;

/**
* Whether the phone number has been verified.
* @default - see the defaults under `StandardAttribute`
*/
readonly phoneNumberVerified?: StandardAttribute;
}

/**
Expand Down Expand Up @@ -341,3 +354,190 @@ export class DateTimeAttribute implements ICustomAttribute {
};
}
}

/**
* This interface contains all standard attributes recognized by Cognito
* from https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-attributes.html
* including `email_verified` and `phone_number_verified`
*/
export interface StandardAttributesMask {
/**
* The user's postal address.
* @default false
*/
readonly address?: boolean;

/**
* The user's birthday, represented as an ISO 8601:2004 format.
* @default false
*/
readonly birthdate?: boolean;

/**
* The user's e-mail address, represented as an RFC 5322 [RFC5322] addr-spec.
* @default false
*/
readonly email?: boolean;

/**
* The surname or last name of the user.
* @default false
*/
readonly familyName?: boolean;

/**
* The user's gender.
* @default false
*/
readonly gender?: boolean;

/**
* The user's first name or give name.
* @default false
*/
readonly givenName?: boolean;

/**
* The user's locale, represented as a BCP47 [RFC5646] language tag.
* @default false
*/
readonly locale?: boolean;

/**
* The user's middle name.
* @default false
*/
readonly middleName?: boolean;

/**
* The user's full name in displayable form, including all name parts, titles and suffixes.
* @default false
*/
readonly fullname?: boolean;

/**
* The user's nickname or casual name.
* @default false
*/
readonly nickname?: boolean;

/**
* The user's telephone number.
* @default false
*/
readonly phoneNumber?: boolean;

/**
* The URL to the user's profile picture.
* @default false
*/
readonly profilePicture?: boolean;

/**
* The user's preffered username, different from the immutable user name.
* @default false
*/
readonly preferredUsername?: boolean;

/**
* The URL to the user's profile page.
* @default false
*/
readonly profilePage?: boolean;

/**
* The user's time zone.
* @default false
*/
readonly timezone?: boolean;

/**
* The time, the user's information was last updated.
* @default false
*/
readonly lastUpdateTime?: boolean;

/**
* The URL to the user's web page or blog.
* @default false
*/
readonly website?: boolean;

/**
* Whether the email address has been verified.
* @default false
*/
readonly emailVerified?: boolean;

/**
* Whether the phone number has been verified.
* @default false
*/
readonly phoneNumberVerified?: boolean;
}


/**
* A set of attributes, useful to set Read and Write attributes
*/
export class ClientAttributes {

/**
* The set of attributes
*/
private attributesSet: Set<string>;

/**
* Creates a ClientAttributes with the specified attributes
*
* @default - a ClientAttributes object without any attributes
*/
constructor() {
this.attributesSet = new Set<string>();
}

/**
* Creates a custom ClientAttributes with the specified attributes
* @param attributes a list of standard attributes to add to the set
*/
public withStandardAttributes(attributes: StandardAttributesMask): ClientAttributes {
let attributesSet = new Set(this.attributesSet);
// iterate through key-values in the `StandardAttributeNames` constant
// to get the value for all attributes
for (const attributeKey in StandardAttributeNames) {
if ((attributes as any)[attributeKey] === true) {
const attributeName = (StandardAttributeNames as any)[attributeKey];
attributesSet.add(attributeName);
}
}
let aux = new ClientAttributes();
aux.attributesSet = attributesSet;
return aux;
}

/**
* Creates a custom ClientAttributes with the specified attributes
* @param attributes a list of custom attributes to add to the set
*/
public withCustomAttributes(...attributes: string[]): ClientAttributes {
let attributesSet: Set<string> = new Set(this.attributesSet);
for (let attribute of attributes) {
// custom attributes MUST begin with `custom:`, so add the string if not present
if (!attribute.startsWith('custom:')) {
attribute = 'custom:' + attribute;
}
attributesSet.add(attribute);
}
let aux = new ClientAttributes();
aux.attributesSet = attributesSet;
return aux;
}

/**
* The list of attributes represented by this ClientAttributes
*/
public attributes(): string[] {
// sorting is unnecessary but it simplify testing
return Array.from(this.attributesSet).sort();
}
}
17 changes: 17 additions & 0 deletions packages/@aws-cdk/aws-cognito/lib/user-pool-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import { IResource, Resource, Duration } from '@aws-cdk/core';
import { Construct } from 'constructs';
import { CfnUserPoolClient } from './cognito.generated';
import { IUserPool } from './user-pool';
import { ClientAttributes } from './user-pool-attr';
import { IUserPoolResourceServer, ResourceServerScope } from './user-pool-resource-server';

/**
Expand Down Expand Up @@ -272,6 +273,20 @@ export interface UserPoolClientOptions {
* @default Duration.minutes(60)
*/
readonly accessTokenValidity?: Duration;

/**
* The set of attributes this client will be able to read.
* @see https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-attributes.html#user-pool-settings-attribute-permissions-and-scopes
* @default - all standard and custom attributes
*/
readonly readAttributes?: ClientAttributes;

/**
* The set of attributes this client will be able to write.
* @see https://docs.aws.amazon.com/cognito/latest/developerguide/user-pool-settings-attributes.html#user-pool-settings-attribute-permissions-and-scopes
* @default - all standard and custom attributes
*/
readonly writeAttributes?: ClientAttributes;
}

/**
Expand Down Expand Up @@ -358,6 +373,8 @@ export class UserPoolClient extends Resource implements IUserPoolClient {
allowedOAuthFlowsUserPoolClient: !props.disableOAuth,
preventUserExistenceErrors: this.configurePreventUserExistenceErrors(props.preventUserExistenceErrors),
supportedIdentityProviders: this.configureIdentityProviders(props),
readAttributes: props.readAttributes?.attributes(),
writeAttributes: props.writeAttributes?.attributes(),
});
this.configureTokenValidity(resource, props);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@
"PreventUserExistenceErrors": "ENABLED",
"SupportedIdentityProviders": [
"COGNITO"
],
"WriteAttributes": [
"address", "birthdate", "custom:attribute_one", "custom:attribute_two", "email",
"family_name", "gender", "given_name", "locale", "middle_name", "name", "nickname", "phone_number",
"picture", "preferred_username", "profile", "updated_at", "website", "zoneinfo"
]
}
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { App, Stack } from '@aws-cdk/core';
import { OAuthScope, UserPool } from '../lib';
import { OAuthScope, UserPool, ClientAttributes } from '../lib';

const app = new App();
const stack = new Stack(app, 'integ-user-pool-client-explicit-props');
Expand Down Expand Up @@ -30,4 +30,24 @@ userpool.addClient('myuserpoolclient', {
callbackUrls: ['https://redirect-here.myapp.com'],
},
preventUserExistenceErrors: true,
writeAttributes: (new ClientAttributes()).withStandardAttributes(
{
address: true,
birthdate: true,
email: true,
familyName: true,
fullname: true,
gender: true,
givenName: true,
lastUpdateTime: true,
locale: true,
middleName: true,
nickname: true,
phoneNumber: true,
preferredUsername: true,
profilePage: true,
profilePicture: true,
timezone: true,
website: true,
}).withCustomAttributes('attribute_one', 'attribute_two'),
});
Loading

0 comments on commit 8d083ff

Please sign in to comment.