Skip to content
Merged
5 changes: 4 additions & 1 deletion obp-api/src/main/resources/props/sample.props.template
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,10 @@ connector=star
#hikari.connectionTimeout=
#hikari.maximumPoolSize=
#hikari.idleTimeout=
#hikari.keepaliveTime=
# keepaliveTime must be set below the database/firewall idle TCP timeout to prevent stale-connection
# failures on the first call after a period of inactivity. HikariCP will ping each idle connection
# at this interval (in ms), keeping it alive. Recommended: 30000 (30s) when DB/firewall timeout is ~60s.
#hikari.keepaliveTime=30000
#hikari.maxLifetime=

## if connector = star, then need to set which connectors will be used. For now, obp support rest, akka.
Expand Down
6 changes: 2 additions & 4 deletions obp-api/src/main/scala/bootstrap/liftweb/CustomDBVendor.scala
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class CustomDBVendor(driverName: String,
val connectionTimeout = APIUtil.getPropsAsLongValue("hikari.connectionTimeout")
val maximumPoolSize = APIUtil.getPropsAsIntValue("hikari.maximumPoolSize")
val idleTimeout = APIUtil.getPropsAsLongValue("hikari.idleTimeout")
val keepaliveTime = APIUtil.getPropsAsLongValue("hikari.keepaliveTime")
val keepaliveTime = APIUtil.getPropsAsLongValue("hikari.keepaliveTime", 30000L)
val maxLifetime = APIUtil.getPropsAsLongValue("hikari.maxLifetime")

if(connectionTimeout.isDefined){
Expand All @@ -42,9 +42,7 @@ class CustomDBVendor(driverName: String,
if(idleTimeout.isDefined){
config.setIdleTimeout(idleTimeout.head)
}
if(keepaliveTime.isDefined){
config.setKeepaliveTime(keepaliveTime.head)
}
config.setKeepaliveTime(keepaliveTime)
if(maxLifetime.isDefined){
config.setMaxLifetime(maxLifetime.head)
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2635,6 +2635,8 @@ object SwaggerDefinitionsJSON {
provider_id = providerIdValueExample.value,
provider = providerValueExample.value,
username = usernameExample.value,
first_name = ExampleValue.firstNameExample.value,
last_name = ExampleValue.lastNameExample.value,
entitlements = entitlementJSONs,
views = Some(viewsJSON300),
agreements = Some(List(userAgreementJson)),
Expand All @@ -2649,6 +2651,22 @@ object SwaggerDefinitionsJSON {
users = List(userInfoJsonV600)
)

lazy val userWithNamesJsonV510 = UserWithNamesJsonV510(
user_id = ExampleValue.userIdExample.value,
email = ExampleValue.emailExample.value,
provider_id = providerIdValueExample.value,
provider = providerValueExample.value,
username = usernameExample.value,
first_name = ExampleValue.firstNameExample.value,
last_name = ExampleValue.lastNameExample.value,
entitlements = entitlementJSONs,
views = Some(viewsJSON300),
agreements = Some(List(userAgreementJson)),
is_deleted = false,
last_marketing_agreement_signed_date = Some(DateWithDayExampleObject),
is_locked = false
)

lazy val migrationScriptLogJsonV600 = MigrationScriptLogJsonV600(
migration_script_log_id = "550e8400-e29b-41d4-a716-446655440000",
name = "addUniqueIndexOnResourceUserUserId",
Expand Down
10 changes: 8 additions & 2 deletions obp-api/src/main/scala/code/api/v5_1_0/APIMethods510.scala
Original file line number Diff line number Diff line change
Expand Up @@ -2670,7 +2670,7 @@ trait APIMethods510 {
|
""".stripMargin,
EmptyBody,
userJsonV400,
userWithNamesJsonV510,
List($AuthenticatedUserIsRequired, UserHasMissingRoles, UserNotFoundByProviderAndUsername, UnknownError),
List(apiTagUser),
Some(List(canGetAnyUser))
Expand All @@ -2685,8 +2685,14 @@ trait APIMethods510 {
}
entitlements <- NewStyle.function.getEntitlementsByUserId(user.userId, cc.callContext)
isLocked = LoginAttempt.userIsLocked(user.provider, user.name)
authUser = AuthUser.find(By(AuthUser.user, user.userPrimaryKey.value))
} yield {
(JSONFactory400.createUserInfoJSON(user, entitlements, None, isLocked), HttpCode.`200`(cc.callContext))
(JSONFactory510.createUserWithNamesJSON(
user,
authUser.map(_.firstName.get).getOrElse(""),
authUser.map(_.lastName.get).getOrElse(""),
entitlements, None, isLocked
), HttpCode.`200`(cc.callContext))
}
}
}
Expand Down
51 changes: 50 additions & 1 deletion obp-api/src/main/scala/code/api/v5_1_0/JSONFactory5.1.0.scala
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,14 @@
import code.api.v3_0_0.JSONFactory300.{createLocationJson, createMetaJson, transformToAddressFromV300}
import code.api.v3_0_0.{AddressJsonV300, OpeningTimesV300}
import code.api.v3_1_0.{CallLimitJson, RateLimit, RedisCallLimitJson}
import code.api.v4_0_0.{EnergySource400, HostedAt400, HostedBy400}
import code.api.v2_0_0.{EntitlementJSONs, JSONFactory200}
import code.api.v3_0_0.ViewsJSON300
import code.api.v4_0_0.{EnergySource400, HostedAt400, HostedBy400, UserAgreementJson}
import code.api.v5_0_0.PostConsentRequestJsonV500
import code.entitlement.Entitlement
import code.model.dataAccess.AuthUser
import code.users.UserAgreement
import net.liftweb.mapper.By
import code.atmattribute.AtmAttribute
import code.atms.Atms.Atm
import code.consent.MappedConsent
Expand Down Expand Up @@ -662,6 +668,22 @@

case class UserValidatedJson(is_validated: Boolean)

case class UserWithNamesJsonV510(
user_id: String,

Check warning on line 672 in obp-api/src/main/scala/code/api/v5_1_0/JSONFactory5.1.0.scala

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this parameter to match the regular expression "^[_a-zA-Z][a-zA-Z0-9]*$".

See more on https://sonarcloud.io/project/issues?id=OpenBankProject_OBP-API&issues=AZy-tgESV-YWNeDpdIiA&open=AZy-tgESV-YWNeDpdIiA&pullRequest=2721
email: String,
provider_id: String,

Check warning on line 674 in obp-api/src/main/scala/code/api/v5_1_0/JSONFactory5.1.0.scala

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this parameter to match the regular expression "^[_a-zA-Z][a-zA-Z0-9]*$".

See more on https://sonarcloud.io/project/issues?id=OpenBankProject_OBP-API&issues=AZy-tgESV-YWNeDpdIiB&open=AZy-tgESV-YWNeDpdIiB&pullRequest=2721
provider: String,
username: String,
first_name: String,

Check warning on line 677 in obp-api/src/main/scala/code/api/v5_1_0/JSONFactory5.1.0.scala

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this parameter to match the regular expression "^[_a-zA-Z][a-zA-Z0-9]*$".

See more on https://sonarcloud.io/project/issues?id=OpenBankProject_OBP-API&issues=AZy-tgESV-YWNeDpdIiC&open=AZy-tgESV-YWNeDpdIiC&pullRequest=2721
last_name: String,

Check warning on line 678 in obp-api/src/main/scala/code/api/v5_1_0/JSONFactory5.1.0.scala

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this parameter to match the regular expression "^[_a-zA-Z][a-zA-Z0-9]*$".

See more on https://sonarcloud.io/project/issues?id=OpenBankProject_OBP-API&issues=AZy-tgESV-YWNeDpdIiD&open=AZy-tgESV-YWNeDpdIiD&pullRequest=2721
entitlements: EntitlementJSONs,
views: Option[ViewsJSON300],
agreements: Option[List[UserAgreementJson]],
is_deleted: Boolean,

Check warning on line 682 in obp-api/src/main/scala/code/api/v5_1_0/JSONFactory5.1.0.scala

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this parameter to match the regular expression "^[_a-zA-Z][a-zA-Z0-9]*$".

See more on https://sonarcloud.io/project/issues?id=OpenBankProject_OBP-API&issues=AZy-tgESV-YWNeDpdIiE&open=AZy-tgESV-YWNeDpdIiE&pullRequest=2721
last_marketing_agreement_signed_date: Option[Date],

Check warning on line 683 in obp-api/src/main/scala/code/api/v5_1_0/JSONFactory5.1.0.scala

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this parameter to match the regular expression "^[_a-zA-Z][a-zA-Z0-9]*$".

See more on https://sonarcloud.io/project/issues?id=OpenBankProject_OBP-API&issues=AZy-tgESV-YWNeDpdIiF&open=AZy-tgESV-YWNeDpdIiF&pullRequest=2721
is_locked: Boolean

Check warning on line 684 in obp-api/src/main/scala/code/api/v5_1_0/JSONFactory5.1.0.scala

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this parameter to match the regular expression "^[_a-zA-Z][a-zA-Z0-9]*$".

See more on https://sonarcloud.io/project/issues?id=OpenBankProject_OBP-API&issues=AZy-tgESV-YWNeDpdIiG&open=AZy-tgESV-YWNeDpdIiG&pullRequest=2721
)


case class BankAccountBalanceRequestJsonV510(
balance_type: String,
Expand Down Expand Up @@ -1346,4 +1368,31 @@

}

def createUserWithNamesJSON(
user: User,
firstName: String,
lastName: String,
entitlements: List[Entitlement],
agreements: Option[List[UserAgreement]],
isLocked: Boolean
): UserWithNamesJsonV510 = {
UserWithNamesJsonV510(
user_id = user.userId,
email = user.emailAddress,
provider_id = user.idGivenByProvider,
provider = stringOrNull(user.provider),
username = stringOrNull(user.name),
first_name = firstName,
last_name = lastName,
entitlements = JSONFactory200.createEntitlementJSONs(entitlements),
views = None,
agreements = agreements.map(
_.map(i => UserAgreementJson(`type` = i.agreementType, text = i.agreementText))
),
is_deleted = user.isDeleted.getOrElse(false),
last_marketing_agreement_signed_date = user.lastMarketingAgreementSignedDate,
is_locked = isLocked
)
}

}
14 changes: 13 additions & 1 deletion obp-api/src/main/scala/code/api/v6_0_0/APIMethods600.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1852,6 +1852,9 @@ trait APIMethods600 {
if (agreementList.isEmpty) None else Some(agreementList)
}
isLocked = LoginAttempt.userIsLocked(user.provider, user.name)
authUser = code.model.dataAccess.AuthUser.find(
By(code.model.dataAccess.AuthUser.user, user.userPrimaryKey.value)
)
// Fetch metrics data for the user
userMetrics <- Future {
code.metrics.MappedMetric.findAll(
Expand All @@ -1863,7 +1866,16 @@ trait APIMethods600 {
lastActivityDate = userMetrics.headOption.map(_.getDate())
recentOperationIds = userMetrics.map(_.getImplementedByPartialFunction()).distinct.take(5)
} yield {
(JSONFactory600.createUserInfoJsonV600(user, entitlements, agreements, isLocked, lastActivityDate, recentOperationIds), HttpCode.`200`(callContext))
(JSONFactory600.createUserInfoJsonV600(
user,
authUser.map(_.firstName.get).getOrElse(""),
authUser.map(_.lastName.get).getOrElse(""),
entitlements,
agreements,
isLocked,
lastActivityDate,
recentOperationIds
), HttpCode.`200`(callContext))
}
}
}
Expand Down
16 changes: 13 additions & 3 deletions obp-api/src/main/scala/code/api/v6_0_0/JSONFactory6.0.0.scala
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,9 @@
import code.featuredapicollection.FeaturedApiCollectionTrait
import code.loginattempts.LoginAttempt
import code.model.ModeratedBankAccountCore
import code.model.dataAccess.ResourceUser
import code.model.dataAccess.{AuthUser, ResourceUser}
import code.users.UserAgreement
import net.liftweb.mapper.By
import code.util.Helper.MdcLoggable
import com.openbankproject.commons.model.{
AmountOfMoneyJsonV121,
Expand Down Expand Up @@ -249,6 +250,8 @@
provider_id: String,
provider: String,
username: String,
first_name: String,
last_name: String,

Check warning on line 254 in obp-api/src/main/scala/code/api/v6_0_0/JSONFactory6.0.0.scala

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this parameter to match the regular expression "^[_a-zA-Z][a-zA-Z0-9]*$".

See more on https://sonarcloud.io/project/issues?id=OpenBankProject_OBP-API&issues=AZy9zmVbBFq0tZyrJ1wL&open=AZy9zmVbBFq0tZyrJ1wL&pullRequest=2721
entitlements: EntitlementJSONs,
views: Option[ViewsJSON300],
agreements: Option[List[UserAgreementJson]],
Expand All @@ -265,7 +268,7 @@
email: String,
username: String,
password: String,
first_name: String,

Check warning on line 271 in obp-api/src/main/scala/code/api/v6_0_0/JSONFactory6.0.0.scala

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this parameter to match the regular expression "^[_a-zA-Z][a-zA-Z0-9]*$".

See more on https://sonarcloud.io/project/issues?id=OpenBankProject_OBP-API&issues=AZy9zmVbBFq0tZyrJ1wO&open=AZy9zmVbBFq0tZyrJ1wO&pullRequest=2721
last_name: String
)

Expand Down Expand Up @@ -1075,8 +1078,10 @@
)
}

def createUserInfoJsonV600(

Check warning on line 1081 in obp-api/src/main/scala/code/api/v6_0_0/JSONFactory6.0.0.scala

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

This function has 8 parameters, which is greater than the 7 authorized.

See more on https://sonarcloud.io/project/issues?id=OpenBankProject_OBP-API&issues=AZy9aCHZfzY_LxO8hr4A&open=AZy9aCHZfzY_LxO8hr4A&pullRequest=2721
user: User,
firstName: String,
lastName: String,
entitlements: List[Entitlement],
agreements: Option[List[UserAgreement]],
isLocked: Boolean,
Expand All @@ -1089,6 +1094,8 @@
username = stringOrNull(user.name),
provider_id = user.idGivenByProvider,
provider = stringOrNull(user.provider),
first_name = firstName,
last_name = lastName,
entitlements = JSONFactory200.createEntitlementJSONs(entitlements),
views = None,
agreements = agreements.map(
Expand All @@ -1111,16 +1118,19 @@
]
): UsersInfoJsonV600 = {
UsersInfoJsonV600(
users.map(t =>
users.map { t =>
val authUser = AuthUser.find(By(AuthUser.user, t._1.id.get))
createUserInfoJsonV600(
t._1,
authUser.map(_.firstName.get).getOrElse(""),
authUser.map(_.lastName.get).getOrElse(""),
t._2.getOrElse(Nil),
t._3,
LoginAttempt.userIsLocked(t._1.provider, t._1.name),
None,
List.empty
)
)
}
)
}

Expand Down
34 changes: 29 additions & 5 deletions obp-api/src/test/scala/code/api/v5_1_0/UserTest.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,16 @@ import code.api.util.APIUtil.OAuth._
import code.api.util.ApiRole.{CanGetAnyUser, CanGetEntitlementsForAnyUserAtAnyBank, CanValidateUser}
import code.api.util.ErrorMessages.{UserHasMissingRoles, AuthenticatedUserIsRequired, attemptedToOpenAnEmptyBox}
import code.api.v3_0_0.UserJsonV300
import code.api.v4_0_0.UserJsonV400
import code.api.v5_1_0.OBPAPI5_1_0.Implementations5_1_0
import code.entitlement.Entitlement
import code.model.UserX
import code.model.dataAccess.AuthUser
import code.users.Users
import com.github.dwickern.macros.NameOf.nameOf
import com.openbankproject.commons.model.ErrorMessage
import com.openbankproject.commons.util.ApiVersion
import net.liftweb.json.Serialization.write
import net.liftweb.util.Helpers.randomString
import org.scalatest.Tag

import java.util.UUID
Expand Down Expand Up @@ -59,14 +60,37 @@ class UserTest extends V510ServerSetup {
When("We make a request v5.1.0")
val request400 = (v5_1_0_Request / "users" / "provider"/user.provider / "username" / user.name ).GET <@(user1)
val response400 = makeGetRequest(request400)
Then("We get successful response")
Then("We get successful response with first_name and last_name fields")
response400.code should equal(200)
response400.body.extract[UserJsonV400]
val json = response400.body.extract[UserWithNamesJsonV510]
json.first_name should equal("")
json.last_name should equal("")
Users.users.vend.deleteResourceUser(user.id.get)
}
}


feature(s"test $ApiEndpoint1 version $VersionOfApi - first_name and last_name populated from AuthUser") {
scenario("We will call the endpoint with an AuthUser that has first and last name set", ApiEndpoint1, VersionOfApi) {
Entitlement.entitlement.vend.addEntitlement("", resourceUser1.userId, CanGetAnyUser.toString)
val username = "user.withnames." + UUID.randomUUID.toString.take(8)
val email = s"$username@example.com"
val user = UserX.createResourceUser(defaultProvider, Some(username), None, Some(username), None, Some(UUID.randomUUID.toString), None).openOrThrowException(attemptedToOpenAnEmptyBox)
val authUser = AuthUser.create
.email(email).username(username).password(randomString(12))
.validated(true).firstName("Alice").lastName("Smith")
.provider(defaultProvider).user(user.userPrimaryKey.value).saveMe()
When("We make a request v5.1.0")
val request = (v5_1_0_Request / "users" / "provider" / user.provider / "username" / user.name).GET <@(user1)
val response = makeGetRequest(request)
Then("We get first_name and last_name from AuthUser")
response.code should equal(200)
val json = response.body.extract[UserWithNamesJsonV510]
json.first_name should equal("Alice")
json.last_name should equal("Smith")
authUser.delete_!
Users.users.vend.deleteResourceUser(user.id.get)
}
}

feature(s"test $ApiEndpoint1 version $VersionOfApi - Authorized access with URL-encoded provider") {
scenario("We will call the endpoint with a provider containing special URL characters (colon, slash)", ApiEndpoint1, VersionOfApi) {
Expand All @@ -81,7 +105,7 @@ class UserTest extends V510ServerSetup {
val response = makeGetRequest(request)
Then("We get successful response - endpoint correctly URL-decodes the provider")
response.code should equal(200)
response.body.extract[UserJsonV400]
response.body.extract[UserWithNamesJsonV510]
Users.users.vend.deleteResourceUser(user.id.get)
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,9 @@ class GetUserByUserIdTest extends V600ServerSetup with DefaultUsers {

And("The response should contain user details")
(response.body \ "user_id").extract[String] should equal(resourceUser1.userId)
And("The response should include first_name and last_name fields")
response.body \ "first_name" should not equal net.liftweb.json.JNothing
response.body \ "last_name" should not equal net.liftweb.json.JNothing
}

}
Expand Down