mirror of
https://github.com/OpenBankProject/OBP-API.git
synced 2026-02-06 15:56:57 +00:00
feature/implement_FAPI_flow: remove flow-A related code, rename login_with_hydra to integrate_with_hydra, enable Consumer and disable Consumer update OAuth2 client grantTypes to enable and disable it.
This commit is contained in:
parent
84213a6c7a
commit
820dc2a31a
@ -865,8 +865,8 @@ outboundAdapterCallContext.generalContext
|
||||
# ------------------------------------------------------------------------------------------
|
||||
|
||||
# ------------------------------ Hydra oauth2 props ------------------------------
|
||||
## if login_with_hydra set to true, all other props must not be empty
|
||||
#login_with_hydra=true
|
||||
## if integrate_with_hydra set to true, all other props must not be empty
|
||||
#integrate_with_hydra=true
|
||||
#hydra_public_url=http://127.0.0.1:4444
|
||||
#hydra_admin_url=http://127.0.0.1:4445
|
||||
#hydra_consents=ReadAccountsBasic,ReadAccountsDetail,ReadBalances,ReadTransactionsBasic,ReadTransactionsDebits,ReadTransactionsDetail
|
||||
|
||||
@ -25,7 +25,7 @@ TESOBE (http://www.tesobe.com/)
|
||||
|
||||
*/
|
||||
package code.model
|
||||
import java.util.Date
|
||||
import java.util.{Collections, Date}
|
||||
|
||||
import code.api.util.APIUtil
|
||||
import code.api.util.migration.Migration.DbFunction
|
||||
@ -36,6 +36,7 @@ import code.nonce.NoncesProvider
|
||||
import code.token.TokensProvider
|
||||
import code.users.Users
|
||||
import code.util.Helper.MdcLoggable
|
||||
import code.util.HydraUtil
|
||||
import code.util.HydraUtil._
|
||||
import com.github.dwickern.macros.NameOf
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
@ -186,7 +187,7 @@ object MappedConsumersProvider extends ConsumersProvider with MdcLoggable {
|
||||
}
|
||||
|
||||
def deleteConsumer(consumer: Consumer): Boolean = {
|
||||
if(mirrorConsumerInHydra) hydraAdmin.deleteOAuth2Client(consumer.key.get)
|
||||
if(integrateWithHydra) hydraAdmin.deleteOAuth2Client(consumer.key.get)
|
||||
Consumer.delete_!(consumer)
|
||||
}
|
||||
|
||||
@ -245,10 +246,28 @@ object MappedConsumersProvider extends ConsumersProvider with MdcLoggable {
|
||||
}
|
||||
val updatedConsumer = c.saveMe()
|
||||
|
||||
if(mirrorConsumerInHydra && Option(originIsActive) != isActive) {
|
||||
if(integrateWithHydra && Option(originIsActive) != isActive && isActive.isDefined) {
|
||||
val clientId = c.key.get
|
||||
val existsOAuth2Client = Box.tryo(hydraAdmin.getOAuth2Client(clientId))
|
||||
.filter(null !=)
|
||||
// if disable consumer, delete hydra client, else if enable consumer, create hydra client
|
||||
// note: hydra update client endpoint have bug, can't update any client, So here delete and create new one
|
||||
if (isActive == Some(false)) {
|
||||
hydraAdmin.deleteOAuth2Client(c.key.get)
|
||||
existsOAuth2Client
|
||||
.map { oAuth2Client =>
|
||||
hydraAdmin.deleteOAuth2Client(clientId)
|
||||
// set grantTypes to empty to disable the client
|
||||
oAuth2Client.setGrantTypes(Collections.emptyList())
|
||||
hydraAdmin.createOAuth2Client(oAuth2Client)
|
||||
}
|
||||
} else if(isActive == Some(true) && existsOAuth2Client.isDefined) {
|
||||
existsOAuth2Client
|
||||
.map { oAuth2Client =>
|
||||
hydraAdmin.deleteOAuth2Client(clientId)
|
||||
// set grantTypes to correct value to enable the client
|
||||
oAuth2Client.setGrantTypes(HydraUtil.grantTypes)
|
||||
hydraAdmin.createOAuth2Client(oAuth2Client)
|
||||
}
|
||||
} else if(isActive == Some(true)) {
|
||||
createHydraClient(updatedConsumer)
|
||||
}
|
||||
@ -402,7 +421,7 @@ object MappedConsumersProvider extends ConsumersProvider with MdcLoggable {
|
||||
case None =>
|
||||
}
|
||||
val createdConsumer = c.saveMe()
|
||||
if(mirrorConsumerInHydra) createHydraClient(createdConsumer)
|
||||
if(integrateWithHydra) createHydraClient(createdConsumer)
|
||||
createdConsumer
|
||||
}
|
||||
}
|
||||
|
||||
@ -859,22 +859,7 @@ def restoreSomeSessions(): Unit = {
|
||||
// val currentUrl = S.uriAndQueryString.getOrElse("/")
|
||||
// AuthUser.loginRedirect.set(Full(Helpers.appendParams(currentUrl, List((LogUserOutParam, "false")))))
|
||||
def checkInternalRedirectAndLogUseIn(preLoginState: () => Unit, redirect: String, user: AuthUser) = {
|
||||
val loginChallengeBox = S.param("login_challenge")
|
||||
.filter(StringUtils.isNotBlank(_))
|
||||
if(loginWithHydra && loginChallengeBox.isDefined) {
|
||||
val challenge = loginChallengeBox.orNull
|
||||
val acceptLoginRequest = new AcceptLoginRequest()
|
||||
acceptLoginRequest.setSubject(user.username.get)
|
||||
acceptLoginRequest.remember(false)
|
||||
acceptLoginRequest.rememberFor(3600)
|
||||
val response = hydraAdmin.acceptLoginRequest(challenge, acceptLoginRequest)
|
||||
val redirectTo = response.getRedirectTo
|
||||
logUserIn(user, () => {
|
||||
S.notice(S.?("logged.in"))
|
||||
preLoginState()
|
||||
S.redirectTo(redirectTo)
|
||||
})
|
||||
} else if (Helper.isValidInternalRedirectUrl(redirect)) {
|
||||
if (Helper.isValidInternalRedirectUrl(redirect)) {
|
||||
logUserIn(user, () => {
|
||||
S.notice(S.?("logged.in"))
|
||||
preLoginState()
|
||||
|
||||
@ -1,249 +0,0 @@
|
||||
/**
|
||||
* Open Bank Project - API
|
||||
* Copyright (C) 2011-2019, TESOBE GmbH.
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU Affero General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Affero General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* Email: contact@tesobe.com
|
||||
* TESOBE GmbH.
|
||||
* Osloer Strasse 16/17
|
||||
* Berlin 13359, Germany
|
||||
*
|
||||
* This product includes software developed at
|
||||
* TESOBE (http://www.tesobe.com/)
|
||||
*
|
||||
*/
|
||||
package code.snippet
|
||||
|
||||
import java.util.Date
|
||||
|
||||
import code.api.UKOpenBanking.v3_1_0.UtilForUKV310
|
||||
import code.api.util.{APIUtil, NewStyle}
|
||||
import code.consent.{Consent, Consents}
|
||||
import code.consumer.Consumers
|
||||
import code.model.dataAccess.AuthUser
|
||||
import code.util.Helper.MdcLoggable
|
||||
import code.util.HydraUtil
|
||||
import code.views.Views
|
||||
import code.webuiprops.MappedWebUiPropsProvider.getWebUiPropsValue
|
||||
import net.liftweb.http.{RequestVar, S, SHtml}
|
||||
import net.liftweb.util.CssSel
|
||||
import net.liftweb.util.Helpers._
|
||||
import sh.ory.hydra.model.{AcceptConsentRequest, ConsentRequestSession, RejectRequest}
|
||||
|
||||
import scala.jdk.CollectionConverters.{asScalaBufferConverter, mapAsJavaMapConverter, seqAsJavaListConverter}
|
||||
import com.openbankproject.commons.ExecutionContext.Implicits.global
|
||||
import com.openbankproject.commons.model.{AccountId, BankId, BankIdAccountId, ViewId, ViewIdBankIdAccountId}
|
||||
import com.openbankproject.commons.util.Functions.Implicits._
|
||||
import net.liftweb.common.{Box, Full}
|
||||
|
||||
import scala.concurrent.{Await, Future}
|
||||
import scala.concurrent.duration.{Duration, SECONDS}
|
||||
|
||||
class ConsentConfirmation extends MdcLoggable {
|
||||
|
||||
private object submitButtonDefenseFlag extends RequestVar("")
|
||||
|
||||
private object cancelButtonDefenseFlag extends RequestVar("")
|
||||
|
||||
|
||||
val confirmConsentButtonValue = getWebUiPropsValue("webui_post_confirm_consent_submit_button_value", "Yes, I confirm")
|
||||
val rejectConsentButtonValue = getWebUiPropsValue("webui_post_reject_consent_submit_button_value", "Cancel")
|
||||
|
||||
def confirmConsentsForm: CssSel = {
|
||||
|
||||
def submitButtonDefense: Unit = {
|
||||
submitButtonDefenseFlag("true")
|
||||
}
|
||||
|
||||
def cancelButtonDefense: Unit = {
|
||||
cancelButtonDefenseFlag("true")
|
||||
}
|
||||
|
||||
|
||||
def formElement(ele: => CssSel): CssSel =
|
||||
"form" #> {
|
||||
"type=submit" #> SHtml.submit(s"$confirmConsentButtonValue", () => submitButtonDefense) &
|
||||
"type=button" #> SHtml.submit(s"$rejectConsentButtonValue", () => cancelButtonDefense) &
|
||||
ele
|
||||
}
|
||||
|
||||
|
||||
val consentChallengeBox = S.param("consent_challenge")
|
||||
if (consentChallengeBox.isEmpty) {
|
||||
return formElement {
|
||||
"#confirm-errors" #> "Please login first."
|
||||
}
|
||||
}
|
||||
val consentChallenge = consentChallengeBox.orNull
|
||||
if (cancelButtonDefenseFlag.get == "true") {
|
||||
val rejectRequest = new RejectRequest()
|
||||
rejectRequest.setError("access_denied")
|
||||
rejectRequest.setErrorDescription("The resource owner denied the request")
|
||||
val rejectResponse = HydraUtil.hydraAdmin.rejectConsentRequest(consentChallenge, rejectRequest)
|
||||
AuthUser.logUserOut()
|
||||
return S.redirectTo(rejectResponse.getRedirectTo)
|
||||
}
|
||||
|
||||
val consentResponse = HydraUtil.hydraAdmin.getConsentRequest(consentChallenge)
|
||||
|
||||
val DateTimeRegex = """(\d+-\d{2}-\d{2}).*(\d{2}:\d{2}:\d{2}).*""".r // style example: 2020-09-09T11:55:22Z
|
||||
def getDateTime(paramName: String): Date = S.param(paramName) match {
|
||||
case Full(DateTimeRegex(date, time)) => APIUtil.DateWithSecondsFormat.parse(s"${date}T${time}Z")
|
||||
case Full(v) => throw new IllegalArgumentException(s"request parameter $paramName is not correct date time format: $v")
|
||||
case _ => throw new IllegalArgumentException(s"request parameter $paramName should not be empty.")
|
||||
}
|
||||
|
||||
if (S.post_?) {
|
||||
// get values of submit form
|
||||
val consents = S.params("consent_scope")
|
||||
val bankId = S.param("bank_id")
|
||||
val accountIds = S.params("account_id")
|
||||
val fromDate = getDateTime("from_date")
|
||||
val toDate = getDateTime("to_date")
|
||||
val expirationDate = getDateTime("expiration_date")
|
||||
|
||||
val currentUser = AuthUser.getCurrentUser.openOrThrowException("User is not logged in, in order to confirm consent the user must be authenticated.")
|
||||
|
||||
{ // TO create consent
|
||||
val accountIdsOpt = if (accountIds.isEmpty) None else Some(accountIds)
|
||||
val consent: Box[Consent] = {
|
||||
val consumer = Consumers.consumers.vend.getConsumerByConsumerKey(consentResponse.getClient.getClientId)
|
||||
val consumerId = consumer.map(_.consumerId.get)
|
||||
Consents.consentProvider.vend.saveUKConsent(Some(currentUser), bankId, accountIdsOpt, consumerId, consents, expirationDate, fromDate, toDate, Some("MXOpenFinance"), Some("0.0.1"))
|
||||
}
|
||||
}
|
||||
|
||||
{ // revoke all consents for all accounts
|
||||
|
||||
// AuthUser.hydraConsents is just the follow values, read from props
|
||||
//ViewId: six fixed
|
||||
//"ReadAccountsBasic"
|
||||
//"ReadAccountsDetail"
|
||||
//"ReadBalances"
|
||||
//"ReadTransactionsBasic"
|
||||
//"ReadTransactionsDebits"
|
||||
//"ReadTransactionsDetail"
|
||||
|
||||
val bankIdAccountIdsFuture: Future[List[BankIdAccountId]] = for {
|
||||
availablePrivateAccounts <- Views.views.vend.getPrivateBankAccountsFuture(currentUser)
|
||||
(accounts, _) <- NewStyle.function.getCoreBankAccountsFuture(availablePrivateAccounts, None)
|
||||
} yield {
|
||||
accounts.map(account => BankIdAccountId(BankId(account.bankId), AccountId(account.id)))
|
||||
}
|
||||
// all the BankIdAccountId for current user
|
||||
val bankIdAccountIds = Await.result(bankIdAccountIdsFuture, Duration(30, SECONDS))
|
||||
val revokeAccessIds: List[ViewIdBankIdAccountId] = for {
|
||||
consent <- HydraUtil.hydraConsents
|
||||
bankIdAccountId <- bankIdAccountIds
|
||||
} yield ViewIdBankIdAccountId(ViewId(consent), bankIdAccountId.bankId, bankIdAccountId.accountId)
|
||||
UtilForUKV310.revokeAccessToViews(currentUser, revokeAccessIds)
|
||||
}
|
||||
|
||||
{ // grant checked consents
|
||||
val grantAccessIds: List[ViewIdBankIdAccountId] = for {
|
||||
consent <- consents
|
||||
accountId <- accountIds
|
||||
} yield ViewIdBankIdAccountId(ViewId(consent), BankId(bankId.orNull), AccountId(accountId))
|
||||
UtilForUKV310.grantAccessToViews(currentUser, grantAccessIds)
|
||||
}
|
||||
|
||||
// inform hydra
|
||||
val consentRequest = new AcceptConsentRequest()
|
||||
val scopes = "openid" :: "offline" :: consents
|
||||
consentRequest.setGrantScope(scopes.asJava)
|
||||
consentRequest.setGrantAccessTokenAudience(consentResponse.getRequestedAccessTokenAudience)
|
||||
consentRequest.setRemember(false)
|
||||
consentRequest.setRememberFor(3600) // TODO set in props
|
||||
|
||||
val session = new ConsentRequestSession()
|
||||
val userName = currentUser.name
|
||||
val idTokenValues = Map("given_name" -> userName,
|
||||
"family_name" -> userName,
|
||||
"name" -> userName,
|
||||
"email" -> currentUser.emailAddress,
|
||||
"email_verified" -> true).asJava
|
||||
|
||||
session.setIdToken(idTokenValues)
|
||||
val accessToken = Map(
|
||||
"bank_id" -> bankId.orNull,
|
||||
"account_id" -> accountIds.asJava,
|
||||
"transactionFromDateTime" -> fromDate,
|
||||
"transactionToDateTime" -> toDate,
|
||||
"expirationDateTime" -> expirationDate,
|
||||
).asJava
|
||||
session.accessToken(accessToken)
|
||||
consentRequest.setSession(session)
|
||||
|
||||
val acceptConsentResponse = HydraUtil.hydraAdmin.acceptConsentRequest(consentChallenge, consentRequest)
|
||||
S.redirectTo(acceptConsentResponse.getRedirectTo)
|
||||
} else {
|
||||
if (consentResponse.getSkip) {
|
||||
val requestBody = new AcceptConsentRequest()
|
||||
requestBody.setGrantScope(consentResponse.getRequestedScope)
|
||||
requestBody.setGrantAccessTokenAudience(consentResponse.getRequestedAccessTokenAudience)
|
||||
val requestSession = new ConsentRequestSession()
|
||||
requestBody.setSession(requestSession)
|
||||
val skipResponse = HydraUtil.hydraAdmin.acceptConsentRequest(consentChallenge, requestBody)
|
||||
S.redirectTo(skipResponse.getRedirectTo)
|
||||
} else {
|
||||
val currentUser = AuthUser.getCurrentUser.openOrThrowException("User is not login, do confirm consent must be authenticated user.")
|
||||
|
||||
val bankAndAccountFuture: Future[List[(String, String, String, String)]] = for {
|
||||
availablePrivateAccounts <- Views.views.vend.getPrivateBankAccountsFuture(currentUser)
|
||||
(accounts, _) <- NewStyle.function.getCoreBankAccountsFuture(availablePrivateAccounts, None)
|
||||
(banks, _) <- NewStyle.function.getBanks(None)
|
||||
} yield {
|
||||
for {
|
||||
bank <- banks
|
||||
account <- accounts
|
||||
if account.bankId == bank.bankId.value
|
||||
} yield (bank.bankId.value, bank.shortName, account.id, account.label)
|
||||
}
|
||||
//(bankId, bankName, accountId, accountLabel)
|
||||
val bankAndAccount: List[(String, String, String, String)] = Await.result(bankAndAccountFuture, Duration(30, SECONDS))
|
||||
|
||||
val banks = bankAndAccount.map(it => it._1 -> it._2).distinctBy(_._1)
|
||||
|
||||
formElement {
|
||||
"#confirm-errors" #> "" &
|
||||
"#consent_challenge [value]" #> consentChallenge &
|
||||
".bank" #> {
|
||||
banks.map { it =>
|
||||
".bank [value]" #> it._1 &
|
||||
".bank *" #> it._2
|
||||
}
|
||||
} &
|
||||
"#account_group" #> {
|
||||
bankAndAccount.map { account =>
|
||||
val (bankId, _, accountId, label) = account
|
||||
"@account_id [value]" #> accountId &
|
||||
"@account_id [id]" #> s"account_$accountId" &
|
||||
"@account_id [bank_id]" #> bankId &
|
||||
"@account_id_label [for]" #> s"account_$accountId" &
|
||||
"@account_id_label *" #> label
|
||||
}
|
||||
} &
|
||||
"#scope_group" #> consentResponse.getRequestedScope.asScala.filter(it => it != "openid" && it != "offline").map { scope =>
|
||||
"@consent_scope [value]" #> scope &
|
||||
"@consent_scope [id]" #> s"consent_$scope" &
|
||||
"@consent_scope_label [for]" #> s"consent_$scope" &
|
||||
"@consent_scope_label *" #> scope
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -99,13 +99,13 @@ class ConsumerRegistration extends MdcLoggable {
|
||||
"#appType" #> SHtml.select(appTypes, Box!! appType.is, appType(_)) &
|
||||
"#appName" #> SHtml.text(nameVar.is, nameVar(_)) &
|
||||
"#redirect_url_label" #> {
|
||||
if (HydraUtil.mirrorConsumerInHydra) "Redirect URL" else "Redirect URL (Optional)"
|
||||
if (HydraUtil.integrateWithHydra) "Redirect URL" else "Redirect URL (Optional)"
|
||||
} &
|
||||
"#appRedirectUrl" #> SHtml.text(redirectionURLVar, redirectionURLVar(_)) &
|
||||
"#appDev" #> SHtml.text(devEmailVar, devEmailVar(_)) &
|
||||
"#appDesc" #> SHtml.textarea(descriptionVar, descriptionVar (_)) &
|
||||
"#appUserAuthenticationUrl" #> SHtml.text(authenticationURLVar.is, authenticationURLVar(_)) & {
|
||||
if(HydraUtil.mirrorConsumerInHydra) {
|
||||
if(HydraUtil.integrateWithHydra) {
|
||||
"#app-client_certificate" #> SHtml.textarea(clientCertificateVar, clientCertificateVar (_))&
|
||||
"#app-request_uri" #> SHtml.text(requestUriVar, requestUriVar(_)) &
|
||||
"#app-signing_alg" #> SHtml.select(signingAlgs, Box!! signingAlgVar.is, signingAlgVar(_)) &
|
||||
@ -127,7 +127,7 @@ class ConsumerRegistration extends MdcLoggable {
|
||||
val jwks = jwksVar.is
|
||||
val jwsAlg = signingAlgVar.is
|
||||
var jwkPrivateKey: String = s"Please change this value to ${if(StringUtils.isNotBlank(jwksUri)) "jwks_uri" else "jwks"} corresponding private key"
|
||||
if(HydraUtil.mirrorConsumerInHydra) {
|
||||
if(HydraUtil.integrateWithHydra) {
|
||||
HydraUtil.createHydraClient(consumer, oAuth2Client => {
|
||||
val signingAlg = signingAlgVar.is
|
||||
|
||||
@ -182,7 +182,7 @@ class ConsumerRegistration extends MdcLoggable {
|
||||
"#directlogin-endpoint a [href]" #> urlDirectLoginEndpoint &
|
||||
"#post-consumer-registration-more-info-link a *" #> registrationMoreInfoText &
|
||||
"#post-consumer-registration-more-info-link a [href]" #> registrationMoreInfoUrl & {
|
||||
if(HydraUtil.mirrorConsumerInHydra) {
|
||||
if(HydraUtil.integrateWithHydra) {
|
||||
"#hydra-client-info-title *" #>"OAuth2" &
|
||||
"#admin_url *" #> HydraUtil.hydraAdminUrl &
|
||||
"#client_id *" #> {consumer.key.get} &
|
||||
@ -314,17 +314,15 @@ class ConsumerRegistration extends MdcLoggable {
|
||||
jwksUriVar.set(jwksUri)
|
||||
jwksVar.set(jwks)
|
||||
|
||||
val oauth2ParamError: CssSel = if(HydraUtil.mirrorConsumerInHydra) {
|
||||
val oauth2ParamError: CssSel = if(HydraUtil.integrateWithHydra) {
|
||||
if(StringUtils.isBlank(redirectionURLVar.is) || Consumer.redirectURLRegex.findFirstIn(redirectionURLVar.is).isEmpty) {
|
||||
showErrorsForDescription("The 'Redirect URL' should be a valid url !")
|
||||
} else if(StringUtils.isNotBlank(requestUri) && !requestUri.matches("""^https?://(www.)?\S+?(:\d{2,6})?\S*$""")) {
|
||||
showErrorsForDescription("The 'request_uri' should be a valid url !")
|
||||
} else if(StringUtils.isNotBlank(jwksUri) && !jwksUri.matches("""^https?://(www.)?\S+?(:\d{2,6})?\S*$""")) {
|
||||
showErrorsForDescription("The 'jwks_uri' should be a valid url !")
|
||||
} else if(StringUtils.isNotBlank(jwksUri) && StringUtils.isBlank(signingAlg)) {
|
||||
showErrorsForDescription("The 'signing_alg' should not be empty when request_uri have value!")
|
||||
} else if(!StringUtils.isAllBlank(jwksUri, jwks) && StringUtils.isBlank(signingAlg)) {
|
||||
showErrorsForDescription("The 'signing_alg' must have value when 'jwks_uri' or 'jwks' have value!")
|
||||
} else if(StringUtils.isBlank(signingAlg)) {
|
||||
showErrorsForDescription("The 'signing_alg' should not be empty!")
|
||||
} else if(StringUtils.isNoneBlank(jwksUri, jwks)) {
|
||||
showErrorsForDescription("The 'jwks_uri' and 'jwks' should not have value at the same time!")
|
||||
} else if (StringUtils.isNotBlank(clientCertificate) && X509.validate(clientCertificate) != Full(true)) {
|
||||
|
||||
@ -18,25 +18,32 @@ import scala.jdk.CollectionConverters.{mapAsJavaMapConverter, seqAsJavaListConve
|
||||
|
||||
object HydraUtil {
|
||||
|
||||
val loginWithHydra = APIUtil.getPropsAsBoolValue("login_with_hydra", false)
|
||||
private val INTEGRATE_WITH_HYDRA = "integrate_with_hydra"
|
||||
|
||||
val integrateWithHydra = APIUtil.getPropsAsBoolValue(INTEGRATE_WITH_HYDRA, false)
|
||||
|
||||
val mirrorConsumerInHydra = APIUtil.getPropsAsBoolValue("mirror_consumer_in_hydra", false)
|
||||
|
||||
lazy val hydraPublicUrl = APIUtil.getPropsValue("hydra_public_url")
|
||||
.openOrThrowException("If props login_with_hydra is true, hydra_public_url value should not be blank")
|
||||
.openOrThrowException(s"If props $INTEGRATE_WITH_HYDRA is true, hydra_public_url value should not be blank")
|
||||
.replaceFirst("/$", "")
|
||||
|
||||
lazy val hydraAdminUrl = APIUtil.getPropsValue("hydra_admin_url")
|
||||
.openOrThrowException("If props login_with_hydra is true, hydra_admin_url value should not be blank")
|
||||
.openOrThrowException(s"If props $INTEGRATE_WITH_HYDRA is true, hydra_admin_url value should not be blank")
|
||||
.replaceFirst("/$", "")
|
||||
|
||||
lazy val hydraConsents = APIUtil.getPropsValue("hydra_consents")
|
||||
.openOrThrowException("If props login_with_hydra is true, hydra_client_scope value should not be blank")
|
||||
.openOrThrowException(s"If props $INTEGRATE_WITH_HYDRA is true, hydra_client_scope value should not be blank")
|
||||
.trim.split("""\s*,\s*""").toList
|
||||
|
||||
private val allConsents = hydraConsents.mkString("openid offline ", " ","")
|
||||
|
||||
|
||||
val grantTypes = ("authorization_code" :: "client_credentials" :: "refresh_token" :: "implicit" :: Nil).asJava
|
||||
|
||||
lazy val hydraAdmin = {
|
||||
val hydraAdminUrl = APIUtil.getPropsValue("hydra_admin_url")
|
||||
.openOrThrowException("If props login_with_hydra is true, hydra_admin_url value should not be blank")
|
||||
.openOrThrowException(s"If props $INTEGRATE_WITH_HYDRA is true, hydra_admin_url value should not be blank")
|
||||
val defaultClient = Configuration.getDefaultApiClient
|
||||
defaultClient.setBasePath(hydraAdminUrl)
|
||||
new AdminApi(defaultClient)
|
||||
@ -44,7 +51,7 @@ object HydraUtil {
|
||||
|
||||
lazy val hydraPublic = {
|
||||
val hydraPublicUrl = APIUtil.getPropsValue("hydra_public_url")
|
||||
.openOrThrowException("If props login_with_hydra is true, hydra_public_url value should not be blank")
|
||||
.openOrThrowException(s"If props $INTEGRATE_WITH_HYDRA is true, hydra_public_url value should not be blank")
|
||||
val apiClient = new ApiClient
|
||||
apiClient.setBasePath(hydraPublicUrl)
|
||||
new PublicApi(apiClient)
|
||||
@ -65,10 +72,10 @@ object HydraUtil {
|
||||
val oAuth2Client = new OAuth2Client()
|
||||
oAuth2Client.setClientId(consumer.key.get)
|
||||
oAuth2Client.setClientSecret(consumer.secret.get)
|
||||
val allConsents = "openid" :: "offline" :: hydraConsents
|
||||
oAuth2Client.setScope(allConsents.mkString(" "))
|
||||
|
||||
oAuth2Client.setGrantTypes(("authorization_code" :: "client_credentials" :: "refresh_token" :: "implicit" :: Nil).asJava)
|
||||
oAuth2Client.setScope(allConsents)
|
||||
|
||||
oAuth2Client.setGrantTypes(grantTypes)
|
||||
oAuth2Client.setResponseTypes(("code" :: "id_token" :: "token" :: "code id_token" :: Nil).asJava)
|
||||
oAuth2Client.setPostLogoutRedirectUris(List(redirectUrl).asJava)
|
||||
|
||||
|
||||
@ -1,146 +0,0 @@
|
||||
<!--
|
||||
Open Bank Project - API
|
||||
Copyright (C) 2011-2017, TESOBE GmbH
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published by
|
||||
the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
|
||||
Email: contact@tesobe.com
|
||||
TESOBE GmbH
|
||||
Osloerstrasse 16/17
|
||||
Berlin 13359, Germany
|
||||
|
||||
This product includes software developed at
|
||||
TESOBE (http://www.tesobe.com/)
|
||||
by
|
||||
Simon Redfern : simon AT tesobe DOT com
|
||||
Sebastian Henschel : sebastian AT tesobe DOT com
|
||||
-->
|
||||
<style>
|
||||
.bootstrap-datetimepicker-widget,
|
||||
.bootstrap-datetimepicker-widget .picker-switch td span{
|
||||
background-color: #fff ;
|
||||
color: #333 ;
|
||||
}
|
||||
</style>
|
||||
<div id="register-consumer" data-lift="surround?with=default;at=content">
|
||||
<div data-lift="ConsentConfirmation.confirmConsentsForm">
|
||||
<h2 style="text-align: center">Confirm the following permissions on your account for your Application:</h2>
|
||||
<form method="post">
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="bank_id">Banks</label>
|
||||
<select class="form-control" id="bank_id" name="bank_id">
|
||||
<option value="">--select a bank--</option>
|
||||
<option class="bank" value="psd201-bank-y--uk">Bank y</option>
|
||||
</select>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-12">
|
||||
<h4>Accounts:</h4>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-6" id="account_group">
|
||||
<div class="form-group">
|
||||
<input type="checkbox" name="account_id" id="account_id" value="account_x" bank_id="bank_x_y">
|
||||
<label for="account_id" name="account_id_label">account x</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-12">
|
||||
<h4>Consents:</h4>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-12" id="scope_group">
|
||||
<div class="form-group">
|
||||
<input type="checkbox" name="consent_scope" id="consent_scope_openid" value="openid">
|
||||
<label for="consent_scope_openid" name="consent_scope_label">openid</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-12">
|
||||
<h4>Date Time:</h4>
|
||||
</div>
|
||||
</div>
|
||||
<br>
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="from_date">TransactionFromDateTime</label>
|
||||
<input type="text" name="from_date" id="from_date" class="form-control" data-date-format="YYYY-MM-DDTHH:mm:ss">
|
||||
</div>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="to_date">TransactionToDateTime</label>
|
||||
<input type="text" name="to_date" id="to_date" class="form-control" data-date-format="YYYY-MM-DDTHH:mm:ss">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="row">
|
||||
<div class="col-xs-12 col-sm-6">
|
||||
<div class="form-group">
|
||||
<label for="expiration_date">ExpirationDateTime</label>
|
||||
<input type="text" name="expiration_date" id="expiration_date" class="form-control" data-date-format="YYYY-MM-DDTHH:mm:ss">
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<input type="hidden" name="consent_challenge" id="consent_challenge">
|
||||
|
||||
<input type="button" name="confirm" value="Cancel" class="btn btn-default" />
|
||||
|
||||
<input type="submit" name="confirm" value="Yes, I confirm" class="btn btn-default" />
|
||||
<div id = "confirm-errors-div" class="hide alert alert-danger">
|
||||
<span data-lift="Msg?id=confirm-errors"/>
|
||||
</div>
|
||||
</form>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
$(function () {
|
||||
$('#from_date, #to_date').datetimepicker({
|
||||
defaultDate: new Date()
|
||||
});
|
||||
$('#expiration_date').datetimepicker({
|
||||
defaultDate: new Date(new Date().setFullYear(new Date().getFullYear() + 1))
|
||||
});
|
||||
// hide all account checkboxes
|
||||
$('input[name=account_id]').prop("checked", false).parent().parent().hide();
|
||||
$('#bank_id').change(function(){
|
||||
var bankId = $(this).val();
|
||||
$('input[name=account_id]').prop("checked", false).parent().parent().hide();
|
||||
if(bankId) {
|
||||
$('input[name=account_id]')
|
||||
.filter(function() { // not use .filter('[bank_id='+bankId+']') reason: bankId may have special characters
|
||||
return $(this).attr('bank_id') === bankId;
|
||||
}).parent().parent().show();
|
||||
}
|
||||
});
|
||||
});
|
||||
</script>
|
||||
Loading…
Reference in New Issue
Block a user