@kensio/yulin 1.20.11 → 1.20.13

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.
Files changed (150) hide show
  1. package/dist/service/acm/command/delete-certificate/delete-certificate-authorizer.js +1 -0
  2. package/dist/service/acm/command/describe-certificate/describe-certificate-authorizer.js +1 -0
  3. package/dist/service/acm/command/list-certificates/list-certificates-authorizer.js +1 -0
  4. package/dist/service/acm/command/request-certificate/request-certificate-authorizer.js +1 -0
  5. package/dist/service/apigateway/serve/auth/sim-rest-api-authorizer-policy.js +3 -0
  6. package/dist/service/apigatewayv2/serve/auth/sim-http-api-authorizer-policy.js +3 -0
  7. package/dist/service/athena/engine/sim-athena-regexp-flags.d.ts +22 -0
  8. package/dist/service/athena/engine/sim-athena-regexp-flags.js +34 -0
  9. package/dist/service/athena/engine/sim-athena-regexp-shims.js +3 -1
  10. package/dist/service/athena/engine/sim-athena-url-parts.d.ts +24 -0
  11. package/dist/service/athena/engine/sim-athena-url-parts.js +76 -0
  12. package/dist/service/athena/engine/sim-athena-url-shims.d.ts +3 -2
  13. package/dist/service/athena/engine/sim-athena-url-shims.js +57 -25
  14. package/dist/service/athena/table/sim-athena-negated-columns.d.ts +17 -0
  15. package/dist/service/athena/table/sim-athena-negated-columns.js +80 -0
  16. package/dist/service/athena/table/sim-athena-partition-filters.d.ts +7 -4
  17. package/dist/service/athena/table/sim-athena-partition-filters.js +12 -5
  18. package/dist/service/aws/factory/sim-aws-account-service-cache.d.ts +3 -0
  19. package/dist/service/aws/factory/sim-aws-account-service-cache.js +5 -0
  20. package/dist/service/aws/factory/sim-aws-service-factory.d.ts +9 -0
  21. package/dist/service/aws/factory/sim-aws-service-factory.js +10 -0
  22. package/dist/service/aws/sim-aws.d.ts +18 -0
  23. package/dist/service/aws/sim-aws.js +19 -0
  24. package/dist/service/cloudformation/resource/cfn/organizations/sim-organizations-cfn-value-adapter.d.ts +6 -0
  25. package/dist/service/cloudformation/resource/cfn/organizations/sim-organizations-cfn-value-adapter.js +23 -0
  26. package/dist/service/cloudformation/resource/cfn/organizations/sim-organizations-cfn.d.ts +66 -0
  27. package/dist/service/cloudformation/resource/cfn/organizations/sim-organizations-cfn.js +136 -0
  28. package/dist/service/cloudformation/resource/cfn/sim-cfn-service-value-adapters.js +2 -0
  29. package/dist/service/cloudformation/resource/resolve/service/sim-cfn-service-factories.js +7 -0
  30. package/dist/service/cloudfront/command/create-distribution/create-distribution-authorizer.js +1 -0
  31. package/dist/service/cloudfront/command/create-function/create-function-authorizer.js +1 -0
  32. package/dist/service/cloudfront/command/delete-distribution/delete-distribution-authorizer.js +1 -0
  33. package/dist/service/cloudfront/command/delete-function/delete-function-authorizer.js +1 -0
  34. package/dist/service/cloudfront/command/get-distribution/get-distribution-authorizer.js +1 -0
  35. package/dist/service/cloudfront/command/update-distribution/update-distribution-authorizer.js +1 -0
  36. package/dist/service/cloudfront/edge/sim-cf-edge-association-auth-z.js +1 -0
  37. package/dist/service/cloudfront/key-value-store/sim-cf-key-value-store-access.js +1 -0
  38. package/dist/service/cloudwatch/command/authorize/sim-cloudwatch-decide.js +1 -0
  39. package/dist/service/cognito/command/authorize/sim-cognito-authorizer.js +1 -0
  40. package/dist/service/dynamodb/command/authorize/sim-dynamodb-authorizer.js +1 -0
  41. package/dist/service/firehose/command/authorize/sim-firehose-authorizer.js +1 -0
  42. package/dist/service/glue/command/authorize/sim-glue-authorize-resources.js +1 -0
  43. package/dist/service/iam/authorize/allow/sim-iam-policy-evaluation.d.ts +45 -0
  44. package/dist/service/iam/authorize/allow/sim-iam-policy-evaluation.js +59 -0
  45. package/dist/service/iam/authorize/context/sim-iam-auth-z-context-builder.d.ts +15 -4
  46. package/dist/service/iam/authorize/context/sim-iam-auth-z-context-builder.js +15 -4
  47. package/dist/service/iam/authorize/context/sim-iam-auth-z-context.d.ts +31 -1
  48. package/dist/service/iam/authorize/context/sim-iam-auth-z-context.factory.js +1 -0
  49. package/dist/service/iam/authorize/context/sim-iam-auth-z-scp-source-builder.d.ts +46 -0
  50. package/dist/service/iam/authorize/context/sim-iam-auth-z-scp-source-builder.js +71 -0
  51. package/dist/service/iam/authorize/scp/sim-iam-scp-gate.d.ts +96 -0
  52. package/dist/service/iam/authorize/scp/sim-iam-scp-gate.js +148 -0
  53. package/dist/service/iam/authorize/scp/sim-iam-scp-resolver.d.ts +53 -0
  54. package/dist/service/iam/authorize/scp/sim-iam-scp-resolver.js +1 -0
  55. package/dist/service/iam/authorize/sim-iam-account-auth-z.d.ts +8 -0
  56. package/dist/service/iam/authorize/sim-iam-account-auth-z.js +1 -0
  57. package/dist/service/iam/authorize/sim-iam-action-authorizer.js +1 -0
  58. package/dist/service/iam/authorize/sim-iam-authorizer.d.ts +2 -0
  59. package/dist/service/iam/authorize/sim-iam-authorizer.js +1 -0
  60. package/dist/service/iam/authorize/sim-iam-decision-value.d.ts +13 -0
  61. package/dist/service/iam/authorize/sim-iam-decision-value.js +12 -0
  62. package/dist/service/iam/authorize/sim-iam-decision.d.ts +33 -16
  63. package/dist/service/iam/authorize/sim-iam-decision.js +64 -49
  64. package/dist/service/iam/authorize/sim-iam-inter-service-auth-z.d.ts +8 -0
  65. package/dist/service/iam/authorize/sim-iam-inter-service-auth-z.js +1 -0
  66. package/dist/service/iam/error/sim-iam.error.d.ts +8 -0
  67. package/dist/service/iam/error/sim-iam.error.js +2 -1
  68. package/dist/service/iam/sim-iam-account-parts.d.ts +9 -0
  69. package/dist/service/iam/sim-iam-account-parts.js +1 -0
  70. package/dist/service/kinesis/command/authorize/sim-kinesis-authorizer.js +1 -0
  71. package/dist/service/kms/command/authorize/sim-kms-authorizer.js +2 -0
  72. package/dist/service/lambda/command/create-function/create-function-authorizer.js +1 -0
  73. package/dist/service/lambda/command/delete-function/delete-function-authorizer.js +1 -0
  74. package/dist/service/lambda/command/event-invoke-config/event-invoke-config-authorizer.js +1 -0
  75. package/dist/service/lambda/command/function-url/function-url-authorizer.js +1 -0
  76. package/dist/service/lambda/command/get-function/get-function-authorizer.js +1 -0
  77. package/dist/service/lambda/command/invoke/invoke-authorizer.js +1 -0
  78. package/dist/service/lambda/command/list-functions/list-functions-authorizer.js +1 -0
  79. package/dist/service/lambda/command/update-function-code/update-function-code-authorizer.js +1 -0
  80. package/dist/service/lambda/command/update-function-configuration/update-function-configuration-authorizer.js +1 -0
  81. package/dist/service/lambda/command/version/version-authorizer.js +1 -0
  82. package/dist/service/logs/command/authorize/sim-logs-authorizer.js +1 -0
  83. package/dist/service/organizations/cfn/sim-cfn-organization-creator.d.ts +19 -0
  84. package/dist/service/organizations/cfn/sim-cfn-organization-creator.js +25 -0
  85. package/dist/service/organizations/cfn/sim-cfn-organizational-unit-creator.d.ts +16 -0
  86. package/dist/service/organizations/cfn/sim-cfn-organizational-unit-creator.js +21 -0
  87. package/dist/service/organizations/cfn/sim-cfn-organizations-account-creator.d.ts +20 -0
  88. package/dist/service/organizations/cfn/sim-cfn-organizations-account-creator.js +34 -0
  89. package/dist/service/organizations/cfn/sim-cfn-organizations-policy-creator.d.ts +21 -0
  90. package/dist/service/organizations/cfn/sim-cfn-organizations-policy-creator.js +40 -0
  91. package/dist/service/organizations/cfn/sim-cfn-organizations-policy-input.d.ts +20 -0
  92. package/dist/service/organizations/cfn/sim-cfn-organizations-policy-input.js +33 -0
  93. package/dist/service/organizations/cfn/sim-cfn-organizations-properties.d.ts +36 -0
  94. package/dist/service/organizations/cfn/sim-cfn-organizations-properties.js +78 -0
  95. package/dist/service/organizations/cfn/sim-cfn-organizations-record.d.ts +40 -0
  96. package/dist/service/organizations/cfn/sim-cfn-organizations-record.js +54 -0
  97. package/dist/service/organizations/cfn/sim-cfn-organizations-remover.d.ts +17 -0
  98. package/dist/service/organizations/cfn/sim-cfn-organizations-remover.js +40 -0
  99. package/dist/service/organizations/cfn/sim-organizations-cfn-resource-factory.d.ts +24 -0
  100. package/dist/service/organizations/cfn/sim-organizations-cfn-resource-factory.js +50 -0
  101. package/dist/service/organizations/index.d.ts +6 -0
  102. package/dist/service/organizations/index.js +6 -0
  103. package/dist/service/organizations/policy/sim-organizations-effective-policies.d.ts +43 -0
  104. package/dist/service/organizations/policy/sim-organizations-effective-policies.js +58 -0
  105. package/dist/service/organizations/policy/sim-organizations-scp-store.d.ts +61 -0
  106. package/dist/service/organizations/policy/sim-organizations-scp-store.js +103 -0
  107. package/dist/service/organizations/sim-organizations-structure.d.ts +94 -0
  108. package/dist/service/organizations/sim-organizations-structure.js +140 -0
  109. package/dist/service/organizations/sim-organizations.d.ts +95 -0
  110. package/dist/service/organizations/sim-organizations.js +99 -0
  111. package/dist/service/organizations/tree/sim-organizations-node.d.ts +57 -0
  112. package/dist/service/organizations/tree/sim-organizations-node.js +58 -0
  113. package/dist/service/organizations/tree/sim-organizations-tree.d.ts +91 -0
  114. package/dist/service/organizations/tree/sim-organizations-tree.js +154 -0
  115. package/dist/service/route53/command/change-resource-record-sets/change-resource-record-sets-authorizer.js +1 -0
  116. package/dist/service/route53/command/create-hosted-zone/create-hosted-zone-authorizer.js +1 -0
  117. package/dist/service/route53/command/delete-hosted-zone/delete-hosted-zone-authorizer.js +1 -0
  118. package/dist/service/route53/command/dnssec/sim-route53-dnssec-authorizer.js +1 -0
  119. package/dist/service/route53/command/get-hosted-zone/get-hosted-zone-authorizer.js +1 -0
  120. package/dist/service/route53/command/list-hosted-zones-by-name/list-hosted-zones-by-name-authorizer.js +1 -0
  121. package/dist/service/route53/command/list-resource-record-sets/list-resource-record-sets-authorizer.js +1 -0
  122. package/dist/service/s3/command/create-bucket/create-bucket.handler.js +1 -0
  123. package/dist/service/s3/command/delete-bucket/delete-bucket-authorizer.js +1 -0
  124. package/dist/service/s3/command/delete-bucket-policy/delete-bucket-policy-authorizer.js +1 -0
  125. package/dist/service/s3/command/delete-object/delete-object-authorizer.js +1 -0
  126. package/dist/service/s3/command/get-bucket-policy/get-bucket-policy-authorizer.js +1 -0
  127. package/dist/service/s3/command/get-object/get-object-authorizer.js +1 -0
  128. package/dist/service/s3/command/head-bucket/head-bucket-authorizer.js +1 -0
  129. package/dist/service/s3/command/lifecycle/sim-s3-lifecycle-authorizer.js +1 -0
  130. package/dist/service/s3/command/list-buckets/list-buckets-authorizer.js +1 -0
  131. package/dist/service/s3/command/list-objects/list-objects-authorizer.js +1 -0
  132. package/dist/service/s3/command/multipart/sim-s3-multipart-authorizer.js +1 -0
  133. package/dist/service/s3/command/notification/sim-s3-notification-authorizer.js +1 -0
  134. package/dist/service/s3/command/public-access-block/sim-s3-public-access-block-authorizer.js +1 -0
  135. package/dist/service/s3/command/put-bucket-policy/put-bucket-policy-authorizer.js +1 -0
  136. package/dist/service/s3/command/put-bucket-website/put-bucket-website-authorizer.js +1 -0
  137. package/dist/service/s3/command/put-object/put-object-authorizer.js +1 -0
  138. package/dist/service/secretsmanager/command/authorize/sim-secrets-manager-authorizer.js +1 -0
  139. package/dist/service/ses/command/authorize/sim-ses-authorizer.js +1 -0
  140. package/dist/service/sqs/command/authorize/sim-sqs-authorizer.js +1 -0
  141. package/dist/service/ssm/command/authorize/sim-ssm-authorizer.js +1 -0
  142. package/dist/service/wafv2/command/authorize/sim-wafv2-authorizer.js +1 -0
  143. package/dist/service/wafv2/command/ip-set/sim-wafv2-ip-set-commands.js +4 -3
  144. package/dist/service/wafv2/command/regex-pattern-set/sim-wafv2-regex-pattern-set-commands.js +4 -3
  145. package/dist/service/wafv2/command/sim-wafv2-input.d.ts +15 -0
  146. package/dist/service/wafv2/command/sim-wafv2-input.js +66 -1
  147. package/dist/service/wafv2/command/web-acl/sim-wafv2-web-acl-commands.js +7 -5
  148. package/dist/service/wafv2/error/sim-wafv2.error.d.ts +11 -0
  149. package/dist/service/wafv2/error/sim-wafv2.error.js +13 -0
  150. package/package.json +5 -1
