UNPKG

14.5 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3exports.normalizeStatement = exports.PostProcessPolicyDocument = void 0;
4const cdk = require("@aws-cdk/core");
5const util_1 = require("../util");
6const merge_statements_1 = require("./merge-statements");
7/**
8 * A Token postprocesser for policy documents
9 *
10 * Removes duplicate statements, merges statements, and assign Sids if necessary
11 *
12 * Because policy documents can contain all kinds of crazy things,
13 * we do all the necessary work here after the document has been mostly resolved
14 * into a predictable CloudFormation form.
15 */
16class PostProcessPolicyDocument {
17 constructor(autoAssignSids, minimize) {
18 this.autoAssignSids = autoAssignSids;
19 this.minimize = minimize;
20 }
21 postProcess(input, _context) {
22 if (!input || !input.Statement) {
23 return input;
24 }
25 if (this.minimize) {
26 input.Statement = merge_statements_1.mergeStatements(input.Statement);
27 }
28 // Also remove full-on duplicates (this will not be necessary if
29 // we minimized, but it might still dedupe statements we didn't
30 // minimize like 'Deny' statements, and definitely is still necessary
31 // if we didn't minimize)
32 const jsonStatements = new Set();
33 const uniqueStatements = [];
34 for (const statement of input.Statement) {
35 const jsonStatement = JSON.stringify(statement);
36 if (!jsonStatements.has(jsonStatement)) {
37 uniqueStatements.push(statement);
38 jsonStatements.add(jsonStatement);
39 }
40 }
41 // assign unique SIDs (the statement index) if `autoAssignSids` is enabled
42 const statements = uniqueStatements.map((s, i) => {
43 if (this.autoAssignSids && !s.Sid) {
44 s.Sid = i.toString();
45 }
46 return s;
47 });
48 return {
49 ...input,
50 Statement: statements,
51 };
52 }
53}
54exports.PostProcessPolicyDocument = PostProcessPolicyDocument;
55function normalizeStatement(s) {
56 return noUndef({
57 Action: _norm(s.Action, { unique: true }),
58 NotAction: _norm(s.NotAction, { unique: true }),
59 Condition: _norm(s.Condition),
60 Effect: _norm(s.Effect),
61 Principal: _normPrincipal(s.Principal),
62 NotPrincipal: _normPrincipal(s.NotPrincipal),
63 Resource: _norm(s.Resource, { unique: true }),
64 NotResource: _norm(s.NotResource, { unique: true }),
65 Sid: _norm(s.Sid),
66 });
67 function _norm(values, { unique = false } = { unique: false }) {
68 if (values == null) {
69 return undefined;
70 }
71 if (cdk.Token.isUnresolved(values)) {
72 return values;
73 }
74 if (Array.isArray(values)) {
75 if (!values || values.length === 0) {
76 return undefined;
77 }
78 if (values.length === 1) {
79 return values[0];
80 }
81 return unique ? Array.from(new Set(values)) : values;
82 }
83 if (values && typeof (values) === 'object') {
84 if (Object.keys(values).length === 0) {
85 return undefined;
86 }
87 }
88 return values;
89 }
90 function _normPrincipal(principal) {
91 if (!principal) {
92 return undefined;
93 }
94 const keys = Object.keys(principal);
95 if (keys.length === 0) {
96 return undefined;
97 }
98 // This is handling a special case for round-tripping a literal
99 // string principal loaded from JSON.
100 if (util_1.LITERAL_STRING_KEY in principal) {
101 return principal[util_1.LITERAL_STRING_KEY][0];
102 }
103 const result = {};
104 for (const key of keys) {
105 const normVal = _norm(principal[key]);
106 if (normVal) {
107 result[key] = normVal;
108 }
109 }
110 return result;
111 }
112}
113exports.normalizeStatement = normalizeStatement;
114function noUndef(x) {
115 const ret = {};
116 for (const [key, value] of Object.entries(x)) {
117 if (value !== undefined) {
118 ret[key] = value;
119 }
120 }
121 return ret;
122}
123//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9zdHByb2Nlc3MtcG9saWN5LWRvY3VtZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicG9zdHByb2Nlc3MtcG9saWN5LWRvY3VtZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLHFDQUFxQztBQUNyQyxrQ0FBNkM7QUFDN0MseURBQXFEO0FBRXJEOzs7Ozs7OztHQVFHO0FBQ0gsTUFBYSx5QkFBeUI7SUFDcEMsWUFBNkIsY0FBdUIsRUFBbUIsUUFBaUI7UUFBM0QsbUJBQWMsR0FBZCxjQUFjLENBQVM7UUFBbUIsYUFBUSxHQUFSLFFBQVEsQ0FBUztLQUN2RjtJQUVNLFdBQVcsQ0FBQyxLQUFVLEVBQUUsUUFBNkI7UUFDMUQsSUFBSSxDQUFDLEtBQUssSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLEVBQUU7WUFDOUIsT0FBTyxLQUFLLENBQUM7U0FDZDtRQUVELElBQUksSUFBSSxDQUFDLFFBQVEsRUFBRTtZQUNqQixLQUFLLENBQUMsU0FBUyxHQUFHLGtDQUFlLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1NBQ3BEO1FBRUQsZ0VBQWdFO1FBQ2hFLCtEQUErRDtRQUMvRCxxRUFBcUU7UUFDckUseUJBQXlCO1FBQ3pCLE1BQU0sY0FBYyxHQUFHLElBQUksR0FBRyxFQUFVLENBQUM7UUFDekMsTUFBTSxnQkFBZ0IsR0FBVSxFQUFFLENBQUM7UUFFbkMsS0FBSyxNQUFNLFNBQVMsSUFBSSxLQUFLLENBQUMsU0FBUyxFQUFFO1lBQ3ZDLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUM7WUFDaEQsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLEVBQUU7Z0JBQ3RDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztnQkFDakMsY0FBYyxDQUFDLEdBQUcsQ0FBQyxhQUFhLENBQUMsQ0FBQzthQUNuQztTQUNGO1FBRUQsMEVBQTBFO1FBQzFF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QUU7WUFBRSxPQUFPLFNBQVMsQ0FBQztTQUFFO1FBRTVDLCtEQUErRDtRQUMvRCxxQ0FBcUM7UUFDckMsSUFBSSx5QkFBa0IsSUFBSSxTQUFTLEVBQUU7WUFDbkMsT0FBTyxTQUFTLENBQUMseUJBQWtCLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztTQUN6QztRQUVELE1BQU0sTUFBTSxHQUFRLEVBQUUsQ0FBQztRQUN2QixLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksRUFBRTtZQUN0QixNQUFNLE9BQU8sR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7WUFDdEMsSUFBSSxPQUFPLEVBQUU7Z0JBQ1gsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLE9BQU8sQ0FBQzthQUN2QjtTQUNGO1FBQ0QsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztBQUNILENBQUM7QUFqRUQsZ0RBaUVDO0FBRUQsU0FBUyxPQUFPLENBQUMsQ0FBTTtJQUNyQixNQUFNLEdBQUcsR0FBUSxFQUFFLENBQUM7SUFDcEIsS0FBSyxNQUFNLENBQUMsR0FBRyxFQUFFLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUU7UUFDNUMsSUFBSSxLQUFLLEtBQUssU0FBUyxFQUFFO1lBQ3ZCLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxLQUFLLENBQUM7U0FDbEI7S0FDRjtJQUNELE9BQU8sR0FBRyxDQUFDO0FBQ2IsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGNkayBmcm9tICdAYXdzLWNkay9jb3JlJztcbmltcG9ydCB7IExJVEVSQUxfU1RSSU5HX0tFWSB9IGZyb20gJy4uL3V0aWwnO1xuaW1wb3J0IHsgbWVyZ2VTdGF0ZW1lbnRzIH0gZnJvbSAnLi9tZXJnZS1zdGF0ZW1lbnRzJztcblxuLyoqXG4gKiBBIFRva2VuIHBvc3Rwcm9jZXNzZXIgZm9yIHBvbGljeSBkb2N1bWVudHNcbiAqXG4gKiBSZW1vdmVzIGR1cGxpY2F0ZSBzdGF0ZW1lbnRzLCBtZXJnZXMgc3RhdGVtZW50cywgYW5kIGFzc2lnbiBTaWRzIGlmIG5lY2Vzc2FyeVxuICpcbiAqIEJlY2F1c2UgcG9saWN5IGRvY3VtZW50cyBjYW4gY29udGFpbiBhbGwga2luZHMgb2YgY3JhenkgdGhpbmdzLFxuICogd2UgZG8gYWxsIHRoZSBuZWNlc3Nhcnkgd29yayBoZXJlIGFmdGVyIHRoZSBkb2N1bWVudCBoYXMgYmVlbiBtb3N0bHkgcmVzb2x2ZWRcbiAqIGludG8gYSBwcmVkaWN0YWJsZSBDbG91ZEZvcm1hdGlvbiBmb3JtLlxuICovXG5leHBvcnQgY2xhc3MgUG9zdFByb2Nlc3NQb2xpY3lEb2N1bWVudCBpbXBsZW1lbnRzIGNkay5JUG9zdFByb2Nlc3NvciB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgYXV0b0Fzc2lnblNpZHM6IGJvb2xlYW4sIHByaXZhdGUgcmVhZG9ubHkgbWluaW1pemU6IGJvb2xlYW4pIHtcbiAgfVxuXG4gIHB1YmxpYyBwb3N0UHJvY2VzcyhpbnB1dDogYW55LCBfY29udGV4dDogY2RrLklSZXNvbHZlQ29udGV4dCk6IGFueSB7XG4gICAgaWYgKCFpbnB1dCB8fCAhaW5wdXQuU3RhdGVtZW50KSB7XG4gICAgICByZXR1cm4gaW5wdXQ7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMubWluaW1pemUpIHtcbiAgICAgIGlucHV0LlN0YXRlbWVudCA9IG1lcmdlU3RhdGVtZW50cyhpbnB1dC5TdGF0ZW1lbnQpO1xuICAgIH1cblxuICAgIC8vIEFsc28gcmVtb3ZlIGZ1bGwtb24gZHVwbGljYXRlcyAodGhpcyB3aWxsIG5vdCBiZSBuZWNlc3NhcnkgaWZcbiAgICAvLyB3ZSBtaW5pbWl6ZWQsIGJ1dCBpdCBtaWdodCBzdGlsbCBkZWR1cGUgc3RhdGVtZW50cyB3ZSBkaWRuJ3RcbiAgICAvLyBtaW5pbWl6ZSBsaWtlICdEZW55JyBzdGF0ZW1lbnRzLCBhbmQgZGVmaW5pdGVseSBpcyBzdGlsbCBuZWNlc3NhcnlcbiAgICAvLyBpZiB3ZSBkaWRuJ3QgbWluaW1pemUpXG4gICAgY29uc3QganNvblN0YXRlbWVudHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBjb25zdCB1bmlxdWVTdGF0ZW1lbnRzOiBhbnlbXSA9IFtdO1xuXG4gICAgZm9yIChjb25zdCBzdGF0ZW1lbnQgb2YgaW5wdXQuU3RhdGVtZW50KSB7XG4gICAgICBjb25zdCBqc29uU3RhdGVtZW50ID0gSlNPTi5zdHJpbmdpZnkoc3RhdGVtZW50KTtcbiAgICAgIGlmICghanNvblN0YXRlbWVudHMuaGFzKGpzb25TdGF0ZW1lbnQpKSB7XG4gICAgICAgIHVuaXF1ZVN0YXRlbWVudHMucHVzaChzdGF0ZW1lbnQpO1xuICAgICAgICBqc29uU3RhdGVtZW50cy5hZGQoanNvblN0YXRlbWVudCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gYXNzaWduIHVuaXF1ZSBTSURzICh0aGUgc3RhdGVtZW50IGluZGV4KSBpZiBgYXV0b0Fzc2lnblNpZHNgIGlzIGVuYWJsZWRcbiAgICBjb25zdCBzdGF0ZW1lbnRzID0gdW5pcXVlU3RhdGVtZW50cy5tYXAoKHMsIGkpID0+IHtcbiAgICAgIGlmICh0aGlzLmF1dG9Bc3NpZ25TaWRzICYmICFzLlNpZCkge1xuICAgICAgICBzLlNpZCA9IGkudG9TdHJpbmcoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHM7XG4gICAgfSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4uaW5wdXQsXG4gICAgICBTdGF0ZW1lbnQ6IHN0YXRlbWVudHMsXG4gICAgfTtcbiAgfVxufVxuXG4vLyBBbiBJQU0gdmFsdWUgaXMgYSBzdHJpbmcgb3IgYSBDbG91ZEZvcm1hdGlvbiBpbnRyaW5zaWNcbmV4cG9ydCB0eXBlIElhbVZhbHVlID0gc3RyaW5nIHwgUmVjb3JkPHN0cmluZywgYW55PiB8IEFycmF5PHN0cmluZyB8IFJlY29yZDxzdHJpbmcsIGFueT4+O1xuXG5leHBvcnQgaW50ZXJmYWNlIFN0YXRlbWVudFNjaGVtYSB7XG4gIHJlYWRvbmx5IFNpZD86IHN0cmluZztcbiAgcmVhZG9ubHkgRWZmZWN0Pzogc3RyaW5nO1xuICByZWFkb25seSBQcmluY2lwYWw/OiBSZWNvcmQ8c3RyaW5nLCBJYW1WYWx1ZT47XG4gIHJlYWRvbmx5IE5vdFByaW5jaXBhbD86IFJlY29yZDxzdHJpbmcsIElhbVZhbHVlPjtcbiAgcmVhZG9ubHkgUmVzb3VyY2U/OiBJYW1WYWx1ZTtcbiAgcmVhZG9ubHkgTm90UmVzb3VyY2U/OiBJYW1WYWx1ZTtcbiAgcmVhZG9ubHkgQWN0aW9uPzogSWFtVmFsdWU7XG4gIHJlYWRvbmx5IE5vdEFjdGlvbj86IElhbVZhbHVlO1xuICByZWFkb25seSBDb25kaXRpb24/OiB1bmtub3duO1xufVxuXG5cbmV4cG9ydCBmdW5jdGlvbiBub3JtYWxpemVTdGF0ZW1lbnQoczogU3RhdGVtZW50U2NoZW1hKSB7XG4gIHJldHVybiBub1VuZGVmKHtcbiAgICBBY3Rpb246IF9ub3JtKHMuQWN0aW9uLCB7IHVuaXF1ZTogdHJ1ZSB9KSxcbiAgICBOb3RBY3Rpb246IF9ub3JtKHMuTm90QWN0aW9uLCB7IHVuaXF1ZTogdHJ1ZSB9KSxcbiAgICBDb25kaXRpb246IF9ub3JtKHMuQ29uZGl0aW9uKSxcbiAgICBFZmZlY3Q6IF9ub3JtKHMuRWZmZWN0KSxcbiAgICBQcmluY2lwYWw6IF9ub3JtUHJpbmNpcGFsKHMuUHJpbmNpcGFsKSxcbiAgICBOb3RQcmluY2lwYWw6IF9ub3JtUHJpbmNpcGFsKHMuTm90UHJpbmNpcGFsKSxcbiAgICBSZXNvdXJjZTogX25vcm0ocy5SZXNvdXJjZSwgeyB1bmlxdWU6IHRydWUgfSksXG4gICAgTm90UmVzb3VyY2U6IF9ub3JtKHMuTm90UmVzb3VyY2UsIHsgdW5pcXVlOiB0cnVlIH0pLFxuICAgIFNpZDogX25vcm0ocy5TaWQpLFxuICB9KTtcblxuICBmdW5jdGlvbiBfbm9ybSh2YWx1ZXM6IGFueSwgeyB1bmlxdWUgPSBmYWxzZSB9OiB7IHVuaXF1ZTogYm9vbGVhbiB9ID0geyB1bmlxdWU6IGZhbHNlIH0pIHtcblxuICAgIGlmICh2YWx1ZXMgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICB9XG5cbiAgICBpZiAoY2RrLlRva2VuLmlzVW5yZXNvbHZlZCh2YWx1ZXMpKSB7XG4gICAgICByZXR1cm4gdmFsdWVzO1xuICAgIH1cblxuICAgIGlmIChBcnJheS5pc0FycmF5KHZhbHVlcykpIHtcbiAgICAgIGlmICghdmFsdWVzIHx8IHZhbHVlcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgaWYgKHZhbHVlcy5sZW5ndGggPT09IDEpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlc1swXTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHVuaXF1ZSA/IEFycmF5LmZyb20obmV3IFNldCh2YWx1ZXMpKSA6IHZhbHVlcztcbiAgICB9XG5cbiAgICBpZiAodmFsdWVzICYmIHR5cGVvZih2YWx1ZXMpID09PSAnb2JqZWN0Jykge1xuICAgICAgaWYgKE9iamVjdC5rZXlzKHZhbHVlcykubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlcztcbiAgfVxuXG4gIGZ1bmN0aW9uIF9ub3JtUHJpbmNpcGFsKHByaW5jaXBhbD86IHsgW2tleTogc3RyaW5nXTogYW55IH0pIHtcbiAgICBpZiAoIXByaW5jaXBhbCkgeyByZXR1cm4gdW5kZWZpbmVkOyB9XG5cbiAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMocHJpbmNpcGFsKTtcbiAgICBpZiAoa2V5cy5sZW5ndGggPT09IDApIHsgcmV0dXJuIHVuZGVmaW5lZDsgfVxuXG4gICAgLy8gVGhpcyBpcyBoYW5kbGluZyBhIHNwZWNpYWwgY2FzZSBmb3Igcm91bmQtdHJpcHBpbmcgYSBsaXRlcmFsXG4gICAgLy8gc3RyaW5nIHByaW5jaXBhbCBsb2FkZWQgZnJvbSBKU09OLlxuICAgIGlmIChMSVRFUkFMX1NUUklOR19LRVkgaW4gcHJpbmNpcGFsKSB7XG4gICAgICByZXR1cm4gcHJpbmNpcGFsW0xJVEVSQUxfU1RSSU5HX0tFWV1bMF07XG4gICAgfVxuXG4gICAgY29uc3QgcmVzdWx0OiBhbnkgPSB7fTtcbiAgICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XG4gICAgICBjb25zdCBub3JtVmFsID0gX25vcm0ocHJpbmNpcGFsW2tleV0pO1xuICAgICAgaWYgKG5vcm1WYWwpIHtcbiAgICAgICAgcmVzdWx0W2tleV0gPSBub3JtVmFsO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59XG5cbmZ1bmN0aW9uIG5vVW5kZWYoeDogYW55KTogYW55IHtcbiAgY29uc3QgcmV0OiBhbnkgPSB7fTtcbiAgZm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoeCkpIHtcbiAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgcmV0W2tleV0gPSB2YWx1ZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJldDtcbn1cbiJdfQ==
\No newline at end of file