@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,200 +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
|
-
const testing_1 = require("@aws-mdaa/testing");
|
|
8
|
-
const lib_1 = require("../lib");
|
|
9
|
-
const aws_s3_1 = require("aws-cdk-lib/aws-s3");
|
|
10
|
-
const aws_iam_1 = require("aws-cdk-lib/aws-iam");
|
|
11
|
-
describe('Test BucketPolicy Helper', () => {
|
|
12
|
-
const testApp = new testing_1.MdaaTestApp();
|
|
13
|
-
const testBucket = aws_s3_1.Bucket.fromBucketName(testApp.testStack, 'test-bucket', 'test-bucket');
|
|
14
|
-
describe('RestrictPrefix', () => {
|
|
15
|
-
const baseTestProps = {
|
|
16
|
-
s3Bucket: testBucket,
|
|
17
|
-
s3Prefix: 'test-prefix',
|
|
18
|
-
};
|
|
19
|
-
test('Read Role Ids', () => {
|
|
20
|
-
const testProps = {
|
|
21
|
-
...baseTestProps,
|
|
22
|
-
readRoleIds: ['test-role-id-1', 'test-role-id-2'],
|
|
23
|
-
};
|
|
24
|
-
const restriction = new lib_1.RestrictObjectPrefixToRoles(testProps);
|
|
25
|
-
// console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
|
|
26
|
-
expect(restriction.statements().length).toBe(1);
|
|
27
|
-
expect(restriction.readStatements().length).toBe(1);
|
|
28
|
-
expect(restriction.readWriteSuperStatements().length).toBe(0);
|
|
29
|
-
expect(restriction.readWriteStatements().length).toBe(0);
|
|
30
|
-
expect(restriction.readStatements()[0].actions).toStrictEqual(['s3:GetObject*']);
|
|
31
|
-
expect(restriction.readStatements()[0].conditions).toStrictEqual({
|
|
32
|
-
StringLike: {
|
|
33
|
-
'aws:userId': ['test-role-id-1:*', 'test-role-id-2:*'],
|
|
34
|
-
},
|
|
35
|
-
});
|
|
36
|
-
expect(restriction.readStatements()[0].effect).toBe('Allow');
|
|
37
|
-
expect(restriction.readStatements()[0].resources).toStrictEqual([
|
|
38
|
-
'arn:test-partition:s3:::test-bucket/test-prefix/*',
|
|
39
|
-
]);
|
|
40
|
-
});
|
|
41
|
-
test('ReadWrite Role Ids', () => {
|
|
42
|
-
const testProps = {
|
|
43
|
-
...baseTestProps,
|
|
44
|
-
readWriteRoleIds: ['test-role-id-1', 'test-role-id-2'],
|
|
45
|
-
};
|
|
46
|
-
const restriction = new lib_1.RestrictObjectPrefixToRoles(testProps);
|
|
47
|
-
// console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
|
|
48
|
-
expect(restriction.statements().length).toBe(1);
|
|
49
|
-
expect(restriction.readWriteStatements().length).toBe(1);
|
|
50
|
-
expect(restriction.readStatements().length).toBe(0);
|
|
51
|
-
expect(restriction.readWriteSuperStatements().length).toBe(0);
|
|
52
|
-
expect(restriction.readWriteStatements()[0].actions).toStrictEqual([
|
|
53
|
-
's3:GetObject*',
|
|
54
|
-
's3:PutObject',
|
|
55
|
-
's3:PutObjectTagging',
|
|
56
|
-
's3:DeleteObject',
|
|
57
|
-
]);
|
|
58
|
-
expect(restriction.readWriteStatements()[0].conditions).toStrictEqual({
|
|
59
|
-
StringLike: {
|
|
60
|
-
'aws:userId': ['test-role-id-1:*', 'test-role-id-2:*'],
|
|
61
|
-
},
|
|
62
|
-
});
|
|
63
|
-
});
|
|
64
|
-
test('ReadWriteSuper Role Ids', () => {
|
|
65
|
-
const testProps = {
|
|
66
|
-
...baseTestProps,
|
|
67
|
-
readWriteSuperRoleIds: ['test-role-id-1', 'test-role-id-2'],
|
|
68
|
-
};
|
|
69
|
-
const restriction = new lib_1.RestrictObjectPrefixToRoles(testProps);
|
|
70
|
-
// console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
|
|
71
|
-
expect(restriction.statements().length).toBe(1);
|
|
72
|
-
expect(restriction.readWriteSuperStatements().length).toBe(1);
|
|
73
|
-
expect(restriction.readStatements().length).toBe(0);
|
|
74
|
-
expect(restriction.readWriteStatements().length).toBe(0);
|
|
75
|
-
expect(restriction.readWriteSuperStatements()[0].actions).toStrictEqual([
|
|
76
|
-
's3:GetObject*',
|
|
77
|
-
's3:PutObject',
|
|
78
|
-
's3:PutObjectTagging',
|
|
79
|
-
's3:DeleteObject',
|
|
80
|
-
's3:DeleteObjectVersion',
|
|
81
|
-
]);
|
|
82
|
-
expect(restriction.readWriteSuperStatements()[0].conditions).toStrictEqual({
|
|
83
|
-
StringLike: {
|
|
84
|
-
'aws:userId': ['test-role-id-1:*', 'test-role-id-2:*'],
|
|
85
|
-
},
|
|
86
|
-
});
|
|
87
|
-
});
|
|
88
|
-
test('Read Principals', () => {
|
|
89
|
-
const testProps = {
|
|
90
|
-
...baseTestProps,
|
|
91
|
-
readPrincipals: [new aws_iam_1.ArnPrincipal('test-role-arn-1')],
|
|
92
|
-
};
|
|
93
|
-
const restriction = new lib_1.RestrictObjectPrefixToRoles(testProps);
|
|
94
|
-
// console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
|
|
95
|
-
expect(restriction.statements().length).toBe(1);
|
|
96
|
-
expect(restriction.readStatements().length).toBe(1);
|
|
97
|
-
expect(restriction.readWriteSuperStatements().length).toBe(0);
|
|
98
|
-
expect(restriction.readWriteStatements().length).toBe(0);
|
|
99
|
-
expect(restriction.readStatements()[0].actions).toStrictEqual(['s3:GetObject*']);
|
|
100
|
-
expect(restriction.readStatements()[0].effect).toBe('Allow');
|
|
101
|
-
expect(restriction.readStatements()[0].resources).toStrictEqual([
|
|
102
|
-
'arn:test-partition:s3:::test-bucket/test-prefix/*',
|
|
103
|
-
]);
|
|
104
|
-
expect(restriction.readStatements()[0].principals.length).toBe(1);
|
|
105
|
-
expect(JSON.stringify(restriction.readStatements()[0].principals[0])).toStrictEqual(JSON.stringify({ AWS: ['test-role-arn-1'] }));
|
|
106
|
-
});
|
|
107
|
-
test('ReadWrite Principals', () => {
|
|
108
|
-
const testProps = {
|
|
109
|
-
...baseTestProps,
|
|
110
|
-
readWritePrincipals: [new aws_iam_1.ArnPrincipal('test-role-arn-1')],
|
|
111
|
-
};
|
|
112
|
-
const restriction = new lib_1.RestrictObjectPrefixToRoles(testProps);
|
|
113
|
-
// console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
|
|
114
|
-
expect(restriction.statements().length).toBe(1);
|
|
115
|
-
expect(restriction.readWriteStatements().length).toBe(1);
|
|
116
|
-
expect(restriction.readStatements().length).toBe(0);
|
|
117
|
-
expect(restriction.readWriteSuperStatements().length).toBe(0);
|
|
118
|
-
expect(restriction.readWriteStatements()[0].actions).toStrictEqual([
|
|
119
|
-
's3:GetObject*',
|
|
120
|
-
's3:PutObject',
|
|
121
|
-
's3:PutObjectTagging',
|
|
122
|
-
's3:DeleteObject',
|
|
123
|
-
]);
|
|
124
|
-
expect(restriction.readWriteStatements()[0].effect).toBe('Allow');
|
|
125
|
-
expect(restriction.readWriteStatements()[0].resources).toStrictEqual([
|
|
126
|
-
'arn:test-partition:s3:::test-bucket/test-prefix/*',
|
|
127
|
-
]);
|
|
128
|
-
expect(restriction.readWriteStatements()[0].principals.length).toBe(1);
|
|
129
|
-
expect(JSON.stringify(restriction.readWriteStatements()[0].principals[0])).toStrictEqual(JSON.stringify({ AWS: ['test-role-arn-1'] }));
|
|
130
|
-
});
|
|
131
|
-
test('ReadWriteSuper Principals', () => {
|
|
132
|
-
const testProps = {
|
|
133
|
-
...baseTestProps,
|
|
134
|
-
readWriteSuperPrincipals: [new aws_iam_1.ArnPrincipal('test-role-arn-1')],
|
|
135
|
-
};
|
|
136
|
-
const restriction = new lib_1.RestrictObjectPrefixToRoles(testProps);
|
|
137
|
-
// console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
|
|
138
|
-
expect(restriction.statements().length).toBe(1);
|
|
139
|
-
expect(restriction.readStatements().length).toBe(0);
|
|
140
|
-
expect(restriction.readWriteStatements().length).toBe(0);
|
|
141
|
-
expect(restriction.readWriteSuperStatements().length).toBe(1);
|
|
142
|
-
expect(restriction.readWriteSuperStatements()[0].actions).toStrictEqual([
|
|
143
|
-
's3:GetObject*',
|
|
144
|
-
's3:PutObject',
|
|
145
|
-
's3:PutObjectTagging',
|
|
146
|
-
's3:DeleteObject',
|
|
147
|
-
's3:DeleteObjectVersion',
|
|
148
|
-
]);
|
|
149
|
-
expect(restriction.readWriteSuperStatements()[0].effect).toBe('Allow');
|
|
150
|
-
expect(restriction.readWriteSuperStatements()[0].resources).toStrictEqual([
|
|
151
|
-
'arn:test-partition:s3:::test-bucket/test-prefix/*',
|
|
152
|
-
]);
|
|
153
|
-
expect(restriction.readWriteSuperStatements()[0].principals.length).toBe(1);
|
|
154
|
-
expect(JSON.stringify(restriction.readWriteSuperStatements()[0].principals[0])).toStrictEqual(JSON.stringify({ AWS: ['test-role-arn-1'] }));
|
|
155
|
-
});
|
|
156
|
-
});
|
|
157
|
-
describe('RestrictBucket', () => {
|
|
158
|
-
const baseTestProps = {
|
|
159
|
-
s3Bucket: testBucket,
|
|
160
|
-
roleExcludeIds: ['test-role-id-1', 'test-role-id-2'],
|
|
161
|
-
principalExcludes: ['test-arn'],
|
|
162
|
-
prefixExcludes: ['exclude-prefix'],
|
|
163
|
-
prefixIncludes: ['exclude-prefix'],
|
|
164
|
-
};
|
|
165
|
-
test('Base Allow', () => {
|
|
166
|
-
const testProps = {
|
|
167
|
-
...baseTestProps,
|
|
168
|
-
};
|
|
169
|
-
const restriction = new lib_1.RestrictBucketToRoles(testProps);
|
|
170
|
-
console.log(JSON.stringify(restriction.allowStatement, undefined, 2));
|
|
171
|
-
expect(restriction.allowStatement.actions).toStrictEqual(['s3:List*', 's3:GetBucket*']);
|
|
172
|
-
expect(restriction.allowStatement.effect).toBe('Allow');
|
|
173
|
-
expect(restriction.allowStatement.conditions).toStrictEqual({
|
|
174
|
-
StringLike: {
|
|
175
|
-
'aws:userId': ['test-role-id-1:*', 'test-role-id-2:*'],
|
|
176
|
-
},
|
|
177
|
-
});
|
|
178
|
-
expect(restriction.allowStatement.resources).toStrictEqual([
|
|
179
|
-
'arn:test-partition:s3:::test-bucket/*',
|
|
180
|
-
'arn:test-partition:s3:::test-bucket',
|
|
181
|
-
]);
|
|
182
|
-
});
|
|
183
|
-
test('Base Deny', () => {
|
|
184
|
-
const testProps = {
|
|
185
|
-
...baseTestProps,
|
|
186
|
-
};
|
|
187
|
-
const restriction = new lib_1.RestrictBucketToRoles(testProps);
|
|
188
|
-
console.log(JSON.stringify(restriction.denyStatement, undefined, 2));
|
|
189
|
-
expect(restriction.denyStatement.actions).toStrictEqual(['s3:PutObject*', 's3:GetObject*', 's3:DeleteObject*']);
|
|
190
|
-
expect(restriction.denyStatement.effect).toBe('Deny');
|
|
191
|
-
expect(restriction.denyStatement.conditions).toStrictEqual({
|
|
192
|
-
'ForAnyValue:StringNotLike': {
|
|
193
|
-
'aws:userId': ['test-role-id-1:*', 'test-role-id-2:*'],
|
|
194
|
-
'aws:PrincipalArn': ['test-arn'],
|
|
195
|
-
},
|
|
196
|
-
});
|
|
197
|
-
});
|
|
198
|
-
});
|
|
199
|
-
});
|
|
200
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnVja2V0cG9saWN5LWhlbHBlci50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiYnVja2V0cG9saWN5LWhlbHBlci50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7O0dBR0c7O0FBRUgsK0NBQWdEO0FBQ2hELGdDQUtnQjtBQUNoQiwrQ0FBNEM7QUFDNUMsaURBQW1EO0FBRW5ELFFBQVEsQ0FBQywwQkFBMEIsRUFBRSxHQUFHLEVBQUU7SUFDeEMsTUFBTSxPQUFPLEdBQUcsSUFBSSxxQkFBVyxFQUFFLENBQUM7SUFDbEMsTUFBTSxVQUFVLEdBQUcsZUFBTSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUMsU0FBUyxFQUFFLGFBQWEsRUFBRSxhQUFhLENBQUMsQ0FBQztJQUMxRixRQUFRLENBQUMsZ0JBQWdCLEVBQUUsR0FBRyxFQUFFO1FBQzlCLE1BQU0sYUFBYSxHQUFpQztZQUNsRCxRQUFRLEVBQUUsVUFBVTtZQUNwQixRQUFRLEVBQUUsYUFBYTtTQUN4QixDQUFDO1FBQ0YsSUFBSSxDQUFDLGVBQWUsRUFBRSxHQUFHLEVBQUU7WUFDekIsTUFBTSxTQUFTLEdBQWlDO2dCQUM5QyxHQUFHLGFBQWE7Z0JBQ2hCLFdBQVcsRUFBRSxDQUFDLGdCQUFnQixFQUFFLGdCQUFnQixDQUFDO2FBQ2xELENBQUM7WUFDRixNQUFNLFdBQVcsR0FBRyxJQUFJLGlDQUEyQixDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQy9ELCtFQUErRTtZQUMvRSxNQUFNLENBQUMsV0FBVyxDQUFDLFVBQVUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNoRCxNQUFNLENBQUMsV0FBVyxDQUFDLGNBQWMsRUFBRSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNwRCxNQUFNLENBQUMsV0FBVyxDQUFDLHdCQUF3QixFQUFFLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFD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LEVBQUUsa0JBQWtCLENBQUMsQ0FBQyxDQUFDO1lBQ2hILE1BQU0sQ0FBQyxXQUFXLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUN0RCxNQUFNLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxhQUFhLENBQUM7Z0JBQ3pELDJCQUEyQixFQUFFO29CQUMzQixZQUFZLEVBQUUsQ0FBQyxrQkFBa0IsRUFBRSxrQkFBa0IsQ0FBQztvQkFDdEQsa0JBQWtCLEVBQUUsQ0FBQyxVQUFVLENBQUM7aUJBQ2pDO2FBQ0YsQ0FBQyxDQUFDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyohXG4gKiBDb3B5cmlnaHQgQW1hem9uLmNvbSwgSW5jLiBvciBpdHMgYWZmaWxpYXRlcy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG4gKi9cblxuaW1wb3J0IHsgTWRhYVRlc3RBcHAgfSBmcm9tICdAYXdzLW1kYWEvdGVzdGluZyc7XG5pbXBvcnQge1xuICBJUmVzdHJpY3RCdWNrZXRUb1JvbGVzLFxuICBJUmVzdHJpY3RPYmplY3RQcmVmaXhUb1JvbGVzLFxuICBSZXN0cmljdEJ1Y2tldFRvUm9sZXMsXG4gIFJlc3RyaWN0T2JqZWN0UHJlZml4VG9Sb2xlcyxcbn0gZnJvbSAnLi4vbGliJztcbmltcG9ydCB7IEJ1Y2tldCB9IGZyb20gJ2F3cy1jZGstbGliL2F3cy1zMyc7XG5pbXBvcnQgeyBBcm5QcmluY2lwYWwgfSBmcm9tICdhd3MtY2RrLWxpYi9hd3MtaWFtJztcblxuZGVzY3JpYmUoJ1Rlc3QgQnVja2V0UG9saWN5IEhlbHBlcicsICgpID0+IHtcbiAgY29uc3QgdGVzdEFwcCA9IG5ldyBNZGFhVGVzdEFwcCgpO1xuICBjb25zdCB0ZXN0QnVja2V0ID0gQnVja2V0LmZyb21CdWNrZXROYW1lKHRlc3RBcHAudGVzdFN0YWNrLCAndGVzdC1idWNrZXQnLCAndGVzdC1idWNrZXQnKTtcbiAgZGVzY3JpYmUoJ1Jlc3RyaWN0UHJlZml4JywgKCkgPT4ge1xuICAgIGNvbnN0IGJhc2VUZXN0UHJvcHM6IElSZXN0cmljdE9iamVjdFByZWZpeFRvUm9sZXMgPSB7XG4gICAgICBzM0J1Y2tldDogdGVzdEJ1Y2tldCxcbiAgICAgIHMzUHJlZml4OiAndGVzdC1wcmVmaXgnLFxuICAgIH07XG4gICAgdGVzdCgnUmVhZCBSb2xlIElkcycsICgpID0+IHtcbiAgICAgIGNvbnN0IHRlc3RQcm9wczogSVJlc3RyaWN0T2JqZWN0UHJlZml4VG9Sb2xlcyA9IHtcbiAgICAgICAgLi4uYmFzZVRlc3RQcm9wcyxcbiAgICAgICAgcmVhZFJvbGVJZHM6IFsndGVzdC1yb2xlLWlkLTEnLCAndGVzdC1yb2xlLWlkLTInXSxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXN0cmljdGlvbiA9IG5ldyBSZXN0cmljdE9iamVjdFByZWZpeFRvUm9sZXModGVzdFByb3BzKTtcbiAgICAgIC8vIGNvbnNvbGUubG9nKCBKU09OLnN0cmluZ2lmeSggcmVzdHJpY3Rpb24uc3RhdGVtZW50cygpWyAwIF0sIHVuZGVmaW5lZCwgMiApIClcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5zdGF0ZW1lbnRzKCkubGVuZ3RoKS50b0JlKDEpO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRTdGF0ZW1lbnRzKCkubGVuZ3RoKS50b0JlKDEpO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN1cGVyU3RhdGVtZW50cygpLmxlbmd0aCkudG9CZSgwKTtcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5yZWFkV3JpdGVTdGF0ZW1lbnRzKCkubGVuZ3RoKS50b0JlKDApO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRTdGF0ZW1lbnRzKClbMF0uYWN0aW9ucykudG9TdHJpY3RFcXVhbChbJ3MzOkdldE9iamVjdConXSk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24ucmVhZFN0YXRlbWVudHMoKVswXS5jb25kaXRpb25zKS50b1N0cmljdEVxdWFsKHtcbiAgICAgICAgU3RyaW5nTGlrZToge1xuICAgICAgICAgICdhd3M6dXNlcklkJzogWyd0ZXN0LXJvbGUtaWQtMToqJywgJ3Rlc3Qtcm9sZS1pZC0yOionXSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRTdGF0ZW1lbnRzKClbMF0uZWZmZWN0KS50b0JlKCdBbGxvdycpO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRTdGF0ZW1lbnRzKClbMF0ucmVzb3VyY2VzKS50b1N0cmljdEVxdWFsKFtcbiAgICAgICAgJ2Fybjp0ZXN0LXBhcnRpdGlvbjpzMzo6OnRlc3QtYnVja2V0L3Rlc3QtcHJlZml4LyonLFxuICAgICAgXSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdSZWFkV3JpdGUgUm9sZSBJZHMnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0UHJvcHM6IElSZXN0cmljdE9iamVjdFByZWZpeFRvUm9sZXMgPSB7XG4gICAgICAgIC4uLmJhc2VUZXN0UHJvcHMsXG4gICAgICAgIHJlYWRXcml0ZVJvbGVJZHM6IFsndGVzdC1yb2xlLWlkLTEnLCAndGVzdC1yb2xlLWlkLTInXSxcbiAgICAgIH07XG4gICAgICBjb25zdCByZXN0cmljdGlvbiA9IG5ldyBSZXN0cmljdE9iamVjdFByZWZpeFRvUm9sZXModGVzdFByb3BzKTtcbiAgICAgIC8vIGNvbnNvbGUubG9nKCBKU09OLnN0cmluZ2lmeSggcmVzdHJpY3Rpb24uc3RhdGVtZW50cygpWyAwIF0sIHVuZGVmaW5lZCwgMiApIClcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5zdGF0ZW1lbnRzKCkubGVuZ3RoKS50b0JlKDEpO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN0YXRlbWVudHMoKS5sZW5ndGgpLnRvQmUoMSk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24ucmVhZFN0YXRlbWVudHMoKS5sZW5ndGgpLnRvQmUoMCk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24ucmVhZFdyaXRlU3VwZXJTdGF0ZW1lbnRzKCkubGVuZ3RoKS50b0JlKDApO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN0YXRlbWVudHMoKVswXS5hY3Rpb25zKS50b1N0cmljdEVxdWFsKFtcbiAgICAgICAgJ3MzOkdldE9iamVjdConLFxuICAgICAgICAnczM6UHV0T2JqZWN0JyxcbiAgICAgICAgJ3MzOlB1dE9iamVjdFRhZ2dpbmcnLFxuICAgICAgICAnczM6RGVsZXRlT2JqZWN0JyxcbiAgICAgIF0pO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN0YXRlbWVudHMoKVswXS5jb25kaXRpb25zKS50b1N0cmljdEVxdWFsKHtcbiAgICAgICAgU3RyaW5nTGlrZToge1xuICAgICAgICAgICdhd3M6dXNlcklkJzogWyd0ZXN0LXJvbGUtaWQtMToqJywgJ3Rlc3Qtcm9sZS1pZC0yOionXSxcbiAgICAgICAgfSxcbiAgICAgIH0pO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnUmVhZFdyaXRlU3VwZXIgUm9sZSBJZHMnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0UHJvcHM6IElSZXN0cmljdE9iamVjdFByZWZpeFRvUm9sZXMgPSB7XG4gICAgICAgIC4uLmJhc2VUZXN0UHJvcHMsXG4gICAgICAgIHJlYWRXcml0ZVN1cGVyUm9sZUlkczogWyd0ZXN0LXJvbGUtaWQtMScsICd0ZXN0LXJvbGUtaWQtMiddLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlc3RyaWN0aW9uID0gbmV3IFJlc3RyaWN0T2JqZWN0UHJlZml4VG9Sb2xlcyh0ZXN0UHJvcHMpO1xuICAgICAgLy8gY29uc29sZS5sb2coIEpTT04uc3RyaW5naWZ5KCByZXN0cmljdGlvbi5zdGF0ZW1lbnRzKClbIDAgXSwgdW5kZWZpbmVkLCAyICkgKVxuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnN0YXRlbWVudHMoKS5sZW5ndGgpLnRvQmUoMSk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24ucmVhZFdyaXRlU3VwZXJTdGF0ZW1lbnRzKCkubGVuZ3RoKS50b0JlKDEpO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRTdGF0ZW1lbnRzKCkubGVuZ3RoKS50b0JlKDApO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN0YXRlbWVudHMoKS5sZW5ndGgpLnRvQmUoMCk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24ucmVhZFdyaXRlU3VwZXJTdGF0ZW1lbnRzKClbMF0uYWN0aW9ucykudG9TdHJpY3RFcXVhbChbXG4gICAgICAgICdzMzpHZXRPYmplY3QqJyxcbiAgICAgICAgJ3MzOlB1dE9iamVjdCcsXG4gICAgICAgICdzMzpQdXRPYmplY3RUYWdnaW5nJyxcbiAgICAgICAgJ3MzOkRlbGV0ZU9iamVjdCcsXG4gICAgICAgICdzMzpEZWxldGVPYmplY3RWZXJzaW9uJyxcbiAgICAgIF0pO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN1cGVyU3RhdGVtZW50cygpWzBdLmNvbmRpdGlvbnMpLnRvU3RyaWN0RXF1YWwoe1xuICAgICAgICBTdHJpbmdMaWtlOiB7XG4gICAgICAgICAgJ2F3czp1c2VySWQnOiBbJ3Rlc3Qtcm9sZS1pZC0xOionLCAndGVzdC1yb2xlLWlkLTI6KiddLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdSZWFkIFByaW5jaXBhbHMnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0UHJvcHM6IElSZXN0cmljdE9iamVjdFByZWZpeFRvUm9sZXMgPSB7XG4gICAgICAgIC4uLmJhc2VUZXN0UHJvcHMsXG4gICAgICAgIHJlYWRQcmluY2lwYWxzOiBbbmV3IEFyblByaW5jaXBhbCgndGVzdC1yb2xlLWFybi0xJyldLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlc3RyaWN0aW9uID0gbmV3IFJlc3RyaWN0T2JqZWN0UHJlZml4VG9Sb2xlcyh0ZXN0UHJvcHMpO1xuICAgICAgLy8gY29uc29sZS5sb2coIEpTT04uc3RyaW5naWZ5KCByZXN0cmljdGlvbi5zdGF0ZW1lbnRzKClbIDAgXSwgdW5kZWZpbmVkLCAyICkgKVxuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnN0YXRlbWVudHMoKS5sZW5ndGgpLnRvQmUoMSk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24ucmVhZFN0YXRlbWVudHMoKS5sZW5ndGgpLnRvQmUoMSk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24ucmVhZFdyaXRlU3VwZXJTdGF0ZW1lbnRzKCkubGVuZ3RoKS50b0JlKDApO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN0YXRlbWVudHMoKS5sZW5ndGgpLnRvQmUoMCk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24ucmVhZFN0YXRlbWVudHMoKVswXS5hY3Rpb25zKS50b1N0cmljdEVxdWFsKFsnczM6R2V0T2JqZWN0KiddKTtcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5yZWFkU3RhdGVtZW50cygpWzBdLmVmZmVjdCkudG9CZSgnQWxsb3cnKTtcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5yZWFkU3RhdGVtZW50cygpWzBdLnJlc291cmNlcykudG9TdHJpY3RFcXVhbChbXG4gICAgICAgICdhcm46dGVzdC1wYXJ0aXRpb246czM6Ojp0ZXN0LWJ1Y2tldC90ZXN0LXByZWZpeC8qJyxcbiAgICAgIF0pO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRTdGF0ZW1lbnRzKClbMF0ucHJpbmNpcGFscy5sZW5ndGgpLnRvQmUoMSk7XG4gICAgICBleHBlY3QoSlNPTi5zdHJpbmdpZnkocmVzdHJpY3Rpb24ucmVhZFN0YXRlbWVudHMoKVswXS5wcmluY2lwYWxzWzBdKSkudG9TdHJpY3RFcXVhbChcbiAgICAgICAgSlNPTi5zdHJpbmdpZnkoeyBBV1M6IFsndGVzdC1yb2xlLWFybi0xJ10gfSksXG4gICAgICApO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnUmVhZFdyaXRlIFByaW5jaXBhbHMnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0UHJvcHM6IElSZXN0cmljdE9iamVjdFByZWZpeFRvUm9sZXMgPSB7XG4gICAgICAgIC4uLmJhc2VUZXN0UHJvcHMsXG4gICAgICAgIHJlYWRXcml0ZVByaW5jaXBhbHM6IFtuZXcgQXJuUHJpbmNpcGFsKCd0ZXN0LXJvbGUtYXJuLTEnKV0sXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVzdHJpY3Rpb24gPSBuZXcgUmVzdHJpY3RPYmplY3RQcmVmaXhUb1JvbGVzKHRlc3RQcm9wcyk7XG4gICAgICAvLyBjb25zb2xlLmxvZyggSlNPTi5zdHJpbmdpZnkoIHJlc3RyaWN0aW9uLnN0YXRlbWVudHMoKVsgMCBdLCB1bmRlZmluZWQsIDIgKSApXG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24uc3RhdGVtZW50cygpLmxlbmd0aCkudG9CZSgxKTtcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5yZWFkV3JpdGVTdGF0ZW1lbnRzKCkubGVuZ3RoKS50b0JlKDEpO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRTdGF0ZW1lbnRzKCkubGVuZ3RoKS50b0JlKDApO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN1cGVyU3RhdGVtZW50cygpLmxlbmd0aCkudG9CZSgwKTtcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5yZWFkV3JpdGVTdGF0ZW1lbnRzKClbMF0uYWN0aW9ucykudG9TdHJpY3RFcXVhbChbXG4gICAgICAgICdzMzpHZXRPYmplY3QqJyxcbiAgICAgICAgJ3MzOlB1dE9iamVjdCcsXG4gICAgICAgICdzMzpQdXRPYmplY3RUYWdnaW5nJyxcbiAgICAgICAgJ3MzOkRlbGV0ZU9iamVjdCcsXG4gICAgICBdKTtcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5yZWFkV3JpdGVTdGF0ZW1lbnRzKClbMF0uZWZmZWN0KS50b0JlKCdBbGxvdycpO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN0YXRlbWVudHMoKVswXS5yZXNvdXJjZXMpLnRvU3RyaWN0RXF1YWwoW1xuICAgICAgICAnYXJuOnRlc3QtcGFydGl0aW9uOnMzOjo6dGVzdC1idWNrZXQvdGVzdC1wcmVmaXgvKicsXG4gICAgICBdKTtcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5yZWFkV3JpdGVTdGF0ZW1lbnRzKClbMF0ucHJpbmNpcGFscy5sZW5ndGgpLnRvQmUoMSk7XG4gICAgICBleHBlY3QoSlNPTi5zdHJpbmdpZnkocmVzdHJpY3Rpb24ucmVhZFdyaXRlU3RhdGVtZW50cygpWzBdLnByaW5jaXBhbHNbMF0pKS50b1N0cmljdEVxdWFsKFxuICAgICAgICBKU09OLnN0cmluZ2lmeSh7IEFXUzogWyd0ZXN0LXJvbGUtYXJuLTEnXSB9KSxcbiAgICAgICk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdSZWFkV3JpdGVTdXBlciBQcmluY2lwYWxzJywgKCkgPT4ge1xuICAgICAgY29uc3QgdGVzdFByb3BzOiBJUmVzdHJpY3RPYmplY3RQcmVmaXhUb1JvbGVzID0ge1xuICAgICAgICAuLi5iYXNlVGVzdFByb3BzLFxuICAgICAgICByZWFkV3JpdGVTdXBlclByaW5jaXBhbHM6IFtuZXcgQXJuUHJpbmNpcGFsKCd0ZXN0LXJvbGUtYXJuLTEnKV0sXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVzdHJpY3Rpb24gPSBuZXcgUmVzdHJpY3RPYmplY3RQcmVmaXhUb1JvbGVzKHRlc3RQcm9wcyk7XG4gICAgICAvLyBjb25zb2xlLmxvZyggSlNPTi5zdHJpbmdpZnkoIHJlc3RyaWN0aW9uLnN0YXRlbWVudHMoKVsgMCBdLCB1bmRlZmluZWQsIDIgKSApXG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24uc3RhdGVtZW50cygpLmxlbmd0aCkudG9CZSgxKTtcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5yZWFkU3RhdGVtZW50cygpLmxlbmd0aCkudG9CZSgwKTtcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5yZWFkV3JpdGVTdGF0ZW1lbnRzKCkubGVuZ3RoKS50b0JlKDApO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN1cGVyU3RhdGVtZW50cygpLmxlbmd0aCkudG9CZSgxKTtcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5yZWFkV3JpdGVTdXBlclN0YXRlbWVudHMoKVswXS5hY3Rpb25zKS50b1N0cmljdEVxdWFsKFtcbiAgICAgICAgJ3MzOkdldE9iamVjdConLFxuICAgICAgICAnczM6UHV0T2JqZWN0JyxcbiAgICAgICAgJ3MzOlB1dE9iamVjdFRhZ2dpbmcnLFxuICAgICAgICAnczM6RGVsZXRlT2JqZWN0JyxcbiAgICAgICAgJ3MzOkRlbGV0ZU9iamVjdFZlcnNpb24nLFxuICAgICAgXSk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24ucmVhZFdyaXRlU3VwZXJTdGF0ZW1lbnRzKClbMF0uZWZmZWN0KS50b0JlKCdBbGxvdycpO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN1cGVyU3RhdGVtZW50cygpWzBdLnJlc291cmNlcykudG9TdHJpY3RFcXVhbChbXG4gICAgICAgICdhcm46dGVzdC1wYXJ0aXRpb246czM6Ojp0ZXN0LWJ1Y2tldC90ZXN0LXByZWZpeC8qJyxcbiAgICAgIF0pO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN1cGVyU3RhdGVtZW50cygpWzBdLnByaW5jaXBhbHMubGVuZ3RoKS50b0JlKDEpO1xuICAgICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KHJlc3RyaWN0aW9uLnJlYWRXcml0ZVN1cGVyU3RhdGVtZW50cygpWzBdLnByaW5jaXBhbHNbMF0pKS50b1N0cmljdEVxdWFsKFxuICAgICAgICBKU09OLnN0cmluZ2lmeSh7IEFXUzogWyd0ZXN0LXJvbGUtYXJuLTEnXSB9KSxcbiAgICAgICk7XG4gICAgfSk7XG4gIH0pO1xuICBkZXNjcmliZSgnUmVzdHJpY3RCdWNrZXQnLCAoKSA9PiB7XG4gICAgY29uc3QgYmFzZVRlc3RQcm9wczogSVJlc3RyaWN0QnVja2V0VG9Sb2xlcyA9IHtcbiAgICAgIHMzQnVja2V0OiB0ZXN0QnVja2V0LFxuICAgICAgcm9sZUV4Y2x1ZGVJZHM6IFsndGVzdC1yb2xlLWlkLTEnLCAndGVzdC1yb2xlLWlkLTInXSxcbiAgICAgIHByaW5jaXBhbEV4Y2x1ZGVzOiBbJ3Rlc3QtYXJuJ10sXG4gICAgICBwcmVmaXhFeGNsdWRlczogWydleGNsdWRlLXByZWZpeCddLFxuICAgICAgcHJlZml4SW5jbHVkZXM6IFsnZXhjbHVkZS1wcmVmaXgnXSxcbiAgICB9O1xuICAgIHRlc3QoJ0Jhc2UgQWxsb3cnLCAoKSA9PiB7XG4gICAgICBjb25zdCB0ZXN0UHJvcHM6IElSZXN0cmljdEJ1Y2tldFRvUm9sZXMgPSB7XG4gICAgICAgIC4uLmJhc2VUZXN0UHJvcHMsXG4gICAgICB9O1xuICAgICAgY29uc3QgcmVzdHJpY3Rpb24gPSBuZXcgUmVzdHJpY3RCdWNrZXRUb1JvbGVzKHRlc3RQcm9wcyk7XG4gICAgICBjb25zb2xlLmxvZyhKU09OLnN0cmluZ2lmeShyZXN0cmljdGlvbi5hbGxvd1N0YXRlbWVudCwgdW5kZWZpbmVkLCAyKSk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24uYWxsb3dTdGF0ZW1lbnQuYWN0aW9ucykudG9TdHJpY3RFcXVhbChbJ3MzOkxpc3QqJywgJ3MzOkdldEJ1Y2tldConXSk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24uYWxsb3dTdGF0ZW1lbnQuZWZmZWN0KS50b0JlKCdBbGxvdycpO1xuICAgICAgZXhwZWN0KHJlc3RyaWN0aW9uLmFsbG93U3RhdGVtZW50LmNvbmRpdGlvbnMpLnRvU3RyaWN0RXF1YWwoe1xuICAgICAgICBTdHJpbmdMaWtlOiB7XG4gICAgICAgICAgJ2F3czp1c2VySWQnOiBbJ3Rlc3Qtcm9sZS1pZC0xOionLCAndGVzdC1yb2xlLWlkLTI6KiddLFxuICAgICAgICB9LFxuICAgICAgfSk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24uYWxsb3dTdGF0ZW1lbnQucmVzb3VyY2VzKS50b1N0cmljdEVxdWFsKFtcbiAgICAgICAgJ2Fybjp0ZXN0LXBhcnRpdGlvbjpzMzo6OnRlc3QtYnVja2V0LyonLFxuICAgICAgICAnYXJuOnRlc3QtcGFydGl0aW9uOnMzOjo6dGVzdC1idWNrZXQnLFxuICAgICAgXSk7XG4gICAgfSk7XG4gICAgdGVzdCgnQmFzZSBEZW55JywgKCkgPT4ge1xuICAgICAgY29uc3QgdGVzdFByb3BzOiBJUmVzdHJpY3RCdWNrZXRUb1JvbGVzID0ge1xuICAgICAgICAuLi5iYXNlVGVzdFByb3BzLFxuICAgICAgfTtcbiAgICAgIGNvbnN0IHJlc3RyaWN0aW9uID0gbmV3IFJlc3RyaWN0QnVja2V0VG9Sb2xlcyh0ZXN0UHJvcHMpO1xuICAgICAgY29uc29sZS5sb2coSlNPTi5zdHJpbmdpZnkocmVzdHJpY3Rpb24uZGVueVN0YXRlbWVudCwgdW5kZWZpbmVkLCAyKSk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24uZGVueVN0YXRlbWVudC5hY3Rpb25zKS50b1N0cmljdEVxdWFsKFsnczM6UHV0T2JqZWN0KicsICdzMzpHZXRPYmplY3QqJywgJ3MzOkRlbGV0ZU9iamVjdConXSk7XG4gICAgICBleHBlY3QocmVzdHJpY3Rpb24uZGVueVN0YXRlbWVudC5lZmZlY3QpLnRvQmUoJ0RlbnknKTtcbiAgICAgIGV4cGVjdChyZXN0cmljdGlvbi5kZW55U3RhdGVtZW50LmNvbmRpdGlvbnMpLnRvU3RyaWN0RXF1YWwoe1xuICAgICAgICAnRm9yQW55VmFsdWU6U3RyaW5nTm90TGlrZSc6IHtcbiAgICAgICAgICAnYXdzOnVzZXJJZCc6IFsndGVzdC1yb2xlLWlkLTE6KicsICd0ZXN0LXJvbGUtaWQtMjoqJ10sXG4gICAgICAgICAgJ2F3czpQcmluY2lwYWxBcm4nOiBbJ3Rlc3QtYXJuJ10sXG4gICAgICAgIH0sXG4gICAgICB9KTtcbiAgICB9KTtcbiAgfSk7XG59KTtcbiJdfQ==
|
|
@@ -1,215 +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 { MdaaTestApp } from '@aws-mdaa/testing';
|
|
7
|
-
import {
|
|
8
|
-
IRestrictBucketToRoles,
|
|
9
|
-
IRestrictObjectPrefixToRoles,
|
|
10
|
-
RestrictBucketToRoles,
|
|
11
|
-
RestrictObjectPrefixToRoles,
|
|
12
|
-
} from '../lib';
|
|
13
|
-
import { Bucket } from 'aws-cdk-lib/aws-s3';
|
|
14
|
-
import { ArnPrincipal } from 'aws-cdk-lib/aws-iam';
|
|
15
|
-
|
|
16
|
-
describe('Test BucketPolicy Helper', () => {
|
|
17
|
-
const testApp = new MdaaTestApp();
|
|
18
|
-
const testBucket = Bucket.fromBucketName(testApp.testStack, 'test-bucket', 'test-bucket');
|
|
19
|
-
describe('RestrictPrefix', () => {
|
|
20
|
-
const baseTestProps: IRestrictObjectPrefixToRoles = {
|
|
21
|
-
s3Bucket: testBucket,
|
|
22
|
-
s3Prefix: 'test-prefix',
|
|
23
|
-
};
|
|
24
|
-
test('Read Role Ids', () => {
|
|
25
|
-
const testProps: IRestrictObjectPrefixToRoles = {
|
|
26
|
-
...baseTestProps,
|
|
27
|
-
readRoleIds: ['test-role-id-1', 'test-role-id-2'],
|
|
28
|
-
};
|
|
29
|
-
const restriction = new RestrictObjectPrefixToRoles(testProps);
|
|
30
|
-
// console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
|
|
31
|
-
expect(restriction.statements().length).toBe(1);
|
|
32
|
-
expect(restriction.readStatements().length).toBe(1);
|
|
33
|
-
expect(restriction.readWriteSuperStatements().length).toBe(0);
|
|
34
|
-
expect(restriction.readWriteStatements().length).toBe(0);
|
|
35
|
-
expect(restriction.readStatements()[0].actions).toStrictEqual(['s3:GetObject*']);
|
|
36
|
-
expect(restriction.readStatements()[0].conditions).toStrictEqual({
|
|
37
|
-
StringLike: {
|
|
38
|
-
'aws:userId': ['test-role-id-1:*', 'test-role-id-2:*'],
|
|
39
|
-
},
|
|
40
|
-
});
|
|
41
|
-
expect(restriction.readStatements()[0].effect).toBe('Allow');
|
|
42
|
-
expect(restriction.readStatements()[0].resources).toStrictEqual([
|
|
43
|
-
'arn:test-partition:s3:::test-bucket/test-prefix/*',
|
|
44
|
-
]);
|
|
45
|
-
});
|
|
46
|
-
|
|
47
|
-
test('ReadWrite Role Ids', () => {
|
|
48
|
-
const testProps: IRestrictObjectPrefixToRoles = {
|
|
49
|
-
...baseTestProps,
|
|
50
|
-
readWriteRoleIds: ['test-role-id-1', 'test-role-id-2'],
|
|
51
|
-
};
|
|
52
|
-
const restriction = new RestrictObjectPrefixToRoles(testProps);
|
|
53
|
-
// console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
|
|
54
|
-
expect(restriction.statements().length).toBe(1);
|
|
55
|
-
expect(restriction.readWriteStatements().length).toBe(1);
|
|
56
|
-
expect(restriction.readStatements().length).toBe(0);
|
|
57
|
-
expect(restriction.readWriteSuperStatements().length).toBe(0);
|
|
58
|
-
expect(restriction.readWriteStatements()[0].actions).toStrictEqual([
|
|
59
|
-
's3:GetObject*',
|
|
60
|
-
's3:PutObject',
|
|
61
|
-
's3:PutObjectTagging',
|
|
62
|
-
's3:DeleteObject',
|
|
63
|
-
]);
|
|
64
|
-
expect(restriction.readWriteStatements()[0].conditions).toStrictEqual({
|
|
65
|
-
StringLike: {
|
|
66
|
-
'aws:userId': ['test-role-id-1:*', 'test-role-id-2:*'],
|
|
67
|
-
},
|
|
68
|
-
});
|
|
69
|
-
});
|
|
70
|
-
|
|
71
|
-
test('ReadWriteSuper Role Ids', () => {
|
|
72
|
-
const testProps: IRestrictObjectPrefixToRoles = {
|
|
73
|
-
...baseTestProps,
|
|
74
|
-
readWriteSuperRoleIds: ['test-role-id-1', 'test-role-id-2'],
|
|
75
|
-
};
|
|
76
|
-
const restriction = new RestrictObjectPrefixToRoles(testProps);
|
|
77
|
-
// console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
|
|
78
|
-
expect(restriction.statements().length).toBe(1);
|
|
79
|
-
expect(restriction.readWriteSuperStatements().length).toBe(1);
|
|
80
|
-
expect(restriction.readStatements().length).toBe(0);
|
|
81
|
-
expect(restriction.readWriteStatements().length).toBe(0);
|
|
82
|
-
expect(restriction.readWriteSuperStatements()[0].actions).toStrictEqual([
|
|
83
|
-
's3:GetObject*',
|
|
84
|
-
's3:PutObject',
|
|
85
|
-
's3:PutObjectTagging',
|
|
86
|
-
's3:DeleteObject',
|
|
87
|
-
's3:DeleteObjectVersion',
|
|
88
|
-
]);
|
|
89
|
-
expect(restriction.readWriteSuperStatements()[0].conditions).toStrictEqual({
|
|
90
|
-
StringLike: {
|
|
91
|
-
'aws:userId': ['test-role-id-1:*', 'test-role-id-2:*'],
|
|
92
|
-
},
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
test('Read Principals', () => {
|
|
97
|
-
const testProps: IRestrictObjectPrefixToRoles = {
|
|
98
|
-
...baseTestProps,
|
|
99
|
-
readPrincipals: [new ArnPrincipal('test-role-arn-1')],
|
|
100
|
-
};
|
|
101
|
-
const restriction = new RestrictObjectPrefixToRoles(testProps);
|
|
102
|
-
// console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
|
|
103
|
-
expect(restriction.statements().length).toBe(1);
|
|
104
|
-
expect(restriction.readStatements().length).toBe(1);
|
|
105
|
-
expect(restriction.readWriteSuperStatements().length).toBe(0);
|
|
106
|
-
expect(restriction.readWriteStatements().length).toBe(0);
|
|
107
|
-
expect(restriction.readStatements()[0].actions).toStrictEqual(['s3:GetObject*']);
|
|
108
|
-
expect(restriction.readStatements()[0].effect).toBe('Allow');
|
|
109
|
-
expect(restriction.readStatements()[0].resources).toStrictEqual([
|
|
110
|
-
'arn:test-partition:s3:::test-bucket/test-prefix/*',
|
|
111
|
-
]);
|
|
112
|
-
expect(restriction.readStatements()[0].principals.length).toBe(1);
|
|
113
|
-
expect(JSON.stringify(restriction.readStatements()[0].principals[0])).toStrictEqual(
|
|
114
|
-
JSON.stringify({ AWS: ['test-role-arn-1'] }),
|
|
115
|
-
);
|
|
116
|
-
});
|
|
117
|
-
|
|
118
|
-
test('ReadWrite Principals', () => {
|
|
119
|
-
const testProps: IRestrictObjectPrefixToRoles = {
|
|
120
|
-
...baseTestProps,
|
|
121
|
-
readWritePrincipals: [new ArnPrincipal('test-role-arn-1')],
|
|
122
|
-
};
|
|
123
|
-
const restriction = new RestrictObjectPrefixToRoles(testProps);
|
|
124
|
-
// console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
|
|
125
|
-
expect(restriction.statements().length).toBe(1);
|
|
126
|
-
expect(restriction.readWriteStatements().length).toBe(1);
|
|
127
|
-
expect(restriction.readStatements().length).toBe(0);
|
|
128
|
-
expect(restriction.readWriteSuperStatements().length).toBe(0);
|
|
129
|
-
expect(restriction.readWriteStatements()[0].actions).toStrictEqual([
|
|
130
|
-
's3:GetObject*',
|
|
131
|
-
's3:PutObject',
|
|
132
|
-
's3:PutObjectTagging',
|
|
133
|
-
's3:DeleteObject',
|
|
134
|
-
]);
|
|
135
|
-
expect(restriction.readWriteStatements()[0].effect).toBe('Allow');
|
|
136
|
-
expect(restriction.readWriteStatements()[0].resources).toStrictEqual([
|
|
137
|
-
'arn:test-partition:s3:::test-bucket/test-prefix/*',
|
|
138
|
-
]);
|
|
139
|
-
expect(restriction.readWriteStatements()[0].principals.length).toBe(1);
|
|
140
|
-
expect(JSON.stringify(restriction.readWriteStatements()[0].principals[0])).toStrictEqual(
|
|
141
|
-
JSON.stringify({ AWS: ['test-role-arn-1'] }),
|
|
142
|
-
);
|
|
143
|
-
});
|
|
144
|
-
|
|
145
|
-
test('ReadWriteSuper Principals', () => {
|
|
146
|
-
const testProps: IRestrictObjectPrefixToRoles = {
|
|
147
|
-
...baseTestProps,
|
|
148
|
-
readWriteSuperPrincipals: [new ArnPrincipal('test-role-arn-1')],
|
|
149
|
-
};
|
|
150
|
-
const restriction = new RestrictObjectPrefixToRoles(testProps);
|
|
151
|
-
// console.log( JSON.stringify( restriction.statements()[ 0 ], undefined, 2 ) )
|
|
152
|
-
expect(restriction.statements().length).toBe(1);
|
|
153
|
-
expect(restriction.readStatements().length).toBe(0);
|
|
154
|
-
expect(restriction.readWriteStatements().length).toBe(0);
|
|
155
|
-
expect(restriction.readWriteSuperStatements().length).toBe(1);
|
|
156
|
-
expect(restriction.readWriteSuperStatements()[0].actions).toStrictEqual([
|
|
157
|
-
's3:GetObject*',
|
|
158
|
-
's3:PutObject',
|
|
159
|
-
's3:PutObjectTagging',
|
|
160
|
-
's3:DeleteObject',
|
|
161
|
-
's3:DeleteObjectVersion',
|
|
162
|
-
]);
|
|
163
|
-
expect(restriction.readWriteSuperStatements()[0].effect).toBe('Allow');
|
|
164
|
-
expect(restriction.readWriteSuperStatements()[0].resources).toStrictEqual([
|
|
165
|
-
'arn:test-partition:s3:::test-bucket/test-prefix/*',
|
|
166
|
-
]);
|
|
167
|
-
expect(restriction.readWriteSuperStatements()[0].principals.length).toBe(1);
|
|
168
|
-
expect(JSON.stringify(restriction.readWriteSuperStatements()[0].principals[0])).toStrictEqual(
|
|
169
|
-
JSON.stringify({ AWS: ['test-role-arn-1'] }),
|
|
170
|
-
);
|
|
171
|
-
});
|
|
172
|
-
});
|
|
173
|
-
describe('RestrictBucket', () => {
|
|
174
|
-
const baseTestProps: IRestrictBucketToRoles = {
|
|
175
|
-
s3Bucket: testBucket,
|
|
176
|
-
roleExcludeIds: ['test-role-id-1', 'test-role-id-2'],
|
|
177
|
-
principalExcludes: ['test-arn'],
|
|
178
|
-
prefixExcludes: ['exclude-prefix'],
|
|
179
|
-
prefixIncludes: ['exclude-prefix'],
|
|
180
|
-
};
|
|
181
|
-
test('Base Allow', () => {
|
|
182
|
-
const testProps: IRestrictBucketToRoles = {
|
|
183
|
-
...baseTestProps,
|
|
184
|
-
};
|
|
185
|
-
const restriction = new RestrictBucketToRoles(testProps);
|
|
186
|
-
console.log(JSON.stringify(restriction.allowStatement, undefined, 2));
|
|
187
|
-
expect(restriction.allowStatement.actions).toStrictEqual(['s3:List*', 's3:GetBucket*']);
|
|
188
|
-
expect(restriction.allowStatement.effect).toBe('Allow');
|
|
189
|
-
expect(restriction.allowStatement.conditions).toStrictEqual({
|
|
190
|
-
StringLike: {
|
|
191
|
-
'aws:userId': ['test-role-id-1:*', 'test-role-id-2:*'],
|
|
192
|
-
},
|
|
193
|
-
});
|
|
194
|
-
expect(restriction.allowStatement.resources).toStrictEqual([
|
|
195
|
-
'arn:test-partition:s3:::test-bucket/*',
|
|
196
|
-
'arn:test-partition:s3:::test-bucket',
|
|
197
|
-
]);
|
|
198
|
-
});
|
|
199
|
-
test('Base Deny', () => {
|
|
200
|
-
const testProps: IRestrictBucketToRoles = {
|
|
201
|
-
...baseTestProps,
|
|
202
|
-
};
|
|
203
|
-
const restriction = new RestrictBucketToRoles(testProps);
|
|
204
|
-
console.log(JSON.stringify(restriction.denyStatement, undefined, 2));
|
|
205
|
-
expect(restriction.denyStatement.actions).toStrictEqual(['s3:PutObject*', 's3:GetObject*', 's3:DeleteObject*']);
|
|
206
|
-
expect(restriction.denyStatement.effect).toBe('Deny');
|
|
207
|
-
expect(restriction.denyStatement.conditions).toStrictEqual({
|
|
208
|
-
'ForAnyValue:StringNotLike': {
|
|
209
|
-
'aws:userId': ['test-role-id-1:*', 'test-role-id-2:*'],
|
|
210
|
-
'aws:PrincipalArn': ['test-arn'],
|
|
211
|
-
},
|
|
212
|
-
});
|
|
213
|
-
});
|
|
214
|
-
});
|
|
215
|
-
});
|