Consent behaviour - WIP 3

This commit is contained in:
Marko Milić 2019-03-13 10:12:28 +01:00
parent f309ee6cce
commit 40a3f255c8
5 changed files with 35 additions and 36 deletions

View File

@ -33,7 +33,7 @@ import code.api.Constant._
import code.api.JSONFactoryGateway.PayloadOfJwtJSON
import code.api.OAuthHandshake._
import code.api.util.APIUtil._
import code.api.util.ErrorMessages.attemptedToOpenAnEmptyBox
import code.api.util.ErrorMessages.{NotImplemented, attemptedToOpenAnEmptyBox}
import code.api.util._
import code.api.v2_0_0.OBPAPI2_0_0.Implementations2_0_0
import code.api.v2_2_0.OBPAPI2_2_0.Implementations2_2_0
@ -179,6 +179,7 @@ trait OBPRestHelper extends RestHelper with MdcLoggable {
val verb = S.request.openOrThrowException(attemptedToOpenAnEmptyBox).requestType.method
val url = URLDecoder.decode(S.uriAndQueryString.getOrElse(""),"UTF-8")
val correlationId = getCorrelationId()
val reqHeaders = S.request.openOrThrowException(attemptedToOpenAnEmptyBox).request.headers
val cc = CallContext(
resourceDocument = rd,
startTime = Some(Helpers.now),
@ -191,6 +192,9 @@ trait OBPRestHelper extends RestHelper with MdcLoggable {
)
if(newStyleEndpoints(rd)) {
fn(cc)
} else if (APIUtil.hasConsentId(reqHeaders)) {
// TODO 1. Get or Create a User 2. Assign entitlements to it 3. Create views
Failure(NotImplemented + RequestHeader.`Consent-Id`)
} else if (hasAnOAuthHeader(authorization)) {
val (usr, callContext) = getUserAndCallContext(cc)
usr match {

View File

@ -160,6 +160,20 @@ object APIUtil extends MdcLoggable {
}
}
/**
* Purpose of this helper function is to get the Consent-Id value from a Request Headers.
* @return the Consent-Id value from a Request Header as a String
*/
def getConsentId(requestHeaders: List[HTTPParam]): Option[String] = {
requestHeaders.toSet.filter(_.name == RequestHeader.`Consent-Id`).toList match {
case x :: Nil => Some(x.values.mkString(", "))
case _ => None
}
}
def hasConsentId(requestHeaders: List[HTTPParam]): Boolean = {
getConsentId(requestHeaders).isDefined
}
def registeredApplication(consumerKey: String): Boolean = {
Consumers.consumers.vend.getConsumerByConsumerKey(consumerKey) match {
case Full(application) => application.isActive.get
@ -1845,9 +1859,12 @@ Returns a string showed to the developer
val correlationId = getCorrelationId()
val reqHeaders = S.request.openOrThrowException(attemptedToOpenAnEmptyBox).request.headers
val res =
if (hasAnOAuthHeader(cc.authReqHeaderField)) {
if (APIUtil.hasConsentId(reqHeaders)) {
// TODO 1. Get or Create a User 2. Assign entitlements to it 3. Create views
Future((Failure(NotImplemented + RequestHeader.`Consent-Id`), Some(cc)))
} else if (hasAnOAuthHeader(cc.authReqHeaderField)) {
getUserFromOAuthHeaderFuture(cc)
} else if (hasAnOAuth2Header(cc.authReqHeaderField)) {
} else if (hasAnOAuth2Header(cc.authReqHeaderField)) {
OAuth2Login.getUserFuture(cc)
} else if (getPropsAsBoolValue("allow_direct_login", true) && hasDirectLoginHeader(cc.authReqHeaderField)) {
DirectLogin.getUserFromDirectLoginHeaderFuture(cc)

View File

@ -87,17 +87,11 @@ case class CallContext(
* Purpose of this helper function is to get the Consent-Id value from a Request Headers.
* @return the Consent-Id value from a Request Header as a String
*/
def getConsentId(): String = {
this.requestHeaders.toSet.filter(_.name == RequestHeader.`Consent-Id`).toList match {
case x :: Nil => x.values.mkString(", ")
case _ => ""
}
def getConsentId(): Option[String] = {
APIUtil.getConsentId(this.requestHeaders)
}
def hasConsentId(): Boolean = {
this.requestHeaders.toSet.filter(_.name == RequestHeader.`Consent-Id`).toList match {
case x :: Nil => true
case _ => false
}
APIUtil.hasConsentId(this.requestHeaders)
}
}
@ -222,14 +216,4 @@ object ApiSession {
}
}
def hasConsent(callContext: Option[CallContext]): Boolean = {
callContext.map(_.getConsentId()) match {
case Some(consent) =>
// TODO Inspect rights based on Consent-Id header value
false
case _ =>
false
}
}
}

View File

@ -487,13 +487,7 @@ object NewStyle {
}
}
def hasEntitlement(bankId: String, userId: String, role: ApiRole, callContext: Option[CallContext] = None): Future[Box[Unit]] = {
ApiSession.hasConsent(callContext) match {
case true =>
// TODO Implement consent feature behaviour
hasEntitlement(UserHasMissingRoles)(bankId, userId, role)
case false =>
hasEntitlement(UserHasMissingRoles)(bankId, userId, role)
}
hasEntitlement(UserHasMissingRoles)(bankId, userId, role)
}
def hasAtLeastOneEntitlement(failMsg: String)(bankId: String, userId: String, role: List[ApiRole]): Future[Box[Unit]] = {

View File

@ -367,7 +367,7 @@ case class BankAccountEx(val bankAccount: BankAccount) extends MdcLoggable {
}
final def moderatedTransaction(transactionId: TransactionId, view: View, user: Box[User], callContext: Option[CallContext] = None) : Box[(ModeratedTransaction, Option[CallContext])] = {
if(APIUtil.hasAccess(view, user) || ApiSession.hasConsent(callContext))
if(APIUtil.hasAccess(view, user))
for{
(transaction, callContext)<-Connector.connector.vend.getTransaction(bankId, accountId, transactionId, callContext)
moderatedTransaction<- view.moderateTransaction(transaction)
@ -376,7 +376,7 @@ case class BankAccountEx(val bankAccount: BankAccount) extends MdcLoggable {
viewNotAllowed(view)
}
final def moderatedTransactionFuture(bankId: BankId, accountId: AccountId, transactionId: TransactionId, view: View, user: Box[User], callContext: Option[CallContext] = None) : Future[Box[(ModeratedTransaction, Option[CallContext])]] = {
if(APIUtil.hasAccess(view, user) || ApiSession.hasConsent(callContext))
if(APIUtil.hasAccess(view, user))
for{
(transaction, callContext)<-Connector.connector.vend.getTransactionFuture(bankId, accountId, transactionId, callContext) map {
x => (unboxFullOrFail(x._1, callContext, ConnectorEmptyResponse, 400), x._2)
@ -397,7 +397,7 @@ case class BankAccountEx(val bankAccount: BankAccount) extends MdcLoggable {
// TODO We should extract params (and their defaults) prior to this call, so this whole function can be cached.
final def getModeratedTransactions(user : Box[User], view : View, callContext: Option[CallContext], queryParams: OBPQueryParam* ): Box[(List[ModeratedTransaction],Option[CallContext])] = {
if(APIUtil.hasAccess(view, user) || ApiSession.hasConsent(callContext)) {
if(APIUtil.hasAccess(view, user)) {
for {
(transactions, callContext) <- Connector.connector.vend.getTransactions(bankId, accountId, callContext, queryParams: _*)
moderated <- view.moderateTransactionsWithSameAccount(transactions) ?~! "Server error"
@ -406,7 +406,7 @@ case class BankAccountEx(val bankAccount: BankAccount) extends MdcLoggable {
else viewNotAllowed(view)
}
final def getModeratedTransactionsFuture(user : Box[User], view : View, callContext: Option[CallContext], queryParams: OBPQueryParam* ): Future[Box[(List[ModeratedTransaction],Option[CallContext])]] = {
if(APIUtil.hasAccess(view, user) || ApiSession.hasConsent(callContext)) {
if(APIUtil.hasAccess(view, user)) {
for {
(transactions, callContext) <- Connector.connector.vend.getTransactionsFuture(bankId, accountId, callContext, queryParams: _*) map {
x => (unboxFullOrFail(x._1, callContext, ConnectorEmptyResponse, 400), x._2)
@ -423,7 +423,7 @@ case class BankAccountEx(val bankAccount: BankAccount) extends MdcLoggable {
// TODO We should extract params (and their defaults) prior to this call, so this whole function can be cached.
final def getModeratedTransactionsCore(user : Box[User], view : View, callContext: Option[CallContext], queryParams: OBPQueryParam* ): Box[(List[ModeratedTransactionCore], Option[CallContext])] = {
if(APIUtil.hasAccess(view, user) || ApiSession.hasConsent(callContext)) {
if(APIUtil.hasAccess(view, user)) {
for {
(transactions, callContext) <- Connector.connector.vend.getTransactionsCore(bankId, accountId, callContext, queryParams: _*) ?~! InvalidConnectorResponseForGetTransactions
moderated <- view.moderateTransactionsWithSameAccountCore(transactions) ?~! UnknownError
@ -433,7 +433,7 @@ case class BankAccountEx(val bankAccount: BankAccount) extends MdcLoggable {
}
final def moderatedBankAccount(view: View, user: Box[User], callContext: Option[CallContext]) : Box[ModeratedBankAccount] = {
if(APIUtil.hasAccess(view, user) || ApiSession.hasConsent(callContext))
if(APIUtil.hasAccess(view, user))
//implicit conversion from option to box
view.moderateAccount(bankAccount)
else
@ -468,7 +468,7 @@ case class BankAccountEx(val bankAccount: BankAccount) extends MdcLoggable {
* account that have at least one transaction in common with this bank account
*/
final def moderatedOtherBankAccount(counterpartyID : String, view : View, user : Box[User], callContext: Option[CallContext]) : Box[ModeratedOtherBankAccount] =
if(APIUtil.hasAccess(view, user) || ApiSession.hasConsent(callContext))
if(APIUtil.hasAccess(view, user))
Connector.connector.vend.getCounterpartyByCounterpartyId(CounterpartyId(counterpartyID), None).map(_._1).flatMap(BankAccount.toInternalCounterparty).flatMap(view.moderateOtherAccount) match {
//First check the explict counterparty
case Full(moderatedOtherBankAccount) => Full(moderatedOtherBankAccount)