@@ -190,14 +190,17 @@ exports.onExecutePostLogin = async (event, api) => {
190190 ) ;
191191 } ;
192192
193- // Process the access cache decision
194- const access_decision = ( access_rules , access_file_conf ) => {
195- const groups = groupsGather ( ) ;
196-
197- //// === Actions don't allow modifying the event.user
198- //// Update user.groups with new merged values
199- //user.groups = groups;
193+ const deny = ( reason ) => {
194+ return {
195+ granted : false ,
196+ denied : {
197+ reason,
198+ } ,
199+ } ;
200+ } ;
200201
202+ // Process the access cache decision
203+ const access_decision = ( groups , access_rules , access_file_conf ) => {
201204 // This is used for authorized user/groups
202205 let authorized = false ;
203206
@@ -214,7 +217,7 @@ exports.onExecutePostLogin = async (event, api) => {
214217 // https://github.com/mozilla-iam/sso-dashboard-configuration/blob/master/apps.yml
215218 if ( apps . length == 0 ) {
216219 console . log ( `No access rules defined for ${ event . client . client_id } ` ) ;
217- return "notingroup" ;
220+ return deny ( "notingroup" ) ;
218221 }
219222
220223 // Check users and groups.
@@ -254,7 +257,7 @@ exports.onExecutePostLogin = async (event, api) => {
254257 `Access denied to ${ event . client . client_id } for user ${ event . user . email } (${ event . user . user_id } )` +
255258 ` - this app denies ALL users and ALL groups")` ;
256259 console . log ( msg ) ;
257- return "notingroup" ;
260+ return deny ( "notingroup" ) ;
258261 }
259262
260263 // Check if the user is authorized to access
@@ -279,7 +282,7 @@ exports.onExecutePostLogin = async (event, api) => {
279282 `Access denied to ${ event . client . client_id } for user ${ event . user . email } (${ event . user . user_id } )` +
280283 ` - not in authorized group or not an authorized user` ;
281284 console . log ( msg ) ;
282- return "notingroup" ;
285+ return deny ( "notingroup" ) ;
283286 }
284287 } // correct client id / we matched the current RP
285288 } // for loop / next rule in apps.yml
@@ -293,6 +296,7 @@ exports.onExecutePostLogin = async (event, api) => {
293296 // Ensure all users have some AAI and AAL attributes, even if its empty
294297 let aai = [ ] ;
295298 let aal = "UNKNOWN" ;
299+ let enableDuo = false ;
296300
297301 // Allow certain LDAP service accounts to fake their MFA. For all other LDAPi accounts, enforce MFA
298302 if ( event . connection . strategy === "ad" ) {
@@ -302,10 +306,7 @@ exports.onExecutePostLogin = async (event, api) => {
302306 ) ;
303307 aai . push ( "2FA" ) ;
304308 } else {
305- api . multifactor . enable ( "duo" , {
306- providerOptions : duoConfig ,
307- allowRememberBrowser : true ,
308- } ) ;
309+ enableDuo = true ;
309310 console . log (
310311 `duosecurity: ${ event . user . email } is in LDAP and requires 2FA check`
311312 ) ;
@@ -416,21 +417,21 @@ exports.onExecutePostLogin = async (event, api) => {
416417 }
417418 }
418419
419- // Set AAI & AAL claims in idToken
420- api . idToken . setCustomClaim ( `${ namespace } /AAI` , aai ) ;
421- api . idToken . setCustomClaim ( `${ namespace } /AAL` , aal ) ;
422- groupsSetCustomClaims ( groups ) ;
423-
424420 if ( ! aai_pass ) {
425421 const msg =
426422 `Access denied to ${ event . client . client_id } for user ${ event . user . email } (${ event . user . user_id } ) - due to` +
427423 ` Identity Assurance Level being too low for this RP. Required AAL: ${ required_aal } (${ aai_pass } )` ;
428424 console . log ( msg ) ;
429- return "aai_failed" ;
425+ return deny ( "aai_failed" ) ;
430426 }
431427
432428 // We matched no rule, access is granted
433- return true ;
429+ return {
430+ granted : true ,
431+ enableDuo,
432+ aai,
433+ aal,
434+ } ;
434435 } ;
435436
436437 const access_file_conf = {
@@ -459,15 +460,25 @@ exports.onExecutePostLogin = async (event, api) => {
459460 try {
460461 const cdnUrl = "https://cdn.sso.mozilla.com/apps.yml" ;
461462 const appsYaml = await getAppsYaml ( cdnUrl ) ;
462- const decision = access_decision ( appsYaml , access_file_conf ) ;
463+ const groups = groupsGather ( ) ;
464+ const decision = access_decision ( groups , appsYaml , access_file_conf ) ;
463465
464- if ( decision === true ) {
465- return ; // Allow login to continue
466- } else {
467- // Go back to the shadow. You shall not pass!
468- postError ( decision ) ;
466+ if ( decision . granted ) {
467+ if ( decision . enableDuo ) {
468+ api . multifactor . enable ( "duo" , {
469+ providerOptions : duoConfig ,
470+ allowRememberBrowser : true ,
471+ } ) ;
472+ }
473+ // Set groups, AAI, and AAL claims in idToken
474+ api . idToken . setCustomClaim ( `${ namespace } /AAI` , decision . aai ) ;
475+ api . idToken . setCustomClaim ( `${ namespace } /AAL` , decision . aal ) ;
476+ groupsSetCustomClaims ( groups ) ;
469477 return ;
470478 }
479+
480+ // Go back to the shadow. You shall not pass!
481+ return postError ( decision . denied . reason ) ;
471482 } catch ( err ) {
472483 // All error should be caught here and we return the callback handler with the error
473484 console . log ( "AccessRules:" , err ) ;
0 commit comments