@@ -366,7 +366,13 @@ object ExchangeApiApp extends App
366366
367367 val reg : Regex = """ ^(\S*?)/(\S*)$""" .r
368368
369-
369+ def getIdentityCacheValueFromDB (organization : String , username : String ): Future [(Identity2 , String )] = {
370+ getResourceIdentityAndPassword(organization, username).map {
371+ // Yield this Resource's identity metadata and construct a future identity object. Resource's stored credential tags along.
372+ // This object will be returned and used if authenticated.
373+ identityMetadata : ((Boolean , Option [UUID ], Boolean , Option [UUID ], Int ), String ) => (new Identity2 (organization, identityMetadata._1, username), identityMetadata._2)
374+ }
375+ }
370376
371377 def myUserPassAuthenticator (credentials : Credentials ): Future [Option [Identity2 ]] = {
372378 credentials match {
@@ -418,16 +424,13 @@ object ExchangeApiApp extends App
418424 }
419425 } yield result
420426 verifiedIdentityFut
421- } else {
427+ }
428+ else {
422429 def identityCacheGet (resource : String ): Future [(Identity2 , String )] = {
423430 cacheResourceIdentity.cachingF(resource)(ttl = Option (Configuration .getConfig.getInt(" api.cache.idsTtlSeconds" ).seconds)) {
424431 // On cache miss execute this block to try and find what the value should be.
425432 // If found add to the cache for next time.
426- getResourceIdentityAndPassword(organization, username).map {
427- // Yield this Resource's identity metadata and construct a future identity object. Resource's stored credential tags along.
428- // This object will be returned and used if authenticated.
429- identityMetadata : ((Boolean , Option [UUID ], Boolean , Option [UUID ], Int ), String ) => (new Identity2 (organization, identityMetadata._1, username), identityMetadata._2)
430- }
433+ getIdentityCacheValueFromDB(organization : String , username : String )
431434 }
432435 }
433436
@@ -469,8 +472,8 @@ object ExchangeApiApp extends App
469472 Password .check(requestPassword, rehashedCredential)
470473 }
471474 else
472- /* logger.debug("Line 333: credential: " + requestPassword + " secret: " + storedSecret);*/
473- Password .check(requestPassword, storedSecret)
475+ /* logger.debug("Line 333: credential: " + requestPassword + " secret: " + storedSecret);*/
476+ Password .check(requestPassword, storedSecret)
474477 })) {
475478 // Root level permissions are used in test environments, any other user should not have root level access in a production environment.
476479 if (resourceIdentityAndCred._1.role == AuthRoles .SuperUser &&
@@ -490,7 +493,22 @@ object ExchangeApiApp extends App
490493 fetchedIdentity <- identityCacheGet(resource)
491494 // _ = logger.debug(s"Async returns: ${a._1.toString}, ${a._1.identifier.getOrElse("None")}")
492495 authenticatedIdentity <- AuthenticationCheck (Option (fetchedIdentity)) fallbackTo(Future {None })
493- } yield authenticatedIdentity
496+ authenticatedIdentityRetry <-
497+ // On failure of the first attempt clear the cache value for this caller's key and run the two functions again. This will force a database pull.
498+ if (authenticatedIdentity.isEmpty) {
499+ cacheResourceIdentity.remove(resource)
500+ identityCacheGet(resource).flatMap( fetchedIdentity => AuthenticationCheck (Option (fetchedIdentity)) fallbackTo(Future {None }))
501+ }
502+ else
503+ Future { None }
504+ authenticatedIdentityWithCacheInvalidation <-
505+ Future {
506+ if (authenticatedIdentity.isDefined)
507+ authenticatedIdentity
508+ else
509+ authenticatedIdentityRetry
510+ }
511+ } yield authenticatedIdentityWithCacheInvalidation
494512 }
495513 }.flatMap(x => x) // Flattens the nested futures.
496514 case _ =>
0 commit comments