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, this.constructor);
|
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.156.1" };
|
226 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWFuYWdlZC1wb2xpY3kuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJtYW5hZ2VkLXBvbGljeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7QUFBQSx3Q0FBcUU7QUFHckUsbURBQW1EO0FBQ25ELHVEQUFtRDtBQUluRCxpQ0FBMEM7QUF5RjFDOzs7R0FHRztBQUNILE1BQWEsYUFBYyxTQUFRLGVBQVE7SUEwR3pDLFlBQVksS0FBZ0IsRUFBRSxFQUFVLEVBQUUsUUFBNEIsRUFBRTtRQUN0RSxLQUFLLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRTtZQUNmLFlBQVksRUFBRSxLQUFLLENBQUMsaUJBQWlCO1NBQ3RDLENBQUMsQ0FBQztRQWpDTDs7V0FFRztRQUNhLGFBQVEsR0FBRyxJQUFJLGdDQUFjLEVBQUUsQ0FBQztRQXVCL0IsVUFBSyxHQUFHLElBQUksS0FBSyxFQUFTLENBQUM7UUFDM0IsVUFBSyxHQUFHLElBQUksS0FBSyxFQUFTLENBQUM7UUFDM0IsV0FBTSxHQUFHLElBQUksS0FBSyxFQUFVLENBQUM7Ozs7Ozs7Ozs7UUFPNUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxLQUFLLENBQUMsV0FBVyxJQUFJLEVBQUUsQ0FBQztRQUMzQyxJQUFJLENBQUMsSUFBSSxHQUFHLEtBQUssQ0FBQyxJQUFJLElBQUksR0FBRyxDQUFDO1FBRTlCLElBQUksS0FBSyxDQUFDLFFBQVEsRUFBRTtZQUNsQixJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQyxRQUFRLENBQUM7U0FDaEM7UUFFRCxNQUFNLFFBQVEsR0FBRyxJQUFJLGdDQUFnQixDQUFDLElBQUksRUFBRSxVQUFVLEVBQUU7WUFDdEQsY0FBYyxFQUFFLElBQUksQ0FBQyxRQUFRO1lBQzdCLGlCQUFpQixFQUFFLElBQUksQ0FBQyxZQUFZO1lBQ3BDLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVztZQUM3QixJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUk7WUFDZixLQUFLLEVBQUUsdUJBQWdC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QyxLQUFhOzs7Ozs7Ozs7O1FBQ2hDLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLEtBQUssS0FBSyxDQUFDLEVBQUU7WUFBRSxPQUFPO1NBQUU7UUFDbkQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7S0FDekI7SUFFUyxRQUFRO1FBQ2hCLE1BQU0sTUFBTSxHQUFHLElBQUksS0FBSyxFQUFVLENBQUM7UUFFbkMsaURBQWlEO1FBQ2pELElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxPQUFPLEVBQUU7WUFDekIsTUFBTSxDQUFDLElBQUksQ0FBQyxnRUFBZ0UsQ0FBQyxDQUFDO1NBQy9FO1FBRUQsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMseUJBQXlCLEVBQUUsQ0FBQyxDQUFDO1FBRTFELE9BQU8sTUFBTSxDQUFDO0tBQ2Y7O0FBcE1ILHNDQXFNQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFybkZvcm1hdCwgUmVzb3VyY2UsIFN0YWNrLCBBcm4sIEF3cyB9IGZyb20gJ0Bhd3MtY2RrL2NvcmUnO1xuaW1wb3J0IHsgQ29uc3RydWN0IH0gZnJvbSAnY29uc3RydWN0cyc7XG5pbXBvcnQgeyBJR3JvdXAgfSBmcm9tICcuL2dyb3VwJztcbmltcG9ydCB7IENmbk1hbmFnZWRQb2xpY3kgfSBmcm9tICcuL2lhbS5nZW5lcmF0ZWQnO1xuaW1wb3J0IHsgUG9saWN5RG9jdW1lbnQgfSBmcm9tICcuL3BvbGljeS1kb2N1bWVudCc7XG5pbXBvcnQgeyBQb2xpY3lTdGF0ZW1lbnQgfSBmcm9tICcuL3BvbGljeS1zdGF0ZW1lbnQnO1xuaW1wb3J0IHsgSVJvbGUgfSBmcm9tICcuL3JvbGUnO1xuaW1wb3J0IHsgSVVzZXIgfSBmcm9tICcuL3VzZXInO1xuaW1wb3J0IHsgdW5kZWZpbmVkSWZFbXB0eSB9IGZyb20gJy4vdXRpbCc7XG5cbi8qKlxuICogQSBtYW5hZ2VkIHBvbGljeVxuICovXG5leHBvcnQgaW50ZXJmYWNlIElNYW5hZ2VkUG9saWN5IHtcbiAgLyoqXG4gICAqIFRoZSBBUk4gb2YgdGhlIG1hbmFnZWQgcG9saWN5XG4gICAqIEBhdHRyaWJ1dGVcbiAgICovXG4gIHJlYWRvbmx5IG1hbmFnZWRQb2xpY3lBcm46IHN0cmluZztcbn1cblxuLyoqXG4gKiBQcm9wZXJ0aWVzIGZvciBkZWZpbmluZyBhbiBJQU0gbWFuYWdlZCBwb2xpY3lcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBNYW5hZ2VkUG9saWN5UHJvcHMge1xuICAvKipcbiAgICogVGhlIG5hbWUgb2YgdGhlIG1hbmFnZWQgcG9saWN5LiBJZiB5b3Ugc3BlY2lmeSBtdWx0aXBsZSBwb2xpY2llcyBmb3IgYW4gZW50aXR5LFxuICAgKiBzcGVjaWZ5IHVuaXF1ZSBuYW1lcy4gRm9yIGV4YW1wbGUsIGlmIHlvdSBzcGVjaWZ5IGEgbGlzdCBvZiBwb2xpY2llcyBmb3JcbiAgICogYW4gSUFNIHJvbGUsIGVhY2ggcG9saWN5IG11c3QgaGF2ZSBhIHVuaXF1ZSBuYW1lLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIEEgbmFtZSBpcyBhdXRvbWF0aWNhbGx5IGdlbmVyYXRlZC5cbiAgICovXG4gIHJlYWRvbmx5IG1hbmFnZWRQb2xpY3lOYW1lPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBBIGRlc2NyaXB0aW9uIG9mIHRoZSBtYW5hZ2VkIHBvbGljeS4gVHlwaWNhbGx5IHVzZWQgdG8gc3RvcmUgaW5mb3JtYXRpb24gYWJvdXQgdGhlXG4gICAqIHBlcm1pc3Npb25zIGRlZmluZWQgaW4gdGhlIHBvbGljeS4gRm9yIGV4YW1wbGUsIFwiR3JhbnRzIGFjY2VzcyB0byBwcm9kdWN0aW9uIER5bmFtb0RCIHRhYmxlcy5cIlxuICAgKiBUaGUgcG9saWN5IGRlc2NyaXB0aW9uIGlzIGltbXV0YWJsZS4gQWZ0ZXIgYSB2YWx1ZSBpcyBhc3NpZ25lZCwgaXQgY2Fubm90IGJlIGNoYW5nZWQuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gZW1wdHlcbiAgICovXG4gIHJlYWRvbmx5IGRlc2NyaXB0aW9uPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgcGF0aCBmb3IgdGhlIHBvbGljeS4gVGhpcyBwYXJhbWV0ZXIgYWxsb3dzICh0aHJvdWdoIGl0cyByZWdleCBwYXR0ZXJuKSBhIHN0cmluZyBvZiBjaGFyYWN0ZXJzXG4gICAqIGNvbnNpc3Rpbmcgb2YgZWl0aGVyIGEgZm9yd2FyZCBzbGFzaCAoLykgYnkgaXRzZWxmIG9yIGEgc3RyaW5nIHRoYXQgbXVzdCBiZWdpbiBhbmQgZW5kIHdpdGggZm9yd2FyZCBzbGFzaGVzLlxuICAgKiBJbiBhZGRpdGlvbiwgaXQgY2FuIGNvbnRhaW4gYW55IEFTQ0lJIGNoYXJhY3RlciBmcm9tIHRoZSAhIChcXHUwMDIxKSB0aHJvdWdoIHRoZSBERUwgY2hhcmFjdGVyIChcXHUwMDdGKSxcbiAgICogaW5jbHVkaW5nIG1vc3QgcHVuY3R1YXRpb24gY2hhcmFjdGVycywgZGlnaXRzLCBhbmQgdXBwZXIgYW5kIGxvd2VyY2FzZWQgbGV0dGVycy5cbiAgICpcbiAgICogRm9yIG1vcmUgaW5mb3JtYXRpb24gYWJvdXQgcGF0aHMsIHNlZSBJQU0gSWRlbnRpZmllcnMgaW4gdGhlIElBTSBVc2VyIEd1aWRlLlxuICAgKlxuICAgKiBAZGVmYXVsdCAtIFwiL1wiXG4gICAqL1xuICByZWFkb25seSBwYXRoPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBVc2VycyB0byBhdHRhY2ggdGhpcyBwb2xpY3kgdG8uXG4gICAqIFlvdSBjYW4gYWxzbyB1c2UgYGF0dGFjaFRvVXNlcih1c2VyKWAgdG8gYXR0YWNoIHRoaXMgcG9saWN5IHRvIGEgdXNlci5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyB1c2Vycy5cbiAgICovXG4gIHJlYWRvbmx5IHVzZXJzPzogSVVzZXJbXTtcblxuICAvKipcbiAgICogUm9sZXMgdG8gYXR0YWNoIHRoaXMgcG9saWN5IHRvLlxuICAgKiBZb3UgY2FuIGFsc28gdXNlIGBhdHRhY2hUb1JvbGUocm9sZSlgIHRvIGF0dGFjaCB0aGlzIHBvbGljeSB0byBhIHJvbGUuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gcm9sZXMuXG4gICAqL1xuICByZWFkb25seSByb2xlcz86IElSb2xlW107XG5cbiAgLyoqXG4gICAqIEdyb3VwcyB0byBhdHRhY2ggdGhpcyBwb2xpY3kgdG8uXG4gICAqIFlvdSBjYW4gYWxzbyB1c2UgYGF0dGFjaFRvR3JvdXAoZ3JvdXApYCB0byBhdHRhY2ggdGhpcyBwb2xpY3kgdG8gYSBncm91cC5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBncm91cHMuXG4gICAqL1xuICByZWFkb25seSBncm91cHM/OiBJR3JvdXBbXTtcblxuICAvKipcbiAgICogSW5pdGlhbCBzZXQgb2YgcGVybWlzc2lvbnMgdG8gYWRkIHRvIHRoaXMgcG9saWN5IGRvY3VtZW50LlxuICAgKiBZb3UgY2FuIGFsc28gdXNlIGBhZGRQZXJtaXNzaW9uKHN0YXRlbWVudClgIHRvIGFkZCBwZXJtaXNzaW9ucyBsYXRlci5cbiAgICpcbiAgICogQGRlZmF1bHQgLSBObyBzdGF0ZW1lbnRzLlxuICAgKi9cbiAgcmVhZG9ubHkgc3RhdGVtZW50cz86IFBvbGljeVN0YXRlbWVudFtdO1xuXG4gIC8qKlxuICAgKiBJbml0aWFsIFBvbGljeURvY3VtZW50IHRvIHVzZSBmb3IgdGhpcyBNYW5hZ2VkUG9saWN5LiBJZiBvbWl0ZWQsIGFueVxuICAgKiBgUG9saWN5U3RhdGVtZW50YCBwcm92aWRlZCBpbiB0aGUgYHN0YXRlbWVudHNgIHByb3BlcnR5IHdpbGwgYmUgYXBwbGllZFxuICAgKiBhZ2FpbnN0IHRoZSBlbXB0eSBkZWZhdWx0IGBQb2xpY3lEb2N1bWVudGAuXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gQW4gZW1wdHkgcG9saWN5LlxuICAgKi9cbiAgcmVhZG9ubHkgZG9jdW1lbnQ/OiBQb2xpY3lEb2N1bWVudDtcbn1cblxuLyoqXG4gKiBNYW5hZ2VkIHBvbGljeVxuICpcbiAqL1xuZXhwb3J0IGNsYXNzIE1hbmFnZWRQb2xpY3kgZXh0ZW5kcyBSZXNvdXJjZSBpbXBsZW1lbnRzIElNYW5hZ2VkUG9saWN5IHtcbiAgLyoqXG4gICAqIEltcG9ydCBhIGN1c3RvbWVyIG1hbmFnZWQgcG9saWN5IGZyb20gdGhlIG1hbmFnZWRQb2xpY3lOYW1lLlxuICAgKlxuICAgKiBGb3IgdGhpcyBtYW5hZ2VkIHBvbGljeSwgeW91IG9ubHkgbmVlZCB0byBrbm93IHRoZSBuYW1lIHRvIGJlIGFibGUgdG8gdXNlIGl0LlxuICAgKlxuICAgKi9cbiAgcHVibGljIHN0YXRpYyBmcm9tTWFuYWdlZFBvbGljeU5hbWUoc2NvcGU6IENvbnN0cnVjdCwgaWQ6IHN0cmluZywgbWFuYWdlZFBvbGljeU5hbWU6IHN0cmluZyk6IElNYW5hZ2VkUG9saWN5IHtcbiAgICBjbGFzcyBJbXBvcnQgZXh0ZW5kcyBSZXNvdXJjZSBpbXBsZW1lbnRzIElNYW5hZ2VkUG9saWN5IHtcbiAgICAgIHB1YmxpYyByZWFkb25seSBtYW5hZ2VkUG9saWN5QXJuID0gU3RhY2sub2Yoc2NvcGUpLmZvcm1hdEFybih7XG4gICAgICAgIHNlcnZpY2U6ICdpYW0nLFxuICAgICAgICByZWdpb246ICcnLCAvLyBubyByZWdpb24gZm9yIG1hbmFnZWQgcG9saWN5XG4gICAgICAgIGFjY291bnQ6IFN0YWNrLm9mKHNjb3BlKS5hY2NvdW50LCAvLyBDYW4gdGhpcyBiZSBzb21ldGhpbmcgdGhlIHVzZXIgc3BlY2lmaWVzP1xuICAgICAgICByZXNvdXJjZTogJ3BvbGljeScsXG4gICAgICAgIHJlc291cmNlTmFtZTogbWFuYWdlZFBvbGljeU5hbWUsXG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBJbXBvcnQoc2NvcGUsIGlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbXBvcnQgYW4gZXh0ZXJuYWwgbWFuYWdlZCBwb2xpY3kgYnkgQVJOLlxuICAgKlxuICAgKiBGb3IgdGhpcyBtYW5hZ2VkIHBvbGljeSwgeW91IG9ubHkgbmVlZCB0byBrbm93IHRoZSBBUk4gdG8gYmUgYWJsZSB0byB1c2UgaXQuXG4gICAqIFRoaXMgY2FuIGJlIHVzZWZ1bCBpZiB5b3UgZ290IHRoZSBBUk4gZnJvbSBhIENsb3VkRm9ybWF0aW9uIEV4cG9ydC5cbiAgICpcbiAgICogSWYgdGhlIGltcG9ydGVkIE1hbmFnZWQgUG9saWN5IEFSTiBpcyBhIFRva2VuIChzdWNoIGFzIGFcbiAgICogYENmblBhcmFtZXRlci52YWx1ZUFzU3RyaW5nYCBvciBhIGBGbi5pbXBvcnRWYWx1ZSgpYCkgKmFuZCogdGhlIHJlZmVyZW5jZWRcbiAgICogbWFuYWdlZCBwb2xpY3kgaGFzIGEgYHBhdGhgIChsaWtlIGBhcm46Li4uOnBvbGljeS9BZG1pblBvbGljeS9BZG1pbkFsbG93YCksIHRoZVxuICAgKiBgbWFuYWdlZFBvbGljeU5hbWVgIHByb3BlcnR5IHdpbGwgbm90IHJlc29sdmUgdG8gdGhlIGNvcnJlY3QgdmFsdWUuIEluc3RlYWQgaXRcbiAgICogd2lsbCByZXNvbHZlIHRvIHRoZSBmaXJzdCBwYXRoIGNvbXBvbmVudC4gV2UgdW5mb3J0dW5hdGVseSBjYW5ub3QgZXhwcmVzc1xuICAgKiB0aGUgY29ycmVjdCBjYWxjdWxhdGlvbiBvZiB0aGUgZnVsbCBwYXRoIG5hbWUgYXMgYSBDbG91ZEZvcm1hdGlvblxuICAgKiBleHByZXNzaW9uLiBJbiB0aGlzIHNjZW5hcmlvIHRoZSBNYW5hZ2VkIFBvbGljeSBBUk4gc2hvdWxkIGJlIHN1cHBsaWVkIHdpdGhvdXQgdGhlXG4gICAqIGBwYXRoYCBpbiBvcmRlciB0byByZXNvbHZlIHRoZSBjb3JyZWN0IG1hbmFnZWQgcG9saWN5IHJlc291cmNlLlxuICAgKlxuICAgKiBAcGFyYW0gc2NvcGUgY29uc3RydWN0IHNjb3BlXG4gICAqIEBwYXJhbSBpZCBjb25zdHJ1Y3QgaWRcbiAgICogQHBhcmFtIG1hbmFnZWRQb2xpY3lBcm4gdGhlIEFSTiBvZiB0aGUgbWFuYWdlZCBwb2xpY3kgdG8gaW1wb3J0XG4gICAqL1xuICBwdWJsaWMgc3RhdGljIGZyb21NYW5hZ2VkUG9saWN5QXJuKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcsIG1hbmFnZWRQb2xpY3lBcm46IHN0cmluZyk6IElNYW5hZ2VkUG9saWN5IHtcbiAgICBjbGFzcyBJbXBvcnQgZXh0ZW5kcyBSZXNvdXJjZSBpbXBsZW1lbnRzIElNYW5hZ2VkUG9saWN5IHtcbiAgICAgIHB1YmxpYyByZWFkb25seSBtYW5hZ2VkUG9saWN5QXJuID0gbWFuYWdlZFBvbGljeUFybjtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBJbXBvcnQoc2NvcGUsIGlkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJbXBvcnQgYSBtYW5hZ2VkIHBvbGljeSBmcm9tIG9uZSBvZiB0aGUgcG9saWNpZXMgdGhhdCBBV1MgbWFuYWdlcy5cbiAgICpcbiAgICogRm9yIHRoaXMgbWFuYWdlZCBwb2xpY3ksIHlvdSBvbmx5IG5lZWQgdG8ga25vdyB0aGUgbmFtZSB0byBiZSBhYmxlIHRvIHVzZSBpdC5cbiAgICpcbiAgICogU29tZSBtYW5hZ2VkIHBvbGljeSBuYW1lcyBzdGFydCB3aXRoIFwic2VydmljZS1yb2xlL1wiLCBzb21lIHN0YXJ0IHdpdGhcbiAgICogXCJqb2ItZnVuY3Rpb24vXCIsIGFuZCBzb21lIGRvbid0IHN0YXJ0IHdpdGggYW55dGhpbmcuIEluY2x1ZGUgdGhlXG4gICAqIHByZWZpeCB3aGVuIGNvbnN0cnVjdGluZyB0aGlzIG9iamVjdC5cbiAgICovXG4gIHB1YmxpYyBzdGF0aWMgZnJvbUF3c01hbmFnZWRQb2xpY3lOYW1lKG1hbmFnZWRQb2xpY3lOYW1lOiBzdHJpbmcpOiBJTWFuYWdlZFBvbGljeSB7XG4gICAgY2xhc3MgQXdzTWFuYWdlZFBvbGljeSBpbXBsZW1lbnRzIElNYW5hZ2VkUG9saWN5IHtcbiAgICAgIHB1YmxpYyByZWFkb25seSBtYW5hZ2VkUG9saWN5QXJuID0gQXJuLmZvcm1hdCh7XG4gICAgICAgIHBhcnRpdGlvbjogQXdzLlBBUlRJVElPTixcbiAgICAgICAgc2VydmljZTogJ2lhbScsXG4gICAgICAgIHJlZ2lvbjogJycsIC8vIG5vIHJlZ2lvbiBmb3IgbWFuYWdlZCBwb2xpY3lcbiAgICAgICAgYWNjb3VudDogJ2F3cycsIC8vIHRoZSBhY2NvdW50IGZvciBhIG1hbmFnZWQgcG9saWN5IGlzICdhd3MnXG4gICAgICAgIHJlc291cmNlOiAncG9saWN5JyxcbiAgICAgICAgcmVzb3VyY2VOYW1lOiBtYW5hZ2VkUG9saWN5TmFtZSxcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IEF3c01hbmFnZWRQb2xpY3koKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBBUk4gb2YgdGhpcyBtYW5hZ2VkIHBvbGljeS5cbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IG1hbmFnZWRQb2xpY3lBcm46IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIHBvbGljeSBkb2N1bWVudC5cbiAgICovXG4gIHB1YmxpYyByZWFkb25seSBkb2N1bWVudCA9IG5ldyBQb2xpY3lEb2N1bWVudCgpO1xuXG4gIC8qKlxuICAgKiBUaGUgbmFtZSBvZiB0aGlzIHBvbGljeS5cbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IG1hbmFnZWRQb2xpY3lOYW1lOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBkZXNjcmlwdGlvbiBvZiB0aGlzIHBvbGljeS5cbiAgICpcbiAgICogQGF0dHJpYnV0ZVxuICAgKi9cbiAgcHVibGljIHJlYWRvbmx5IGRlc2NyaXB0aW9uOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIFRoZSBwYXRoIG9mIHRoaXMgcG9saWN5LlxuICAgKlxuICAgKiBAYXR0cmlidXRlXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgcGF0aDogc3RyaW5nO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgcm9sZXMgPSBuZXcgQXJyYXk8SVJvbGU+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgdXNlcnMgPSBuZXcgQXJyYXk8SVVzZXI+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgZ3JvdXBzID0gbmV3IEFycmF5PElHcm91cD4oKTtcblxuICBjb25zdHJ1Y3RvcihzY29wZTogQ29uc3RydWN0LCBpZDogc3RyaW5nLCBwcm9wczogTWFuYWdlZFBvbGljeVByb3BzID0ge30pIHtcbiAgICBzdXBlcihzY29wZSwgaWQsIHtcbiAgICAgIHBoeXNpY2FsTmFtZTogcHJvcHMubWFuYWdlZFBvbGljeU5hbWUsXG4gICAgfSk7XG5cbiAgICB0aGlzLmRlc2NyaXB0aW9uID0gcHJvcHMuZGVzY3JpcHRpb24gfHwgJyc7XG4gICAgdGhpcy5wYXRoID0gcHJvcHMucGF0aCB8fCAnLyc7XG5cbiAgICBpZiAocHJvcHMuZG9jdW1lbnQpIHtcbiAgICAgIHRoaXMuZG9jdW1lbnQgPSBwcm9wcy5kb2N1bWVudDtcbiAgICB9XG5cbiAgICBjb25zdCByZXNvdXJjZSA9IG5ldyBDZm5NYW5hZ2VkUG9saWN5KHRoaXMsICdSZXNvdXJjZScsIHtcbiAgICAgIHBvbGljeURvY3VtZW50OiB0aGlzLmRvY3VtZW50LFxuICAgICAgbWFuYWdlZFBvbGljeU5hbWU6IHRoaXMucGh5c2ljYWxOYW1lLFxuICAgICAgZGVzY3JpcHRpb246IHRoaXMuZGVzY3JpcHRpb24sXG4gICAgICBwYXRoOiB0aGlzLnBhdGgsXG4gICAgICByb2xlczogdW5kZWZpbmVkSWZFbXB0eSgoKSA9PiB0aGlzLnJvbGVzLm1hcChyID0+IHIucm9sZU5hbWUpKSxcbiAgICAgIHVzZXJzOiB1bmRlZmluZWRJZkVtcHR5KCgpID0+IHRoaXMudXNlcnMubWFwKHUgPT4gdS51c2VyTmFtZSkpLFxuICAgICAgZ3JvdXBzOiB1bmRlZmluZWRJZkVtcHR5KCgpID0+IHRoaXMuZ3JvdXBzLm1hcChnID0+IGcuZ3JvdXBOYW1lKSksXG4gICAgfSk7XG5cbiAgICBpZiAocHJvcHMudXNlcnMpIHtcbiAgICAgIHByb3BzLnVzZXJzLmZvckVhY2godSA9PiB0aGlzLmF0dGFjaFRvVXNlcih1KSk7XG4gICAgfVxuXG4gICAgaWYgKHByb3BzLmdyb3Vwcykge1xuICAgICAgcHJvcHMuZ3JvdXBzLmZvckVhY2goZyA9PiB0aGlzLmF0dGFjaFRvR3JvdXAoZykpO1xuICAgIH1cblxuICAgIGlmIChwcm9wcy5yb2xlcykge1xuICAgICAgcHJvcHMucm9sZXMuZm9yRWFjaChyID0+IHRoaXMuYXR0YWNoVG9Sb2xlKHIpKTtcbiAgICB9XG5cbiAgICBpZiAocHJvcHMuc3RhdGVtZW50cykge1xuICAgICAgcHJvcHMuc3RhdGVtZW50cy5mb3JFYWNoKHAgPT4gdGhpcy5hZGRTdGF0ZW1lbnRzKHApKTtcbiAgICB9XG5cbiAgICAvLyBhcm46YXdzOmlhbTo6MTIzNDU2Nzg5MDEyOnBvbGljeS90ZXN0c3RhY2stQ3JlYXRlVGVzdERCUG9saWN5LTE2TTIzWUUzQ1M3MDBcbiAgICB0aGlzLm1hbmFnZWRQb2xpY3lOYW1lID0gdGhpcy5nZXRSZXNvdXJjZU5hbWVBdHRyaWJ1dGUoU3RhY2sub2YodGhpcykuc3BsaXRBcm4ocmVzb3VyY2UucmVmLCBBcm5Gb3JtYXQuU0xBU0hfUkVTT1VSQ0VfTkFNRSkucmVzb3VyY2VOYW1lISk7XG4gICAgdGhpcy5tYW5hZ2VkUG9saWN5QXJuID0gdGhpcy5nZXRSZXNvdXJjZUFybkF0dHJpYnV0ZShyZXNvdXJjZS5yZWYsIHtcbiAgICAgIHJlZ2lvbjogJycsIC8vIElBTSBpcyBnbG9iYWwgaW4gZWFjaCBwYXJ0aXRpb25cbiAgICAgIHNlcnZpY2U6ICdpYW0nLFxuICAgICAgcmVzb3VyY2U6ICdwb2xpY3knLFxuICAgICAgcmVzb3VyY2VOYW1lOiB0aGlzLnBoeXNpY2FsTmFtZSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBZGRzIGEgc3RhdGVtZW50IHRvIHRoZSBwb2xpY3kgZG9jdW1lbnQuXG4gICAqL1xuICBwdWJsaWMgYWRkU3RhdGVtZW50cyguLi5zdGF0ZW1lbnQ6IFBvbGljeVN0YXRlbWVudFtdKSB7XG4gICAgdGhpcy5kb2N1bWVudC5hZGRTdGF0ZW1lbnRzKC4uLnN0YXRlbWVudCk7XG4gIH1cblxuICAvKipcbiAgICogQXR0YWNoZXMgdGhpcyBwb2xpY3kgdG8gYSB1c2VyLlxuICAgKi9cbiAgcHVibGljIGF0dGFjaFRvVXNlcih1c2VyOiBJVXNlcikge1xuICAgIGlmICh0aGlzLnVzZXJzLmZpbmQodSA9PiB1ID09PSB1c2VyKSkgeyByZXR1cm47IH1cbiAgICB0aGlzLnVzZXJzLnB1c2godXNlcik7XG4gIH1cblxuICAvKipcbiAgICogQXR0YWNoZXMgdGhpcyBwb2xpY3kgdG8gYSByb2xlLlxuICAgKi9cbiAgcHVibGljIGF0dGFjaFRvUm9sZShyb2xlOiBJUm9sZSkge1xuICAgIGlmICh0aGlzLnJvbGVzLmZpbmQociA9PiByID09PSByb2xlKSkgeyByZXR1cm47IH1cbiAgICB0aGlzLnJvbGVzLnB1c2gocm9sZSk7XG4gIH1cblxuICAvKipcbiAgICogQXR0YWNoZXMgdGhpcyBwb2xpY3kgdG8gYSBncm91cC5cbiAgICovXG4gIHB1YmxpYyBhdHRhY2hUb0dyb3VwKGdyb3VwOiBJR3JvdXApIHtcbiAgICBpZiAodGhpcy5ncm91cHMuZmluZChnID0+IGcgPT09IGdyb3VwKSkgeyByZXR1cm47IH1cbiAgICB0aGlzLmdyb3Vwcy5wdXNoKGdyb3VwKTtcbiAgfVxuXG4gIHByb3RlY3RlZCB2YWxpZGF0ZSgpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgcmVzdWx0ID0gbmV3IEFycmF5PHN0cmluZz4oKTtcblxuICAgIC8vIHZhbGlkYXRlIHRoYXQgdGhlIHBvbGljeSBkb2N1bWVudCBpcyBub3QgZW1wdHlcbiAgICBpZiAodGhpcy5kb2N1bWVudC5pc0VtcHR5KSB7XG4gICAgICByZXN1bHQucHVzaCgnTWFuYWdlZCBQb2xpY3kgaXMgZW1wdHkuIFlvdSBtdXN0IGFkZCBzdGF0ZW1lbnRzIHRvIHRoZSBwb2xpY3knKTtcbiAgICB9XG5cbiAgICByZXN1bHQucHVzaCguLi50aGlzLmRvY3VtZW50LnZhbGlkYXRlRm9ySWRlbnRpdHlQb2xpY3koKSk7XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59XG4iXX0= |
\ | No newline at end of file |