Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
6b91237
test/update 4 files
hongwei1 Mar 5, 2026
7f6929b
refactor/modify AuthUser
hongwei1 Mar 5, 2026
3e93298
feature/add code to AuthUser
hongwei1 Mar 5, 2026
e62dce4
test/update tests in AuthenticationPropertyTest
hongwei1 Mar 5, 2026
d3d44bb
test/update tests in AuthenticationPropertyTest
hongwei1 Mar 5, 2026
bc80a97
test/update tests in AuthenticationPropertyTest
hongwei1 Mar 5, 2026
eaf705d
test/update tests in AuthenticationPropertyTest
hongwei1 Mar 5, 2026
3946760
test/update 2 files
hongwei1 Mar 5, 2026
fdc46ca
test/update 2 files
hongwei1 Mar 5, 2026
72d3b8f
test/update 2 files
hongwei1 Mar 5, 2026
bf000b4
test/fix compilation errors in AuthenticationRefactorTest by replacin…
hongwei1 Mar 5, 2026
120a342
test/add comprehensive property-based and unit tests for centralized …
hongwei1 Mar 5, 2026
fdc2430
bugfix/use setPropsValues instead of System.setProperty for connector…
hongwei1 Mar 5, 2026
4d57f40
bugfix/adjust lockout test frequency for 10 iterations in Property 6 …
hongwei1 Mar 5, 2026
946d036
bugfix/add setPropsValues for external provider tests and fix provide…
hongwei1 Mar 5, 2026
522d1c4
test/update 2 files
hongwei1 Mar 5, 2026
1d1a8d7
refactor/added comments and made code robust
hongwei1 Mar 6, 2026
4035043
test/add/update test methods (afterEach) in AuthenticationPropertyTes…
hongwei1 Mar 6, 2026
565af07
refactor/commented the test
hongwei1 Mar 6, 2026
cda45da
refactor/uncommented the test
hongwei1 Mar 6, 2026
40ece43
refactor/removed emojis
hongwei1 Mar 6, 2026
db0d8de
refactor/reduced iterations to 10
hongwei1 Mar 6, 2026
1a17898
docfix/added comments for userId_
hongwei1 Mar 6, 2026
b356de4
test/fixed the failed tests
hongwei1 Mar 6, 2026
718837f
refactor/remove redundant externalUserHelper method and use checkExte…
hongwei1 Mar 6, 2026
129766c
docfix/improve checkExternalUserViaConnector Scaladoc with comprehens…
hongwei1 Mar 6, 2026
660033d
refactor/remove default provider in getResourceUserId
hongwei1 Mar 6, 2026
317149c
enhancement/add debug logging to DirectLogin getUserId to distinguish…
hongwei1 Mar 6, 2026
cbecb00
refactor/remove unused registeredUserHelper method for obsolete rest_…
hongwei1 Mar 6, 2026
f7de1b6
refactor/migrate BankAccountCreationDispatcher from Legacy to async s…
hongwei1 Mar 6, 2026
eb141b4
bugfix/restore UpdatesRequestSender.sendMsg call to original location…
hongwei1 Mar 8, 2026
c335c99
Merge remote-tracking branch 'OBP/develop' into obp-develop
hongwei1 Mar 8, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 20 additions & 3 deletions obp-api/src/main/scala/code/api/directlogin.scala
Original file line number Diff line number Diff line change
Expand Up @@ -575,9 +575,26 @@ object DirectLogin extends RestHelper with MdcLoggable {
val username = directLoginParameters.getOrElse("username", "")
val password = directLoginParameters.getOrElse("password", "")

//we first try to get the userId from local, if not find, we try to get it from external
AuthUser.getResourceUserId(username, password)
.or(AuthUser.externalUserHelper(username, password).map(_.user.get))
logger.debug(s"getUserId: attempting authentication for username: $username")

// Try local provider first
val localResult = AuthUser.getResourceUserId(username, password, Constant.localIdentityProvider)
localResult match {
case Full(userId) =>
logger.debug(s"getUserId: local authentication succeeded for username: $username, userId: $userId")
localResult
case _ =>
logger.debug(s"getUserId: local authentication failed for username: $username, trying external provider")
// Try external provider as fallback
val externalResult = AuthUser.getResourceUserId(username, password, s"External")
externalResult match {
case Full(userId) =>
logger.debug(s"getUserId: external authentication succeeded for username: $username, userId: $userId")
case _ =>
logger.debug(s"getUserId: external authentication also failed for username: $username")
}
externalResult
}
}