@@ -0,0 +1,154 @@
1
+ import { makeSimOrganizationsOrganizationalUnitId, makeSimOrganizationsRootId, SimOrganizationsOrganizationalUnit, SimOrganizationsRoot, } from "./sim-organizations-node.js";
2
+ /**
3
+ * Thrown for an organizational unit this organization has never seen.
4
+ */
5
+ export class SimOrganizationsUnknownNode extends Error {
6
+ constructor(nodeId) {
7
+ super(`Unknown simulated Organizations node "${nodeId}"`);
8
+ this.name = "SimOrganizationsUnknownNode";
9
+ }
10
+ }
11
+ /**
12
+ * Where the Accounts and organizational units of one simulated organization
13
+ * sit relative to each other.
14
+ *
15
+ * The tree answers one question for authorization: which nodes lie on the path
16
+ * from the root down to an Account. Every policy on that path applies to the
17
+ * Account, which is what makes an organizational unit worth modelling at all.
18
+ *
19
+ * An Account joins the organization the moment it is named, whether by being
20
+ * moved into a unit or by having a policy attached to it. An Account never
21
+ * named sits outside the organization and is unrestricted.
22
+ */
23
+ export class SimOrganizationsTree {
24
+ root = new SimOrganizationsRoot(makeSimOrganizationsRootId());
25
+ organizationalUnits = new Map();
26
+ accountParents = new Map();
27
+ /**
28
+ * Create an organizational unit, under the root unless another unit is
29
+ * named as its parent.
30
+ */
31
+ createOrganizationalUnit(name, parentId = this.root.id) {
32
+ this.requireKnown(parentId);
33
+ const unit = new SimOrganizationsOrganizationalUnit(makeSimOrganizationsOrganizationalUnitId(this.root.id), name, parentId);
34
+ this.organizationalUnits.set(unit.id, unit);
35
+ return unit;
36
+ }
37
+ /**
38
+ * Place an Account under a node, joining the organization if it was outside
39
+ * it.
40
+ */
41
+ placeAccount(accountId, parentId = this.root.id) {
42
+ this.requireKnown(parentId);
43
+ this.accountParents.set(accountId, parentId);
44
+ }
45
+ /**
46
+ * Take an Account out of the organization.
47
+ */
48
+ removeAccount(accountId) {
49
+ this.accountParents.delete(accountId);
50
+ }
51
+ /**
52
+ * Take an organizational unit out of the organization.
53
+ *
54
+ * Whatever still sits under it moves up to its parent, which is the only
55
+ * answer that leaves every Account on a path back to the root. AWS refuses
56
+ * to delete a unit that still holds anything, and a Stack tears down in
57
+ * reverse dependency order, so nothing should still be there.
58
+ */
59
+ removeOrganizationalUnit(unitId) {
60
+ const unit = this.organizationalUnits.get(unitId);
61
+ if (unit === undefined) {
62
+ return;
63
+ }
64
+ this.organizationalUnits.delete(unitId);
65
+ this.reparent(unitId, unit.parentId);
66
+ }
67
+ /**
68
+ * Every Account in the organization.
69
+ */
70
+ accountIds() {
71
+ return this.accountParents.keys().toArray();
72
+ }
73
+ /**
74
+ * Whether this Account is in the organization.
75
+ */
76
+ holds(accountId) {
77
+ return this.accountParents.has(accountId);
78
+ }
79
+ /**
80
+ * Refuse a root or organizational unit this organization never created.
81
+ *
82
+ * A handle from another simulated organization would otherwise be attached
83
+ * to and then never read, because no Account here has it on its path. A
84
+ * policy that silently applies to nothing is worse than a refusal.
85
+ */
86
+ requireNode(nodeId) {
87
+ this.requireKnown(nodeId);
88
+ }
89
+ /**
90
+ * Whether this organization has a root or unit under an id.
91
+ */
92
+ hasNode(nodeId) {
93
+ return nodeId === this.root.id || this.organizationalUnits.has(nodeId);
94
+ }
95
+ /**
96
+ * The nodes a request against an Account is filtered by, root first.
97
+ *
98
+ * The Account itself is the last of them, because a policy attached to an
99
+ * Account applies alongside the ones it inherits.
100
+ */
101
+ pathTo(accountId) {
102
+ const parentId = this.accountParents.get(accountId);
103
+ if (parentId === undefined) {
104
+ return [];
105
+ }
106
+ return [...this.ancestors(parentId), accountId];
107
+ }
108
+ /**
109
+ * What to call a node in a denial.
110
+ */
111
+ nameOf(nodeId) {
112
+ if (nodeId === this.root.id) {
113
+ return this.root.name;
114
+ }
115
+ return this.organizationalUnits.get(nodeId)?.name ?? String(nodeId);
116
+ }
117
+ /**
118
+ * Move everything under one node up to another.
119
+ */
120
+ reparent(fromId, toId) {
121
+ for (const [accountId, parentId] of this.accountParents) {
122
+ if (parentId === fromId) {
123
+ this.accountParents.set(accountId, toId);
124
+ }
125
+ }
126
+ const orphaned = this.organizationalUnits
127
+ .values()
128
+ .filter((unit) => unit.parentId === fromId)
129
+ .toArray();
130
+ for (const unit of orphaned) {
131
+ this.organizationalUnits.set(unit.id, new SimOrganizationsOrganizationalUnit(unit.id, unit.name, toId));
132
+ }
133
+ }
134
+ /**
135
+ * The nodes from the root down to one node, root first.
136
+ */
137
+ ancestors(nodeId) {
138
+ const path = [];
139
+ let currentId = nodeId;
140
+ while (currentId !== undefined && currentId !== this.root.id) {
141
+ path.unshift(currentId);
142
+ currentId = this.organizationalUnits.get(currentId)?.parentId;
143
+ }
144
+ return [this.root.id, ...path];
145
+ }
146
+ /**
147
+ * Refuse a node this organization never created.
148
+ */
149
+ requireKnown(nodeId) {
150
+ if (nodeId !== this.root.id && !this.organizationalUnits.has(nodeId)) {
151
+ throw new SimOrganizationsUnknownNode(nodeId);
152
+ }
153
+ }
154
+ }
@@ -33,6 +33,7 @@ export class ChangeResourceRecordSetsAuthorizer {
33
33
  if (decision.isDenied) {
34
34
  throw new SimIamAccessDenied({
35
35
  principal: decision.caller.principal,
36
+ reason: decision.denialReason,
36
37
  action: ChangeResourceRecordSetsAuthorizer.action,
37
38
  resource: hostedZoneArn,
38
39
  });
@@ -29,6 +29,7 @@ export class CreateHostedZoneAuthorizer {
29
29
  if (decision.isDenied) {
30
30
  throw new SimIamAccessDenied({
31
31
  principal: decision.caller.principal,
32
+ reason: decision.denialReason,
32
33
  action: CreateHostedZoneAuthorizer.action,
33
34
  resource: CreateHostedZoneAuthorizer.resource,
34
35
  });
@@ -27,6 +27,7 @@ export class DeleteHostedZoneAuthorizer {
27
27
  if (decision.isDenied) {
28
28
  throw new SimIamAccessDenied({
29
29
  principal: decision.caller.principal,
30
+ reason: decision.denialReason,
30
31
  action: DeleteHostedZoneAuthorizer.action,
31
32
  resource: hostedZoneArn,
32
33
  });
@@ -22,6 +22,7 @@ export class SimRoute53DnssecAuthorizer {
22
22
  if (decision.isDenied) {
23
23
  throw new SimIamAccessDenied({
24
24
  principal: decision.caller.principal,
25
+ reason: decision.denialReason,
25
26
  action,
26
27
  resource,
27
28
  });
@@ -31,6 +31,7 @@ export class GetHostedZoneAuthorizer {
31
31
  if (decision.isDenied) {
32
32
  throw new SimIamAccessDenied({
33
33
  principal: decision.caller.principal,
34
+ reason: decision.denialReason,
34
35
  action: GetHostedZoneAuthorizer.action,
35
36
  resource: hostedZoneArn,
36
37
  });
@@ -30,6 +30,7 @@ export class ListHostedZonesByNameAuthorizer {
30
30
  if (decision.isDenied) {
31
31
  throw new SimIamAccessDenied({
32
32
  principal: decision.caller.principal,
33
+ reason: decision.denialReason,
33
34
  action: ListHostedZonesByNameAuthorizer.action,
34
35
  resource: ListHostedZonesByNameAuthorizer.resource,
35
36
  });
@@ -33,6 +33,7 @@ export class ListResourceRecordSetsAuthorizer {
33
33
  if (decision.isDenied) {
34
34
  throw new SimIamAccessDenied({
35
35
  principal: decision.caller.principal,
36
+ reason: decision.denialReason,
36
37
  action: ListResourceRecordSetsAuthorizer.action,
37
38
  resource: hostedZoneArn,
38
39
  });
@@ -44,6 +44,7 @@ export class CreateBucketCommandHandler {
44
44
  if (decision.isDenied) {
45
45
  throw new SimIamAccessDenied({
46
46
  principal: decision.caller.principal,
47
+ reason: decision.denialReason,
47
48
  action: "s3:CreateBucket",
48
49
  resource,
49
50
  });
@@ -30,6 +30,7 @@ export class DeleteBucketAuthorizer {
30
30
  if (decision.isDenied) {
31
31
  throw new SimIamAccessDenied({
32
32
  principal: decision.caller.principal,
33
+ reason: decision.denialReason,
33
34
  action: DeleteBucketAuthorizer.action,
34
35
  resource,
35
36
  });
@@ -29,6 +29,7 @@ export class DeleteBucketPolicyAuthorizer {
29
29
  if (decision.isDenied) {
30
30
  throw new SimIamAccessDenied({
31
31
  principal: decision.caller.principal,
32
+ reason: decision.denialReason,
32
33
  action: DeleteBucketPolicyAuthorizer.action,
33
34
  resource,
34
35
  });
@@ -38,6 +38,7 @@ export class DeleteObjectAuthorizer {
38
38
  if (decision.isDenied) {
39
39
  throw new SimIamAccessDenied({
40
40
  principal: decision.caller.principal,
41
+ reason: decision.denialReason,
41
42
  action: DeleteObjectAuthorizer.action,
42
43
  resource,
43
44
  });
@@ -26,6 +26,7 @@ export class GetBucketPolicyAuthorizer {
26
26
  if (decision.isDenied) {
27
27
  throw new SimIamAccessDenied({
28
28
  principal: decision.caller.principal,
29
+ reason: decision.denialReason,
29
30
  action: GetBucketPolicyAuthorizer.action,
30
31
  resource,
31
32
  });
@@ -41,6 +41,7 @@ export class GetObjectAuthorizer {
41
41
  if (decision.isDenied) {
42
42
  throw new SimIamAccessDenied({
43
43
  principal: decision.caller.principal,
44
+ reason: decision.denialReason,
44
45
  action: GetObjectAuthorizer.action,
45
46
  resource,
46
47
  });
@@ -39,6 +39,7 @@ export class HeadBucketAuthorizer {
39
39
  if (decision.isDenied) {
40
40
  throw new SimIamAccessDenied({
41
41
  principal: decision.caller.principal,
42
+ reason: decision.denialReason,
42
43
  action: HeadBucketAuthorizer.action,
43
44
  resource,
44
45
  });
@@ -42,6 +42,7 @@ export class SimS3LifecycleAuthorizer {
42
42
  if (decision.isDenied) {
43
43
  throw new SimIamAccessDenied({
44
44
  principal: decision.caller.principal,
45
+ reason: decision.denialReason,
45
46
  action,
46
47
  resource,
47
48
  });
@@ -37,6 +37,7 @@ export class ListBucketsAuthorizer {
37
37
  if (decision.isDenied) {
38
38
  throw new SimIamAccessDenied({
39
39
  principal: decision.caller.principal,
40
+ reason: decision.denialReason,
40
41
  action: ListBucketsAuthorizer.action,
41
42
  resource: ListBucketsAuthorizer.resource,
42
43
  });
@@ -48,6 +48,7 @@ export class ListObjectsAuthorizer {
48
48
  if (decision.isDenied) {
49
49
  throw new SimIamAccessDenied({
50
50
  principal: decision.caller.principal,
51
+ reason: decision.denialReason,
51
52
  action: ListObjectsAuthorizer.action,
52
53
  resource,
53
54
  });
@@ -42,6 +42,7 @@ export class SimS3MultipartAuthorizer {
42
42
  if (decision.isDenied) {
43
43
  throw new SimIamAccessDenied({
44
44
  principal: decision.caller.principal,
45
+ reason: decision.denialReason,
45
46
  action: SimS3MultipartAuthorizer.action,
46
47
  resource,
47
48
  });
@@ -43,6 +43,7 @@ export class SimS3NotificationAuthorizer {
43
43
  if (decision.isDenied) {
44
44
  throw new SimIamAccessDenied({
45
45
  principal: decision.caller.principal,
46
+ reason: decision.denialReason,
46
47
  action,
47
48
  resource,
48
49
  });
@@ -41,6 +41,7 @@ export class SimS3PublicAccessBlockAuthorizer {
41
41
  if (decision.isDenied) {
42
42
  throw new SimIamAccessDenied({
43
43
  principal: decision.caller.principal,
44
+ reason: decision.denialReason,
44
45
  action,
45
46
  resource,
46
47
  });
@@ -23,6 +23,7 @@ export class PutBucketPolicyAuthorizer {
23
23
  if (decision.isDenied) {
24
24
  throw new SimIamAccessDenied({
25
25
  principal: decision.caller.principal,
26
+ reason: decision.denialReason,
26
27
  action: PutBucketPolicyAuthorizer.action,
27
28
  resource,
28
29
  });
@@ -40,6 +40,7 @@ export class PutBucketWebsiteAuthorizer {
40
40
  if (decision.isDenied) {
41
41
  throw new SimIamAccessDenied({
42
42
  principal: decision.caller.principal,
43
+ reason: decision.denialReason,
43
44
  action: PutBucketWebsiteAuthorizer.action,
44
45
  resource,
45
46
  });
@@ -41,6 +41,7 @@ export class PutObjectAuthorizer {
41
41
  if (decision.isDenied) {
42
42
  throw new SimIamAccessDenied({
43
43
  principal: decision.caller.principal,
44
+ reason: decision.denialReason,
44
45
  action: PutObjectAuthorizer.action,
45
46
  resource,
46
47
  });
@@ -38,6 +38,7 @@ export class SimSecretsManagerAuthorizer {
38
38
  if (decision.isDenied) {
39
39
  throw new SimIamAccessDenied({
40
40
  principal: decision.caller.principal,
41
+ reason: decision.denialReason,
41
42
  action,
42
43
  resource,
43
44
  });
@@ -78,6 +78,7 @@ export class SimSesAuthorizer {
78
78
  if (decision.isDenied) {
79
79
  throw new SimIamAccessDenied({
80
80
  principal: decision.caller.principal,
81
+ reason: decision.denialReason,
81
82
  action,
82
83
  resource,
83
84
  });
@@ -69,6 +69,7 @@ export class SimSqsAuthorizer {
69
69
  if (decision.isDenied) {
70
70
  throw new SimIamAccessDenied({
71
71
  principal: decision.caller.principal,
72
+ reason: decision.denialReason,
72
73
  action: input.action,
73
74
  resource: input.resource,
74
75
  });
@@ -55,6 +55,7 @@ export class SimSsmAuthorizer {
55
55
  if (decision.isDenied) {
56
56
  throw new SimIamAccessDenied({
57
57
  principal: decision.caller.principal,
58
+ reason: decision.denialReason,
58
59
  action,
59
60
  resource,
60
61
  });
@@ -34,6 +34,7 @@ export class SimWafAuthorizer {
34
34
  if (decision.isDenied) {
35
35
  throw new SimIamAccessDenied({
36
36
  principal: decision.caller.principal,
37
+ reason: decision.denialReason,
37
38
  action,
38
39
  resource,
39
40
  });
@@ -1,7 +1,7 @@
1
1
  import { SimWafIpSet, requiredSimWafIpAddressVersion, } from "../../ip-set/sim-waf-ip-set.js";
2
2
  import { requiredSimWafScope } from "../../scope/sim-waf-scope.js";
3
3
  import { SimWafPage } from "../sim-wafv2-page.js";
4
- import { refuseSimWafTags, requiredSimWafName } from "../sim-wafv2-input.js";
4
+ import { checkedSimWafDescription, refuseSimWafTags, requiredSimWafName, } from "../sim-wafv2-input.js";
5
5
  import { requireSimWafResource } from "../sim-wafv2-resource-lookup.js";
6
6
  /**
7
7
  * The commands that make, read, list and remove IP sets.
@@ -29,7 +29,7 @@ export class SimWafIpSetCommands {
29
29
  name: requiredSimWafName(input.Name),
30
30
  scope: requiredSimWafScope(input.Scope, this.#accountRegionScope.regionName),
31
31
  accountRegionScope: this.#accountRegionScope,
32
- description: input.Description,
32
+ description: checkedSimWafDescription(input.Description),
33
33
  ipAddressVersion: requiredSimWafIpAddressVersion(input.IPAddressVersion),
34
34
  addresses: input.Addresses ?? [],
35
35
  });
@@ -59,10 +59,11 @@ export class SimWafIpSetCommands {
59
59
  */
60
60
  updateIpSet(command, options) {
61
61
  const { input } = command;
62
+ const description = checkedSimWafDescription(input.Description);
62
63
  const ipSet = this.require(input, "wafv2:UpdateIPSet", options);
63
64
  ipSet.replaceAddresses({
64
65
  addresses: input.Addresses ?? [],
65
- description: input.Description,
66
+ description,
66
67
  lockToken: input.LockToken,
67
68
  });
68
69
  return { $metadata: {}, NextLockToken: ipSet.lockToken };
@@ -1,7 +1,7 @@
1
1
  import { SimWafRegexPatternSet } from "../../regex-pattern-set/sim-waf-regex-pattern-set.js";
2
2
  import { requiredSimWafScope } from "../../scope/sim-waf-scope.js";
3
3
  import { SimWafPage } from "../sim-wafv2-page.js";
4
- import { refuseSimWafTags, requiredSimWafName } from "../sim-wafv2-input.js";
4
+ import { checkedSimWafDescription, refuseSimWafTags, requiredSimWafName, } from "../sim-wafv2-input.js";
5
5
  import { requireSimWafResource } from "../sim-wafv2-resource-lookup.js";
6
6
  /**
7
7
  * The commands that make, read, list and remove regex pattern sets.
@@ -29,7 +29,7 @@ export class SimWafRegexPatternSetCommands {
29
29
  name: requiredSimWafName(input.Name),
30
30
  scope: requiredSimWafScope(input.Scope, this.#accountRegionScope.regionName),
31
31
  accountRegionScope: this.#accountRegionScope,
32
- description: input.Description,
32
+ description: checkedSimWafDescription(input.Description),
33
33
  regularExpressions: input.RegularExpressionList ?? [],
34
34
  });
35
35
  this.#authorizer.authorizeResource("wafv2:CreateRegexPatternSet", patternSet.arn, options?.caller);
@@ -66,10 +66,11 @@ export class SimWafRegexPatternSetCommands {
66
66
  */
67
67
  updateRegexPatternSet(command, options) {
68
68
  const { input } = command;
69
+ const description = checkedSimWafDescription(input.Description);
69
70
  const patternSet = this.require(input, "wafv2:UpdateRegexPatternSet", options);
70
71
  patternSet.replaceExpressions({
71
72
  regularExpressions: input.RegularExpressionList ?? [],
72
- description: input.Description,
73
+ description,
73
74
  lockToken: input.LockToken,
74
75
  });
75
76
  return { $metadata: {}, NextLockToken: patternSet.lockToken };
@@ -24,3 +24,18 @@ export declare function refuseSimWafTags(tags: readonly unknown[] | undefined, o
24
24
  * by ARN, and neither has anything else to fall back on.
25
25
  */
26
26
  export declare function requiredSimWafArn(arn: string | undefined, parameter: string): string;
27
+ /**
28
+ * Read the description a write gave, refusing one WAFv2 will not store.
29
+ *
30
+ * The empty string is the one worth catching. Code that reads a resource,
31
+ * changes part of it and writes the rest back hands the description straight
32
+ * through, and AWS answers `""` for some resources nobody has described. WAFv2
33
+ * refuses that write. A simulation that took it would leave the failure for
34
+ * the account to report.
35
+ *
36
+ * The two constraints are checked apart because AWS checks them apart. The
37
+ * pattern matches three characters at the shortest. `ab` is long enough for
38
+ * the length and still refused, and `""` fails both at once, which is how one
39
+ * message comes to report two errors.
40
+ */
41
+ export declare function checkedSimWafDescription(description: string | undefined): string | undefined;
@@ -1,4 +1,4 @@
1
- import { SimWafInvalidParameterException, SimWafUnsimulatedInputException, } from "../error/sim-wafv2.error.js";
1
+ import { SimWafInvalidParameterException, SimWafUnsimulatedInputException, SimWafValidationException, } from "../error/sim-wafv2.error.js";
2
2
  /**
3
3
  * Read the name a request named, refusing a request with none.
4
4
  */
@@ -47,3 +47,68 @@ export function requiredSimWafArn(arn, parameter) {
47
47
  }
48
48
  return arn;
49
49
  }
50
+ /**
51
+ * The shape WAFv2 documents for the description of a web ACL, an IP set and a
52
+ * regex pattern set.
53
+ *
54
+ * The refusal below quotes this expression back, the way WAFv2 quotes its own.
55
+ * WAFv2 writes the dots inside the character classes escaped and this does
56
+ * not, which is the same set of characters written two ways.
57
+ */
58
+ const descriptionExpression = /^[\w+=:#@/\-,.][\w+=:#@/\-,.\s]+[\w+=:#@/\-,.]$/;
59
+ const descriptionMaxLength = 256;
60
+ /**
61
+ * Read the description a write gave, refusing one WAFv2 will not store.
62
+ *
63
+ * The empty string is the one worth catching. Code that reads a resource,
64
+ * changes part of it and writes the rest back hands the description straight
65
+ * through, and AWS answers `""` for some resources nobody has described. WAFv2
66
+ * refuses that write. A simulation that took it would leave the failure for
67
+ * the account to report.
68
+ *
69
+ * The two constraints are checked apart because AWS checks them apart. The
70
+ * pattern matches three characters at the shortest. `ab` is long enough for
71
+ * the length and still refused, and `""` fails both at once, which is how one
72
+ * message comes to report two errors.
73
+ */
74
+ export function checkedSimWafDescription(description) {
75
+ if (description === undefined) {
76
+ return undefined;
77
+ }
78
+ const failures = [
79
+ ...lengthFailures(description),
80
+ ...patternFailures(description),
81
+ ];
82
+ if (failures.length === 0) {
83
+ return description;
84
+ }
85
+ throw new SimWafValidationException(`${failures.length} validation error${failures.length === 1 ? "" : "s"} detected: ${failures
86
+ .map((failure) => `Value '${description}' at 'description' failed to satisfy ` +
87
+ `constraint: ${failure}`)
88
+ .join("; ")}`);
89
+ }
90
+ /**
91
+ * What the length of a description falls foul of, if anything.
92
+ */
93
+ function lengthFailures(description) {
94
+ if (description.length === 0) {
95
+ return ["Member must have length greater than or equal to 1"];
96
+ }
97
+ if (description.length > descriptionMaxLength) {
98
+ return [
99
+ `Member must have length less than or equal to ${descriptionMaxLength}`,
100
+ ];
101
+ }
102
+ return [];
103
+ }
104
+ /**
105
+ * What the shape of a description falls foul of, if anything.
106
+ */
107
+ function patternFailures(description) {
108
+ if (descriptionExpression.test(description)) {
109
+ return [];
110
+ }
111
+ return [
112
+ `Member must satisfy regular expression pattern: ${descriptionExpression.source}`,
113
+ ];
114
+ }
@@ -2,7 +2,7 @@ import { SimWafAssociatedItemException } from "../../error/sim-wafv2.error.js";
2
2
  import { requiredSimWafScope } from "../../scope/sim-waf-scope.js";
3
3
  import { SimWafWebAcl } from "../../web-acl/sim-waf-web-acl.js";
4
4
  import { SimWafPage } from "../sim-wafv2-page.js";
5
- import { requiredSimWafName } from "../sim-wafv2-input.js";
5
+ import { checkedSimWafDescription, requiredSimWafName, } from "../sim-wafv2-input.js";
6
6
  import { requireSimWafResource, } from "../sim-wafv2-resource-lookup.js";
7
7
  import { refuseUnsimulatedSimWafWebAclInput } from "./sim-wafv2-unsimulated-web-acl-input.js";
8
8
  import { simWafWebAclOutput } from "./sim-waf-web-acl-output.js";
@@ -38,12 +38,13 @@ export class SimWafWebAclCommands {
38
38
  const name = requiredSimWafName(input.Name);
39
39
  const scope = requiredSimWafScope(input.Scope, this.#accountRegionScope.regionName);
40
40
  refuseUnsimulatedSimWafWebAclInput(input, "CreateWebACL");
41
+ const configuration = configurationOf(input);
41
42
  const webAcl = new SimWafWebAcl({
42
43
  name,
43
44
  scope,
44
45
  accountRegionScope: this.#accountRegionScope,
45
- description: input.Description,
46
- configuration: configurationOf(input),
46
+ description: configuration.description,
47
+ configuration,
47
48
  regexPatternSets: this.#regexPatternSets,
48
49
  managedRules: this.#managedRules,
49
50
  clock: this.#clock,
@@ -68,8 +69,9 @@ export class SimWafWebAclCommands {
68
69
  updateWebAcl(command, options) {
69
70
  const { input } = command;
70
71
  refuseUnsimulatedSimWafWebAclInput(input, "UpdateWebACL");
72
+ const configuration = configurationOf(input);
71
73
  const webAcl = this.require(input, "wafv2:UpdateWebACL", options);
72
- webAcl.reconfigure(configurationOf(input), input.LockToken);
74
+ webAcl.reconfigure(configuration, input.LockToken);
73
75
  return { $metadata: {}, NextLockToken: webAcl.lockToken };
74
76
  }
75
77
  /**
@@ -134,6 +136,6 @@ function configurationOf(input) {
134
136
  rules: input.Rules,
135
137
  customResponseBodies: input.CustomResponseBodies,
136
138
  visibilityConfig: input.VisibilityConfig,
137
- description: input.Description,
139
+ description: checkedSimWafDescription(input.Description),
138
140
  };
139
141
  }
@@ -89,6 +89,17 @@ export declare class SimWafAssociatedItemException extends SimWafError {
89
89
  readonly name = "WAFAssociatedItemException";
90
90
  constructor(message: string);
91
91
  }
92
+ /**
93
+ * Simulated WAFv2 ValidationException error.
94
+ *
95
+ * WAFv2 checks the length and shape of a few members before the request
96
+ * reaches the rest of the API, and reports every failure in one message. A
97
+ * description of `""` fails two of those checks at once.
98
+ */
99
+ export declare class SimWafValidationException extends SimWafError {
100
+ readonly name = "ValidationException";
101
+ constructor(message: string);
102
+ }
92
103
  /**
93
104
  * A match declared against this simulation that it cannot answer with.
94
105
  *
@@ -100,6 +100,19 @@ export class SimWafAssociatedItemException extends SimWafError {
100
100
  super(message, { httpStatusCode: 400 });
101
101
  }
102
102
  }
103
+ /**
104
+ * Simulated WAFv2 ValidationException error.
105
+ *
106
+ * WAFv2 checks the length and shape of a few members before the request
107
+ * reaches the rest of the API, and reports every failure in one message. A
108
+ * description of `""` fails two of those checks at once.
109
+ */
110
+ export class SimWafValidationException extends SimWafError {
111
+ name = "ValidationException";
112
+ constructor(message) {
113
+ super(message, { httpStatusCode: 400 });
114
+ }
115
+ }
103
116
  /**
104
117
  * A match declared against this simulation that it cannot answer with.
105
118
  *