Merge pull request #2491 from hongwei1/develop

bugfix/fixed the create sandbox endpoint issue
This commit is contained in:
Simon Redfern 2025-02-17 12:48:03 +01:00 committed by GitHub
commit 470db53549
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 91 additions and 12 deletions

View File

@ -1367,5 +1367,15 @@ regulated_entities = []
# "grantee_consumer_id": "fb327484-94d7-44d2-83e5-8d27301e8279" \
#}]
# Bootstrap Super User
# Given the following credentials, OBP will create a user if they do not already exist.
# This user's password will be valid for a limited time.
# This user will be granted ONLY the CanCreateEntitlementAtAnyBank permission.
# This feature can also be used in a "Break Glass" scenario.
# If you want to use this feature, please set up all three values properly at the same time.
# super_admin_username=TomWilliams
# super_admin_inital_password=681aeeb9f681aeeb9f681aeeb9
# super_admin_email=tom@tesobe.com
# Note: For secure and http only settings for cookies see resources/web.xml which is mentioned in the README.md

View File

@ -43,6 +43,7 @@ import code.api.ResourceDocs1_4_0._
import code.api._
import code.api.attributedefinition.AttributeDefinition
import code.api.cache.Redis
import code.api.util.ApiRole.CanCreateEntitlementAtAnyBank
import code.api.util.APIUtil.{enableVersionIfAllowed, errorJsonResponse, getPropsValue, gitCommit}
import code.api.util._
import code.api.util.migration.Migration
@ -76,7 +77,7 @@ import code.dynamicMessageDoc.DynamicMessageDoc
import code.dynamicResourceDoc.DynamicResourceDoc
import code.endpointMapping.EndpointMapping
import code.endpointTag.EndpointTag
import code.entitlement.MappedEntitlement
import code.entitlement.{Entitlement, MappedEntitlement}
import code.entitlementrequest.MappedEntitlementRequest
import code.fx.{MappedCurrency, MappedFXRate}
import code.kafka.{KafkaHelperActors, OBPKafkaConsumer}
@ -318,6 +319,8 @@ class Boot extends MdcLoggable {
//see the notes for this method:
createDefaultBankAndDefaultAccountsIfNotExisting()
createBootstrapSuperUser()
//launch the scheduler to clean the database from the expired tokens and nonces, 1 hour
DataBaseCleanerScheduler.start(intervalInSeconds = 60*60)
@ -954,6 +957,60 @@ class Boot extends MdcLoggable {
logger.debug(s"creating BankAccount(${defaultBankId}, $outgoingAccountId).")
}
}
/**
* Bootstrap Super User
* Given the following credentials, OBP will create a user *if it does not exist already*.
* This user's password will be valid for a limited amount of time.
* This user will be granted ONLY CanCreateEntitlementAtAnyBank
* This feature can also be used in a "Break Glass scenario"
*/
private def createBootstrapSuperUser() ={
val superAdminUsername = APIUtil.getPropsValue("super_admin_username","")
val superAdminInitalPassword = APIUtil.getPropsValue("super_admin_inital_password","")
val superAdminEmail = APIUtil.getPropsValue("super_admin_email","")
val isPropsNotSetProperly = superAdminUsername==""||superAdminInitalPassword ==""||superAdminEmail==""
//This is the logic to check if an AuthUser exists for the `create sandbox` endpoint, AfterApiAuth, OpenIdConnect ,,,
val existingAuthUser = AuthUser.find(By(AuthUser.username, superAdminUsername))
if(isPropsNotSetProperly) {
//Nothing happens, props is not set
}else if(existingAuthUser.isDefined) {
logger.error(s"createBootstrapSuperUser- Errors: Existing AuthUser with username ${superAdminUsername} detected in data import where no ResourceUser was found")
} else {
val authUser = AuthUser.create
.email(superAdminEmail)
.firstName(superAdminUsername)
.lastName(superAdminUsername)
.username(superAdminUsername)
.password(superAdminInitalPassword)
.passwordShouldBeChanged(true)
.validated(true)
val validationErrors = authUser.validate
if(!validationErrors.isEmpty)
logger.error(s"createBootstrapSuperUser- Errors: ${validationErrors.map(_.msg)}")
else {
Full(authUser.save()) //this will create/update the resourceUser.
val userBox = Users.users.vend.getUserByProviderAndUsername(authUser.getProvider(), authUser.username.get)
val resultBox = userBox.map(user => Entitlement.entitlement.vend.addEntitlement("", user.userId, CanCreateEntitlementAtAnyBank.toString))
if(resultBox.isEmpty){
logger.error(s"createBootstrapSuperUser- Errors: ${resultBox}")
}
}
}
}
}
object ToSchemify {

View File

@ -96,6 +96,8 @@ class AuthUser extends MegaProtoUser[AuthUser] with CreatedUpdated with MdcLogga
def getSingleton = AuthUser // what's the "meta" server
object user extends MappedLongForeignKey(this, ResourceUser)
object passwordShouldBeChanged extends MappedBoolean(this)
override lazy val firstName = new MyFirstName
@ -185,7 +187,7 @@ class AuthUser extends MegaProtoUser[AuthUser] with CreatedUpdated with MdcLogga
case e if usernameRegex.findFirstMatchIn(e).isDefined => Nil
case _ => List(FieldError(this, Text(msg)))
}
override def displayName = S.?("Username")
override def displayName = Helper.i18n("Username")
@deprecated("Use UniqueIndex(username, provider)","27 December 2021")
override def dbIndexed_? = false // We use more general index UniqueIndex(username, provider) :: super.dbIndexes
override def validations = isEmpty(Helper.i18n("Please.enter.your.username")) _ ::
@ -398,7 +400,7 @@ class AuthUser extends MegaProtoUser[AuthUser] with CreatedUpdated with MdcLogga
override def validate = i_is_! match {
case null => List(FieldError(this, Text(Helper.i18n("Please.enter.your.email"))))
case e if e.trim.isEmpty => List(FieldError(this, Text(Helper.i18n("Please.enter.your.email"))))
case e if (!isEmailValid(e)) => List(FieldError(this, Text(S.?("invalid.email.address"))))
case e if (!isEmailValid(e)) => List(FieldError(this, Text(Helper.i18n("invalid.email.address"))))
case _ => Nil
}
override def _toForm: Box[Elem] =

