Skip to content

Commit 6d88c89

Browse files
authored
Merge pull request OpenBankProject#2719 from simonredfern/develop
Putting back auth requirement for verify user credentials. More Log but throw in Direct Login. More logging in create consent
2 parents bd5117f + a310df7 commit 6d88c89

5 files changed

Lines changed: 35 additions & 19 deletions

File tree

obp-api/src/main/resources/props/sample.props.template

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1632,7 +1632,7 @@ regulated_entities = []
16321632
# "grantee_consumer_id": "fb327484-94d7-44d2-83e5-8d27301e8279" \
16331633
#}]
16341634

1635-
# Bootstrap Super User
1635+
# Bootstrap Super User / Break Glass
16361636
# Given the following credentials, OBP will create a user if they do not already exist.
16371637
# This user's password will be valid for a limited time.
16381638
# This user will be granted ONLY the CanCreateEntitlementAtAnyBank permission.

obp-api/src/main/scala/code/api/directlogin.scala

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -352,10 +352,10 @@ object DirectLogin extends RestHelper with MdcLoggable {
352352
case false => false
353353
}*/
354354
case _ => false
355-
} recover {
355+
} recoverWith {
356356
case e: Throwable =>
357357
logger.error(s"validatorFuture.validAccessTokenFuture failed: ${e.getMessage}", e)
358-
false
358+
Future.failed(e)
359359
}
360360
}
361361

@@ -431,10 +431,10 @@ object DirectLogin extends RestHelper with MdcLoggable {
431431
Tokens.tokens.vend.getTokenByKeyAndTypeFuture(tokenKey, TokenType.Access) map {
432432
case Full(token) => token.isValid
433433
case _ => false
434-
} recover {
434+
} recoverWith {
435435
case e: Throwable =>
436436
logger.error(s"validatorFutureWithParams.validAccessTokenFuture failed: ${e.getMessage}", e)
437-
false
437+
Future.failed(e)
438438
}
439439
}
440440

@@ -638,10 +638,10 @@ object DirectLogin extends RestHelper with MdcLoggable {
638638
Tokens.tokens.vend.getTokenByKeyFuture(token) map {
639639
case Full(t) => t.consumerId.foreign
640640
case _ => Empty
641-
} recover {
641+
} recoverWith {
642642
case e: Throwable =>
643643
logger.error(s"getConsumerFromDirectLoginToken failed: ${e.getMessage}", e)
644-
Empty
644+
Future.failed(e)
645645
}
646646
}
647647

@@ -661,10 +661,10 @@ object DirectLogin extends RestHelper with MdcLoggable {
661661
}
662662
} yield {
663663
user
664-
}) recover {
664+
}) recoverWith {
665665
case e: Throwable =>
666666
logger.error(s"getUserFromDirectLoginToken failed: ${e.getMessage}", e)
667-
Empty
667+
Future.failed(e)
668668
}
669669
}
670670
}

obp-api/src/main/scala/code/api/util/APIUtil.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3998,7 +3998,8 @@ object APIUtil extends MdcLoggable with CustomJsonFormats{
39983998
"public_keycloak_url" -> getPropsValue("public_keycloak_url").openOr("http://localhost:7787"),
39993999
"public_obp_hola_url" -> getPropsValue("public_obp_hola_url").openOr("http://localhost:8087"),
40004000
"public_obp_mcp_url" -> getPropsValue("public_obp_mcp_url").openOr("http://localhost:9100"),
4001-
"public_obp_opey_url" -> getPropsValue("public_obp_opey_url").openOr("http://localhost:5000")
4001+
"public_obp_opey_url" -> getPropsValue("public_obp_opey_url").openOr("http://localhost:5000"),
4002+
"public_rabbit_cats_adapter_url" -> getPropsValue("public_rabbit_cats_adapter_url").openOr("http://localhost:8089")
40024003
)
40034004
val publicAppUrlPropNames: List[String] = publicAppUrlDefaults.keys.toList.sorted
40044005
// Register defaults so they appear in getConfigPropsPairs

obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2374,6 +2374,19 @@ trait APIMethods510 {
23742374
}
23752375
requestedEntitlements = consentJson.entitlements
23762376
myEntitlements <- Entitlement.entitlement.vend.getEntitlementsByUserIdFuture(user.userId)
2377+
_ = logger.info(s"createConsent says: userId=${user.userId}, userName=${user.name}, requestedEntitlements=${requestedEntitlements.map(re => s"(role_name=${re.role_name}, bank_id=${re.bank_id})")}, myEntitlements=${myEntitlements.getOrElse(Nil).map(e => s"(roleName=${e.roleName}, bankId=${e.bankId})")}")
2378+
_ = {
2379+
val myEnts = myEntitlements.getOrElse(Nil)
2380+
requestedEntitlements.foreach { re =>
2381+
val matched = myEnts.exists(e => e.roleName == re.role_name && e.bankId == re.bank_id)
2382+
logger.info(s"createConsent says: checking requested role_name=${re.role_name}, bank_id='${re.bank_id}' => matched=$matched")
2383+
if (!matched) {
2384+
myEnts.foreach { e =>
2385+
logger.info(s"createConsent says: comparing with roleName=${e.roleName}, bankId='${e.bankId}' => nameMatch=${e.roleName == re.role_name}, bankIdMatch=${e.bankId == re.bank_id}")
2386+
}
2387+
}
2388+
}
2389+
}
23772390
_ <- Helper.booleanToFuture(RolesAllowedInConsent, cc = callContext) {
23782391
requestedEntitlements.forall(
23792392
re => myEntitlements.getOrElse(Nil).exists(

obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala

Lines changed: 11 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2253,19 +2253,17 @@ trait APIMethods600 {
22532253
JSONFactory600.createProvidersJson(List("http://127.0.0.1:8080", "OBP", "google.com")),
22542254
List(
22552255
$AuthenticatedUserIsRequired,
2256-
UserHasMissingRoles,
22572256
UnknownError
22582257
),
22592258
List(apiTagUser),
2260-
Some(List(canGetProviders))
2259+
None
22612260
)
22622261

22632262
lazy val getProviders: OBPEndpoint = {
22642263
case "providers" :: Nil JsonGet _ =>
22652264
cc => implicit val ec = EndpointContext(Some(cc))
22662265
for {
22672266
(Full(u), callContext) <- authenticatedAccess(cc)
2268-
_ <- NewStyle.function.hasEntitlement("", u.userId, canGetProviders, callContext)
22692267
providers <- Future { code.model.dataAccess.ResourceUser.getDistinctProviders }
22702268
} yield {
22712269
(JSONFactory600.createProvidersJson(providers), HttpCode.`200`(callContext))
@@ -8751,8 +8749,12 @@ trait APIMethods600 {
87518749
lazy val verifyUserCredentials: OBPEndpoint = {
87528750
case "users" :: "verify-credentials" :: Nil JsonPost json -> _ => {
87538751
cc => implicit val ec = EndpointContext(Some(cc))
8752+
// TODO: Consider allowing Client Credentials (app-level) auth instead of user-level auth,
8753+
// so the caller doesn't need to be logged in as a user (which is circular for credential verification).
8754+
// TODO: Add rate limiting / anti-DOS protection for this endpoint to prevent credential enumeration/spamming.
87548755
for {
8755-
postedData <- NewStyle.function.tryons(s"$InvalidJsonFormat The Json body should be the PostVerifyUserCredentialsJsonV600", 400, Some(cc)) {
8756+
(Full(u), callContext) <- authenticatedAccess(cc)
8757+
postedData <- NewStyle.function.tryons(s"$InvalidJsonFormat The Json body should be the PostVerifyUserCredentialsJsonV600", 400, callContext) {
87568758
json.extract[PostVerifyUserCredentialsJsonV600]
87578759
}
87588760
// Validate credentials using the existing AuthUser mechanism
@@ -8787,27 +8789,27 @@ trait APIMethods600 {
87878789
}
87888790
}
87898791
// Check if account is locked
8790-
_ <- Helper.booleanToFuture(UsernameHasBeenLocked, 401, Some(cc)) {
8792+
_ <- Helper.booleanToFuture(UsernameHasBeenLocked, 401, callContext) {
87918793
resourceUserIdBox != Full(code.model.dataAccess.AuthUser.usernameLockedStateCode)
87928794
}
87938795
// Check if credentials are valid
87948796
resourceUserId <- Future {
87958797
resourceUserIdBox
87968798
} map {
8797-
x => unboxFullOrFail(x, Some(cc), s"$InvalidLoginCredentials Failed to authenticate user credentials.", 401)
8799+
x => unboxFullOrFail(x, callContext, s"$InvalidLoginCredentials Failed to authenticate user credentials.", 401)
87988800
}
87998801
// Get the user object
88008802
user <- Future {
88018803
Users.users.vend.getUserByResourceUserId(resourceUserId)
88028804
} map {
8803-
x => unboxFullOrFail(x, Some(cc), s"$InvalidLoginCredentials User account not found in system.", 401)
8805+
x => unboxFullOrFail(x, callContext, s"$InvalidLoginCredentials User account not found in system.", 401)
88048806
}
88058807
// Verify provider matches if specified and not empty
8806-
_ <- Helper.booleanToFuture(s"$InvalidLoginCredentials Authentication provider mismatch.", 401, Some(cc)) {
8808+
_ <- Helper.booleanToFuture(s"$InvalidLoginCredentials Authentication provider mismatch.", 401, callContext) {
88078809
postedData.provider.isEmpty || user.provider == postedData.provider
88088810
}
88098811
} yield {
8810-
(JSONFactory200.createUserJSON(user), HttpCode.`200`(Some(cc)))
8812+
(JSONFactory200.createUserJSON(user), HttpCode.`200`(callContext))
88118813
}
88128814
}
88138815
}

0 commit comments

Comments
 (0)