UNPKG

23.7 kBJavaScriptView Raw
1"use strict";
2var _a;
3Object.defineProperty(exports, "__esModule", { value: true });
4exports.Policy = void 0;
5const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
6const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
7const core_1 = require("@aws-cdk/core");
8const iam_generated_1 = require("./iam.generated");
9const policy_document_1 = require("./policy-document");
10const util_1 = require("./util");
11/**
12 * The AWS::IAM::Policy resource associates an IAM policy with IAM users, roles,
13 * or groups. For more information about IAM policies, see [Overview of IAM
14 * Policies](http://docs.aws.amazon.com/IAM/latest/UserGuide/policies_overview.html)
15 * in the IAM User Guide guide.
16 */
17class Policy extends core_1.Resource {
18 constructor(scope, id, props = {}) {
19 super(scope, id, {
20 physicalName: props.policyName ||
21 // generatePolicyName will take the last 128 characters of the logical id since
22 // policy names are limited to 128. the last 8 chars are a stack-unique hash, so
23 // that shouod be sufficient to ensure uniqueness within a principal.
24 core_1.Lazy.string({ produce: () => util_1.generatePolicyName(scope, resource.logicalId) }),
25 });
26 /**
27 * The policy document.
28 */
29 this.document = new policy_document_1.PolicyDocument();
30 this.roles = new Array();
31 this.users = new Array();
32 this.groups = new Array();
33 this.referenceTaken = false;
34 try {
35 jsiiDeprecationWarnings._aws_cdk_aws_iam_PolicyProps(props);
36 }
37 catch (error) {
38 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
39 Error.captureStackTrace(error, Policy);
40 }
41 throw error;
42 }
43 const self = this;
44 class CfnPolicyConditional extends iam_generated_1.CfnPolicy {
45 /**
46 * This function returns `true` if the CFN resource should be included in
47 * the cloudformation template unless `force` is `true`, if the policy
48 * document is empty, the resource will not be included.
49 */
50 shouldSynthesize() {
51 return self.force || self.referenceTaken || (!self.document.isEmpty && self.isAttached);
52 }
53 }
54 if (props.document) {
55 this.document = props.document;
56 }
57 const resource = new CfnPolicyConditional(this, 'Resource', {
58 policyDocument: this.document,
59 policyName: this.physicalName,
60 roles: util_1.undefinedIfEmpty(() => this.roles.map(r => r.roleName)),
61 users: util_1.undefinedIfEmpty(() => this.users.map(u => u.userName)),
62 groups: util_1.undefinedIfEmpty(() => this.groups.map(g => g.groupName)),
63 });
64 this._policyName = this.physicalName;
65 this.force = props.force ?? false;
66 if (props.users) {
67 props.users.forEach(u => this.attachToUser(u));
68 }
69 if (props.groups) {
70 props.groups.forEach(g => this.attachToGroup(g));
71 }
72 if (props.roles) {
73 props.roles.forEach(r => this.attachToRole(r));
74 }
75 if (props.statements) {
76 props.statements.forEach(p => this.addStatements(p));
77 }
78 }
79 /**
80 * Import a policy in this app based on its name
81 */
82 static fromPolicyName(scope, id, policyName) {
83 class Import extends core_1.Resource {
84 constructor() {
85 super(...arguments);
86 this.policyName = policyName;
87 }
88 }
89 return new Import(scope, id);
90 }
91 /**
92 * Adds a statement to the policy document.
93 */
94 addStatements(...statement) {
95 try {
96 jsiiDeprecationWarnings._aws_cdk_aws_iam_PolicyStatement(statement);
97 }
98 catch (error) {
99 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
100 Error.captureStackTrace(error, this.addStatements);
101 }
102 throw error;
103 }
104 this.document.addStatements(...statement);
105 }
106 /**
107 * Attaches this policy to a user.
108 */
109 attachToUser(user) {
110 try {
111 jsiiDeprecationWarnings._aws_cdk_aws_iam_IUser(user);
112 }
113 catch (error) {
114 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
115 Error.captureStackTrace(error, this.attachToUser);
116 }
117 throw error;
118 }
119 if (this.users.find(u => u === user)) {
120 return;
121 }
122 this.users.push(user);
123 user.attachInlinePolicy(this);
124 }
125 /**
126 * Attaches this policy to a role.
127 */
128 attachToRole(role) {
129 try {
130 jsiiDeprecationWarnings._aws_cdk_aws_iam_IRole(role);
131 }
132 catch (error) {
133 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
134 Error.captureStackTrace(error, this.attachToRole);
135 }
136 throw error;
137 }
138 if (this.roles.find(r => r === role)) {
139 return;
140 }
141 this.roles.push(role);
142 role.attachInlinePolicy(this);
143 }
144 /**
145 * Attaches this policy to a group.
146 */
147 attachToGroup(group) {
148 try {
149 jsiiDeprecationWarnings._aws_cdk_aws_iam_IGroup(group);
150 }
151 catch (error) {
152 if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
153 Error.captureStackTrace(error, this.attachToGroup);
154 }
155 throw error;
156 }
157 if (this.groups.find(g => g === group)) {
158 return;
159 }
160 this.groups.push(group);
161 group.attachInlinePolicy(this);
162 }
163 /**
164 * The name of this policy.
165 *
166 * @attribute
167 */
168 get policyName() {
169 this.referenceTaken = true;
170 return this._policyName;
171 }
172 validate() {
173 const result = new Array();
174 // validate that the policy document is not empty
175 if (this.document.isEmpty) {
176 if (this.force) {
177 result.push('Policy created with force=true is empty. You must add statements to the policy');
178 }
179 if (!this.force && this.referenceTaken) {
180 result.push('This Policy has been referenced by a resource, so it must contain at least one statement.');
181 }
182 }
183 // validate that the policy is attached to at least one principal (role, user or group).
184 if (!this.isAttached) {
185 if (this.force) {
186 result.push('Policy created with force=true must be attached to at least one principal: user, group or role');
187 }
188 if (!this.force && this.referenceTaken) {
189 result.push('This Policy has been referenced by a resource, so it must be attached to at least one user, group or role.');
190 }
191 }
192 result.push(...this.document.validateForIdentityPolicy());
193 return result;
194 }
195 /**
196 * Whether the policy resource has been attached to any identity
197 */
198 get isAttached() {
199 return this.groups.length + this.users.length + this.roles.length > 0;
200 }
201}
202exports.Policy = Policy;
203_a = JSII_RTTI_SYMBOL_1;
204Policy[_a] = { fqn: "@aws-cdk/aws-iam.Policy", version: "1.161.0" };
205//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9saWN5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicG9saWN5LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7OztBQUFBLHdDQUEwRDtBQUcxRCxtREFBNEM7QUFDNUMsdURBQW1EO0FBSW5ELGlDQUE4RDtBQXdGOUQ7Ozs7O0dBS0c7QUFDSCxNQUFhLE1BQU8sU0FBUSxlQUFRO0lBeUJsQyxZQUFZLEtBQWdCLEVBQUUsRUFBVSxFQUFFLFFBQXFCLEVBQUU7UUFDL0QsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLEVBQUU7WUFDZixZQUFZLEVBQUUsS0FBSyxDQUFDLFVBQVU7Z0JBQzVCLCtFQUErRTtnQkFDL0UsZ0ZBQWdGO2dCQUNoRixxRUFBcUU7Z0JBQ3JFLFdBQUksQ0FBQyxNQUFNLENBQUMsRUFBRSxPQUFPLEVBQUUsR0FBRyxFQUFFLENBQUMseUJBQWtCLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDO1NBQ2hGLENBQUMsQ0FBQztRQW5CTDs7V0FFRztRQUNhLGFBQVEsR0FBRyxJQUFJLGdDQUFjLEVBQUUsQ0FBQztRQUcvQixVQUFLLEdBQUcsSUFBSSxLQUFLLEVBQVMsQ0FBQztRQUMzQixVQUFLLEdBQUcsSUFBSSxLQUFLLEVBQVMsQ0FBQztRQUMzQixXQUFNLEdBQUcsSUFBSSxLQUFLLEVBQVUsQ0FBQztRQUV0QyxtQkFBYyxHQUFHLEtBQUssQ0FBQzs7Ozs7OytDQXZCcEIsTUFBTTs7OztRQWtDZixNQUFNLElBQUksR0FBRyxJQUFJLENBQUM7UUFFbEIsTUFBTSxvQkFBcUIsU0FBUSx5QkFBUztZQUMxQzs7OztlQUlHO1lBQ08sZ0JBQWdCO2dCQUN4QixPQUFPLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLGNBQWMsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1lBQzFGLENBQUM7U0FDRjtRQUVELElB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Z0JBQ2QsTUFBTSxDQUFDLElBQUksQ0FBQyxnR0FBZ0csQ0FBQyxDQUFDO2FBQy9HO1lBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLGNBQWMsRUFBRTtnQkFDdEMsTUFBTSxDQUFDLElBQUksQ0FBQyw0R0FBNEcsQ0FBQyxDQUFDO2FBQzNIO1NBQ0Y7UUFFRCxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyx5QkFBeUIsRUFBRSxDQUFDLENBQUM7UUFFMUQsT0FBTyxNQUFNLENBQUM7S0FDZjtJQUVEOztPQUVHO0lBQ0gsSUFBWSxVQUFVO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0tBQ3ZFOztBQTVKSCx3QkE2SkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJUmVzb3VyY2UsIExhenksIFJlc291cmNlIH0gZnJvbSAnQGF3cy1jZGsvY29yZSc7XG5pbXBvcnQgeyBDb25zdHJ1Y3QgfSBmcm9tICdjb25zdHJ1Y3RzJztcbmltcG9ydCB7IElHcm91cCB9IGZyb20gJy4vZ3JvdXAnO1xuaW1wb3J0IHsgQ2ZuUG9saWN5IH0gZnJvbSAnLi9pYW0uZ2VuZXJhdGVkJztcbmltcG9ydCB7IFBvbGljeURvY3VtZW50IH0gZnJvbSAnLi9wb2xpY3ktZG9jdW1lbnQnO1xuaW1wb3J0IHsgUG9saWN5U3RhdGVtZW50IH0gZnJvbSAnLi9wb2xpY3ktc3RhdGVtZW50JztcbmltcG9ydCB7IElSb2xlIH0gZnJvbSAnLi9yb2xlJztcbmltcG9ydCB7IElVc2VyIH0gZnJvbSAnLi91c2VyJztcbmltcG9ydCB7IGdlbmVyYXRlUG9saWN5TmFtZSwgdW5kZWZpbmVkSWZFbXB0eSB9IGZyb20gJy4vdXRpbCc7XG5cbi8qKlxuICogUmVwcmVzZW50cyBhbiBJQU0gUG9saWN5XG4gKlxuICogQHNlZSBodHRwczovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvYWNjZXNzX3BvbGljaWVzX21hbmFnZS5odG1sXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgSVBvbGljeSBleHRlbmRzIElSZXNvdXJjZSB7XG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGlzIHBvbGljeS5cbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcmVhZG9ubHkgcG9saWN5TmFtZTogc3RyaW5nO1xufVxuXG4vKipcbiAqIFByb3BlcnRpZXMgZm9yIGRlZmluaW5nIGFuIElBTSBpbmxpbmUgcG9saWN5IGRvY3VtZW50XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUG9saWN5UHJvcHMge1xuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIHBvbGljeS4gSWYgeW91IHNwZWNpZnkgbXVsdGlwbGUgcG9saWNpZXMgZm9yIGFuIGVudGl0eSxcbiAgICogc3BlY2lmeSB1bmlxdWUgbmFtZXMuIEZvciBleGFtcGxlLCBpZiB5b3Ugc3BlY2lmeSBhIGxpc3Qgb2YgcG9saWNpZXMgZm9yXG4gICAqIGFuIElBTSByb2xlLCBlYWNoIHBvbGljeSBtdXN0IGhhdmUgYSB1bmlxdWUgbmFtZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBVc2VzIHRoZSBsb2dpY2FsIElEIG9mIHRoZSBwb2xpY3kgcmVzb3VyY2UsIHdoaWNoIGlzIGVuc3VyZWRcbiAgICogdG8gYmUgdW5pcXVlIHdpdGhpbiB0aGUgc3RhY2suXG4gICAqL1xuICByZWFkb25seSBwb2xpY3lOYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBVc2VycyB0byBhdHRhY2ggdGhpcyBwb2xpY3kgdG8uXG4gICAqIFlvdSBjYW4gYWxzbyB1c2UgYGF0dGFjaFRvVXNlcih1c2VyKWAgdG8gYXR0YWNoIHRoaXMgcG9saWN5IHRvIGEgdXNlci5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyB1c2Vycy5cbiAgICovXG4gIHJlYWRvbmx5IHVzZXJzPzogSVVzZXJbXTtcblxuICAvKipcbiAgICogUm9sZXMgdG8gYXR0YWNoIHRoaXMgcG9saWN5IHRvLlxuICAgKiBZb3UgY2FuIGFsc28gdXNlIGBhdHRhY2hUb1JvbGUocm9sZSlgIHRvIGF0dGFjaCB0aGlzIHBvbGljeSB0byBhIHJvbGUuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gcm9sZXMuXG4gICAqL1xuICByZWFkb25seSByb2xlcz86IElSb2xlW107XG5cbiAgLyoqXG4gICAqIEdyb3VwcyB0byBhdHRhY2ggdGhpcyBwb2xpY3kgdG8uXG4gICAqIFlvdSBjYW4gYWxzbyB1c2UgYGF0dGFjaFRvR3JvdXAoZ3JvdXApYCB0byBhdHRhY2ggdGhpcyBwb2xpY3kgdG8gYSBncm91cC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBncm91cHMuXG4gICAqL1xuICByZWFkb25seSBncm91cHM/OiBJR3JvdXBbXTtcblxuICAvKipcbiAgICogSW5pdGlhbCBzZXQgb2YgcGVybWlzc2lvbnMgdG8gYWRkIHRvIHRoaXMgcG9saWN5IGRvY3VtZW50LlxuICAgKiBZb3UgY2FuIGFsc28gdXNlIGBhZGRTdGF0ZW1lbnRzKC4uLnN0YXRlbWVudClgIHRvIGFkZCBwZXJtaXNzaW9ucyBsYXRlci5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBzdGF0ZW1lbnRzLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RhdGVtZW50cz86IFBvbGljeVN0YXRlbWVudFtdO1xuXG4gIC8qKlxuICAgKiBGb3JjZSBjcmVhdGlvbiBvZiBhbiBgQVdTOjpJQU06OlBvbGljeWBcbiAgICpcbiAgICogVW5sZXNzIHNldCB0byBgdHJ1ZWAsIHRoaXMgYFBvbGljeWAgY29uc3RydWN0IHdpbGwgbm90IG1hdGVyaWFsaXplIHRvIGFuXG4gICAqIGBBV1M6OklBTTo6UG9saWN5YCBDbG91ZEZvcm1hdGlvbiByZXNvdXJjZSBpbiBjYXNlIGl0IHdvdWxkIGhhdmUgbm8gZWZmZWN0XG4gICAqIChmb3IgZXhhbXBsZSwgaWYgaXQgcmVtYWlucyB1bmF0dGFjaGVkIHRvIGFuIElBTSBpZGVudGl0eSBvciBpZiBpdCBoYXMgbm9cbiAgICogc3RhdGVtZW50cykuIFRoaXMgaXMgZ2VuZXJhbGx5IGRlc2lyZWQgYmVoYXZpb3IsIHNpbmNlIGl0IHByZXZlbnRzXG4gICAqIGNyZWF0aW5nIGludmFsaWQtLWFuZCBoZW5jZSB1bmRlcGxveWFibGUtLUNsb3VkRm9ybWF0aW9uIHRlbXBsYXRlcy5cbiAgICpcbiAgICogSW4gY2FzZXMgd2hlcmUgeW91IGtub3cgdGhlIHBvbGljeSBtdXN0IGJlIGNyZWF0ZWQgYW5kIGl0IGlzIGFjdHVhbGx5XG4gICAqIGFuIGVycm9yIGlmIG5vIHN0YXRlbWVudHMgaGF2ZSBiZWVuIGFkZGVkIHRvIGl0LCB5b3UgY2FuIHNldCB0aGlzIHRvIGB0cnVlYC5cbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGZvcmNlPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogSW5pdGlhbCBQb2xpY3lEb2N1bWVudCB0byB1c2UgZm9yIHRoaXMgUG9saWN5LiBJZiBvbWl0ZWQsIGFueVxuICAgKiBgUG9saWN5U3RhdGVtZW50YCBwcm92aWRlZCBpbiB0aGUgYHN0YXRlbWVudHNgIHByb3BlcnR5IHdpbGwgYmUgYXBwbGllZFxuICAgKiBhZ2FpbnN0IHRoZSBlbXB0eSBkZWZhdWx0IGBQb2xpY3lEb2N1bWVudGAuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gQW4gZW1wdHkgcG9saWN5LlxuICAgKi9cbiAgcmVhZG9ubHkgZG9jdW1lbnQ/OiBQb2xpY3lEb2N1bWVudDtcbn1cblxuLyoqXG4gKiBUaGUgQVdTOjpJQU06OlBvbGljeSByZXNvdXJjZSBhc3NvY2lhdGVzIGFuIElBTSBwb2xpY3kgd2l0aCBJQU0gdXNlcnMsIHJvbGVzLFxuICogb3IgZ3JvdXBzLiBGb3IgbW9yZSBpbmZvcm1hdGlvbiBhYm91dCBJQU0gcG9saWNpZXMsIHNlZSBbT3ZlcnZpZXcgb2YgSUFNXG4gKiBQb2xpY2llc10oaHR0cDovL2RvY3MuYXdzLmFtYXpvbi5jb20vSUFNL2xhdGVzdC9Vc2VyR3VpZGUvcG9saWNpZXNfb3ZlcnZpZXcuaHRtbClcbiAqIGluIHRoZSBJQU0gVXNlciBHdWlkZSBndWlkZS5cbiAqL1xuZXhwb3J0IGNsYXNzIFBvbGljeSBleHRlbmRzIFJlc291cmNlIGltcGxlbWVudHMgSVBvbGljeSB7XG5cbiAgLyoqXG4gICAqIEltcG9ydCBhIHBvbGljeSBpbiB0aGlzIGFwcCBiYXNlZCBvbiBpdHMgbmFtZVxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBmcm9tUG9saWN5TmFtZShzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwb2xpY3lOYW1lOiBzdHJpbmcpOiBJUG9saWN5IHtcbiAgICBjbGFzcyBJbXBvcnQgZXh0ZW5kcyBSZXNvdXJjZSBpbXBsZW1lbnRzIElQb2xpY3kge1xuICAgICAgcHVibGljIHJlYWRvbmx5IHBvbGljeU5hbWUgPSBwb2xpY3lOYW1lO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgSW1wb3J0KHNjb3BlLCBpZCk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHBvbGljeSBkb2N1bWVudC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBkb2N1bWVudCA9IG5ldyBQb2xpY3lEb2N1bWVudCgpO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgX3BvbGljeU5hbWU6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSByb2xlcyA9IG5ldyBBcnJheTxJUm9sZT4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSB1c2VycyA9IG5ldyBBcnJheTxJVXNlcj4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBncm91cHMgPSBuZXcgQXJyYXk8SUdyb3VwPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IGZvcmNlOiBib29sZWFuO1xuICBwcml2YXRlIHJlZmVyZW5jZVRha2VuID0gZmFsc2U7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IFBvbGljeVByb3BzID0ge30pIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHtcbiAgICAgIHBoeXNpY2FsTmFtZTogcHJvcHMucG9saWN5TmFtZSB8fFxuICAgICAgICAvLyBnZW5lcmF0ZVBvbGljeU5hbWUgd2lsbCB0YWtlIHRoZSBsYXN0IDEyOCBjaGFyYWN0ZXJzIG9mIHRoZSBsb2dpY2FsIGlkIHNpbmNlXG4gICAgICAgIC8vIHBvbGljeSBuYW1lcyBhcmUgbGltaXRlZCB0byAxMjguIHRoZSBsYXN0IDggY2hhcnMgYXJlIGEgc3RhY2stdW5pcXVlIGhhc2gsIHNvXG4gICAgICAgIC8vIHRoYXQgc2hvdW9kIGJlIHN1ZmZpY2llbnQgdG8gZW5zdXJlIHVuaXF1ZW5lc3Mgd2l0aGluIGEgcHJpbmNpcGFsLlxuICAgICAgICBMYXp5LnN0cmluZyh7IHByb2R1Y2U6ICgpID0+IGdlbmVyYXRlUG9saWN5TmFtZShzY29wZSwgcmVzb3VyY2UubG9naWNhbElkKSB9KSxcbiAgICB9KTtcblxuICAgIGNvbnN0IHNlbGYgPSB0aGlzO1xuXG4gICAgY2xhc3MgQ2ZuUG9saWN5Q29uZGl0aW9uYWwgZXh0ZW5kcyBDZm5Qb2xpY3kge1xuICAgICAgLyoqXG4gICAgICAgKiBUaGlzIGZ1bmN0aW9uIHJldHVybnMgYHRydWVgIGlmIHRoZSBDRk4gcmVzb3VyY2Ugc2hvdWxkIGJlIGluY2x1ZGVkIGluXG4gICAgICAgKiB0aGUgY2xvdWRmb3JtYXRpb24gdGVtcGxhdGUgdW5sZXNzIGBmb3JjZWAgaXMgYHRydWVgLCBpZiB0aGUgcG9saWN5XG4gICAgICAgKiBkb2N1bWVudCBpcyBlbXB0eSwgdGhlIHJlc291cmNlIHdpbGwgbm90IGJlIGluY2x1ZGVkLlxuICAgICAgICovXG4gICAgICBwcm90ZWN0ZWQgc2hvdWxkU3ludGhlc2l6ZSgpIHtcbiAgICAgICAgcmV0dXJuIHNlbGYuZm9yY2UgfHwgc2VsZi5yZWZlcmVuY2VUYWtlbiB8fCAoIXNlbGYuZG9jdW1lbnQuaXNFbXB0eSAmJiBzZWxmLmlzQXR0YWNoZWQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChwcm9wcy5kb2N1bWVudCkge1xuICAgICAgdGhpcy5kb2N1bWVudCA9IHByb3BzLmRvY3VtZW50O1xuICAgIH1cblxuICAgIGNvbnN0IHJlc291cmNlID0gbmV3IENmblBvbGljeUNvbmRpdGlvbmFsKHRoaXMsICdSZXNvdXJjZScsIHtcbiAgICAgIHBvbGljeURvY3VtZW50OiB0aGlzLmRvY3VtZW50LFxuICAgICAgcG9saWN5TmFtZTogdGhpcy5waHlzaWNhbE5hbWUsXG4gICAgICByb2xlczogdW5kZWZpbmVkSWZFbXB0eSgoKSA9PiB0aGlzLnJvbGVzLm1hcChyID0+IHIucm9sZU5hbWUpKSxcbiAgICAgIHVzZXJzOiB1bmRlZmluZWRJZkVtcHR5KCgpID0+IHRoaXMudXNlcnMubWFwKHUgPT4gdS51c2VyTmFtZSkpLFxuICAgICAgZ3JvdXBzOiB1bmRlZmluZWRJZkVtcHR5KCgpID0+IHRoaXMuZ3JvdXBzLm1hcChnID0+IGcuZ3JvdXBOYW1lKSksXG4gICAgfSk7XG5cbiAgICB0aGlzLl9wb2xpY3lOYW1lID0gdGhpcy5waHlzaWNhbE5hbWUhO1xuICAgIHRoaXMuZm9yY2UgPSBwcm9wcy5mb3JjZSA/PyBmYWxzZTtcblxuICAgIGlmIChwcm9wcy51c2Vycykge1xuICAgICAgcHJvcHMudXNlcnMuZm9yRWFjaCh1ID0+IHRoaXMuYXR0YWNoVG9Vc2VyKHUpKTtcbiAgICB9XG5cbiAgICBpZiAocHJvcHMuZ3JvdXBzKSB7XG4gICAgICBwcm9wcy5ncm91cHMuZm9yRWFjaChnID0+IHRoaXMuYXR0YWNoVG9Hcm91cChnKSk7XG4gICAgfVxuXG4gICAgaWYgKHByb3BzLnJvbGVzKSB7XG4gICAgICBwcm9wcy5yb2xlcy5mb3JFYWNoKHIgPT4gdGhpcy5hdHRhY2hUb1JvbGUocikpO1xuICAgIH1cblxuICAgIGlmIChwcm9wcy5zdGF0ZW1lbnRzKSB7XG4gICAgICBwcm9wcy5zdGF0ZW1lbnRzLmZvckVhY2gocCA9PiB0aGlzLmFkZFN0YXRlbWVudHMocCkpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgc3RhdGVtZW50IHRvIHRoZSBwb2xpY3kgZG9jdW1lbnQuXG4gICAqL1xuICBwdWJsaWMgYWRkU3RhdGVtZW50cyguLi5zdGF0ZW1lbnQ6IFBvbGljeVN0YXRlbWVudFtdKSB7XG4gICAgdGhpcy5kb2N1bWVudC5hZGRTdGF0ZW1lbnRzKC4uLnN0YXRlbWVudCk7XG4gIH1cblxuICAvKipcbiAgICogQXR0YWNoZXMgdGhpcyBwb2xpY3kgdG8gYSB1c2VyLlxuICAgKi9cbiAgcHVibGljIGF0dGFjaFRvVXNlcih1c2VyOiBJVXNlcikge1xuICAgIGlmICh0aGlzLnVzZXJzLmZpbmQodSA9PiB1ID09PSB1c2VyKSkgeyByZXR1cm47IH1cbiAgICB0aGlzLnVzZXJzLnB1c2godXNlcik7XG4gICAgdXNlci5hdHRhY2hJbmxpbmVQb2xpY3kodGhpcyk7XG4gIH1cblxuICAvKipcbiAgICogQXR0YWNoZXMgdGhpcyBwb2xpY3kgdG8gYSByb2xlLlxuICAgKi9cbiAgcHVibGljIGF0dGFjaFRvUm9sZShyb2xlOiBJUm9sZSkge1xuICAgIGlmICh0aGlzLnJvbGVzLmZpbmQociA9PiByID09PSByb2xlKSkgeyByZXR1cm47IH1cbiAgICB0aGlzLnJvbGVzLnB1c2gocm9sZSk7XG4gICAgcm9sZS5hdHRhY2hJbmxpbmVQb2xpY3kodGhpcyk7XG4gIH1cblxuICAvKipcbiAgICogQXR0YWNoZXMgdGhpcyBwb2xpY3kgdG8gYSBncm91cC5cbiAgICovXG4gIHB1YmxpYyBhdHRhY2hUb0dyb3VwKGdyb3VwOiBJR3JvdXApIHtcbiAgICBpZiAodGhpcy5ncm91cHMuZmluZChnID0+IGcgPT09IGdyb3VwKSkgeyByZXR1cm47IH1cbiAgICB0aGlzLmdyb3Vwcy5wdXNoKGdyb3VwKTtcbiAgICBncm91cC5hdHRhY2hJbmxpbmVQb2xpY3kodGhpcyk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhpcyBwb2xpY3kuXG4gICAqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHB1YmxpYyBnZXQgcG9saWN5TmFtZSgpOiBzdHJpbmcge1xuICAgIHRoaXMucmVmZXJlbmNlVGFrZW4gPSB0cnVlO1xuICAgIHJldHVybiB0aGlzLl9wb2xpY3lOYW1lO1xuICB9XG5cbiAgcHJvdGVjdGVkIHZhbGlkYXRlKCk6IHN0cmluZ1tdIHtcbiAgICBjb25zdCByZXN1bHQgPSBuZXcgQXJyYXk8c3RyaW5nPigpO1xuXG4gICAgLy8gdmFsaWRhdGUgdGhhdCB0aGUgcG9saWN5IGRvY3VtZW50IGlzIG5vdCBlbXB0eVxuICAgIGlmICh0aGlzLmRvY3VtZW50LmlzRW1wdHkpIHtcbiAgICAgIGlmICh0aGlzLmZvcmNlKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKCdQb2xpY3kgY3JlYXRlZCB3aXRoIGZvcmNlPXRydWUgaXMgZW1wdHkuIFlvdSBtdXN0IGFkZCBzdGF0ZW1lbnRzIHRvIHRoZSBwb2xpY3knKTtcbiAgICAgIH1cbiAgICAgIGlmICghdGhpcy5mb3JjZSAmJiB0aGlzLnJlZmVyZW5jZVRha2VuKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKCdUaGlzIFBvbGljeSBoYXMgYmVlbiByZWZlcmVuY2VkIGJ5IGEgcmVzb3VyY2UsIHNvIGl0IG11c3QgY29udGFpbiBhdCBsZWFzdCBvbmUgc3RhdGVtZW50LicpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIHZhbGlkYXRlIHRoYXQgdGhlIHBvbGljeSBpcyBhdHRhY2hlZCB0byBhdCBsZWFzdCBvbmUgcHJpbmNpcGFsIChyb2xlLCB1c2VyIG9yIGdyb3VwKS5cbiAgICBpZiAoIXRoaXMuaXNBdHRhY2hlZCkge1xuICAgICAgaWYgKHRoaXMuZm9yY2UpIHtcbiAgICAgICAgcmVzdWx0LnB1c2goJ1BvbGljeSBjcmVhdGVkIHdpdGggZm9yY2U9dHJ1ZSBtdXN0IGJlIGF0dGFjaGVkIHRvIGF0IGxlYXN0IG9uZSBwcmluY2lwYWw6IHVzZXIsIGdyb3VwIG9yIHJvbGUnKTtcbiAgICAgIH1cbiAgICAgIGlmICghdGhpcy5mb3JjZSAmJiB0aGlzLnJlZmVyZW5jZVRha2VuKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKCdUaGlzIFBvbGljeSBoYXMgYmVlbiByZWZlcmVuY2VkIGJ5IGEgcmVzb3VyY2UsIHNvIGl0IG11c3QgYmUgYXR0YWNoZWQgdG8gYXQgbGVhc3Qgb25lIHVzZXIsIGdyb3VwIG9yIHJvbGUuJyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmVzdWx0LnB1c2goLi4udGhpcy5kb2N1bWVudC52YWxpZGF0ZUZvcklkZW50aXR5UG9saWN5KCkpO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBwb2xpY3kgcmVzb3VyY2UgaGFzIGJlZW4gYXR0YWNoZWQgdG8gYW55IGlkZW50aXR5XG4gICAqL1xuICBwcml2YXRlIGdldCBpc0F0dGFjaGVkKCkge1xuICAgIHJldHVybiB0aGlzLmdyb3Vwcy5sZW5ndGggKyB0aGlzLnVzZXJzLmxlbmd0aCArIHRoaXMucm9sZXMubGVuZ3RoID4gMDtcbiAgfVxufVxuIl19
\No newline at end of file