View File

@ -264,7 +264,7 @@ class VrpConsentCreation extends MdcLoggable with RestHelper with APIMethods510
case Full(consumerJsonV310) =>
//4th: get the redirect url.
val redirectURL = consumerJsonV310.redirect_url.trim
S.redirectTo(s"$redirectURL?CONSENT_REQUEST_ID=${consentJsonV510.consent_request_id.getOrElse("")}")
S.redirectTo(s"$redirectURL?CONSENT_REQUEST_ID=${consentJsonV510.consent_request_id.getOrElse("")}&status=${consentJsonV510.status}")
case _ =>
S.error(s"$InvalidJsonFormat The Json body should be the $ConsumerJsonV310. " +
s"Please check `Get Consumer` !")

View File

@ -386,15 +386,21 @@ object Helper extends Loggable {
}
def i18n(message: String, default: Option[String] = None): String = {
if(S.?(message)==message) {
val words = message.split('.').toList match {
case x :: Nil => Helpers.capify(x) :: Nil
case x :: xs => Helpers.capify(x) :: xs
case _ => Nil
}
default.getOrElse(words.mkString(" ") + ".")
if (S.inStatefulScope_?) {
if (S.?(message) == message) {
val words = message.split('.').toList match {
case x :: Nil => Helpers.capify(x) :: Nil
case x :: xs => Helpers.capify(x) :: xs
case _ => Nil
}
default.getOrElse(words.mkString(" ") + ".")
} else
S.?(message)
} else {
logger.error(s"i18n(message($message), default${default}: Attempted to use resource bundles outside of an initialized S scope. " +
s"S only usable when initialized, such as during request processing. Did you call S.? from Future?")
default.getOrElse(message)
}
else S.?(message)
}
/**

View File

@ -3,6 +3,10 @@
### Most recent changes at top of file
```
Date Commit Action
17/02/2025 5877d2f2 Bootstrap Super User
Added props super_admin_username=TomWilliams
Added props super_admin_inital_password=681aeeb9f681aeeb9f681aeeb9
Added props super_admin_email=tom@tesobe.com
24/01/2025 ad68f054 Added props skip_consent_sca_for_consumer_id_pairs .
03/02/2024 7bcb6bc5 Added props oauth2.keycloak.source_of_truth, default is false.
oauth2.keycloak.source_of_truth = true turns sync ON.