UNPKG

@cloud-copilot/iam-policy

Version:
226 lines 9.13 kB
import { ActionImpl } from '../actions/action.js'; import { ConditionImpl } from '../conditions/condition.js'; import { PrincipalImpl } from '../principals/principal.js'; import { ResourceImpl } from '../resources/resource.js'; /** * Implementation of the Statement interface and all its sub-interfaces */ export class StatementImpl { constructor(statementObject, _index, otherProps) { this.statementObject = statementObject; this._index = _index; this.otherProps = otherProps; } index() { return this._index; } path() { return this.otherProps.path; } sid() { return this.statementObject.Sid; } effect() { return this.statementObject.Effect; } isAllow() { return this.effect() === 'Allow'; } isDeny() { return this.effect() === 'Deny'; } isPrincipalStatement() { return this.statementObject.Principal !== undefined; } isNotPrincipalStatement() { return this.statementObject.NotPrincipal !== undefined; } principals() { if (!this.isPrincipalStatement()) { throw new Error('Called principals on a statement without Principal, use isPrincipalStatement before calling principals'); } return this.parsePrincipalObject(this.statementObject.Principal); } principalTypeIsArray(principalType) { if (!this.isPrincipalStatement()) { throw new Error('Called principalTypeIsArray on a statement without Principal, use isPrincipalStatement before calling principalTypeIsArray'); } return (typeof this.statementObject.Principal === 'object' && Array.isArray(this.statementObject.Principal[principalType])); } hasSingleWildcardPrincipal() { if (!this.isPrincipalStatement()) { throw new Error('Called hasSingleWildcardPrincipal on a statement without Principal, use isPrincipalStatement before calling hasSingleWildcardPrincipal'); } return this.statementObject.Principal === '*'; } notPrincipals() { if (!this.isNotPrincipalStatement()) { throw new Error('Called notPrincipals on a statement without NotPrincipal, use isNotPrincipalStatement before calling notPrincipals'); } return this.parsePrincipalObject(this.statementObject.NotPrincipal); } notPrincipalTypeIsArray(notPrincipalType) { if (!this.isNotPrincipalStatement()) { throw new Error('Called notPrincipalTypeIsArray on a statement without NotPrincipal, use isNotPrincipalStatement before calling notPrincipalTypeIsArray'); } return (typeof this.statementObject.NotPrincipal === 'object' && Array.isArray(this.statementObject.NotPrincipal[notPrincipalType])); } hasSingleWildcardNotPrincipal() { if (!this.isNotPrincipalStatement()) { throw new Error('Called hasSingleWildcardNotPrincipal on a statement without NotPrincipal, use isNotPrincipalStatement before calling hasSingleWildcardNotPrincipal'); } return this.statementObject.NotPrincipal === '*'; } /** * Parse the principal object into PrincipalImpl objects. * * This is non trivial and we don't want to implement this in each function. * * @param principals the Principal or NotPrincipal object ot parse * @returns the backing principals for a Principal or NotPrincipal object */ parsePrincipalObject(principals) { if (typeof principals === 'string') { return [new PrincipalImpl('AWS', principals)]; } return Object.entries(principals) .map(([principalType, principalValue]) => { if (typeof principalValue === 'string') { return new PrincipalImpl(principalType, principalValue); } return Object.entries(principalValue).map(([key, value]) => { return new PrincipalImpl(principalType, value); }); }) .flat(); } isActionStatement() { return this.statementObject.Action !== undefined; } isNotActionStatement() { return this.statementObject.NotAction !== undefined; } actions() { if (!this.isActionStatement()) { throw new Error('Called actions on a statement without Action, use isActionStatement before calling actions'); } return this.createNewActions(); } createNewActions() { if (!this.actionIsArray()) { return [new ActionImpl(this.statementObject.Action, { path: `${this.path()}.Action` })]; } return [this.statementObject.Action].flat().map((action, index) => { return new ActionImpl(action, { path: `${this.path()}.Action[${index}]` }); }); } actionIsArray() { return Array.isArray(this.statementObject.Action); } notActions() { if (!this.isNotActionStatement()) { throw new Error('Called notActions on a statement without NotAction, use isNotActionStatement before calling notActions'); } return this.createNewNotActions(); } createNewNotActions() { if (!this.notActionIsArray()) { return [new ActionImpl(this.statementObject.NotAction, { path: `${this.path()}.NotAction` })]; } return [this.statementObject.NotAction].flat().map((action, index) => { return new ActionImpl(action, { path: `${this.path()}.NotAction[${index}]` }); }); } notActionIsArray() { return Array.isArray(this.statementObject.NotAction); } isResourceStatement() { return this.statementObject.Resource !== undefined; } isNotResourceStatement() { return this.statementObject.NotResource !== undefined; } resources() { if (!this.isResourceStatement()) { throw new Error('Called resources on a statement without Resource, use isResourceStatement before calling resources'); } return this.createNewResources(); } createNewResources() { if (!this.resourceIsArray()) { return [new ResourceImpl(this.statementObject.Resource, { path: `${this.path()}.Resource` })]; } return [this.statementObject.Resource].flat().map((resource, index) => { return new ResourceImpl(resource, { path: `${this.path()}.Resource[${index}]` }); }); } hasSingleResourceWildcard() { if (!this.isResourceStatement()) { throw new Error('Called hasSingleResourceWildcard on a statement without Resource, use isResourceStatement before calling hasSingleResourceWildcard'); } return this.statementObject.Resource === '*'; } resourceIsArray() { return Array.isArray(this.statementObject.Resource); } notResources() { if (!this.isNotResourceStatement()) { throw new Error('Called notResources on a statement without NotResource, use isNotResourceStatement before calling notResources'); } return this.createNewNotResources(); } createNewNotResources() { if (!this.notResourceIsArray()) { return [ new ResourceImpl(this.statementObject.NotResource, { path: `${this.path()}.NotResource` }) ]; } return [this.statementObject.NotResource].flat().map((resource, index) => { return new ResourceImpl(resource, { path: `${this.path()}.NotResource[${index}]` }); }); } notResourceIsArray() { return Array.isArray(this.statementObject.NotResource); } hasSingleNotResourceWildcard() { if (!this.isNotResourceStatement()) { throw new Error('Called hasSingleNotResourceWildcard on a statement without NotResource, use isNotResourceStatement before calling hasSingleNotResourceWildcard'); } return this.statementObject.NotResource === '*'; } conditionMap() { if (!this.statementObject.Condition) { return undefined; } const result = {}; for (const key of Object.keys(this.statementObject.Condition)) { const value = this.statementObject.Condition[key]; result[key] = {}; for (const subKey of Object.keys(value)) { const subValue = value[subKey]; result[key][subKey] = Array.isArray(subValue) ? subValue : [subValue]; } } return result; } conditions() { return this.createNewConditions(); } createNewConditions() { if (!this.statementObject.Condition) { return []; } return Object.entries(this.statementObject.Condition) .map(([opKey, opValue]) => { return Object.entries(opValue).map(([condKey, condValue]) => { return new ConditionImpl(opKey, condKey, condValue, { conditionPath: `${this.path()}.Condition` }); }); }) .flat(); } } //# sourceMappingURL=statement.js.map