Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
10 changes: 10 additions & 0 deletions obp-api/src/main/resources/props/sample.props.template
Original file line number Diff line number Diff line change
Expand Up @@ -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
59 changes: 58 additions & 1 deletion obp-api/src/main/scala/bootstrap/liftweb/Boot.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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}
Expand Down Expand Up @@ -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)

Expand Down Expand Up @@ -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 {
Expand Down
6 changes: 4 additions & 2 deletions obp-api/src/main/scala/code/model/dataAccess/AuthUser.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down Expand Up @@ -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")) _ ::
Expand Down Expand Up @@ -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] =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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` !")
Expand Down
22 changes: 14 additions & 8 deletions obp-api/src/main/scala/code/util/Helper.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}

/**
Expand Down
4 changes: 4 additions & 0 deletions release_notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -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.
Expand Down