@aws-mdaa/dataops-job-l3-construct 1.5.0 → 1.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/.jsii +38 -28
- package/README.md +5 -0
- package/lib/dataops-job-l3-construct.d.ts +8 -1
- package/lib/dataops-job-l3-construct.js +40 -13
- package/node_modules/@aws-mdaa/config/README.md +3 -0
- package/node_modules/@aws-mdaa/config/lib/blueprint-value-transformer.d.ts +20 -0
- package/node_modules/@aws-mdaa/config/lib/blueprint-value-transformer.js +70 -0
- package/node_modules/@aws-mdaa/config/lib/blueprint-value-transformer.ts +88 -0
- package/node_modules/@aws-mdaa/config/lib/config.d.ts +87 -0
- package/node_modules/@aws-mdaa/config/lib/config.js +7 -0
- package/node_modules/@aws-mdaa/config/lib/config.ts +92 -0
- package/node_modules/@aws-mdaa/config/lib/index.d.ts +11 -0
- package/node_modules/@aws-mdaa/config/lib/index.js +28 -0
- package/node_modules/@aws-mdaa/config/lib/index.ts +12 -0
- package/node_modules/@aws-mdaa/config/lib/param-transformer.d.ts +49 -0
- package/node_modules/@aws-mdaa/config/lib/param-transformer.js +160 -0
- package/node_modules/@aws-mdaa/config/lib/param-transformer.ts +159 -0
- package/node_modules/@aws-mdaa/config/lib/path-value-transformer.d.ts +10 -0
- package/node_modules/@aws-mdaa/config/lib/path-value-transformer.js +30 -0
- package/node_modules/@aws-mdaa/config/lib/path-value-transformer.ts +27 -0
- package/node_modules/@aws-mdaa/config/lib/ref-value-transformer.d.ts +44 -0
- package/node_modules/@aws-mdaa/config/lib/ref-value-transformer.js +243 -0
- package/node_modules/@aws-mdaa/config/lib/ref-value-transformer.ts +302 -0
- package/node_modules/@aws-mdaa/config/lib/ssm-ref-transformer.d.ts +8 -0
- package/node_modules/@aws-mdaa/config/lib/ssm-ref-transformer.js +22 -0
- package/node_modules/@aws-mdaa/config/lib/ssm-ref-transformer.ts +21 -0
- package/node_modules/@aws-mdaa/config/lib/transformer.d.ts +35 -0
- package/node_modules/@aws-mdaa/config/lib/transformer.js +66 -0
- package/node_modules/@aws-mdaa/config/lib/transformer.ts +74 -0
- package/node_modules/@aws-mdaa/config/package.json +42 -0
- package/node_modules/@aws-mdaa/config/test/blueprint-value-transformer.test.js +224 -0
- package/node_modules/@aws-mdaa/config/test/blueprint-value-transformer.test.ts +259 -0
- package/node_modules/@aws-mdaa/config/test/config-nt.test.d.ts +5 -0
- package/node_modules/@aws-mdaa/config/test/config-nt.test.js +129 -0
- package/node_modules/@aws-mdaa/config/test/config-nt.test.ts +163 -0
- package/node_modules/@aws-mdaa/config/test/config.test.d.ts +5 -0
- package/node_modules/@aws-mdaa/config/test/config.test.js +409 -0
- package/node_modules/@aws-mdaa/config/test/config.test.ts +517 -0
- package/node_modules/@aws-mdaa/config/test/param-transformer.test.d.ts +5 -0
- package/node_modules/@aws-mdaa/config/test/param-transformer.test.js +216 -0
- package/node_modules/@aws-mdaa/config/test/param-transformer.test.ts +234 -0
- package/node_modules/@aws-mdaa/config/test/path-value-transformer.test.d.ts +5 -0
- package/node_modules/@aws-mdaa/config/test/path-value-transformer.test.js +59 -0
- package/node_modules/@aws-mdaa/config/test/path-value-transformer.test.ts +68 -0
- package/node_modules/@aws-mdaa/config/test/ref-value-transformer.test.d.ts +5 -0
- package/node_modules/@aws-mdaa/config/test/ref-value-transformer.test.js +254 -0
- package/node_modules/@aws-mdaa/config/test/ref-value-transformer.test.ts +304 -0
- package/node_modules/@aws-mdaa/config/test/ssm-ref-transformer.test.d.ts +5 -0
- package/node_modules/@aws-mdaa/config/test/ssm-ref-transformer.test.js +66 -0
- package/node_modules/@aws-mdaa/config/test/ssm-ref-transformer.test.ts +79 -0
- package/node_modules/@aws-mdaa/config/tsconfig.tsbuildinfo +1 -0
- package/node_modules/lodash/README.md +2 -2
- package/node_modules/lodash/_baseOrderBy.js +1 -1
- package/node_modules/lodash/_baseUnset.js +7 -20
- package/node_modules/lodash/_setCacheHas.js +1 -1
- package/node_modules/lodash/compact.js +1 -1
- package/node_modules/lodash/core.js +3 -3
- package/node_modules/lodash/core.min.js +26 -25
- package/node_modules/lodash/fromPairs.js +3 -1
- package/node_modules/lodash/lodash.js +38 -27
- package/node_modules/lodash/lodash.min.js +125 -129
- package/node_modules/lodash/package.json +4 -2
- package/node_modules/lodash/random.js +9 -0
- package/node_modules/lodash/template.js +16 -4
- package/node_modules/lodash/templateSettings.js +4 -0
- package/package.json +27 -32
- package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/README.md +0 -185
- package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/lib/index.d.ts +0 -57
- package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/lib/index.js +0 -198
- package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/lib/index.ts +0 -241
- package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/package.json +0 -44
- package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/test/bucketpolicy-helper.test.js +0 -200
- package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/test/bucketpolicy-helper.test.ts +0 -215
- package/node_modules/@aws-mdaa/s3-bucketpolicy-helper/tsconfig.tsbuildinfo +0 -1
- package/node_modules/@aws-mdaa/s3-inventory-helper/.npmignore +0 -34
- package/node_modules/@aws-mdaa/s3-inventory-helper/README.md +0 -3
- package/node_modules/@aws-mdaa/s3-inventory-helper/jest.config.js +0 -5
- package/node_modules/@aws-mdaa/s3-inventory-helper/lib/index.d.ts +0 -48
- package/node_modules/@aws-mdaa/s3-inventory-helper/lib/index.js +0 -213
- package/node_modules/@aws-mdaa/s3-inventory-helper/lib/index.ts +0 -241
- package/node_modules/@aws-mdaa/s3-inventory-helper/package.json +0 -44
- package/node_modules/@aws-mdaa/s3-inventory-helper/test/TODO +0 -0
- package/node_modules/@aws-mdaa/s3-inventory-helper/tsconfig.json +0 -40
- package/node_modules/@aws-mdaa/s3-inventory-helper/tsconfig.tsbuildinfo +0 -1
- package/node_modules/@aws-mdaa/s3-inventory-helper/typedoc.json +0 -7
- /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper → config}/.npmignore +0 -0
- /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper → config}/jest.config.js +0 -0
- /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper/test/bucketpolicy-helper.test.d.ts → config/test/blueprint-value-transformer.test.d.ts} +0 -0
- /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper → config}/tsconfig.json +0 -0
- /package/node_modules/@aws-mdaa/{s3-bucketpolicy-helper → config}/typedoc.json +0 -0
|
@@ -1,198 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
/*!
|
|
3
|
-
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
4
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
5
|
-
*/
|
|
6
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
7
|
-
exports.RestrictBucketToRoles = exports.RestrictObjectPrefixToRoles = void 0;
|
|
8
|
-
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
|
|
9
|
-
/** Helper class for generating S3 bucket policy statements which grant access to specific object prefixes */
|
|
10
|
-
class RestrictObjectPrefixToRoles {
|
|
11
|
-
constructor(props) {
|
|
12
|
-
this._readStatements = [];
|
|
13
|
-
this._readWriteStatements = [];
|
|
14
|
-
this._readWriteSuperStatements = [];
|
|
15
|
-
this._formattedPrefix = '/' + this.formatS3Prefix(props.s3Prefix) + '/*';
|
|
16
|
-
// Covers our case where two / get resolved because our prefix is actually /
|
|
17
|
-
this._formattedPrefix = this._formattedPrefix.replace(/\/\//, '/');
|
|
18
|
-
// FEDERATED / READ
|
|
19
|
-
if (props.readRoleIds != undefined && props.readRoleIds.length > 0) {
|
|
20
|
-
// Construct our User:Id roles for read
|
|
21
|
-
const statement = this._readStatementScaffold(props);
|
|
22
|
-
statement.addCondition('StringLike', { 'aws:userId': props.readRoleIds.map(x => `${x}:*`) });
|
|
23
|
-
statement.addAnyPrincipal();
|
|
24
|
-
this._readStatements.push(statement);
|
|
25
|
-
}
|
|
26
|
-
// FEDERATED / READWRITE
|
|
27
|
-
if (props.readWriteRoleIds != undefined && props.readWriteRoleIds.length > 0) {
|
|
28
|
-
const statement = this._readWriteStatementScaffold(props);
|
|
29
|
-
statement.addCondition('StringLike', { 'aws:userId': props.readWriteRoleIds.map(x => `${x}:*`) });
|
|
30
|
-
statement.addAnyPrincipal();
|
|
31
|
-
this._readWriteStatements.push(statement);
|
|
32
|
-
}
|
|
33
|
-
// FEDERATED / READWRITESUPER
|
|
34
|
-
if (props.readWriteSuperRoleIds != undefined && props.readWriteSuperRoleIds.length > 0) {
|
|
35
|
-
const statement = this._readWriteSuperStatementScaffold(props);
|
|
36
|
-
statement.addCondition('StringLike', { 'aws:userId': props.readWriteSuperRoleIds.map(x => `${x}:*`) });
|
|
37
|
-
statement.addAnyPrincipal();
|
|
38
|
-
this._readWriteSuperStatements.push(statement);
|
|
39
|
-
}
|
|
40
|
-
// NONFEDERATED / READ
|
|
41
|
-
if (props.readPrincipals != undefined && props.readPrincipals.length > 0) {
|
|
42
|
-
const statement = this._readStatementScaffold(props);
|
|
43
|
-
props.readPrincipals.forEach(principal => {
|
|
44
|
-
statement.addPrincipals(principal);
|
|
45
|
-
});
|
|
46
|
-
this._readStatements.push(statement);
|
|
47
|
-
}
|
|
48
|
-
// NONFEDERATED / READWRITE
|
|
49
|
-
if (props.readWritePrincipals != undefined && props.readWritePrincipals.length > 0) {
|
|
50
|
-
const statement = this._readWriteStatementScaffold(props);
|
|
51
|
-
props.readWritePrincipals.forEach(principal => {
|
|
52
|
-
statement.addPrincipals(principal);
|
|
53
|
-
});
|
|
54
|
-
this._readWriteStatements.push(statement);
|
|
55
|
-
}
|
|
56
|
-
// NONFEDERATED / READWRITESUPER
|
|
57
|
-
if (props.readWriteSuperPrincipals != undefined && props.readWriteSuperPrincipals.length > 0) {
|
|
58
|
-
const statement = this._readWriteSuperStatementScaffold(props);
|
|
59
|
-
props.readWriteSuperPrincipals.forEach(principal => {
|
|
60
|
-
statement.addPrincipals(principal);
|
|
61
|
-
});
|
|
62
|
-
this._readWriteSuperStatements.push(statement);
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
_readStatementScaffold(props) {
|
|
66
|
-
return new aws_iam_1.PolicyStatement({
|
|
67
|
-
sid: `${props.s3Prefix.replace(/\\W/g, '')}_Read`,
|
|
68
|
-
effect: aws_iam_1.Effect.ALLOW,
|
|
69
|
-
resources: [props.s3Bucket.bucketArn + this._formattedPrefix],
|
|
70
|
-
actions: RestrictObjectPrefixToRoles.READ_ACTIONS,
|
|
71
|
-
});
|
|
72
|
-
}
|
|
73
|
-
_readWriteStatementScaffold(props) {
|
|
74
|
-
return new aws_iam_1.PolicyStatement({
|
|
75
|
-
sid: `${props.s3Prefix.replace(/\\W/g, '')}_ReadWrite`,
|
|
76
|
-
effect: aws_iam_1.Effect.ALLOW,
|
|
77
|
-
resources: [props.s3Bucket.bucketArn + this._formattedPrefix],
|
|
78
|
-
actions: RestrictObjectPrefixToRoles.READ_WRITE_ACTIONS,
|
|
79
|
-
});
|
|
80
|
-
}
|
|
81
|
-
_readWriteSuperStatementScaffold(props) {
|
|
82
|
-
return new aws_iam_1.PolicyStatement({
|
|
83
|
-
sid: `${props.s3Prefix.replace(/\\W/g, '')}_ReadWriteSuper`,
|
|
84
|
-
effect: aws_iam_1.Effect.ALLOW,
|
|
85
|
-
resources: [props.s3Bucket.bucketArn + this._formattedPrefix],
|
|
86
|
-
actions: RestrictObjectPrefixToRoles.READ_WRITE_SUPER_ACTIONS,
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
|
-
readStatements() {
|
|
90
|
-
return this._readStatements;
|
|
91
|
-
}
|
|
92
|
-
readWriteStatements() {
|
|
93
|
-
return this._readWriteStatements;
|
|
94
|
-
}
|
|
95
|
-
readWriteSuperStatements() {
|
|
96
|
-
return this._readWriteSuperStatements;
|
|
97
|
-
}
|
|
98
|
-
statements() {
|
|
99
|
-
return [...this._readStatements, ...this._readWriteStatements, ...this._readWriteSuperStatements];
|
|
100
|
-
}
|
|
101
|
-
formatS3Prefix(prefix) {
|
|
102
|
-
let rawPrefix = prefix;
|
|
103
|
-
// Removes trailing slashes
|
|
104
|
-
rawPrefix = rawPrefix.endsWith('/') ? rawPrefix.slice(0, -1) : rawPrefix;
|
|
105
|
-
// Removes leading slashes
|
|
106
|
-
rawPrefix = rawPrefix.startsWith('/') ? rawPrefix.substring(1) : rawPrefix;
|
|
107
|
-
return rawPrefix;
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
exports.RestrictObjectPrefixToRoles = RestrictObjectPrefixToRoles;
|
|
111
|
-
RestrictObjectPrefixToRoles.READ_ACTIONS = ['s3:GetObject*'];
|
|
112
|
-
RestrictObjectPrefixToRoles.READ_WRITE_ACTIONS = [
|
|
113
|
-
...RestrictObjectPrefixToRoles.READ_ACTIONS,
|
|
114
|
-
's3:PutObject',
|
|
115
|
-
's3:PutObjectTagging',
|
|
116
|
-
's3:DeleteObject',
|
|
117
|
-
];
|
|
118
|
-
RestrictObjectPrefixToRoles.READ_WRITE_SUPER_ACTIONS = [
|
|
119
|
-
...RestrictObjectPrefixToRoles.READ_WRITE_ACTIONS,
|
|
120
|
-
's3:DeleteObjectVersion',
|
|
121
|
-
];
|
|
122
|
-
RestrictObjectPrefixToRoles.BUCKET_ALLOW_ACTIONS = ['s3:List*', 's3:GetBucket*'];
|
|
123
|
-
RestrictObjectPrefixToRoles.BUCKET_DENY_ACTIONS = ['s3:PutObject*', 's3:GetObject*', 's3:DeleteObject*'];
|
|
124
|
-
/** Helper class for generating bucket policy statements
|
|
125
|
-
* which allow or deny access to an entire bucket. Used to
|
|
126
|
-
* create bucket-level default deny statements to block accesses
|
|
127
|
-
* not granted in the bucket policy. */
|
|
128
|
-
class RestrictBucketToRoles {
|
|
129
|
-
constructor(props) {
|
|
130
|
-
this.resource = [];
|
|
131
|
-
this.notResource = [];
|
|
132
|
-
this.denyConditionalNotEquals = {};
|
|
133
|
-
// Statement allowing access to the bucket for the AROAs
|
|
134
|
-
this.allowStatement = new aws_iam_1.PolicyStatement({
|
|
135
|
-
sid: `BucketAllow`,
|
|
136
|
-
effect: aws_iam_1.Effect.ALLOW,
|
|
137
|
-
resources: [props.s3Bucket.bucketArn + '/*', props.s3Bucket.bucketArn],
|
|
138
|
-
actions: RestrictObjectPrefixToRoles.BUCKET_ALLOW_ACTIONS,
|
|
139
|
-
});
|
|
140
|
-
this.allowStatement.addAnyPrincipal();
|
|
141
|
-
this.allowStatement.addCondition('StringLike', { 'aws:userId': props.roleExcludeIds.map(x => `${x}:*`) });
|
|
142
|
-
// Constuct our deny statement.
|
|
143
|
-
// prefixIncludes denotes we want to include a prefix in our deny meaning Resource
|
|
144
|
-
if (props.prefixIncludes) {
|
|
145
|
-
this.resource = props.prefixIncludes.map(prefix => {
|
|
146
|
-
return `${props.s3Bucket.bucketArn}/${this.formatS3Prefix(prefix)}`;
|
|
147
|
-
});
|
|
148
|
-
}
|
|
149
|
-
else {
|
|
150
|
-
this.resource = [props.s3Bucket.bucketArn + '/*'];
|
|
151
|
-
}
|
|
152
|
-
// prefixExcludes denote we want to exclude a prefix in our deny meaning notResource
|
|
153
|
-
if (props.prefixExcludes) {
|
|
154
|
-
this.notResource = props.prefixExcludes.map(prefix => {
|
|
155
|
-
return `${props.s3Bucket.bucketArn}/${this.formatS3Prefix(prefix)}`;
|
|
156
|
-
});
|
|
157
|
-
}
|
|
158
|
-
if (this.notResource.length > 0) {
|
|
159
|
-
this.denyStatement = new aws_iam_1.PolicyStatement({
|
|
160
|
-
sid: `BucketDeny`,
|
|
161
|
-
effect: aws_iam_1.Effect.DENY,
|
|
162
|
-
notResources: this.notResource,
|
|
163
|
-
actions: RestrictObjectPrefixToRoles.BUCKET_DENY_ACTIONS,
|
|
164
|
-
});
|
|
165
|
-
}
|
|
166
|
-
else {
|
|
167
|
-
this.denyStatement = new aws_iam_1.PolicyStatement({
|
|
168
|
-
sid: `BucketDeny`,
|
|
169
|
-
effect: aws_iam_1.Effect.DENY,
|
|
170
|
-
resources: this.resource,
|
|
171
|
-
actions: RestrictObjectPrefixToRoles.BUCKET_DENY_ACTIONS,
|
|
172
|
-
});
|
|
173
|
-
}
|
|
174
|
-
this.denyStatement.addAnyPrincipal();
|
|
175
|
-
// Build our conditionals.
|
|
176
|
-
this.denyConditionalNotEquals['aws:userId'] = props.roleExcludeIds.map(x => `${x}:*`);
|
|
177
|
-
if (props.principalExcludes && props.principalExcludes.length > 0) {
|
|
178
|
-
this.denyConditionalNotEquals['aws:PrincipalArn'] = [...new Set(props.principalExcludes)].sort((a, b) => a.localeCompare(b));
|
|
179
|
-
}
|
|
180
|
-
// Construct our conditional for our deny
|
|
181
|
-
if (Object.keys(this.denyConditionalNotEquals).length == 1) {
|
|
182
|
-
this.denyStatement.addCondition('StringNotLike', this.denyConditionalNotEquals);
|
|
183
|
-
}
|
|
184
|
-
else {
|
|
185
|
-
this.denyStatement.addCondition('ForAnyValue:StringNotLike', this.denyConditionalNotEquals);
|
|
186
|
-
}
|
|
187
|
-
}
|
|
188
|
-
formatS3Prefix(prefix) {
|
|
189
|
-
let rawPrefix = prefix;
|
|
190
|
-
// Removes trailing slashes
|
|
191
|
-
rawPrefix = rawPrefix.endsWith('/') ? rawPrefix.slice(0, -1) : rawPrefix;
|
|
192
|
-
// Removes leading slashes
|
|
193
|
-
rawPrefix = rawPrefix.startsWith('/') ? rawPrefix.substring(1) : rawPrefix;
|
|
194
|
-
return `${rawPrefix}/*`;
|
|
195
|
-
}
|
|
196
|
-
}
|
|
197
|
-
exports.RestrictBucketToRoles = RestrictBucketToRoles;
|
|
198
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJpbmRleC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7OztHQUdHOzs7QUFFSCxpREFBMEU7QUFzQjFFLDZHQUE2RztBQUM3RyxNQUFhLDJCQUEyQjtJQW9CdEMsWUFBWSxLQUFtQztRQUx2QyxvQkFBZSxHQUFzQixFQUFFLENBQUM7UUFDeEMseUJBQW9CLEdBQXNCLEVBQUUsQ0FBQztRQUM3Qyw4QkFBeUIsR0FBc0IsRUFBRSxDQUFDO1FBSXhELElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxHQUFHLEdBQUcsSUFBSSxDQUFDLGNBQWMsQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLEdBQUcsSUFBSSxDQUFDO1FBQ3pFLDRFQUE0RTtRQUM1RSxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUM7UUFFbkUsbUJBQW1CO1FBQ25CLElBQUksS0FBSyxDQUFDLFdBQVcsSUFBSSxTQUFTLElBQUksS0FBSyxDQUFDLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDbkUsdUNBQXVDO1lBQ3ZDLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNyRCxTQUFTLENBQUMsWUFBWSxDQUFDLFlBQVksRUFBRSxFQUFFLFlBQVksRUFBRSxLQUFLLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDN0YsU0FBUyxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQzVCLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3ZDLENBQUM7UUFDRCx3QkFBd0I7UUFDeEIsSUFBSSxLQUFLLENBQUMsZ0JBQWdCLElBQUksU0FBUyxJQUFJ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UyxJQUFJLENBQUM7SUFDMUIsQ0FBQztDQUNGO0FBL0VELHNEQStFQyIsInNvdXJjZXNDb250ZW50IjpbIi8qIVxuICogQ29weXJpZ2h0IEFtYXpvbi5jb20sIEluYy4gb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKiBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuICovXG5cbmltcG9ydCB7IElQcmluY2lwYWwsIFBvbGljeVN0YXRlbWVudCwgRWZmZWN0IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLWlhbSc7XG5pbXBvcnQgeyBJQnVja2V0IH0gZnJvbSAnYXdzLWNkay1saWIvYXdzLXMzJztcblxuZXhwb3J0IGludGVyZmFjZSBJUmVzdHJpY3RPYmplY3RQcmVmaXhUb1JvbGVzIHtcbiAgcmVhZG9ubHkgczNCdWNrZXQ6IElCdWNrZXQ7XG4gIHJlYWRvbmx5IHMzUHJlZml4OiBzdHJpbmc7XG4gIHJlYWRvbmx5IHJlYWRSb2xlSWRzPzogc3RyaW5nW107XG4gIHJlYWRvbmx5IHJlYWRXcml0ZVJvbGVJZHM/OiBzdHJpbmdbXTtcbiAgcmVhZG9ubHkgcmVhZFdyaXRlU3VwZXJSb2xlSWRzPzogc3RyaW5nW107XG4gIHJlYWRvbmx5IHJlYWRQcmluY2lwYWxzPzogSVByaW5jaXBhbFtdO1xuICByZWFkb25seSByZWFkV3JpdGVQcmluY2lwYWxzPzogSVByaW5jaXBhbFtdO1xuICByZWFkb25seSByZWFkV3JpdGVTdXBlclByaW5jaXBhbHM/OiBJUHJpbmNpcGFsW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgSVJlc3RyaWN0QnVja2V0VG9Sb2xlcyB7XG4gIHJlYWRvbmx5IHMzQnVja2V0OiBJQnVja2V0O1xuICByZWFkb25seSByb2xlRXhjbHVkZUlkczogc3RyaW5nW107XG4gIHJlYWRvbmx5IHByaW5jaXBhbEV4Y2x1ZGVzPzogc3RyaW5nW107XG4gIHJlYWRvbmx5IHByZWZpeEV4Y2x1ZGVzPzogc3RyaW5nW107XG4gIHJlYWRvbmx5IHByZWZpeEluY2x1ZGVzPzogc3RyaW5nW107XG59XG5cbi8qKiBIZWxwZXIgY2xhc3MgZm9yIGdlbmVyYXRpbmcgUzMgYnVja2V0IHBvbGljeSBzdGF0ZW1lbnRzIHdoaWNoIGdyYW50IGFjY2VzcyB0byBzcGVjaWZpYyBvYmplY3QgcHJlZml4ZXMgKi9cbmV4cG9ydCBjbGFzcyBSZXN0cmljdE9iamVjdFByZWZpeFRvUm9sZXMge1xuICBzdGF0aWMgcmVhZG9ubHkgUkVBRF9BQ1RJT05TID0gWydzMzpHZXRPYmplY3QqJ107XG4gIHN0YXRpYyByZWFkb25seSBSRUFEX1dSSVRFX0FDVElPTlMgPSBbXG4gICAgLi4uUmVzdHJpY3RPYmplY3RQcmVmaXhUb1JvbGVzLlJFQURfQUNUSU9OUyxcbiAgICAnczM6UHV0T2JqZWN0JyxcbiAgICAnczM6UHV0T2JqZWN0VGFnZ2luZycsXG4gICAgJ3MzOkRlbGV0ZU9iamVjdCcsXG4gIF07XG4gIHN0YXRpYyByZWFkb25seSBSRUFEX1dSSVRFX1NVUEVSX0FDVElPTlMgPSBbXG4gICAgLi4uUmVzdHJpY3RPYmplY3RQcmVmaXhUb1JvbGVzLlJFQURfV1JJVEVfQUNUSU9OUyxcbiAgICAnczM6RGVsZXRlT2JqZWN0VmVyc2lvbicsXG4gIF07XG4gIHN0YXRpYyByZWFkb25seSBCVUNLRVRfQUxMT1dfQUNUSU9OUyA9IFsnczM6TGlzdConLCAnczM6R2V0QnVja2V0KiddO1xuICBzdGF0aWMgcmVhZG9ubHkgQlVDS0VUX0RFTllfQUNUSU9OUyA9IFsnczM6UHV0T2JqZWN0KicsICdzMzpHZXRPYmplY3QqJywgJ3MzOkRlbGV0ZU9iamVjdConXTtcblxuICBwcml2YXRlIF9yZWFkU3RhdGVtZW50czogUG9saWN5U3RhdGVtZW50W10gPSBbXTtcbiAgcHJpdmF0ZSBfcmVhZFdyaXRlU3RhdGVtZW50czogUG9saWN5U3RhdGVtZW50W10gPSBbXTtcbiAgcHJpdmF0ZSBfcmVhZFdyaXRlU3VwZXJTdGF0ZW1lbnRzOiBQb2xpY3lTdGF0ZW1lbnRbXSA9IFtdO1xuICBwcml2YXRlIF9mb3JtYXR0ZWRQcmVmaXg6IHN0cmluZztcblxuICBjb25zdHJ1Y3Rvcihwcm9wczogSVJlc3RyaWN0T2JqZWN0UHJlZml4VG9Sb2xlcykge1xuICAgIHRoaXMuX2Zvcm1hdHRlZFByZWZpeCA9ICcvJyArIHRoaXMuZm9ybWF0UzNQcmVmaXgocHJvcHMuczNQcmVmaXgpICsgJy8qJztcbiAgICAvLyBDb3ZlcnMgb3VyIGNhc2Ugd2hlcmUgdHdvIC8gZ2V0IHJlc29sdmVkIGJlY2F1c2Ugb3VyIHByZWZpeCBpcyBhY3R1YWxseSAvXG4gICAgdGhpcy5fZm9ybWF0dGVkUHJlZml4ID0gdGhpcy5fZm9ybWF0dGVkUHJlZml4LnJlcGxhY2UoL1xcL1xcLy8sICcvJyk7XG5cbiAgICAvLyBGRURFUkFURUQgLyBSRUFEXG4gICAgaWYgKHByb3BzLnJlYWRSb2xlSWRzICE9IHVuZGVmaW5lZCAmJiBwcm9wcy5yZWFkUm9sZUlkcy5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBDb25zdHJ1Y3Qgb3VyIFVzZXI6SWQgcm9sZXMgZm9yIHJlYWRcbiAgICAgIGNvbnN0IHN0YXRlbWVudCA9IHRoaXMuX3JlYWRTdGF0ZW1lbnRTY2FmZm9sZChwcm9wcyk7XG4gICAgICBzdGF0ZW1lbnQuYWRkQ29uZGl0aW9uKCdTdHJpbmdMaWtlJywgeyAnYXdzOnVzZXJJZCc6IHByb3BzLnJlYWRSb2xlSWRzLm1hcCh4ID0+IGAke3h9OipgKSB9KTtcbiAgICAgIHN0YXRlbWVudC5hZGRBbnlQcmluY2lwYWwoKTtcbiAgICAgIHRoaXMuX3JlYWRTdGF0ZW1lbnRzLnB1c2goc3RhdGVtZW50KTtcbiAgICB9XG4gICAgLy8gRkVERVJBVEVEIC8gUkVBRFdSSVRFXG4gICAgaWYgKHByb3BzLnJlYWRXcml0ZVJvbGVJZHMgIT0gdW5kZWZpbmVkICYmIHByb3BzLnJlYWRXcml0ZVJvbGVJZHMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3Qgc3RhdGVtZW50ID0gdGhpcy5fcmVhZFdyaXRlU3RhdGVtZW50U2NhZmZvbGQocHJvcHMpO1xuICAgICAgc3RhdGVtZW50LmFkZENvbmRpdGlvbignU3RyaW5nTGlrZScsIHsgJ2F3czp1c2VySWQnOiBwcm9wcy5yZWFkV3JpdGVSb2xlSWRzLm1hcCh4ID0+IGAke3h9OipgKSB9KTtcbiAgICAgIHN0YXRlbWVudC5hZGRBbnlQcmluY2lwYWwoKTtcbiAgICAgIHRoaXMuX3JlYWRXcml0ZVN0YXRlbWVudHMucHVzaChzdGF0ZW1lbnQpO1xuICAgIH1cblxuICAgIC8vIEZFREVSQVRFRCAvIFJFQURXUklURVNVUEVSXG4gICAgaWYgKHByb3BzLnJlYWRXcml0ZVN1cGVyUm9sZUlkcyAhPSB1bmRlZmluZWQgJiYgcHJvcHMucmVhZFdyaXRlU3VwZXJSb2xlSWRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IHN0YXRlbWVudCA9IHRoaXMuX3JlYWRXcml0ZVN1cGVyU3RhdGVtZW50U2NhZmZvbGQocHJvcHMpO1xuICAgICAgc3RhdGVtZW50LmFkZENvbmRpdGlvbignU3RyaW5nTGlrZScsIHsgJ2F3czp1c2VySWQnOiBwcm9wcy5yZWFkV3JpdGVTdXBlclJvbGVJZHMubWFwKHggPT4gYCR7eH06KmApIH0pO1xuICAgICAgc3RhdGVtZW50LmFkZEFueVByaW5jaXBhbCgpO1xuICAgICAgdGhpcy5fcmVhZFdyaXRlU3VwZXJTdGF0ZW1lbnRzLnB1c2goc3RhdGVtZW50KTtcbiAgICB9XG5cbiAgICAvLyBOT05GRURFUkFURUQgLyBSRUFEXG4gICAgaWYgKHByb3BzLnJlYWRQcmluY2lwYWxzICE9IHVuZGVmaW5lZCAmJiBwcm9wcy5yZWFkUHJpbmNpcGFscy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBzdGF0ZW1lbnQgPSB0aGlzLl9yZWFkU3RhdGVtZW50U2NhZmZvbGQocHJvcHMpO1xuICAgICAgcHJvcHMucmVhZFByaW5jaXBhbHMuZm9yRWFjaChwcmluY2lwYWwgPT4ge1xuICAgICAgICBzdGF0ZW1lbnQuYWRkUHJpbmNpcGFscyhwcmluY2lwYWwpO1xuICAgICAgfSk7XG4gICAgICB0aGlzLl9yZWFkU3RhdGVtZW50cy5wdXNoKHN0YXRlbWVudCk7XG4gICAgfVxuICAgIC8vIE5PTkZFREVSQVRFRCAvIFJFQURXUklURVxuICAgIGlmIChwcm9wcy5yZWFkV3JpdGVQcmluY2lwYWxzICE9IHVuZGVmaW5lZCAmJiBwcm9wcy5yZWFkV3JpdGVQcmluY2lwYWxzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IHN0YXRlbWVudCA9IHRoaXMuX3JlYWRXcml0ZVN0YXRlbWVudFNjYWZmb2xkKHByb3BzKTtcbiAgICAgIHByb3BzLnJlYWRXcml0ZVByaW5jaXBhbHMuZm9yRWFjaChwcmluY2lwYWwgPT4ge1xuICAgICAgICBzdGF0ZW1lbnQuYWRkUHJpbmNpcGFscyhwcmluY2lwYWwpO1xuICAgICAgfSk7XG4gICAgICB0aGlzLl9yZWFkV3JpdGVTdGF0ZW1lbnRzLnB1c2goc3RhdGVtZW50KTtcbiAgICB9XG4gICAgLy8gTk9ORkVERVJBVEVEIC8gUkVBRFdSSVRFU1VQRVJcbiAgICBpZiAocHJvcHMucmVhZFdyaXRlU3VwZXJQcmluY2lwYWxzICE9IHVuZGVmaW5lZCAmJiBwcm9wcy5yZWFkV3JpdGVTdXBlclByaW5jaXBhbHMubGVuZ3RoID4gMCkge1xuICAgICAgY29uc3Qgc3RhdGVtZW50ID0gdGhpcy5fcmVhZFdyaXRlU3VwZXJTdGF0ZW1lbnRTY2FmZm9sZChwcm9wcyk7XG4gICAgICBwcm9wcy5yZWFkV3JpdGVTdXBlclByaW5jaXBhbHMuZm9yRWFjaChwcmluY2lwYWwgPT4ge1xuICAgICAgICBzdGF0ZW1lbnQuYWRkUHJpbmNpcGFscyhwcmluY2lwYWwpO1xuICAgICAgfSk7XG4gICAgICB0aGlzLl9yZWFkV3JpdGVTdXBlclN0YXRlbWVudHMucHVzaChzdGF0ZW1lbnQpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX3JlYWRTdGF0ZW1lbnRTY2FmZm9sZChwcm9wczogSVJlc3RyaWN0T2JqZWN0UHJlZml4VG9Sb2xlcyk6IFBvbGljeVN0YXRlbWVudCB7XG4gICAgcmV0dXJuIG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgc2lkOiBgJHtwcm9wcy5zM1ByZWZpeC5yZXBsYWNlKC9cXFxcVy9nLCAnJyl9X1JlYWRgLFxuICAgICAgZWZmZWN0OiBFZmZlY3QuQUxMT1csXG4gICAgICByZXNvdXJjZXM6IFtwcm9wcy5zM0J1Y2tldC5idWNrZXRBcm4gKyB0aGlzLl9mb3JtYXR0ZWRQcmVmaXhdLFxuICAgICAgYWN0aW9uczogUmVzdHJpY3RPYmplY3RQcmVmaXhUb1JvbGVzLlJFQURfQUNUSU9OUyxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX3JlYWRXcml0ZVN0YXRlbWVudFNjYWZmb2xkKHByb3BzOiBJUmVzdHJpY3RPYmplY3RQcmVmaXhUb1JvbGVzKTogUG9saWN5U3RhdGVtZW50IHtcbiAgICByZXR1cm4gbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICBzaWQ6IGAke3Byb3BzLnMzUHJlZml4LnJlcGxhY2UoL1xcXFxXL2csICcnKX1fUmVhZFdyaXRlYCxcbiAgICAgIGVmZmVjdDogRWZmZWN0LkFMTE9XLFxuICAgICAgcmVzb3VyY2VzOiBbcHJvcHMuczNCdWNrZXQuYnVja2V0QXJuICsgdGhpcy5fZm9ybWF0dGVkUHJlZml4XSxcbiAgICAgIGFjdGlvbnM6IFJlc3RyaWN0T2JqZWN0UHJlZml4VG9Sb2xlcy5SRUFEX1dSSVRFX0FDVElPTlMsXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9yZWFkV3JpdGVTdXBlclN0YXRlbWVudFNjYWZmb2xkKHByb3BzOiBJUmVzdHJpY3RPYmplY3RQcmVmaXhUb1JvbGVzKTogUG9saWN5U3RhdGVtZW50IHtcbiAgICByZXR1cm4gbmV3IFBvbGljeVN0YXRlbWVudCh7XG4gICAgICBzaWQ6IGAke3Byb3BzLnMzUHJlZml4LnJlcGxhY2UoL1xcXFxXL2csICcnKX1fUmVhZFdyaXRlU3VwZXJgLFxuICAgICAgZWZmZWN0OiBFZmZlY3QuQUxMT1csXG4gICAgICByZXNvdXJjZXM6IFtwcm9wcy5zM0J1Y2tldC5idWNrZXRBcm4gKyB0aGlzLl9mb3JtYXR0ZWRQcmVmaXhdLFxuICAgICAgYWN0aW9uczogUmVzdHJpY3RPYmplY3RQcmVmaXhUb1JvbGVzLlJFQURfV1JJVEVfU1VQRVJfQUNUSU9OUyxcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyByZWFkU3RhdGVtZW50cygpOiBQb2xpY3lTdGF0ZW1lbnRbXSB7XG4gICAgcmV0dXJuIHRoaXMuX3JlYWRTdGF0ZW1lbnRzO1xuICB9XG5cbiAgcHVibGljIHJlYWRXcml0ZVN0YXRlbWVudHMoKTogUG9saWN5U3RhdGVtZW50W10ge1xuICAgIHJldHVybiB0aGlzLl9yZWFkV3JpdGVTdGF0ZW1lbnRzO1xuICB9XG5cbiAgcHVibGljIHJlYWRXcml0ZVN1cGVyU3RhdGVtZW50cygpOiBQb2xpY3lTdGF0ZW1lbnRbXSB7XG4gICAgcmV0dXJuIHRoaXMuX3JlYWRXcml0ZVN1cGVyU3RhdGVtZW50cztcbiAgfVxuXG4gIHB1YmxpYyBzdGF0ZW1lbnRzKCk6IFBvbGljeVN0YXRlbWVudFtdIHtcbiAgICByZXR1cm4gWy4uLnRoaXMuX3JlYWRTdGF0ZW1lbnRzLCAuLi50aGlzLl9yZWFkV3JpdGVTdGF0ZW1lbnRzLCAuLi50aGlzLl9yZWFkV3JpdGVTdXBlclN0YXRlbWVudHNdO1xuICB9XG5cbiAgcHVibGljIGZvcm1hdFMzUHJlZml4KHByZWZpeDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBsZXQgcmF3UHJlZml4ID0gcHJlZml4O1xuXG4gICAgLy8gUmVtb3ZlcyB0cmFpbGluZyBzbGFzaGVzXG4gICAgcmF3UHJlZml4ID0gcmF3UHJlZml4LmVuZHNXaXRoKCcvJykgPyByYXdQcmVmaXguc2xpY2UoMCwgLTEpIDogcmF3UHJlZml4O1xuICAgIC8vIFJlbW92ZXMgbGVhZGluZyBzbGFzaGVzXG4gICAgcmF3UHJlZml4ID0gcmF3UHJlZml4LnN0YXJ0c1dpdGgoJy8nKSA/IHJhd1ByZWZpeC5zdWJzdHJpbmcoMSkgOiByYXdQcmVmaXg7XG4gICAgcmV0dXJuIHJhd1ByZWZpeDtcbiAgfVxufVxuXG4vKiogSGVscGVyIGNsYXNzIGZvciBnZW5lcmF0aW5nIGJ1Y2tldCBwb2xpY3kgc3RhdGVtZW50c1xuICogd2hpY2ggYWxsb3cgb3IgZGVueSBhY2Nlc3MgdG8gYW4gZW50aXJlIGJ1Y2tldC4gVXNlZCB0b1xuICogY3JlYXRlIGJ1Y2tldC1sZXZlbCBkZWZhdWx0IGRlbnkgc3RhdGVtZW50cyB0byBibG9jayBhY2Nlc3Nlc1xuICogbm90IGdyYW50ZWQgaW4gdGhlIGJ1Y2tldCBwb2xpY3kuICovXG5leHBvcnQgY2xhc3MgUmVzdHJpY3RCdWNrZXRUb1JvbGVzIHtcbiAgcHVibGljIHJlYWRvbmx5IGRlbnlTdGF0ZW1lbnQ6IFBvbGljeVN0YXRlbWVudDtcbiAgcHVibGljIHJlYWRvbmx5IGFsbG93U3RhdGVtZW50OiBQb2xpY3lTdGF0ZW1lbnQ7XG4gIHByaXZhdGUgcmVzb3VyY2U6IHN0cmluZ1tdID0gW107XG4gIHByaXZhdGUgbm90UmVzb3VyY2U6IHN0cmluZ1tdID0gW107XG4gIHByaXZhdGUgZGVueUNvbmRpdGlvbmFsTm90RXF1YWxzOiB7XG4gICAgJ2F3czp1c2VySWQnPzogc3RyaW5nW107XG4gICAgJ2F3czpQcmluY2lwYWxBcm4nPzogc3RyaW5nW107XG4gIH0gPSB7fTtcblxuICBjb25zdHJ1Y3Rvcihwcm9wczogSVJlc3RyaWN0QnVja2V0VG9Sb2xlcykge1xuICAgIC8vIFN0YXRlbWVudCBhbGxvd2luZyBhY2Nlc3MgdG8gdGhlIGJ1Y2tldCBmb3IgdGhlIEFST0FzXG4gICAgdGhpcy5hbGxvd1N0YXRlbWVudCA9IG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgc2lkOiBgQnVja2V0QWxsb3dgLFxuICAgICAgZWZmZWN0OiBFZmZlY3QuQUxMT1csXG4gICAgICByZXNvdXJjZXM6IFtwcm9wcy5zM0J1Y2tldC5idWNrZXRBcm4gKyAnLyonLCBwcm9wcy5zM0J1Y2tldC5idWNrZXRBcm5dLFxuICAgICAgYWN0aW9uczogUmVzdHJpY3RPYmplY3RQcmVmaXhUb1JvbGVzLkJVQ0tFVF9BTExPV19BQ1RJT05TLFxuICAgIH0pO1xuICAgIHRoaXMuYWxsb3dTdGF0ZW1lbnQuYWRkQW55UHJpbmNpcGFsKCk7XG4gICAgdGhpcy5hbGxvd1N0YXRlbWVudC5hZGRDb25kaXRpb24oJ1N0cmluZ0xpa2UnLCB7ICdhd3M6dXNlcklkJzogcHJvcHMucm9sZUV4Y2x1ZGVJZHMubWFwKHggPT4gYCR7eH06KmApIH0pO1xuXG4gICAgLy8gQ29uc3R1Y3Qgb3VyIGRlbnkgc3RhdGVtZW50LlxuICAgIC8vIHByZWZpeEluY2x1ZGVzIGRlbm90ZXMgd2Ugd2FudCB0byBpbmNsdWRlIGEgcHJlZml4IGluIG91ciBkZW55IG1lYW5pbmcgUmVzb3VyY2VcbiAgICBpZiAocHJvcHMucHJlZml4SW5jbHVkZXMpIHtcbiAgICAgIHRoaXMucmVzb3VyY2UgPSBwcm9wcy5wcmVmaXhJbmNsdWRlcy5tYXAocHJlZml4ID0+IHtcbiAgICAgICAgcmV0dXJuIGAke3Byb3BzLnMzQnVja2V0LmJ1Y2tldEFybn0vJHt0aGlzLmZvcm1hdFMzUHJlZml4KHByZWZpeCl9YDtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnJlc291cmNlID0gW3Byb3BzLnMzQnVja2V0LmJ1Y2tldEFybiArICcvKiddO1xuICAgIH1cbiAgICAvLyBwcmVmaXhFeGNsdWRlcyBkZW5vdGUgd2Ugd2FudCB0byBleGNsdWRlIGEgcHJlZml4IGluIG91ciBkZW55IG1lYW5pbmcgbm90UmVzb3VyY2VcbiAgICBpZiAocHJvcHMucHJlZml4RXhjbHVkZXMpIHtcbiAgICAgIHRoaXMubm90UmVzb3VyY2UgPSBwcm9wcy5wcmVmaXhFeGNsdWRlcy5tYXAocHJlZml4ID0+IHtcbiAgICAgICAgcmV0dXJuIGAke3Byb3BzLnMzQnVja2V0LmJ1Y2tldEFybn0vJHt0aGlzLmZvcm1hdFMzUHJlZml4KHByZWZpeCl9YDtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm5vdFJlc291cmNlLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuZGVueVN0YXRlbWVudCA9IG5ldyBQb2xpY3lTdGF0ZW1lbnQoe1xuICAgICAgICBzaWQ6IGBCdWNrZXREZW55YCxcbiAgICAgICAgZWZmZWN0OiBFZmZlY3QuREVOWSxcbiAgICAgICAgbm90UmVzb3VyY2VzOiB0aGlzLm5vdFJlc291cmNlLFxuICAgICAgICBhY3Rpb25zOiBSZXN0cmljdE9iamVjdFByZWZpeFRvUm9sZXMuQlVDS0VUX0RFTllfQUNUSU9OUyxcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmRlbnlTdGF0ZW1lbnQgPSBuZXcgUG9saWN5U3RhdGVtZW50KHtcbiAgICAgICAgc2lkOiBgQnVja2V0RGVueWAsXG4gICAgICAgIGVmZmVjdDogRWZmZWN0LkRFTlksXG4gICAgICAgIHJlc291cmNlczogdGhpcy5yZXNvdXJjZSxcbiAgICAgICAgYWN0aW9uczogUmVzdHJpY3RPYmplY3RQcmVmaXhUb1JvbGVzLkJVQ0tFVF9ERU5ZX0FDVElPTlMsXG4gICAgICB9KTtcbiAgICB9XG4gICAgdGhpcy5kZW55U3RhdGVtZW50LmFkZEFueVByaW5jaXBhbCgpO1xuXG4gICAgLy8gQnVpbGQgb3VyIGNvbmRpdGlvbmFscy5cbiAgICB0aGlzLmRlbnlDb25kaXRpb25hbE5vdEVxdWFsc1snYXdzOnVzZXJJZCddID0gcHJvcHMucm9sZUV4Y2x1ZGVJZHMubWFwKHggPT4gYCR7eH06KmApO1xuICAgIGlmIChwcm9wcy5wcmluY2lwYWxFeGNsdWRlcyAmJiBwcm9wcy5wcmluY2lwYWxFeGNsdWRlcy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmRlbnlDb25kaXRpb25hbE5vdEVxdWFsc1snYXdzOlByaW5jaXBhbEFybiddID0gWy4uLm5ldyBTZXQocHJvcHMucHJpbmNpcGFsRXhjbHVkZXMpXS5zb3J0KChhLCBiKSA9PlxuICAgICAgICBhLmxvY2FsZUNvbXBhcmUoYiksXG4gICAgICApO1xuICAgIH1cblxuICAgIC8vIENvbnN0cnVjdCBvdXIgY29uZGl0aW9uYWwgZm9yIG91ciBkZW55XG4gICAgaWYgKE9iamVjdC5rZXlzKHRoaXMuZGVueUNvbmRpdGlvbmFsTm90RXF1YWxzKS5sZW5ndGggPT0gMSkge1xuICAgICAgdGhpcy5kZW55U3RhdGVtZW50LmFkZENvbmRpdGlvbignU3RyaW5nTm90TGlrZScsIHRoaXMuZGVueUNvbmRpdGlvbmFsTm90RXF1YWxzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kZW55U3RhdGVtZW50LmFkZENvbmRpdGlvbignRm9yQW55VmFsdWU6U3RyaW5nTm90TGlrZScsIHRoaXMuZGVueUNvbmRpdGlvbmFsTm90RXF1YWxzKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGZvcm1hdFMzUHJlZml4KHByZWZpeDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBsZXQgcmF3UHJlZml4ID0gcHJlZml4O1xuXG4gICAgLy8gUmVtb3ZlcyB0cmFpbGluZyBzbGFzaGVzXG4gICAgcmF3UHJlZml4ID0gcmF3UHJlZml4LmVuZHNXaXRoKCcvJykgPyByYXdQcmVmaXguc2xpY2UoMCwgLTEpIDogcmF3UHJlZml4O1xuICAgIC8vIFJlbW92ZXMgbGVhZGluZyBzbGFzaGVzXG4gICAgcmF3UHJlZml4ID0gcmF3UHJlZml4LnN0YXJ0c1dpdGgoJy8nKSA/IHJhd1ByZWZpeC5zdWJzdHJpbmcoMSkgOiByYXdQcmVmaXg7XG4gICAgcmV0dXJuIGAke3Jhd1ByZWZpeH0vKmA7XG4gIH1cbn1cbiJdfQ==
|
|
@@ -1,241 +0,0 @@
|
|
|
1
|
-
/*!
|
|
2
|
-
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
3
|
-
* SPDX-License-Identifier: Apache-2.0
|
|
4
|
-
*/
|
|
5
|
-
|
|
6
|
-
import { IPrincipal, PolicyStatement, Effect } from 'aws-cdk-lib/aws-iam';
|
|
7
|
-
import { IBucket } from 'aws-cdk-lib/aws-s3';
|
|
8
|
-
|
|
9
|
-
export interface IRestrictObjectPrefixToRoles {
|
|
10
|
-
readonly s3Bucket: IBucket;
|
|
11
|
-
readonly s3Prefix: string;
|
|
12
|
-
readonly readRoleIds?: string[];
|
|
13
|
-
readonly readWriteRoleIds?: string[];
|
|
14
|
-
readonly readWriteSuperRoleIds?: string[];
|
|
15
|
-
readonly readPrincipals?: IPrincipal[];
|
|
16
|
-
readonly readWritePrincipals?: IPrincipal[];
|
|
17
|
-
readonly readWriteSuperPrincipals?: IPrincipal[];
|
|
18
|
-
}
|
|
19
|
-
|
|
20
|
-
export interface IRestrictBucketToRoles {
|
|
21
|
-
readonly s3Bucket: IBucket;
|
|
22
|
-
readonly roleExcludeIds: string[];
|
|
23
|
-
readonly principalExcludes?: string[];
|
|
24
|
-
readonly prefixExcludes?: string[];
|
|
25
|
-
readonly prefixIncludes?: string[];
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
/** Helper class for generating S3 bucket policy statements which grant access to specific object prefixes */
|
|
29
|
-
export class RestrictObjectPrefixToRoles {
|
|
30
|
-
static readonly READ_ACTIONS = ['s3:GetObject*'];
|
|
31
|
-
static readonly READ_WRITE_ACTIONS = [
|
|
32
|
-
...RestrictObjectPrefixToRoles.READ_ACTIONS,
|
|
33
|
-
's3:PutObject',
|
|
34
|
-
's3:PutObjectTagging',
|
|
35
|
-
's3:DeleteObject',
|
|
36
|
-
];
|
|
37
|
-
static readonly READ_WRITE_SUPER_ACTIONS = [
|
|
38
|
-
...RestrictObjectPrefixToRoles.READ_WRITE_ACTIONS,
|
|
39
|
-
's3:DeleteObjectVersion',
|
|
40
|
-
];
|
|
41
|
-
static readonly BUCKET_ALLOW_ACTIONS = ['s3:List*', 's3:GetBucket*'];
|
|
42
|
-
static readonly BUCKET_DENY_ACTIONS = ['s3:PutObject*', 's3:GetObject*', 's3:DeleteObject*'];
|
|
43
|
-
|
|
44
|
-
private _readStatements: PolicyStatement[] = [];
|
|
45
|
-
private _readWriteStatements: PolicyStatement[] = [];
|
|
46
|
-
private _readWriteSuperStatements: PolicyStatement[] = [];
|
|
47
|
-
private _formattedPrefix: string;
|
|
48
|
-
|
|
49
|
-
constructor(props: IRestrictObjectPrefixToRoles) {
|
|
50
|
-
this._formattedPrefix = '/' + this.formatS3Prefix(props.s3Prefix) + '/*';
|
|
51
|
-
// Covers our case where two / get resolved because our prefix is actually /
|
|
52
|
-
this._formattedPrefix = this._formattedPrefix.replace(/\/\//, '/');
|
|
53
|
-
|
|
54
|
-
// FEDERATED / READ
|
|
55
|
-
if (props.readRoleIds != undefined && props.readRoleIds.length > 0) {
|
|
56
|
-
// Construct our User:Id roles for read
|
|
57
|
-
const statement = this._readStatementScaffold(props);
|
|
58
|
-
statement.addCondition('StringLike', { 'aws:userId': props.readRoleIds.map(x => `${x}:*`) });
|
|
59
|
-
statement.addAnyPrincipal();
|
|
60
|
-
this._readStatements.push(statement);
|
|
61
|
-
}
|
|
62
|
-
// FEDERATED / READWRITE
|
|
63
|
-
if (props.readWriteRoleIds != undefined && props.readWriteRoleIds.length > 0) {
|
|
64
|
-
const statement = this._readWriteStatementScaffold(props);
|
|
65
|
-
statement.addCondition('StringLike', { 'aws:userId': props.readWriteRoleIds.map(x => `${x}:*`) });
|
|
66
|
-
statement.addAnyPrincipal();
|
|
67
|
-
this._readWriteStatements.push(statement);
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
// FEDERATED / READWRITESUPER
|
|
71
|
-
if (props.readWriteSuperRoleIds != undefined && props.readWriteSuperRoleIds.length > 0) {
|
|
72
|
-
const statement = this._readWriteSuperStatementScaffold(props);
|
|
73
|
-
statement.addCondition('StringLike', { 'aws:userId': props.readWriteSuperRoleIds.map(x => `${x}:*`) });
|
|
74
|
-
statement.addAnyPrincipal();
|
|
75
|
-
this._readWriteSuperStatements.push(statement);
|
|
76
|
-
}
|
|
77
|
-
|
|
78
|
-
// NONFEDERATED / READ
|
|
79
|
-
if (props.readPrincipals != undefined && props.readPrincipals.length > 0) {
|
|
80
|
-
const statement = this._readStatementScaffold(props);
|
|
81
|
-
props.readPrincipals.forEach(principal => {
|
|
82
|
-
statement.addPrincipals(principal);
|
|
83
|
-
});
|
|
84
|
-
this._readStatements.push(statement);
|
|
85
|
-
}
|
|
86
|
-
// NONFEDERATED / READWRITE
|
|
87
|
-
if (props.readWritePrincipals != undefined && props.readWritePrincipals.length > 0) {
|
|
88
|
-
const statement = this._readWriteStatementScaffold(props);
|
|
89
|
-
props.readWritePrincipals.forEach(principal => {
|
|
90
|
-
statement.addPrincipals(principal);
|
|
91
|
-
});
|
|
92
|
-
this._readWriteStatements.push(statement);
|
|
93
|
-
}
|
|
94
|
-
// NONFEDERATED / READWRITESUPER
|
|
95
|
-
if (props.readWriteSuperPrincipals != undefined && props.readWriteSuperPrincipals.length > 0) {
|
|
96
|
-
const statement = this._readWriteSuperStatementScaffold(props);
|
|
97
|
-
props.readWriteSuperPrincipals.forEach(principal => {
|
|
98
|
-
statement.addPrincipals(principal);
|
|
99
|
-
});
|
|
100
|
-
this._readWriteSuperStatements.push(statement);
|
|
101
|
-
}
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
private _readStatementScaffold(props: IRestrictObjectPrefixToRoles): PolicyStatement {
|
|
105
|
-
return new PolicyStatement({
|
|
106
|
-
sid: `${props.s3Prefix.replace(/\\W/g, '')}_Read`,
|
|
107
|
-
effect: Effect.ALLOW,
|
|
108
|
-
resources: [props.s3Bucket.bucketArn + this._formattedPrefix],
|
|
109
|
-
actions: RestrictObjectPrefixToRoles.READ_ACTIONS,
|
|
110
|
-
});
|
|
111
|
-
}
|
|
112
|
-
|
|
113
|
-
private _readWriteStatementScaffold(props: IRestrictObjectPrefixToRoles): PolicyStatement {
|
|
114
|
-
return new PolicyStatement({
|
|
115
|
-
sid: `${props.s3Prefix.replace(/\\W/g, '')}_ReadWrite`,
|
|
116
|
-
effect: Effect.ALLOW,
|
|
117
|
-
resources: [props.s3Bucket.bucketArn + this._formattedPrefix],
|
|
118
|
-
actions: RestrictObjectPrefixToRoles.READ_WRITE_ACTIONS,
|
|
119
|
-
});
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
private _readWriteSuperStatementScaffold(props: IRestrictObjectPrefixToRoles): PolicyStatement {
|
|
123
|
-
return new PolicyStatement({
|
|
124
|
-
sid: `${props.s3Prefix.replace(/\\W/g, '')}_ReadWriteSuper`,
|
|
125
|
-
effect: Effect.ALLOW,
|
|
126
|
-
resources: [props.s3Bucket.bucketArn + this._formattedPrefix],
|
|
127
|
-
actions: RestrictObjectPrefixToRoles.READ_WRITE_SUPER_ACTIONS,
|
|
128
|
-
});
|
|
129
|
-
}
|
|
130
|
-
|
|
131
|
-
public readStatements(): PolicyStatement[] {
|
|
132
|
-
return this._readStatements;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
public readWriteStatements(): PolicyStatement[] {
|
|
136
|
-
return this._readWriteStatements;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
public readWriteSuperStatements(): PolicyStatement[] {
|
|
140
|
-
return this._readWriteSuperStatements;
|
|
141
|
-
}
|
|
142
|
-
|
|
143
|
-
public statements(): PolicyStatement[] {
|
|
144
|
-
return [...this._readStatements, ...this._readWriteStatements, ...this._readWriteSuperStatements];
|
|
145
|
-
}
|
|
146
|
-
|
|
147
|
-
public formatS3Prefix(prefix: string): string {
|
|
148
|
-
let rawPrefix = prefix;
|
|
149
|
-
|
|
150
|
-
// Removes trailing slashes
|
|
151
|
-
rawPrefix = rawPrefix.endsWith('/') ? rawPrefix.slice(0, -1) : rawPrefix;
|
|
152
|
-
// Removes leading slashes
|
|
153
|
-
rawPrefix = rawPrefix.startsWith('/') ? rawPrefix.substring(1) : rawPrefix;
|
|
154
|
-
return rawPrefix;
|
|
155
|
-
}
|
|
156
|
-
}
|
|
157
|
-
|
|
158
|
-
/** Helper class for generating bucket policy statements
|
|
159
|
-
* which allow or deny access to an entire bucket. Used to
|
|
160
|
-
* create bucket-level default deny statements to block accesses
|
|
161
|
-
* not granted in the bucket policy. */
|
|
162
|
-
export class RestrictBucketToRoles {
|
|
163
|
-
public readonly denyStatement: PolicyStatement;
|
|
164
|
-
public readonly allowStatement: PolicyStatement;
|
|
165
|
-
private resource: string[] = [];
|
|
166
|
-
private notResource: string[] = [];
|
|
167
|
-
private denyConditionalNotEquals: {
|
|
168
|
-
'aws:userId'?: string[];
|
|
169
|
-
'aws:PrincipalArn'?: string[];
|
|
170
|
-
} = {};
|
|
171
|
-
|
|
172
|
-
constructor(props: IRestrictBucketToRoles) {
|
|
173
|
-
// Statement allowing access to the bucket for the AROAs
|
|
174
|
-
this.allowStatement = new PolicyStatement({
|
|
175
|
-
sid: `BucketAllow`,
|
|
176
|
-
effect: Effect.ALLOW,
|
|
177
|
-
resources: [props.s3Bucket.bucketArn + '/*', props.s3Bucket.bucketArn],
|
|
178
|
-
actions: RestrictObjectPrefixToRoles.BUCKET_ALLOW_ACTIONS,
|
|
179
|
-
});
|
|
180
|
-
this.allowStatement.addAnyPrincipal();
|
|
181
|
-
this.allowStatement.addCondition('StringLike', { 'aws:userId': props.roleExcludeIds.map(x => `${x}:*`) });
|
|
182
|
-
|
|
183
|
-
// Constuct our deny statement.
|
|
184
|
-
// prefixIncludes denotes we want to include a prefix in our deny meaning Resource
|
|
185
|
-
if (props.prefixIncludes) {
|
|
186
|
-
this.resource = props.prefixIncludes.map(prefix => {
|
|
187
|
-
return `${props.s3Bucket.bucketArn}/${this.formatS3Prefix(prefix)}`;
|
|
188
|
-
});
|
|
189
|
-
} else {
|
|
190
|
-
this.resource = [props.s3Bucket.bucketArn + '/*'];
|
|
191
|
-
}
|
|
192
|
-
// prefixExcludes denote we want to exclude a prefix in our deny meaning notResource
|
|
193
|
-
if (props.prefixExcludes) {
|
|
194
|
-
this.notResource = props.prefixExcludes.map(prefix => {
|
|
195
|
-
return `${props.s3Bucket.bucketArn}/${this.formatS3Prefix(prefix)}`;
|
|
196
|
-
});
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
if (this.notResource.length > 0) {
|
|
200
|
-
this.denyStatement = new PolicyStatement({
|
|
201
|
-
sid: `BucketDeny`,
|
|
202
|
-
effect: Effect.DENY,
|
|
203
|
-
notResources: this.notResource,
|
|
204
|
-
actions: RestrictObjectPrefixToRoles.BUCKET_DENY_ACTIONS,
|
|
205
|
-
});
|
|
206
|
-
} else {
|
|
207
|
-
this.denyStatement = new PolicyStatement({
|
|
208
|
-
sid: `BucketDeny`,
|
|
209
|
-
effect: Effect.DENY,
|
|
210
|
-
resources: this.resource,
|
|
211
|
-
actions: RestrictObjectPrefixToRoles.BUCKET_DENY_ACTIONS,
|
|
212
|
-
});
|
|
213
|
-
}
|
|
214
|
-
this.denyStatement.addAnyPrincipal();
|
|
215
|
-
|
|
216
|
-
// Build our conditionals.
|
|
217
|
-
this.denyConditionalNotEquals['aws:userId'] = props.roleExcludeIds.map(x => `${x}:*`);
|
|
218
|
-
if (props.principalExcludes && props.principalExcludes.length > 0) {
|
|
219
|
-
this.denyConditionalNotEquals['aws:PrincipalArn'] = [...new Set(props.principalExcludes)].sort((a, b) =>
|
|
220
|
-
a.localeCompare(b),
|
|
221
|
-
);
|
|
222
|
-
}
|
|
223
|
-
|
|
224
|
-
// Construct our conditional for our deny
|
|
225
|
-
if (Object.keys(this.denyConditionalNotEquals).length == 1) {
|
|
226
|
-
this.denyStatement.addCondition('StringNotLike', this.denyConditionalNotEquals);
|
|
227
|
-
} else {
|
|
228
|
-
this.denyStatement.addCondition('ForAnyValue:StringNotLike', this.denyConditionalNotEquals);
|
|
229
|
-
}
|
|
230
|
-
}
|
|
231
|
-
|
|
232
|
-
private formatS3Prefix(prefix: string): string {
|
|
233
|
-
let rawPrefix = prefix;
|
|
234
|
-
|
|
235
|
-
// Removes trailing slashes
|
|
236
|
-
rawPrefix = rawPrefix.endsWith('/') ? rawPrefix.slice(0, -1) : rawPrefix;
|
|
237
|
-
// Removes leading slashes
|
|
238
|
-
rawPrefix = rawPrefix.startsWith('/') ? rawPrefix.substring(1) : rawPrefix;
|
|
239
|
-
return `${rawPrefix}/*`;
|
|
240
|
-
}
|
|
241
|
-
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "@aws-mdaa/s3-bucketpolicy-helper",
|
|
3
|
-
"description": "MDAA s3-bucketpolicy-helper utility",
|
|
4
|
-
"author": {
|
|
5
|
-
"name": "Amazon Web Services",
|
|
6
|
-
"url": "https://aws.amazon.com/solutions"
|
|
7
|
-
},
|
|
8
|
-
"version": "1.5.0",
|
|
9
|
-
"license": "Apache-2.0",
|
|
10
|
-
"main": "lib/index.js",
|
|
11
|
-
"types": "lib/index.d.ts",
|
|
12
|
-
"scripts": {
|
|
13
|
-
"build": "tsc",
|
|
14
|
-
"watch": "tsc -w",
|
|
15
|
-
"test": "jest --passWithNoTests --testPathIgnorePatterns='.*\\.snapshot\\.test\\.ts'",
|
|
16
|
-
"lint": "eslint --max-warnings 0 -c ../../../eslint.config.mjs",
|
|
17
|
-
"test:coverage": "jest --passWithNoTests --coverage --testPathIgnorePatterns='.*\\.snapshot\\.test\\.ts'",
|
|
18
|
-
"test:snapshots": "jest --passWithNoTests --testPathPattern='.*\\.snapshot\\.test\\.ts'",
|
|
19
|
-
"test:snapshots:update": "jest --passWithNoTests --testPathPattern='.*\\.snapshot\\.test\\.ts' --updateSnapshot"
|
|
20
|
-
},
|
|
21
|
-
"devDependencies": {
|
|
22
|
-
"@aws-mdaa/testing": "1.5.0",
|
|
23
|
-
"@types/jest": "29.5.14",
|
|
24
|
-
"@types/node": "22.9.0",
|
|
25
|
-
"@types/prettier": "2.6.0",
|
|
26
|
-
"jest": "29.7.0",
|
|
27
|
-
"ts-jest": "29.4.6",
|
|
28
|
-
"ts-node": "10.9.2",
|
|
29
|
-
"typescript": "5.9.3",
|
|
30
|
-
"typescript-json-schema": "0.67.1"
|
|
31
|
-
},
|
|
32
|
-
"dependencies": {
|
|
33
|
-
"@aws-mdaa/iam-role-helper": "1.5.0",
|
|
34
|
-
"@aws-mdaa/naming": "1.5.0",
|
|
35
|
-
"aws-cdk-lib": "2.220.0",
|
|
36
|
-
"cdk-nag": "2.37.55",
|
|
37
|
-
"constructs": "10.0.96"
|
|
38
|
-
},
|
|
39
|
-
"gitHead": "8b49a2b371014baec046605ffdbfe38951099c31",
|
|
40
|
-
"repository": {
|
|
41
|
-
"type": "git",
|
|
42
|
-
"url": "https://github.com/aws/modern-data-architecture-accelerator"
|
|
43
|
-
}
|
|
44
|
-
}
|