1 | ;
|
2 | var _a;
|
3 | Object.defineProperty(exports, "__esModule", { value: true });
|
4 | exports.ManagedPolicy = void 0;
|
5 | const jsiiDeprecationWarnings = require("../.warnings.jsii.js");
|
6 | const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
|
7 | const core_1 = require("@aws-cdk/core");
|
8 | const iam_generated_1 = require("./iam.generated");
|
9 | const policy_document_1 = require("./policy-document");
|
10 | const util_1 = require("./util");
|
11 | /**
|
12 | * Managed policy
|
13 | *
|
14 | */
|
15 | class ManagedPolicy extends core_1.Resource {
|
16 | constructor(scope, id, props = {}) {
|
17 | super(scope, id, {
|
18 | physicalName: props.managedPolicyName,
|
19 | });
|
20 | /**
|
21 | * The policy document.
|
22 | */
|
23 | this.document = new policy_document_1.PolicyDocument();
|
24 | this.roles = new Array();
|
25 | this.users = new Array();
|
26 | this.groups = new Array();
|
27 | try {
|
28 | jsiiDeprecationWarnings._aws_cdk_aws_iam_ManagedPolicyProps(props);
|
29 | }
|
30 | catch (error) {
|
31 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
32 | Error.captureStackTrace(error, ManagedPolicy);
|
33 | }
|
34 | throw error;
|
35 | }
|
36 | this.description = props.description || '';
|
37 | this.path = props.path || '/';
|
38 | if (props.document) {
|
39 | this.document = props.document;
|
40 | }
|
41 | const resource = new iam_generated_1.CfnManagedPolicy(this, 'Resource', {
|
42 | policyDocument: this.document,
|
43 | managedPolicyName: this.physicalName,
|
44 | description: this.description,
|
45 | path: this.path,
|
46 | roles: util_1.undefinedIfEmpty(() => this.roles.map(r => r.roleName)),
|
47 | users: util_1.undefinedIfEmpty(() => this.users.map(u => u.userName)),
|
48 | groups: util_1.undefinedIfEmpty(() => this.groups.map(g => g.groupName)),
|
49 | });
|
50 | if (props.users) {
|
51 | props.users.forEach(u => this.attachToUser(u));
|
52 | }
|
53 | if (props.groups) {
|
54 | props.groups.forEach(g => this.attachToGroup(g));
|
55 | }
|
56 | if (props.roles) {
|
57 | props.roles.forEach(r => this.attachToRole(r));
|
58 | }
|
59 | if (props.statements) {
|
60 | props.statements.forEach(p => this.addStatements(p));
|
61 | }
|
62 | // arn:aws:iam::123456789012:policy/teststack-CreateTestDBPolicy-16M23YE3CS700
|
63 | this.managedPolicyName = this.getResourceNameAttribute(core_1.Stack.of(this).splitArn(resource.ref, core_1.ArnFormat.SLASH_RESOURCE_NAME).resourceName);
|
64 | this.managedPolicyArn = this.getResourceArnAttribute(resource.ref, {
|
65 | region: '',
|
66 | service: 'iam',
|
67 | resource: 'policy',
|
68 | resourceName: this.physicalName,
|
69 | });
|
70 | }
|
71 | /**
|
72 | * Import a customer managed policy from the managedPolicyName.
|
73 | *
|
74 | * For this managed policy, you only need to know the name to be able to use it.
|
75 | *
|
76 | */
|
77 | static fromManagedPolicyName(scope, id, managedPolicyName) {
|
78 | class Import extends core_1.Resource {
|
79 | constructor() {
|
80 | super(...arguments);
|
81 | this.managedPolicyArn = core_1.Stack.of(scope).formatArn({
|
82 | service: 'iam',
|
83 | region: '',
|
84 | account: core_1.Stack.of(scope).account,
|
85 | resource: 'policy',
|
86 | resourceName: managedPolicyName,
|
87 | });
|
88 | }
|
89 | }
|
90 | return new Import(scope, id);
|
91 | }
|
92 | /**
|
93 | * Import an external managed policy by ARN.
|
94 | *
|
95 | * For this managed policy, you only need to know the ARN to be able to use it.
|
96 | * This can be useful if you got the ARN from a CloudFormation Export.
|
97 | *
|
98 | * If the imported Managed Policy ARN is a Token (such as a
|
99 | * `CfnParameter.valueAsString` or a `Fn.importValue()`) *and* the referenced
|
100 | * managed policy has a `path` (like `arn:...:policy/AdminPolicy/AdminAllow`), the
|
101 | * `managedPolicyName` property will not resolve to the correct value. Instead it
|
102 | * will resolve to the first path component. We unfortunately cannot express
|
103 | * the correct calculation of the full path name as a CloudFormation
|
104 | * expression. In this scenario the Managed Policy ARN should be supplied without the
|
105 | * `path` in order to resolve the correct managed policy resource.
|
106 | *
|
107 | * @param scope construct scope
|
108 | * @param id construct id
|
109 | * @param managedPolicyArn the ARN of the managed policy to import
|
110 | */
|
111 | static fromManagedPolicyArn(scope, id, managedPolicyArn) {
|
112 | class Import extends core_1.Resource {
|
113 | constructor() {
|
114 | super(...arguments);
|
115 | this.managedPolicyArn = managedPolicyArn;
|
116 | }
|
117 | }
|
118 | return new Import(scope, id);
|
119 | }
|
120 | /**
|
121 | * Import a managed policy from one of the policies that AWS manages.
|
122 | *
|
123 | * For this managed policy, you only need to know the name to be able to use it.
|
124 | *
|
125 | * Some managed policy names start with "service-role/", some start with
|
126 | * "job-function/", and some don't start with anything. Include the
|
127 | * prefix when constructing this object.
|
128 | */
|
129 | static fromAwsManagedPolicyName(managedPolicyName) {
|
130 | class AwsManagedPolicy {
|
131 | constructor() {
|
132 | this.managedPolicyArn = core_1.Arn.format({
|
133 | partition: core_1.Aws.PARTITION,
|
134 | service: 'iam',
|
135 | region: '',
|
136 | account: 'aws',
|
137 | resource: 'policy',
|
138 | resourceName: managedPolicyName,
|
139 | });
|
140 | }
|
141 | }
|
142 | return new AwsManagedPolicy();
|
143 | }
|
144 | /**
|
145 | * Adds a statement to the policy document.
|
146 | */
|
147 | addStatements(...statement) {
|
148 | try {
|
149 | jsiiDeprecationWarnings._aws_cdk_aws_iam_PolicyStatement(statement);
|
150 | }
|
151 | catch (error) {
|
152 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
153 | Error.captureStackTrace(error, this.addStatements);
|
154 | }
|
155 | throw error;
|
156 | }
|
157 | this.document.addStatements(...statement);
|
158 | }
|
159 | /**
|
160 | * Attaches this policy to a user.
|
161 | */
|
162 | attachToUser(user) {
|
163 | try {
|
164 | jsiiDeprecationWarnings._aws_cdk_aws_iam_IUser(user);
|
165 | }
|
166 | catch (error) {
|
167 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
168 | Error.captureStackTrace(error, this.attachToUser);
|
169 | }
|
170 | throw error;
|
171 | }
|
172 | if (this.users.find(u => u === user)) {
|
173 | return;
|
174 | }
|
175 | this.users.push(user);
|
176 | }
|
177 | /**
|
178 | * Attaches this policy to a role.
|
179 | */
|
180 | attachToRole(role) {
|
181 | try {
|
182 | jsiiDeprecationWarnings._aws_cdk_aws_iam_IRole(role);
|
183 | }
|
184 | catch (error) {
|
185 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
186 | Error.captureStackTrace(error, this.attachToRole);
|
187 | }
|
188 | throw error;
|
189 | }
|
190 | if (this.roles.find(r => r === role)) {
|
191 | return;
|
192 | }
|
193 | this.roles.push(role);
|
194 | }
|
195 | /**
|
196 | * Attaches this policy to a group.
|
197 | */
|
198 | attachToGroup(group) {
|
199 | try {
|
200 | jsiiDeprecationWarnings._aws_cdk_aws_iam_IGroup(group);
|
201 | }
|
202 | catch (error) {
|
203 | if (process.env.JSII_DEBUG !== "1" && error.name === "DeprecationError") {
|
204 | Error.captureStackTrace(error, this.attachToGroup);
|
205 | }
|
206 | throw error;
|
207 | }
|
208 | if (this.groups.find(g => g === group)) {
|
209 | return;
|
210 | }
|
211 | this.groups.push(group);
|
212 | }
|
213 | validate() {
|
214 | const result = new Array();
|
215 | // validate that the policy document is not empty
|
216 | if (this.document.isEmpty) {
|
217 | result.push('Managed Policy is empty. You must add statements to the policy');
|
218 | }
|
219 | result.push(...this.document.validateForIdentityPolicy());
|
220 | return result;
|
221 | }
|
222 | }
|
223 | exports.ManagedPolicy = ManagedPolicy;
|
224 | _a = JSII_RTTI_SYMBOL_1;
|
225 | ManagedPolicy[_a] = { fqn: "@aws-cdk/aws-iam.ManagedPolicy", version: "1.161.0" };
|
226 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFuYWdlZC1wb2xpY3kuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJtYW5hZ2VkLXBvbGljeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSx3Q0FBcUU7QUFHckUsbURBQW1EO0FBQ25ELHVEQUFtRDtBQUluRCxpQ0FBMEM7QUF5RjFDOzs7R0FHRztBQUNILE1BQWEsYUFBYyxTQUFRLGVBQVE7SUEwR3pDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsUUFBNEIsRUFBRTtRQUN0RSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRTtZQUNmLFlBQVksRUFBRSxLQUFLLENBQUMsaUJBQWlCO1NBQ3RDLENBQUMsQ0FBQztRQWpDTDs7V0FFRztRQUNhLGFBQVEsR0FBRyxJQUFJLGdDQUFjLEVBQUUsQ0FBQztRQXVCL0IsVUFBSyxHQUFHLElBQUksS0FBSyxFQUFTLENBQUM7UUFDM0IsVUFBSyxHQUFHLElBQUksS0FBSyxFQUFTLENBQUM7UUFDM0IsV0FBTSxHQUFHLElBQUksS0FBSyxFQUFVLENBQUM7Ozs7OzsrQ0F4R25DLGFBQWE7Ozs7UUErR3RCLElBQUksQ0FBQyxXQUFXLEdBQUcsS0FBSyxDQUFDLFdBQVcsSUFBSSxFQUFFLENBQUM7UUFDM0MsSUFBSSxDQUFDLElBQUksR0FBRyxLQUFLLENBQUMsSUFBSSxJQUFJLEdBQUcsQ0FBQztRQUU5QixJQUFJLEtBQUssQ0FBQyxRQUFRLEVBQUU7WUFDbEIsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUMsUUFBUSxDQUFDO1NBQ2hDO1FBRUQsTUFBTSxRQUFRLEdBQUcsSUFBSSxnQ0FBZ0IsQ0FBQyxJQUFJLEVBQUUsVUFBVSxFQUFFO1lBQ3RELGNBQWMsRUFBRSxJQUFJLENBQUMsUUFBUTtZQUM3QixpQkFBaUIsRUFBRSxJQUFJLENBQUMsWUFBWTtZQUNwQyxXQUFXLEVBQUUsSUFBSSxDQUFDLFdBQVc7WUFDN0IsSUFBSSxFQUFFLElBQUksQ0FBQyxJQUFJO1lBQ2YsS0FB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SUFDSSxhQUFhLENBQUMsS0FBYTs7Ozs7Ozs7OztRQUNoQyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxLQUFLLEtBQUssQ0FBQyxFQUFFO1lBQUUsT0FBTztTQUFFO1FBQ25ELElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO0tBQ3pCO0lBRVMsUUFBUTtRQUNoQixNQUFNLE1BQU0sR0FBRyxJQUFJLEtBQUssRUFBVSxDQUFDO1FBRW5DLGlEQUFpRDtRQUNqRCxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsT0FBTyxFQUFFO1lBQ3pCLE1BQU0sQ0FBQyxJQUFJLENBQUMsZ0VBQWdFLENBQUMsQ0FBQztTQUMvRTtRQUVELE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLHlCQUF5QixFQUFFLENBQUMsQ0FBQztRQUUxRCxPQUFPLE1BQU0sQ0FBQztLQUNmOztBQXBNSCxzQ0FxTUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBcm5Gb3JtYXQsIFJlc291cmNlLCBTdGFjaywgQXJuLCBBd3MgfSBmcm9tICdAYXdzLWNkay9jb3JlJztcbmltcG9ydCB7IENvbnN0cnVjdCB9IGZyb20gJ2NvbnN0cnVjdHMnO1xuaW1wb3J0IHsgSUdyb3VwIH0gZnJvbSAnLi9ncm91cCc7XG5pbXBvcnQgeyBDZm5NYW5hZ2VkUG9saWN5IH0gZnJvbSAnLi9pYW0uZ2VuZXJhdGVkJztcbmltcG9ydCB7IFBvbGljeURvY3VtZW50IH0gZnJvbSAnLi9wb2xpY3ktZG9jdW1lbnQnO1xuaW1wb3J0IHsgUG9saWN5U3RhdGVtZW50IH0gZnJvbSAnLi9wb2xpY3ktc3RhdGVtZW50JztcbmltcG9ydCB7IElSb2xlIH0gZnJvbSAnLi9yb2xlJztcbmltcG9ydCB7IElVc2VyIH0gZnJvbSAnLi91c2VyJztcbmltcG9ydCB7IHVuZGVmaW5lZElmRW1wdHkgfSBmcm9tICcuL3V0aWwnO1xuXG4vKipcbiAqIEEgbWFuYWdlZCBwb2xpY3lcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBJTWFuYWdlZFBvbGljeSB7XG4gIC8qKlxuICAgKiBUaGUgQVJOIG9mIHRoZSBtYW5hZ2VkIHBvbGljeVxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICByZWFkb25seSBtYW5hZ2VkUG9saWN5QXJuOiBzdHJpbmc7XG59XG5cbi8qKlxuICogUHJvcGVydGllcyBmb3IgZGVmaW5pbmcgYW4gSUFNIG1hbmFnZWQgcG9saWN5XG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTWFuYWdlZFBvbGljeVByb3BzIHtcbiAgLyoqXG4gICAqIFRoZSBuYW1lIG9mIHRoZSBtYW5hZ2VkIHBvbGljeS4gSWYgeW91IHNwZWNpZnkgbXVsdGlwbGUgcG9saWNpZXMgZm9yIGFuIGVudGl0eSxcbiAgICogc3BlY2lmeSB1bmlxdWUgbmFtZXMuIEZvciBleGFtcGxlLCBpZiB5b3Ugc3BlY2lmeSBhIGxpc3Qgb2YgcG9saWNpZXMgZm9yXG4gICAqIGFuIElBTSByb2xlLCBlYWNoIHBvbGljeSBtdXN0IGhhdmUgYSB1bmlxdWUgbmFtZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBBIG5hbWUgaXMgYXV0b21hdGljYWxseSBnZW5lcmF0ZWQuXG4gICAqL1xuICByZWFkb25seSBtYW5hZ2VkUG9saWN5TmFtZT86IHN0cmluZztcblxuICAvKipcbiAgICogQSBkZXNjcmlwdGlvbiBvZiB0aGUgbWFuYWdlZCBwb2xpY3kuIFR5cGljYWxseSB1c2VkIHRvIHN0b3JlIGluZm9ybWF0aW9uIGFib3V0IHRoZVxuICAgKiBwZXJtaXNzaW9ucyBkZWZpbmVkIGluIHRoZSBwb2xpY3kuIEZvciBleGFtcGxlLCBcIkdyYW50cyBhY2Nlc3MgdG8gcHJvZHVjdGlvbiBEeW5hbW9EQiB0YWJsZXMuXCJcbiAgICogVGhlIHBvbGljeSBkZXNjcmlwdGlvbiBpcyBpbW11dGFibGUuIEFmdGVyIGEgdmFsdWUgaXMgYXNzaWduZWQsIGl0IGNhbm5vdCBiZSBjaGFuZ2VkLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIGVtcHR5XG4gICAqL1xuICByZWFkb25seSBkZXNjcmlwdGlvbj86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHBhdGggZm9yIHRoZSBwb2xpY3kuIFRoaXMgcGFyYW1ldGVyIGFsbG93cyAodGhyb3VnaCBpdHMgcmVnZXggcGF0dGVybikgYSBzdHJpbmcgb2YgY2hhcmFjdGVyc1xuICAgKiBjb25zaXN0aW5nIG9mIGVpdGhlciBhIGZvcndhcmQgc2xhc2ggKC8pIGJ5IGl0c2VsZiBvciBhIHN0cmluZyB0aGF0IG11c3QgYmVnaW4gYW5kIGVuZCB3aXRoIGZvcndhcmQgc2xhc2hlcy5cbiAgICogSW4gYWRkaXRpb24sIGl0IGNhbiBjb250YWluIGFueSBBU0NJSSBjaGFyYWN0ZXIgZnJvbSB0aGUgISAoXFx1MDAyMSkgdGhyb3VnaCB0aGUgREVMIGNoYXJhY3RlciAoXFx1MDA3RiksXG4gICAqIGluY2x1ZGluZyBtb3N0IHB1bmN0dWF0aW9uIGNoYXJhY3RlcnMsIGRpZ2l0cywgYW5kIHVwcGVyIGFuZCBsb3dlcmNhc2VkIGxldHRlcnMuXG4gICAqXG4gICAqIEZvciBtb3JlIGluZm9ybWF0aW9uIGFib3V0IHBhdGhzLCBzZWUgSUFNIElkZW50aWZpZXJzIGluIHRoZSBJQU0gVXNlciBHdWlkZS5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBcIi9cIlxuICAgKi9cbiAgcmVhZG9ubHkgcGF0aD86IHN0cmluZztcblxuICAvKipcbiAgICogVXNlcnMgdG8gYXR0YWNoIHRoaXMgcG9saWN5IHRvLlxuICAgKiBZb3UgY2FuIGFsc28gdXNlIGBhdHRhY2hUb1VzZXIodXNlcilgIHRvIGF0dGFjaCB0aGlzIHBvbGljeSB0byBhIHVzZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gdXNlcnMuXG4gICAqL1xuICByZWFkb25seSB1c2Vycz86IElVc2VyW107XG5cbiAgLyoqXG4gICAqIFJvbGVzIHRvIGF0dGFjaCB0aGlzIHBvbGljeSB0by5cbiAgICogWW91IGNhbiBhbHNvIHVzZSBgYXR0YWNoVG9Sb2xlKHJvbGUpYCB0byBhdHRhY2ggdGhpcyBwb2xpY3kgdG8gYSByb2xlLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIE5vIHJvbGVzLlxuICAgKi9cbiAgcmVhZG9ubHkgcm9sZXM/OiBJUm9sZVtdO1xuXG4gIC8qKlxuICAgKiBHcm91cHMgdG8gYXR0YWNoIHRoaXMgcG9saWN5IHRvLlxuICAgKiBZb3UgY2FuIGFsc28gdXNlIGBhdHRhY2hUb0dyb3VwKGdyb3VwKWAgdG8gYXR0YWNoIHRoaXMgcG9saWN5IHRvIGEgZ3JvdXAuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gZ3JvdXBzLlxuICAgKi9cbiAgcmVhZG9ubHkgZ3JvdXBzPzogSUdyb3VwW107XG5cbiAgLyoqXG4gICAqIEluaXRpYWwgc2V0IG9mIHBlcm1pc3Npb25zIHRvIGFkZCB0byB0aGlzIHBvbGljeSBkb2N1bWVudC5cbiAgICogWW91IGNhbiBhbHNvIHVzZSBgYWRkUGVybWlzc2lvbihzdGF0ZW1lbnQpYCB0byBhZGQgcGVybWlzc2lvbnMgbGF0ZXIuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gc3RhdGVtZW50cy5cbiAgICovXG4gIHJlYWRvbmx5IHN0YXRlbWVudHM/OiBQb2xpY3lTdGF0ZW1lbnRbXTtcblxuICAvKipcbiAgICogSW5pdGlhbCBQb2xpY3lEb2N1bWVudCB0byB1c2UgZm9yIHRoaXMgTWFuYWdlZFBvbGljeS4gSWYgb21pdGVkLCBhbnlcbiAgICogYFBvbGljeVN0YXRlbWVudGAgcHJvdmlkZWQgaW4gdGhlIGBzdGF0ZW1lbnRzYCBwcm9wZXJ0eSB3aWxsIGJlIGFwcGxpZWRcbiAgICogYWdhaW5zdCB0aGUgZW1wdHkgZGVmYXVsdCBgUG9saWN5RG9jdW1lbnRgLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIEFuIGVtcHR5IHBvbGljeS5cbiAgICovXG4gIHJlYWRvbmx5IGRvY3VtZW50PzogUG9saWN5RG9jdW1lbnQ7XG59XG5cbi8qKlxuICogTWFuYWdlZCBwb2xpY3lcbiAqXG4gKi9cbmV4cG9ydCBjbGFzcyBNYW5hZ2VkUG9saWN5IGV4dGVuZHMgUmVzb3VyY2UgaW1wbGVtZW50cyBJTWFuYWdlZFBvbGljeSB7XG4gIC8qKlxuICAgKiBJbXBvcnQgYSBjdXN0b21lciBtYW5hZ2VkIHBvbGljeSBmcm9tIHRoZSBtYW5hZ2VkUG9saWN5TmFtZS5cbiAgICpcbiAgICogRm9yIHRoaXMgbWFuYWdlZCBwb2xpY3ksIHlvdSBvbmx5IG5lZWQgdG8ga25vdyB0aGUgbmFtZSB0byBiZSBhYmxlIHRvIHVzZSBpdC5cbiAgICpcbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZnJvbU1hbmFnZWRQb2xpY3lOYW1lKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIG1hbmFnZWRQb2xpY3lOYW1lOiBzdHJpbmcpOiBJTWFuYWdlZFBvbGljeSB7XG4gICAgY2xhc3MgSW1wb3J0IGV4dGVuZHMgUmVzb3VyY2UgaW1wbGVtZW50cyBJTWFuYWdlZFBvbGljeSB7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgbWFuYWdlZFBvbGljeUFybiA9IFN0YWNrLm9mKHNjb3BlKS5mb3JtYXRBcm4oe1xuICAgICAgICBzZXJ2aWNlOiAnaWFtJyxcbiAgICAgICAgcmVnaW9uOiAnJywgLy8gbm8gcmVnaW9uIGZvciBtYW5hZ2VkIHBvbGljeVxuICAgICAgICBhY2NvdW50OiBTdGFjay5vZihzY29wZSkuYWNjb3VudCwgLy8gQ2FuIHRoaXMgYmUgc29tZXRoaW5nIHRoZSB1c2VyIHNwZWNpZmllcz9cbiAgICAgICAgcmVzb3VyY2U6ICdwb2xpY3knLFxuICAgICAgICByZXNvdXJjZU5hbWU6IG1hbmFnZWRQb2xpY3lOYW1lLFxuICAgICAgfSk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgSW1wb3J0KHNjb3BlLCBpZCk7XG4gIH1cblxuICAvKipcbiAgICogSW1wb3J0IGFuIGV4dGVybmFsIG1hbmFnZWQgcG9saWN5IGJ5IEFSTi5cbiAgICpcbiAgICogRm9yIHRoaXMgbWFuYWdlZCBwb2xpY3ksIHlvdSBvbmx5IG5lZWQgdG8ga25vdyB0aGUgQVJOIHRvIGJlIGFibGUgdG8gdXNlIGl0LlxuICAgKiBUaGlzIGNhbiBiZSB1c2VmdWwgaWYgeW91IGdvdCB0aGUgQVJOIGZyb20gYSBDbG91ZEZvcm1hdGlvbiBFeHBvcnQuXG4gICAqXG4gICAqIElmIHRoZSBpbXBvcnRlZCBNYW5hZ2VkIFBvbGljeSBBUk4gaXMgYSBUb2tlbiAoc3VjaCBhcyBhXG4gICAqIGBDZm5QYXJhbWV0ZXIudmFsdWVBc1N0cmluZ2Agb3IgYSBgRm4uaW1wb3J0VmFsdWUoKWApICphbmQqIHRoZSByZWZlcmVuY2VkXG4gICAqIG1hbmFnZWQgcG9saWN5IGhhcyBhIGBwYXRoYCAobGlrZSBgYXJuOi4uLjpwb2xpY3kvQWRtaW5Qb2xpY3kvQWRtaW5BbGxvd2ApLCB0aGVcbiAgICogYG1hbmFnZWRQb2xpY3lOYW1lYCBwcm9wZXJ0eSB3aWxsIG5vdCByZXNvbHZlIHRvIHRoZSBjb3JyZWN0IHZhbHVlLiBJbnN0ZWFkIGl0XG4gICAqIHdpbGwgcmVzb2x2ZSB0byB0aGUgZmlyc3QgcGF0aCBjb21wb25lbnQuIFdlIHVuZm9ydHVuYXRlbHkgY2Fubm90IGV4cHJlc3NcbiAgICogdGhlIGNvcnJlY3QgY2FsY3VsYXRpb24gb2YgdGhlIGZ1bGwgcGF0aCBuYW1lIGFzIGEgQ2xvdWRGb3JtYXRpb25cbiAgICogZXhwcmVzc2lvbi4gSW4gdGhpcyBzY2VuYXJpbyB0aGUgTWFuYWdlZCBQb2xpY3kgQVJOIHNob3VsZCBiZSBzdXBwbGllZCB3aXRob3V0IHRoZVxuICAgKiBgcGF0aGAgaW4gb3JkZXIgdG8gcmVzb2x2ZSB0aGUgY29ycmVjdCBtYW5hZ2VkIHBvbGljeSByZXNvdXJjZS5cbiAgICpcbiAgICogQHBhcmFtIHNjb3BlIGNvbnN0cnVjdCBzY29wZVxuICAgKiBAcGFyYW0gaWQgY29uc3RydWN0IGlkXG4gICAqIEBwYXJhbSBtYW5hZ2VkUG9saWN5QXJuIHRoZSBBUk4gb2YgdGhlIG1hbmFnZWQgcG9saWN5IHRvIGltcG9ydFxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBmcm9tTWFuYWdlZFBvbGljeUFybihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBtYW5hZ2VkUG9saWN5QXJuOiBzdHJpbmcpOiBJTWFuYWdlZFBvbGljeSB7XG4gICAgY2xhc3MgSW1wb3J0IGV4dGVuZHMgUmVzb3VyY2UgaW1wbGVtZW50cyBJTWFuYWdlZFBvbGljeSB7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgbWFuYWdlZFBvbGljeUFybiA9IG1hbmFnZWRQb2xpY3lBcm47XG4gICAgfVxuICAgIHJldHVybiBuZXcgSW1wb3J0KHNjb3BlLCBpZCk7XG4gIH1cblxuICAvKipcbiAgICogSW1wb3J0IGEgbWFuYWdlZCBwb2xpY3kgZnJvbSBvbmUgb2YgdGhlIHBvbGljaWVzIHRoYXQgQVdTIG1hbmFnZXMuXG4gICAqXG4gICAqIEZvciB0aGlzIG1hbmFnZWQgcG9saWN5LCB5b3Ugb25seSBuZWVkIHRvIGtub3cgdGhlIG5hbWUgdG8gYmUgYWJsZSB0byB1c2UgaXQuXG4gICAqXG4gICAqIFNvbWUgbWFuYWdlZCBwb2xpY3kgbmFtZXMgc3RhcnQgd2l0aCBcInNlcnZpY2Utcm9sZS9cIiwgc29tZSBzdGFydCB3aXRoXG4gICAqIFwiam9iLWZ1bmN0aW9uL1wiLCBhbmQgc29tZSBkb24ndCBzdGFydCB3aXRoIGFueXRoaW5nLiBJbmNsdWRlIHRoZVxuICAgKiBwcmVmaXggd2hlbiBjb25zdHJ1Y3RpbmcgdGhpcyBvYmplY3QuXG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGZyb21Bd3NNYW5hZ2VkUG9saWN5TmFtZShtYW5hZ2VkUG9saWN5TmFtZTogc3RyaW5nKTogSU1hbmFnZWRQb2xpY3kge1xuICAgIGNsYXNzIEF3c01hbmFnZWRQb2xpY3kgaW1wbGVtZW50cyBJTWFuYWdlZFBvbGljeSB7XG4gICAgICBwdWJsaWMgcmVhZG9ubHkgbWFuYWdlZFBvbGljeUFybiA9IEFybi5mb3JtYXQoe1xuICAgICAgICBwYXJ0aXRpb246IEF3cy5QQVJUSVRJT04sXG4gICAgICAgIHNlcnZpY2U6ICdpYW0nLFxuICAgICAgICByZWdpb246ICcnLCAvLyBubyByZWdpb24gZm9yIG1hbmFnZWQgcG9saWN5XG4gICAgICAgIGFjY291bnQ6ICdhd3MnLCAvLyB0aGUgYWNjb3VudCBmb3IgYSBtYW5hZ2VkIHBvbGljeSBpcyAnYXdzJ1xuICAgICAgICByZXNvdXJjZTogJ3BvbGljeScsXG4gICAgICAgIHJlc291cmNlTmFtZTogbWFuYWdlZFBvbGljeU5hbWUsXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBBd3NNYW5hZ2VkUG9saWN5KCk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgQVJOIG9mIHRoaXMgbWFuYWdlZCBwb2xpY3kuXG4gICAqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBtYW5hZ2VkUG9saWN5QXJuOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBwb2xpY3kgZG9jdW1lbnQuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgZG9jdW1lbnQgPSBuZXcgUG9saWN5RG9jdW1lbnQoKTtcblxuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhpcyBwb2xpY3kuXG4gICAqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBtYW5hZ2VkUG9saWN5TmFtZTogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgZGVzY3JpcHRpb24gb2YgdGhpcyBwb2xpY3kuXG4gICAqXG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBkZXNjcmlwdGlvbjogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgcGF0aCBvZiB0aGlzIHBvbGljeS5cbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IHBhdGg6IHN0cmluZztcblxuICBwcml2YXRlIHJlYWRvbmx5IHJvbGVzID0gbmV3IEFycmF5PElSb2xlPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IHVzZXJzID0gbmV3IEFycmF5PElVc2VyPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IGdyb3VwcyA9IG5ldyBBcnJheTxJR3JvdXA+KCk7XG5cbiAgY29uc3RydWN0b3Ioc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgcHJvcHM6IE1hbmFnZWRQb2xpY3lQcm9wcyA9IHt9KSB7XG4gICAgc3VwZXIoc2NvcGUsIGlkLCB7XG4gICAgICBwaHlzaWNhbE5hbWU6IHByb3BzLm1hbmFnZWRQb2xpY3lOYW1lLFxuICAgIH0pO1xuXG4gICAgdGhpcy5kZXNjcmlwdGlvbiA9IHByb3BzLmRlc2NyaXB0aW9uIHx8ICcnO1xuICAgIHRoaXMucGF0aCA9IHByb3BzLnBhdGggfHwgJy8nO1xuXG4gICAgaWYgKHByb3BzLmRvY3VtZW50KSB7XG4gICAgICB0aGlzLmRvY3VtZW50ID0gcHJvcHMuZG9jdW1lbnQ7XG4gICAgfVxuXG4gICAgY29uc3QgcmVzb3VyY2UgPSBuZXcgQ2ZuTWFuYWdlZFBvbGljeSh0aGlzLCAnUmVzb3VyY2UnLCB7XG4gICAgICBwb2xpY3lEb2N1bWVudDogdGhpcy5kb2N1bWVudCxcbiAgICAgIG1hbmFnZWRQb2xpY3lOYW1lOiB0aGlzLnBoeXNpY2FsTmFtZSxcbiAgICAgIGRlc2NyaXB0aW9uOiB0aGlzLmRlc2NyaXB0aW9uLFxuICAgICAgcGF0aDogdGhpcy5wYXRoLFxuICAgICAgcm9sZXM6IHVuZGVmaW5lZElmRW1wdHkoKCkgPT4gdGhpcy5yb2xlcy5tYXAociA9PiByLnJvbGVOYW1lKSksXG4gICAgICB1c2VyczogdW5kZWZpbmVkSWZFbXB0eSgoKSA9PiB0aGlzLnVzZXJzLm1hcCh1ID0+IHUudXNlck5hbWUpKSxcbiAgICAgIGdyb3VwczogdW5kZWZpbmVkSWZFbXB0eSgoKSA9PiB0aGlzLmdyb3Vwcy5tYXAoZyA9PiBnLmdyb3VwTmFtZSkpLFxuICAgIH0pO1xuXG4gICAgaWYgKHByb3BzLnVzZXJzKSB7XG4gICAgICBwcm9wcy51c2Vycy5mb3JFYWNoKHUgPT4gdGhpcy5hdHRhY2hUb1VzZXIodSkpO1xuICAgIH1cblxuICAgIGlmIChwcm9wcy5ncm91cHMpIHtcbiAgICAgIHByb3BzLmdyb3Vwcy5mb3JFYWNoKGcgPT4gdGhpcy5hdHRhY2hUb0dyb3VwKGcpKTtcbiAgICB9XG5cbiAgICBpZiAocHJvcHMucm9sZXMpIHtcbiAgICAgIHByb3BzLnJvbGVzLmZvckVhY2gociA9PiB0aGlzLmF0dGFjaFRvUm9sZShyKSk7XG4gICAgfVxuXG4gICAgaWYgKHByb3BzLnN0YXRlbWVudHMpIHtcbiAgICAgIHByb3BzLnN0YXRlbWVudHMuZm9yRWFjaChwID0+IHRoaXMuYWRkU3RhdGVtZW50cyhwKSk7XG4gICAgfVxuXG4gICAgLy8gYXJuOmF3czppYW06OjEyMzQ1Njc4OTAxMjpwb2xpY3kvdGVzdHN0YWNrLUNyZWF0ZVRlc3REQlBvbGljeS0xNk0yM1lFM0NTNzAwXG4gICAgdGhpcy5tYW5hZ2VkUG9saWN5TmFtZSA9IHRoaXMuZ2V0UmVzb3VyY2VOYW1lQXR0cmlidXRlKFN0YWNrLm9mKHRoaXMpLnNwbGl0QXJuKHJlc291cmNlLnJlZiwgQXJuRm9ybWF0LlNMQVNIX1JFU09VUkNFX05BTUUpLnJlc291cmNlTmFtZSEpO1xuICAgIHRoaXMubWFuYWdlZFBvbGljeUFybiA9IHRoaXMuZ2V0UmVzb3VyY2VBcm5BdHRyaWJ1dGUocmVzb3VyY2UucmVmLCB7XG4gICAgICByZWdpb246ICcnLCAvLyBJQU0gaXMgZ2xvYmFsIGluIGVhY2ggcGFydGl0aW9uXG4gICAgICBzZXJ2aWNlOiAnaWFtJyxcbiAgICAgIHJlc291cmNlOiAncG9saWN5JyxcbiAgICAgIHJlc291cmNlTmFtZTogdGhpcy5waHlzaWNhbE5hbWUsXG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBhIHN0YXRlbWVudCB0byB0aGUgcG9saWN5IGRvY3VtZW50LlxuICAgKi9cbiAgcHVibGljIGFkZFN0YXRlbWVudHMoLi4uc3RhdGVtZW50OiBQb2xpY3lTdGF0ZW1lbnRbXSkge1xuICAgIHRoaXMuZG9jdW1lbnQuYWRkU3RhdGVtZW50cyguLi5zdGF0ZW1lbnQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dGFjaGVzIHRoaXMgcG9saWN5IHRvIGEgdXNlci5cbiAgICovXG4gIHB1YmxpYyBhdHRhY2hUb1VzZXIodXNlcjogSVVzZXIpIHtcbiAgICBpZiAodGhpcy51c2Vycy5maW5kKHUgPT4gdSA9PT0gdXNlcikpIHsgcmV0dXJuOyB9XG4gICAgdGhpcy51c2Vycy5wdXNoKHVzZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dGFjaGVzIHRoaXMgcG9saWN5IHRvIGEgcm9sZS5cbiAgICovXG4gIHB1YmxpYyBhdHRhY2hUb1JvbGUocm9sZTogSVJvbGUpIHtcbiAgICBpZiAodGhpcy5yb2xlcy5maW5kKHIgPT4gciA9PT0gcm9sZSkpIHsgcmV0dXJuOyB9XG4gICAgdGhpcy5yb2xlcy5wdXNoKHJvbGUpO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dGFjaGVzIHRoaXMgcG9saWN5IHRvIGEgZ3JvdXAuXG4gICAqL1xuICBwdWJsaWMgYXR0YWNoVG9Hcm91cChncm91cDogSUdyb3VwKSB7XG4gICAgaWYgKHRoaXMuZ3JvdXBzLmZpbmQoZyA9PiBnID09PSBncm91cCkpIHsgcmV0dXJuOyB9XG4gICAgdGhpcy5ncm91cHMucHVzaChncm91cCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgdmFsaWRhdGUoKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IHJlc3VsdCA9IG5ldyBBcnJheTxzdHJpbmc+KCk7XG5cbiAgICAvLyB2YWxpZGF0ZSB0aGF0IHRoZSBwb2xpY3kgZG9jdW1lbnQgaXMgbm90IGVtcHR5XG4gICAgaWYgKHRoaXMuZG9jdW1lbnQuaXNFbXB0eSkge1xuICAgICAgcmVzdWx0LnB1c2goJ01hbmFnZWQgUG9saWN5IGlzIGVtcHR5LiBZb3UgbXVzdCBhZGQgc3RhdGVtZW50cyB0byB0aGUgcG9saWN5Jyk7XG4gICAgfVxuXG4gICAgcmVzdWx0LnB1c2goLi4udGhpcy5kb2N1bWVudC52YWxpZGF0ZUZvcklkZW50aXR5UG9saWN5KCkpO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxufVxuIl19 |
\ | No newline at end of file |