@@ -6,19 +6,27 @@ import { transformTagKeyValue } from './utils/objectTags';
66import RequestContext from './RequestContext' ;
77import { Logger } from 'werelogs' ;
88
9- const operatorsWithVariables = [ 'StringEquals' , 'StringNotEquals' ,
10- 'StringEqualsIgnoreCase' , 'StringNotEqualsIgnoreCase' ,
11- 'StringLike' , 'StringNotLike' , 'ArnEquals' , 'ArnNotEquals' ,
12- 'ArnLike' , 'ArnNotLike' ] ;
13- const operatorsWithNegation = [ 'StringNotEquals' ,
14- 'StringNotEqualsIgnoreCase' , 'StringNotLike' , 'ArnNotEquals' ,
15- 'ArnNotLike' , 'NumericNotEquals' ] ;
16- const tagConditions = new Set ( [
17- 's3:ExistingObjectTag' ,
18- 's3:RequestObjectTagKey' ,
19- 's3:RequestObjectTagKeys' ,
20- ] ) ;
21-
9+ const operatorsWithVariables = [
10+ 'StringEquals' ,
11+ 'StringNotEquals' ,
12+ 'StringEqualsIgnoreCase' ,
13+ 'StringNotEqualsIgnoreCase' ,
14+ 'StringLike' ,
15+ 'StringNotLike' ,
16+ 'ArnEquals' ,
17+ 'ArnNotEquals' ,
18+ 'ArnLike' ,
19+ 'ArnNotLike' ,
20+ ] ;
21+ const operatorsWithNegation = [
22+ 'StringNotEquals' ,
23+ 'StringNotEqualsIgnoreCase' ,
24+ 'StringNotLike' ,
25+ 'ArnNotEquals' ,
26+ 'ArnNotLike' ,
27+ 'NumericNotEquals' ,
28+ ] ;
29+ const tagConditions = new Set ( [ 's3:ExistingObjectTag' , 's3:RequestObjectTagKey' , 's3:RequestObjectTagKeys' ] ) ;
2230
2331/**
2432 * Check whether resource in policy statement applies to request resource
@@ -45,21 +53,16 @@ export function isResourceApplicable(
4553 const requestRelativeId = requestResourceArr . slice ( 5 ) . join ( ':' ) ;
4654 for ( let i = 0 ; i < statementResource . length ; i ++ ) {
4755 // Handle variables (must handle BEFORE wildcards)
48- const policyResource =
49- substituteVariables ( statementResource [ i ] , requestContext ) ;
56+ const policyResource = substituteVariables ( statementResource [ i ] , requestContext ) ;
5057 // Handle wildcards
51- const arnSegmentsMatch =
52- checkArnMatch ( policyResource , requestRelativeId ,
53- requestResourceArr , true ) ;
58+ const arnSegmentsMatch = checkArnMatch ( policyResource , requestRelativeId , requestResourceArr ) ;
5459 if ( arnSegmentsMatch ) {
55- log . trace ( 'policy resource is applicable to request' ,
56- { requestResource : resource , policyResource } ) ;
60+ log . trace ( 'policy resource is applicable to request' , { requestResource : resource , policyResource } ) ;
5761 return true ;
5862 }
5963 continue ;
6064 }
61- log . trace ( 'no policy resource is applicable to request' ,
62- { requestResource : resource } ) ;
65+ log . trace ( 'no policy resource is applicable to request' , { requestResource : resource } ) ;
6366 // If no match found, no resource is applicable
6467 return false ;
6568}
@@ -72,29 +75,24 @@ export function isResourceApplicable(
7275 * @param log - logger
7376 * @return true if applicable, false if not
7477 */
75- export function isActionApplicable (
76- requestAction : string ,
77- statementAction : string | string [ ] ,
78- log : Logger ,
79- ) : boolean {
78+ export function isActionApplicable ( requestAction : string , statementAction : string | string [ ] , log : Logger ) : boolean {
8079 if ( ! Array . isArray ( statementAction ) ) {
8180 statementAction = [ statementAction ] ;
8281 }
8382 const length = statementAction . length ;
8483 for ( let i = 0 ; i < length ; i ++ ) {
8584 // No variables in actions so no need to handle
86- const regExStrOfStatementAction =
87- handleWildcards ( statementAction [ i ] ) ;
85+ const regExStrOfStatementAction = handleWildcards ( statementAction [ i ] ) ;
8886 const actualRegEx = new RegExp ( regExStrOfStatementAction , 'i' ) ;
8987 if ( actualRegEx . test ( requestAction ) ) {
9088 log . trace ( 'policy action is applicable to request action' , {
91- requestAction, policyAction : statementAction [ i ] ,
89+ requestAction,
90+ policyAction : statementAction [ i ] ,
9291 } ) ;
9392 return true ;
9493 }
9594 }
96- log . trace ( 'no action in policy applicable to request action' ,
97- { requestAction } ) ;
95+ log . trace ( 'no action in policy applicable to request action' , { requestAction } ) ;
9896 // If no match found, return false
9997 return false ;
10098}
@@ -111,11 +109,7 @@ export function isActionApplicable(
111109 * provided (namely, for tag conditions, request tags and/or object
112110 * tags have to be provided to evaluate the condition)
113111 */
114- export function meetConditions (
115- requestContext : RequestContext ,
116- statementCondition : any ,
117- log : Logger ,
118- ) : boolean | null {
112+ export function meetConditions ( requestContext : RequestContext , statementCondition : any , log : Logger ) : boolean | null {
119113 let hasTagConditions = false ;
120114 // The Condition portion of a policy is an object with different
121115 // operators as keys
@@ -124,16 +118,13 @@ export function meetConditions(
124118 const hasIfExistsCondition = operator . endsWith ( 'IfExists' ) ;
125119 // If has "IfExists" added to operator name, or operator has "ForAnyValue" or
126120 // "ForAllValues" prefix, find operator name without "IfExists" or prefix
127- let bareOperator = hasIfExistsCondition ? operator . slice ( 0 , - 8 ) :
128- operator ;
121+ let bareOperator = hasIfExistsCondition ? operator . slice ( 0 , - 8 ) : operator ;
129122 let prefix : string | undefined ;
130123 if ( hasPrefix ) {
131124 [ prefix , bareOperator ] = bareOperator . split ( ':' ) ;
132125 }
133- const operatorCanHaveVariables =
134- operatorsWithVariables . indexOf ( bareOperator ) > - 1 ;
135- const isNegationOperator =
136- operatorsWithNegation . indexOf ( bareOperator ) > - 1 ;
126+ const operatorCanHaveVariables = operatorsWithVariables . indexOf ( bareOperator ) > - 1 ;
127+ const isNegationOperator = operatorsWithNegation . indexOf ( bareOperator ) > - 1 ;
137128 // Loop through conditions with the same operator
138129 // Note: this should be the actual operator name, not the bareOperator
139130 const conditionsWithSameOperator = statementCondition [ operator ] ;
@@ -147,8 +138,7 @@ export function meetConditions(
147138 }
148139 // Handle variables
149140 if ( operatorCanHaveVariables ) {
150- value = value . map ( ( item : any ) =>
151- substituteVariables ( item , requestContext ) ) ;
141+ value = value . map ( ( item : any ) => substituteVariables ( item , requestContext ) ) ;
152142 }
153143 // if condition key is RequestObjectTag or ExistingObjectTag,
154144 // tag key is included in condition key and needs to be
@@ -164,25 +154,29 @@ export function meetConditions(
164154 // condition has "ForAnyValue" or "ForAllValues".
165155 // (see http://docs.aws.amazon.com/IAM/latest/UserGuide/
166156 // reference_policies_multi-value-conditions.html)
167- let keyBasedOnRequestContext =
168- findConditionKey ( transformedKey , requestContext ) ;
157+ let keyBasedOnRequestContext = findConditionKey ( transformedKey , requestContext ) ;
169158 // Handle IfExists and negation operators
170- if ( ( keyBasedOnRequestContext === undefined ||
171- keyBasedOnRequestContext === null ) &&
172- ( hasIfExistsCondition || isNegationOperator ) ) {
173- log . trace ( 'satisfies condition due to IfExists operator or ' +
174- 'negation operator' , { method : 'evaluators.evaluatePolicy' } ) ;
159+ if (
160+ ( keyBasedOnRequestContext === undefined || keyBasedOnRequestContext === null ) &&
161+ ( hasIfExistsCondition || isNegationOperator )
162+ ) {
163+ log . trace ( 'satisfies condition due to IfExists operator or ' + 'negation operator' , {
164+ method : 'evaluators.evaluatePolicy' ,
165+ } ) ;
175166 continue ;
176167 }
177168 // If no IfExists qualifier, the key does not exist and the
178169 // condition operator is not Null, the
179170 // condition is not met so return false.
180- if ( ( keyBasedOnRequestContext === null ||
181- keyBasedOnRequestContext === undefined ) &&
182- bareOperator !== 'Null' ) {
183- log . trace ( 'condition not satisfied due to ' +
184- 'missing info' , { operator,
185- conditionKey : transformedKey , policyValue : transformedValue } ) ;
171+ if (
172+ ( keyBasedOnRequestContext === null || keyBasedOnRequestContext === undefined ) &&
173+ bareOperator !== 'Null'
174+ ) {
175+ log . trace ( 'condition not satisfied due to ' + 'missing info' , {
176+ operator,
177+ conditionKey : transformedKey ,
178+ policyValue : transformedValue ,
179+ } ) ;
186180 return false ;
187181 }
188182 // If condition operator prefix is included, the key should be an array
@@ -196,8 +190,11 @@ export function meetConditions(
196190 // are the only operators where wildcards are allowed
197191 // @ts -expect-error
198192 if ( ! operatorFunction ( keyBasedOnRequestContext , transformedValue , prefix ) ) {
199- log . trace ( 'did not satisfy condition' , { operator : bareOperator ,
200- keyBasedOnRequestContext, policyValue : transformedValue } ) ;
193+ log . trace ( 'did not satisfy condition' , {
194+ operator : bareOperator ,
195+ keyBasedOnRequestContext,
196+ policyValue : transformedValue ,
197+ } ) ;
201198 return false ;
202199 }
203200 }
@@ -220,11 +217,7 @@ export function meetConditions(
220217 * @return Allow if permitted, Deny if not permitted or Neutral
221218 * if not applicable
222219 */
223- export function evaluatePolicy (
224- requestContext : RequestContext ,
225- policy : any ,
226- log : Logger ,
227- ) : string {
220+ export function evaluatePolicy ( requestContext : RequestContext , policy : any , log : Logger ) : string {
228221 // TODO: For bucket policies need to add Principal evaluation
229222 let allow = false ;
230223 let allowWithTagCondition = false ;
@@ -237,34 +230,30 @@ export function evaluatePolicy(
237230 const currentStatement = policy . Statement [ i ] ;
238231 // If affirmative resource is in policy and request resource is
239232 // not applicable, move on to next statement
240- if ( currentStatement . Resource && ! isResourceApplicable ( requestContext ,
241- currentStatement . Resource , log ) ) {
233+ if ( currentStatement . Resource && ! isResourceApplicable ( requestContext , currentStatement . Resource , log ) ) {
242234 continue ;
243235 }
244236 // If NotResource is in policy and resource matches NotResource
245237 // in policy, move on to next statement
246- if ( currentStatement . NotResource &&
247- isResourceApplicable ( requestContext ,
248- currentStatement . NotResource , log ) ) {
238+ if ( currentStatement . NotResource && isResourceApplicable ( requestContext , currentStatement . NotResource , log ) ) {
249239 continue ;
250240 }
251241 // If affirmative action is in policy and request action is not
252242 // applicable, move on to next statement
253- if ( currentStatement . Action &&
254- ! isActionApplicable ( requestContext . getAction ( ) ,
255- currentStatement . Action , log ) ) {
243+ if ( currentStatement . Action && ! isActionApplicable ( requestContext . getAction ( ) , currentStatement . Action , log ) ) {
256244 continue ;
257245 }
258246 // If NotAction is in policy and action matches NotAction in policy,
259247 // move on to next statement
260- if ( currentStatement . NotAction &&
261- isActionApplicable ( requestContext . getAction ( ) ,
262- currentStatement . NotAction , log ) ) {
248+ if (
249+ currentStatement . NotAction &&
250+ isActionApplicable ( requestContext . getAction ( ) , currentStatement . NotAction , log )
251+ ) {
263252 continue ;
264253 }
265- const conditionEval = currentStatement . Condition ?
266- meetConditions ( requestContext , currentStatement . Condition , log ) :
267- true ;
254+ const conditionEval = currentStatement . Condition
255+ ? meetConditions ( requestContext , currentStatement . Condition , log )
256+ : true ;
268257 // If do not meet conditions move on to next statement
269258 if ( conditionEval === false ) {
270259 continue ;
@@ -318,11 +307,7 @@ export function evaluatePolicy(
318307 * @return Allow if permitted, Deny if not permitted.
319308 * Default is to Deny. Deny overrides an Allow
320309 */
321- export function evaluateAllPolicies (
322- requestContext : RequestContext ,
323- allPolicies : any [ ] ,
324- log : Logger ,
325- ) : string {
310+ export function evaluateAllPolicies ( requestContext : RequestContext , allPolicies : any [ ] , log : Logger ) : string {
326311 return standardEvaluateAllPolicies ( requestContext , allPolicies , log ) . verdict ;
327312}
328313export function standardEvaluateAllPolicies (
0 commit comments