Expand Down
2 changes: 1 addition & 1 deletion obp-api/src/main/scala/code/api/util/Glossary.scala
Original file line number Diff line number Diff line change
Expand Up @@ -5237,7 +5237,7 @@ object Glossary extends MdcLoggable {
|
|1. **Check only** — validates credentials and returns user info, but does not create a session or token
|2. **Requires an already-authenticated caller** with `canVerifyUserCredentials` role (or SuperAdmin)
|3. **May auto-provision users** — if the local lookup fails and the external fallback via `externalUserHelper()` / `checkExternalUserViaConnector()` succeeds, a new AuthUser and ResourceUser will be created locally (same behaviour as the web login flow)
|3. **May auto-provision users** — if the local lookup fails and the external fallback via `checkExternalUserViaConnector()` succeeds, a new AuthUser and ResourceUser will be created locally (same behaviour as the web login flow)
|4. **Provider matching** — optionally verifies the user's provider matches what was posted (skipped if provider is empty)
|
|### Key Source Files
Expand Down
36 changes: 7 additions & 29 deletions obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala
Original file line number Diff line number Diff line change
Expand Up @@ -8772,39 +8772,17 @@ trait APIMethods600 {
decodedProvider = URLDecoder.decode(postedData.provider, StandardCharsets.UTF_8)
// Validate credentials using the existing AuthUser mechanism

resourceUserIdBox =
if (decodedProvider == Constant.localIdentityProvider || decodedProvider.isEmpty) {
// Local provider: only check local credentials. No external fallback.
val result = code.model.dataAccess.AuthUser.getResourceUserId(
postedData.username, postedData.password, Constant.localIdentityProvider
)
logger.info(s"verifyUserCredentials says: local getResourceUserId result: $result")
result
} else {
// External provider: validate via connector. Local DB stores a random UUID
// as password for external users, so getResourceUserId would always fail.
if (LoginAttempt.userIsLocked(decodedProvider, postedData.username)) {
logger.info(s"verifyUserCredentials says: external user is locked, provider: ${decodedProvider}, username: ${postedData.username}")
Full(code.model.dataAccess.AuthUser.usernameLockedStateCode)
} else {
val connectorResult = code.model.dataAccess.AuthUser.externalUserHelper(
postedData.username, postedData.password
).map(_.user.get)
logger.info(s"verifyUserCredentials says: externalUserHelper result: $connectorResult")
connectorResult match {
case Full(_) =>
LoginAttempt.resetBadLoginAttempts(decodedProvider, postedData.username)
connectorResult
case _ =>
LoginAttempt.incrementBadLoginAttempts(decodedProvider, postedData.username)
connectorResult
}
}
}
resourceUserIdBox = code.model.dataAccess.AuthUser.getResourceUserId(
postedData.username, postedData.password, decodedProvider
)
// Check if account is locked
_ <- Helper.booleanToFuture(UsernameHasBeenLocked, 401, callContext) {
resourceUserIdBox != Full(code.model.dataAccess.AuthUser.usernameLockedStateCode)
}
// Check if email is validated
_ <- Helper.booleanToFuture(UserEmailNotValidated, 401, callContext) {
resourceUserIdBox != Full(code.model.dataAccess.AuthUser.userEmailNotValidatedStateCode)
}
// Check if credentials are valid
resourceUserId <- Future {
resourceUserIdBox
Expand Down
Loading