@@ -65,7 +65,7 @@ export abstract class PolicyPrincipal {
65
65
*/
66
66
export class PrincipalPolicyFragment {
67
67
constructor (
68
- public readonly principalJson : any ,
68
+ public readonly principalJson : { [ key : string ] : any } ,
69
69
public readonly conditions : { [ key : string ] : any } = { } ) {
70
70
}
71
71
}
@@ -144,18 +144,9 @@ export class AccountRootPrincipal extends AccountPrincipal {
144
144
/**
145
145
* A principal representing all identities in all accounts
146
146
*/
147
- export class Anyone extends PolicyPrincipal {
148
- /**
149
- * Interface compatibility with AccountPrincipal for the purposes of the Lambda library
150
- *
151
- * The Lambda's addPermission() call works differently from regular
152
- * statements, and will use the value of this property directly if present
153
- * (which leads to the correct statement ultimately).
154
- */
155
- public readonly accountId = '*' ;
156
-
157
- public policyFragment ( ) : PrincipalPolicyFragment {
158
- return new PrincipalPolicyFragment ( '*' ) ;
147
+ export class Anyone extends ArnPrincipal {
148
+ constructor ( ) {
149
+ super ( '*' ) ;
159
150
}
160
151
}
161
152
@@ -164,7 +155,7 @@ export class Anyone extends PolicyPrincipal {
164
155
*/
165
156
export class PolicyStatement extends Token {
166
157
private action = new Array < any > ( ) ;
167
- private principal = new Array < any > ( ) ;
158
+ private principal : { [ key : string ] : any [ ] } = { } ;
168
159
private resource = new Array < any > ( ) ;
169
160
private condition : { [ key : string ] : any } = { } ;
170
161
private effect ?: PolicyStatementEffect ;
@@ -197,12 +188,23 @@ export class PolicyStatement extends Token {
197
188
* Indicates if this permission has a "Principal" section.
198
189
*/
199
190
public get hasPrincipal ( ) {
200
- return this . principal && this . principal . length > 0 ;
191
+ return Object . keys ( this . principal ) . length > 0 ;
201
192
}
202
193
203
194
public addPrincipal ( principal : PolicyPrincipal ) : PolicyStatement {
204
195
const fragment = principal . policyFragment ( ) ;
205
- this . principal . push ( fragment . principalJson ) ;
196
+ for ( const key of Object . keys ( fragment . principalJson ) ) {
197
+ if ( Object . keys ( this . principal ) . length > 0 && ! ( key in this . principal ) ) {
198
+ throw new Error ( `Attempted to add principal key ${ key } in principal of type ${ Object . keys ( this . principal ) [ 0 ] } ` ) ;
199
+ }
200
+ this . principal [ key ] = this . principal [ key ] || [ ] ;
201
+ const value = fragment . principalJson [ key ] ;
202
+ if ( Array . isArray ( value ) ) {
203
+ this . principal [ key ] . push ( ...value ) ;
204
+ } else {
205
+ this . principal [ key ] . push ( value ) ;
206
+ }
207
+ }
206
208
this . addConditions ( fragment . conditions ) ;
207
209
return this ;
208
210
}
@@ -330,7 +332,7 @@ export class PolicyStatement extends Token {
330
332
Action : _norm ( this . action ) ,
331
333
Condition : _norm ( this . condition ) ,
332
334
Effect : _norm ( this . effect ) ,
333
- Principal : _norm ( this . principal ) ,
335
+ Principal : _normPrincipal ( this . principal ) ,
334
336
Resource : _norm ( this . resource ) ,
335
337
Sid : _norm ( this . sid ) ,
336
338
} ;
@@ -361,6 +363,22 @@ export class PolicyStatement extends Token {
361
363
362
364
return values ;
363
365
}
366
+
367
+ function _normPrincipal ( principal : { [ key : string ] : any [ ] } ) {
368
+ const keys = Object . keys ( principal ) ;
369
+ if ( keys . length === 0 ) { return undefined ; }
370
+ const result : any = { } ;
371
+ for ( const key of keys ) {
372
+ const normVal = _norm ( principal [ key ] ) ;
373
+ if ( normVal ) {
374
+ result [ key ] = normVal ;
375
+ }
376
+ }
377
+ if ( Object . keys ( result ) . length === 1 && result . AWS === '*' ) {
378
+ return '*' ;
379
+ }
380
+ return result ;
381
+ }
364
382
}
365
383
}
366
384
0 commit comments