UNPKG

cdk-iam-floyd

Version:

AWS IAM policy statement generator with fluent interface for AWS CDK

207 lines 25 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.PolicyStatementWithPrincipal = exports.PrincipalType = void 0; const _7_arn_defaults_CDK_1 = require("./7-arn-defaults-CDK"); var PrincipalType; (function (PrincipalType) { PrincipalType["aws"] = "AWS"; PrincipalType["federated"] = "Federated"; PrincipalType["canonicalUser"] = "CanonicalUser"; PrincipalType["service"] = "Service"; })(PrincipalType || (exports.PrincipalType = PrincipalType = {})); /** * Adds "principal" functionality to the Policy Statement */ class PolicyStatementWithPrincipal extends _7_arn_defaults_CDK_1.PolicyStatementWithArnDefaultsForCdk { constructor() { super(...arguments); this.useNotPrincipal = false; this.myPrincipals = {}; } /** * Injects principals into the statement. * * Only relevant for the main package. In CDK mode this only calls super. */ toJSON() { // @ts-ignore only available after swapping 1-base if (typeof this.addResources == 'function') { this.cdkApplyPrincipals(); return super.toJSON(); } const mode = this.useNotPrincipal ? 'NotPrincipal' : 'Principal'; const statement = super.toJSON(); if (this.hasPrincipals()) { statement[mode] = this.myPrincipals; } return statement; } toStatementJson() { this.cdkApplyPrincipals(); // @ts-ignore only available after swapping 1-base return super.toStatementJson(); } freeze() { // @ts-ignore only available after swapping 1-base if (!this.frozen) { this.cdkApplyPrincipals(); } return super.freeze(); } cdkApplyPrincipals() { } /** * Switches the statement to use [`notPrincipal`](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_policies_elements_notprincipal.html). */ notPrincipal() { this.useNotPrincipal = true; return this; } /** * Checks weather a principal was applied to the policy */ hasPrincipals() { return Object.keys(this.myPrincipals).length > 0; } /** * Adds a principal to the statement * * @param prefix One of **AWS**, **Federated**, **CanonicalUser** or **Service** * @param principal The principal string */ addPrincipal(prefix, principal) { this.skipAutoResource = true; if (!(prefix in this.myPrincipals)) { this.myPrincipals[prefix] = []; } this.myPrincipals[prefix].push(principal); return this; } /** * Adds any principal to the statement * * @param arn The ARN of the principal * @param prefix One of **AWS**, **Federated**, **CanonicalUser** or **Service** - Default: **AWS** */ for(arn, prefix) { return this.addPrincipal(prefix ?? PrincipalType.aws, arn); } /** * Adds one or more account principals to the statement * * @param accounts ID of the AWS account */ forAccount(...accounts) { accounts.forEach((account) => this.addPrincipal(PrincipalType.aws, `arn:${this.defaultPartition}:iam::${account}:root`)); return this; } /** * Adds one or more [federated](https://aws.amazon.com/identity/federation/) (web identity) principals to the statement * * @param providers ID of the AWS account */ forFederated(...providers) { providers.forEach((provider) => this.addPrincipal(PrincipalType.federated, provider)); return this; } /** * Adds a federated [AWS Cognito](https://docs.aws.amazon.com/IAM/latest/UserGuide/id_roles_providers_oidc_cognito.html) principal to the statement */ forFederatedCognito() { return this.forFederated('cognito-identity.amazonaws.com'); } /** * Adds a federated [Amazon](https://login.amazon.com/) principal to the statement */ forFederatedAmazon() { return this.forFederated('www.amazon.com'); } /** * Adds a federated [Facebook](https://developers.facebook.com/docs/facebook-login) principal to the statement */ forFederatedFacebook() { return this.forFederated('graph.facebook.com'); } /** * Adds a federated [Google](https://developers.google.com/identity/protocols/oauth2/openid-connect) principal to the statement */ forFederatedGoogle() { return this.forFederated('accounts.google.com'); } /** * Adds one or more canonical user principals to the statement * * @param userIDs The user ID * * You can [find the canonical user ID](https://docs.aws.amazon.com/general/latest/gr/acct-identifiers.html#FindingCanonicalId) for your AWS account in the AWS Management Console. The canonical user ID for an AWS account is specific to the account. You can retrieve the canonical user ID for your AWS account as either the root user or an IAM user. */ forCanonicalUser(...userIDs) { userIDs.forEach((userID) => this.addPrincipal(PrincipalType.canonicalUser, userID)); return this; } /** * Adds one or more federated SAML principals to the statement * * @param account ID of the AWS account * @param providerNames Name of the SAML provider */ forSaml(account, ...providerNames) { providerNames.forEach((providerName) => this.forFederated(`arn:${this.defaultPartition}:iam::${account}:saml-provider/${providerName}`)); return this; } /** * Adds one or more IAM user principals to the statement * * @param account ID of the AWS account * @param users Name of the IAM user */ forUser(account, ...users) { users.forEach((user) => this.addPrincipal(PrincipalType.aws, `arn:${this.defaultPartition}:iam::${account}:user/${user}`)); return this; } /** * Adds one or more IAM role principals to the statement * * @param account ID of the AWS account * @param roles Name of the IAM role */ forRole(account, ...roles) { roles.forEach((role) => this.addPrincipal(PrincipalType.aws, `arn:${this.defaultPartition}:iam::${account}:role/${role}`)); return this; } /** * Adds one or more specific assumed role session principals to the statement * * @param account ID of the AWS account * @param roleName Name of the IAM role * @param sessionNames Name of the session. You cannot use a wildcard (`*`) to mean *all sessions*. Principals must always name a specific session */ forAssumedRoleSession(account, roleName, ...sessionNames) { sessionNames.forEach((sessionName) => { this.addPrincipal(PrincipalType.aws, `arn:${this.defaultPartition}:sts::${account}:assumed-role/${roleName}/${sessionName}`); }); return this; } /** * Adds one or more service principals to the statement * * @param services Long version of the service name. Usually in the format: `long_service-name.amazonaws.com` * * The service principal is defined by the service. To learn the service principal for a service, see the documentation for that service. For some services, see [AWS Services That Work with IAM](https://docs.aws.amazon.com/IAM/latest/UserGuide/reference_aws-services-that-work-with-iam.html) and look for the services that have **Yes** in the **Service-Linked Role** column. Choose a **Yes** with a link to view the service-linked role documentation for that service. View the **Service-Linked Role Permissions** section for that service to view the service principal. */ forService(...services) { services.forEach((service) => this.addPrincipal(PrincipalType.service, service)); return this; } /** * Grants public asses * * **EVERYONE IN THE WORLD HAS ACCESS** * * We strongly recommend that you do not use a wildcard in the Principal element in a role's trust policy unless you otherwise restrict access through a Condition element in the policy. Otherwise, any IAM user in any account in your partition can access the role. */ forPublic() { return this.addPrincipal(PrincipalType.aws, '*'); } } exports.PolicyStatementWithPrincipal = PolicyStatementWithPrincipal; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiOC1wcmluY2lwYWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiOC1wcmluY2lwYWxzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLDhEQUE0RTtBQVE1RSxJQUFZLGFBS1g7QUFMRCxXQUFZLGFBQWE7SUFDdkIsNEJBQVcsQ0FBQTtJQUNYLHdDQUF1QixDQUFBO0lBQ3ZCLGdEQUErQixDQUFBO0lBQy9CLG9DQUFtQixDQUFBO0FBQ3JCLENBQUMsRUFMVyxhQUFhLDZCQUFiLGFBQWEsUUFLeEI7QUFFRDs7R0FFRztBQUNILE1BQWEsNEJBQTZCLFNBQVEsMERBQW9DO0lBQXRGOztRQUNZLG9CQUFlLEdBQUcsS0FBSyxDQUFDO1FBQ3hCLGlCQUFZLEdBQWUsRUFBRSxDQUFDO0lBbVAxQyxDQUFDO0lBalBDOzs7O09BSUc7SUFDSSxNQUFNO1FBQ1gsa0RBQWtEO1FBQ2xELElBQUksT0FBTyxJQUFJLENBQUMsWUFBWSxJQUFJLFVBQVUsRUFBRSxDQUFDO1lBQzNDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1lBQzFCLE9BQU8sS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ3hCLENBQUM7UUFFRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQztRQUNqRSxNQUFNLFNBQVMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUM7UUFFakMsSUFBSSxJQUFJLENBQUMsYUFBYSxFQUFFLEVBQUUsQ0FBQztZQUN6QixTQUFTLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQztRQUN0QyxDQUFDO1FBRUQsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUVNLGVBQWU7UUFDcEIsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUM7UUFDMUIsa0RBQWtEO1FBQ2xELE9BQU8sS0FBSyxDQUFDLGVBQWUsRUFBRSxDQUFDO0lBQ2pDLENB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RztJQUVJLFVBQVUsQ0FBQyxHQUFHLFFBQWtCO1FBQ3JDLFFBQVEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUMzQixJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQ2xELENBQUM7UUFDRixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSxTQUFTO1FBQ2QsT0FBTyxJQUFJLENBQUMsWUFBWSxDQUFDLGFBQWEsQ0FBQyxHQUFHLEVBQUUsR0FBRyxDQUFDLENBQUM7SUFDbkQsQ0FBQztDQUNGO0FBclBELG9FQXFQQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFBvbGljeVN0YXRlbWVudFdpdGhBcm5EZWZhdWx0c0ZvckNkayB9IGZyb20gJy4vNy1hcm4tZGVmYXVsdHMtQ0RLJztcbmltcG9ydCB7IGF3c19pYW0gYXMgX2lhbSB9IGZyb20gXCJhd3MtY2RrLWxpYlwiO1xuXG4vKipcbiAqIEEgY29sbGVjdGlvbiBvZiBQcmluY2lwYWwnc1xuICovXG5leHBvcnQgdHlwZSBQcmluY2lwYWxzID0gUGFydGlhbDxSZWNvcmQ8UHJpbmNpcGFsVHlwZSwgc3RyaW5nW10+PjtcblxuZXhwb3J0IGVudW0gUHJpbmNpcGFsVHlwZSB7XG4gIGF3cyA9ICdBV1MnLFxuICBmZWRlcmF0ZWQgPSAnRmVkZXJhdGVkJyxcbiAgY2Fub25pY2FsVXNlciA9ICdDYW5vbmljYWxVc2VyJyxcbiAgc2VydmljZSA9ICdTZXJ2aWNlJyxcbn1cblxuLyoqXG4gKiBBZGRzIFwicHJpbmNpcGFsXCIgZnVuY3Rpb25hbGl0eSB0byB0aGUgUG9saWN5IFN0YXRlbWVudFxuICovXG5leHBvcnQgY2xhc3MgUG9saWN5U3RhdGVtZW50V2l0aFByaW5jaXBhbCBleHRlbmRzIFBvbGljeVN0YXRlbWVudFdpdGhBcm5EZWZhdWx0c0ZvckNkayB7XG4gIHByb3RlY3RlZCB1c2VOb3RQcmluY2lwYWwgPSBmYWxzZTtcbiAgcHJvdGVjdGVkIG15UHJpbmNpcGFsczogUHJpbmNpcGFscyA9IHt9O1xuXG4gIC8qKlxuICAgKiBJbmplY3RzIHByaW5jaXBhbHMgaW50byB0aGUgc3RhdGVtZW50LlxuICAgKlxuICAgKiBPbmx5IHJlbGV2YW50IGZvciB0aGUgbWFpbiBwYWNrYWdlLiBJbiBDREsgbW9kZSB0aGlzIG9ubHkgY2FsbHMgc3VwZXIuXG4gICAqL1xuICBwdWJsaWMgdG9KU09OKCk6IGFueSB7XG4gICAgLy8gQHRzLWlnbm9yZSBvbmx5IGF2YWlsYWJsZSBhZnRlciBzd2FwcGluZyAxLWJhc2VcbiAgICBpZiAodHlwZW9mIHRoaXMuYWRkUmVzb3VyY2VzID09ICdmdW5jdGlvbicpIHtcbiAgICAgIHRoaXMuY2RrQXBwbHlQcmluY2lwYWxzKCk7XG4gICAgICByZXR1cm4gc3VwZXIudG9KU09OKCk7XG4gICAgfVxuXG4gICAgY29uc3QgbW9kZSA9IHRoaXMudXNlTm90UHJpbmNpcGFsID8gJ05vdFByaW5jaXBhbCcgOiAnUHJpbmNpcGFsJztcbiAgICBjb25zdCBzdGF0ZW1lbnQgPSBzdXBlci50b0pTT04oKTtcblxuICAgIGlmICh0aGlzLmhhc1ByaW5jaXBhbHMoKSkge1xuICAgICAgc3RhdGVtZW50W21vZGVdID0gdGhpcy5teVByaW5jaXBhbHM7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN0YXRlbWVudDtcbiAgfVxuXG4gIHB1YmxpYyB0b1N0YXRlbWVudEpzb24oKTogYW55IHtcbiAgICB0aGlzLmNka0FwcGx5UHJpbmNpcGFscygpO1xuICAgIC8vIEB0cy1pZ25vcmUgb25seSBhdmFpbGFibGUgYWZ0ZXIgc3dhcHBpbmcgMS1iYXNlXG4gICAgcmV0dXJuIHN1cGVyLnRvU3RhdGVtZW50SnNvbigpO1xuICB9XG5cbiAgcHVibGljIGZyZWV6ZSgpIHtcbiAgICAvLyBAdHMtaWdub3JlIG9ubHkgYXZhaWxhYmxlIGFmdGVyIHN3YXBwaW5nIDEtYmFzZVxuICAgIGlmICghdGhpcy5mcm96ZW4pIHtcbiAgICAgIHRoaXMuY2RrQXBwbHlQcmluY2lwYWxzKCk7XG4gICAgfVxuICAgIHJldHVybiBzdXBlci5mcmVlemUoKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBjZGtBcHBseVByaW5jaXBhbHMoKSB7fVxuXG4gIC8qKlxuICAgKiBTd2l0Y2hlcyB0aGUgc3RhdGVtZW50IHRvIHVzZSBbYG5vdFByaW5jaXBhbGBdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9yZWZlcmVuY2VfcG9saWNpZXNfZWxlbWVudHNfbm90cHJpbmNpcGFsLmh0bWwpLlxuICAgKi9cbiAgcHVibGljIG5vdFByaW5jaXBhbCgpIHtcbiAgICB0aGlzLnVzZU5vdFByaW5jaXBhbCA9IHRydWU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIHdlYXRoZXIgYSBwcmluY2lwYWwgd2FzIGFwcGxpZWQgdG8gdGhlIHBvbGljeVxuICAgKi9cbiAgcHVibGljIGhhc1ByaW5jaXBhbHMoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKHRoaXMubXlQcmluY2lwYWxzKS5sZW5ndGggPiAwO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBwcmluY2lwYWwgdG8gdGhlIHN0YXRlbWVudFxuICAgKlxuICAgKiBAcGFyYW0gcHJlZml4IE9uZSBvZiAqKkFXUyoqLCAqKkZlZGVyYXRlZCoqLCAqKkNhbm9uaWNhbFVzZXIqKiBvciAqKlNlcnZpY2UqKlxuICAgKiBAcGFyYW0gcHJpbmNpcGFsIFRoZSBwcmluY2lwYWwgc3RyaW5nXG4gICAqL1xuICBwcm90ZWN0ZWQgYWRkUHJpbmNpcGFsKHByZWZpeDogUHJpbmNpcGFsVHlwZSwgcHJpbmNpcGFsOiBzdHJpbmcpIHtcbiAgICB0aGlzLnNraXBBdXRvUmVzb3VyY2UgPSB0cnVlO1xuICAgIGlmICghKHByZWZpeCBpbiB0aGlzLm15UHJpbmNpcGFscykpIHtcbiAgICAgIHRoaXMubXlQcmluY2lwYWxzW3ByZWZpeF0gPSBbXTtcbiAgICB9XG4gICAgdGhpcy5teVByaW5jaXBhbHNbcHJlZml4XSEucHVzaChwcmluY2lwYWwpO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYW55IHByaW5jaXBhbCB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIEBwYXJhbSBhcm4gVGhlIEFSTiBvZiB0aGUgcHJpbmNpcGFsXG4gICAqIEBwYXJhbSBwcmVmaXggT25lIG9mICoqQVdTKiosICoqRmVkZXJhdGVkKiosICoqQ2Fub25pY2FsVXNlcioqIG9yICoqU2VydmljZSoqIC0gRGVmYXVsdDogKipBV1MqKlxuICAgKi9cbiAgcHVibGljIGZvcihhcm46IHN0cmluZywgcHJlZml4PzogUHJpbmNpcGFsVHlwZSkge1xuICAgIHJldHVybiB0aGlzLmFkZFByaW5jaXBhbChwcmVmaXggPz8gUHJpbmNpcGFsVHlwZS5hd3MsIGFybik7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBvbmUgb3IgbW9yZSBhY2NvdW50IHByaW5jaXBhbHMgdG8gdGhlIHN0YXRlbWVudFxuICAgKlxuICAgKiBAcGFyYW0gYWNjb3VudHMgSUQgb2YgdGhlIEFXUyBhY2NvdW50XG4gICAqL1xuICBwdWJsaWMgZm9yQWNjb3VudCguLi5hY2NvdW50czogc3RyaW5nW10pIHtcbiAgICBhY2NvdW50cy5mb3JFYWNoKChhY2NvdW50KSA9PlxuICAgICAgdGhpcy5hZGRQcmluY2lwYWwoXG4gICAgICAgIFByaW5jaXBhbFR5cGUuYXdzLFxuICAgICAgICBgYXJuOiR7IHRoaXMuZGVmYXVsdFBhcnRpdGlvbiB9OmlhbTo6JHsgYWNjb3VudCB9OnJvb3RgLFxuICAgICAgKSxcbiAgICApO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgb25lIG9yIG1vcmUgW2ZlZGVyYXRlZF0oaHR0cHM6Ly9hd3MuYW1hem9uLmNvbS9pZGVudGl0eS9mZWRlcmF0aW9uLykgKHdlYiBpZGVudGl0eSkgcHJpbmNpcGFscyB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIEBwYXJhbSBwcm92aWRlcnMgSUQgb2YgdGhlIEFXUyBhY2NvdW50XG4gICAqL1xuICBwdWJsaWMgZm9yRmVkZXJhdGVkKC4uLnByb3ZpZGVyczogc3RyaW5nW10pIHtcbiAgICBwcm92aWRlcnMuZm9yRWFjaCgocHJvdmlkZXIpID0+XG4gICAgICB0aGlzLmFkZFByaW5jaXBhbChQcmluY2lwYWxUeXBlLmZlZGVyYXRlZCwgcHJvdmlkZXIpLFxuICAgICk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIGZlZGVyYXRlZCBbQVdTIENvZ25pdG9dKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9JQU0vbGF0ZXN0L1VzZXJHdWlkZS9pZF9yb2xlc19wcm92aWRlcnNfb2lkY19jb2duaXRvLmh0bWwpIHByaW5jaXBhbCB0byB0aGUgc3RhdGVtZW50XG4gICAqL1xuICBwdWJsaWMgZm9yRmVkZXJhdGVkQ29nbml0bygpIHtcbiAgICByZXR1cm4gdGhpcy5mb3JGZWRlcmF0ZWQoJ2NvZ25pdG8taWRlbnRpdHkuYW1hem9uYXdzLmNvbScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBmZWRlcmF0ZWQgW0FtYXpvbl0oaHR0cHM6Ly9sb2dpbi5hbWF6b24uY29tLykgcHJpbmNpcGFsIHRvIHRoZSBzdGF0ZW1lbnRcbiAgICovXG4gIHB1YmxpYyBmb3JGZWRlcmF0ZWRBbWF6b24oKSB7XG4gICAgcmV0dXJuIHRoaXMuZm9yRmVkZXJhdGVkKCd3d3cuYW1hem9uLmNvbScpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgYSBmZWRlcmF0ZWQgW0ZhY2Vib29rXShodHRwczovL2RldmVsb3BlcnMuZmFjZWJvb2suY29tL2RvY3MvZmFjZWJvb2stbG9naW4pIHByaW5jaXBhbCB0byB0aGUgc3RhdGVtZW50XG4gICAqL1xuICBwdWJsaWMgZm9yRmVkZXJhdGVkRmFjZWJvb2soKSB7XG4gICAgcmV0dXJuIHRoaXMuZm9yRmVkZXJhdGVkKCdncmFwaC5mYWNlYm9vay5jb20nKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgZmVkZXJhdGVkIFtHb29nbGVdKGh0dHBzOi8vZGV2ZWxvcGVycy5nb29nbGUuY29tL2lkZW50aXR5L3Byb3RvY29scy9vYXV0aDIvb3BlbmlkLWNvbm5lY3QpIHByaW5jaXBhbCB0byB0aGUgc3RhdGVtZW50XG4gICAqL1xuXG4gIHB1YmxpYyBmb3JGZWRlcmF0ZWRHb29nbGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuZm9yRmVkZXJhdGVkKCdhY2NvdW50cy5nb29nbGUuY29tJyk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBvbmUgb3IgbW9yZSBjYW5vbmljYWwgdXNlciBwcmluY2lwYWxzIHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogQHBhcmFtIHVzZXJJRHMgVGhlIHVzZXIgSURcbiAgICpcbiAgICogWW91IGNhbiBbZmluZCB0aGUgY2Fub25pY2FsIHVzZXIgSURdKGh0dHBzOi8vZG9jcy5hd3MuYW1hem9uLmNvbS9nZW5lcmFsL2xhdGVzdC9nci9hY2N0LWlkZW50aWZpZXJzLmh0bWwjRmluZGluZ0Nhbm9uaWNhbElkKSBmb3IgeW91ciBBV1MgYWNjb3VudCBpbiB0aGUgQVdTIE1hbmFnZW1lbnQgQ29uc29sZS4gVGhlIGNhbm9uaWNhbCB1c2VyIElEIGZvciBhbiBBV1MgYWNjb3VudCBpcyBzcGVjaWZpYyB0byB0aGUgYWNjb3VudC4gWW91IGNhbiByZXRyaWV2ZSB0aGUgY2Fub25pY2FsIHVzZXIgSUQgZm9yIHlvdXIgQVdTIGFjY291bnQgYXMgZWl0aGVyIHRoZSByb290IHVzZXIgb3IgYW4gSUFNIHVzZXIuXG4gICAqL1xuICBwdWJsaWMgZm9yQ2Fub25pY2FsVXNlciguLi51c2VySURzOiBzdHJpbmdbXSkge1xuICAgIHVzZXJJRHMuZm9yRWFjaCgodXNlcklEKSA9PlxuICAgICAgdGhpcy5hZGRQcmluY2lwYWwoUHJpbmNpcGFsVHlwZS5jYW5vbmljYWxVc2VyLCB1c2VySUQpLFxuICAgICk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBvbmUgb3IgbW9yZSBmZWRlcmF0ZWQgU0FNTCBwcmluY2lwYWxzIHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogQHBhcmFtIGFjY291bnQgSUQgb2YgdGhlIEFXUyBhY2NvdW50XG4gICAqIEBwYXJhbSBwcm92aWRlck5hbWVzIE5hbWUgb2YgdGhlIFNBTUwgcHJvdmlkZXJcbiAgICovXG4gIHB1YmxpYyBmb3JTYW1sKGFjY291bnQ6IHN0cmluZywgLi4ucHJvdmlkZXJOYW1lczogc3RyaW5nW10pIHtcbiAgICBwcm92aWRlck5hbWVzLmZvckVhY2goKHByb3ZpZGVyTmFtZSkgPT5cbiAgICAgIHRoaXMuZm9yRmVkZXJhdGVkKFxuICAgICAgICBgYXJuOiR7IHRoaXMuZGVmYXVsdFBhcnRpdGlvbiB9OmlhbTo6JHsgYWNjb3VudCB9OnNhbWwtcHJvdmlkZXIvJHsgcHJvdmlkZXJOYW1lIH1gLFxuICAgICAgKSxcbiAgICApO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgb25lIG9yIG1vcmUgSUFNIHVzZXIgcHJpbmNpcGFscyB0byB0aGUgc3RhdGVtZW50XG4gICAqXG4gICAqIEBwYXJhbSBhY2NvdW50IElEIG9mIHRoZSBBV1MgYWNjb3VudFxuICAgKiBAcGFyYW0gdXNlcnMgTmFtZSBvZiB0aGUgSUFNIHVzZXJcbiAgICovXG4gIHB1YmxpYyBmb3JVc2VyKGFjY291bnQ6IHN0cmluZywgLi4udXNlcnM6IHN0cmluZ1tdKSB7XG4gICAgdXNlcnMuZm9yRWFjaCgodXNlcikgPT5cbiAgICAgIHRoaXMuYWRkUHJpbmNpcGFsKFxuICAgICAgICBQcmluY2lwYWxUeXBlLmF3cyxcbiAgICAgICAgYGFybjokeyB0aGlzLmRlZmF1bHRQYXJ0aXRpb24gfTppYW06OiR7IGFjY291bnQgfTp1c2VyLyR7IHVzZXIgfWAsXG4gICAgICApLFxuICAgICk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBvbmUgb3IgbW9yZSBJQU0gcm9sZSBwcmluY2lwYWxzIHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogQHBhcmFtIGFjY291bnQgSUQgb2YgdGhlIEFXUyBhY2NvdW50XG4gICAqIEBwYXJhbSByb2xlcyBOYW1lIG9mIHRoZSBJQU0gcm9sZVxuICAgKi9cbiAgcHVibGljIGZvclJvbGUoYWNjb3VudDogc3RyaW5nLCAuLi5yb2xlczogc3RyaW5nW10pIHtcbiAgICByb2xlcy5mb3JFYWNoKChyb2xlKSA9PlxuICAgICAgdGhpcy5hZGRQcmluY2lwYWwoXG4gICAgICAgIFByaW5jaXBhbFR5cGUuYXdzLFxuICAgICAgICBgYXJuOiR7IHRoaXMuZGVmYXVsdFBhcnRpdGlvbiB9OmlhbTo6JHsgYWNjb3VudCB9OnJvbGUvJHsgcm9sZSB9YCxcbiAgICAgICksXG4gICAgKTtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIG9uZSBvciBtb3JlIHNwZWNpZmljIGFzc3VtZWQgcm9sZSBzZXNzaW9uIHByaW5jaXBhbHMgdG8gdGhlIHN0YXRlbWVudFxuICAgKlxuICAgKiBAcGFyYW0gYWNjb3VudCBJRCBvZiB0aGUgQVdTIGFjY291bnRcbiAgICogQHBhcmFtIHJvbGVOYW1lIE5hbWUgb2YgdGhlIElBTSByb2xlXG4gICAqIEBwYXJhbSBzZXNzaW9uTmFtZXMgTmFtZSBvZiB0aGUgc2Vzc2lvbi4gWW91IGNhbm5vdCB1c2UgYSB3aWxkY2FyZCAoYCpgKSB0byBtZWFuICphbGwgc2Vzc2lvbnMqLiBQcmluY2lwYWxzIG11c3QgYWx3YXlzIG5hbWUgYSBzcGVjaWZpYyBzZXNzaW9uXG4gICAqL1xuICBwdWJsaWMgZm9yQXNzdW1lZFJvbGVTZXNzaW9uKFxuICAgIGFjY291bnQ6IHN0cmluZyxcbiAgICByb2xlTmFtZTogc3RyaW5nLFxuICAgIC4uLnNlc3Npb25OYW1lczogc3RyaW5nW11cbiAgKSB7XG4gICAgc2Vzc2lvbk5hbWVzLmZvckVhY2goKHNlc3Npb25OYW1lKSA9PiB7XG4gICAgICB0aGlzLmFkZFByaW5jaXBhbChcbiAgICAgICAgUHJpbmNpcGFsVHlwZS5hd3MsXG4gICAgICAgIGBhcm46JHsgdGhpcy5kZWZhdWx0UGFydGl0aW9uIH06c3RzOjokeyBhY2NvdW50IH06YXNzdW1lZC1yb2xlLyR7IHJvbGVOYW1lIH0vJHsgc2Vzc2lvbk5hbWUgfWAsXG4gICAgICApO1xuICAgIH0pO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIEFkZHMgb25lIG9yIG1vcmUgc2VydmljZSBwcmluY2lwYWxzIHRvIHRoZSBzdGF0ZW1lbnRcbiAgICpcbiAgICogQHBhcmFtIHNlcnZpY2VzIExvbmcgdmVyc2lvbiBvZiB0aGUgc2VydmljZSBuYW1lLiBVc3VhbGx5IGluIHRoZSBmb3JtYXQ6IGBsb25nX3NlcnZpY2UtbmFtZS5hbWF6b25hd3MuY29tYFxuICAgKlxuICAgKiBUaGUgc2VydmljZSBwcmluY2lwYWwgaXMgZGVmaW5lZCBieSB0aGUgc2VydmljZS4gVG8gbGVhcm4gdGhlIHNlcnZpY2UgcHJpbmNpcGFsIGZvciBhIHNlcnZpY2UsIHNlZSB0aGUgZG9jdW1lbnRhdGlvbiBmb3IgdGhhdCBzZXJ2aWNlLiBGb3Igc29tZSBzZXJ2aWNlcywgc2VlIFtBV1MgU2VydmljZXMgVGhhdCBXb3JrIHdpdGggSUFNXShodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcmVmZXJlbmNlX2F3cy1zZXJ2aWNlcy10aGF0LXdvcmstd2l0aC1pYW0uaHRtbCkgYW5kIGxvb2sgZm9yIHRoZSBzZXJ2aWNlcyB0aGF0IGhhdmUgKipZZXMqKiBpbiB0aGUgKipTZXJ2aWNlLUxpbmtlZCBSb2xlKiogY29sdW1uLiBDaG9vc2UgYSAqKlllcyoqIHdpdGggYSBsaW5rIHRvIHZpZXcgdGhlIHNlcnZpY2UtbGlua2VkIHJvbGUgZG9jdW1lbnRhdGlvbiBmb3IgdGhhdCBzZXJ2aWNlLiBWaWV3IHRoZSAqKlNlcnZpY2UtTGlua2VkIFJvbGUgUGVybWlzc2lvbnMqKiBzZWN0aW9uIGZvciB0aGF0IHNlcnZpY2UgdG8gdmlldyB0aGUgc2VydmljZSBwcmluY2lwYWwuXG4gICAqL1xuXG4gIHB1YmxpYyBmb3JTZXJ2aWNlKC4uLnNlcnZpY2VzOiBzdHJpbmdbXSkge1xuICAgIHNlcnZpY2VzLmZvckVhY2goKHNlcnZpY2UpID0+XG4gICAgICB0aGlzLmFkZFByaW5jaXBhbChQcmluY2lwYWxUeXBlLnNlcnZpY2UsIHNlcnZpY2UpLFxuICAgICk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogR3JhbnRzIHB1YmxpYyBhc3Nlc1xuICAgKlxuICAgKiAqKkVWRVJZT05FIElOIFRIRSBXT1JMRCBIQVMgQUNDRVNTKipcbiAgICpcbiAgICogV2Ugc3Ryb25nbHkgcmVjb21tZW5kIHRoYXQgeW91IGRvIG5vdCB1c2UgYSB3aWxkY2FyZCBpbiB0aGUgUHJpbmNpcGFsIGVsZW1lbnQgaW4gYSByb2xlJ3MgdHJ1c3QgcG9saWN5IHVubGVzcyB5b3Ugb3RoZXJ3aXNlIHJlc3RyaWN0IGFjY2VzcyB0aHJvdWdoIGEgQ29uZGl0aW9uIGVsZW1lbnQgaW4gdGhlIHBvbGljeS4gT3RoZXJ3aXNlLCBhbnkgSUFNIHVzZXIgaW4gYW55IGFjY291bnQgaW4geW91ciBwYXJ0aXRpb24gY2FuIGFjY2VzcyB0aGUgcm9sZS5cbiAgICovXG4gIHB1YmxpYyBmb3JQdWJsaWMoKSB7XG4gICAgcmV0dXJuIHRoaXMuYWRkUHJpbmNpcGFsKFByaW5jaXBhbFR5cGUuYXdzLCAnKicpO1xuICB9XG59XG4iXX0=