feature/Add connector method getChallengesByConsentId

This commit is contained in:
Marko Milić 2020-12-03 20:33:09 +01:00
parent b8006c1ca4
commit d25074acc3
13 changed files with 216 additions and 20 deletions

View File

@ -19,6 +19,7 @@ import code.views.Views
import com.github.dwickern.macros.NameOf.nameOf
import com.openbankproject.commons.ExecutionContext.Implicits.global
import com.openbankproject.commons.model._
import com.openbankproject.commons.model.enums.StrongCustomerAuthenticationStatus.SCAStatus
import com.openbankproject.commons.model.enums.{ChallengeType, StrongCustomerAuthentication, StrongCustomerAuthenticationStatus}
import net.liftweb.common.Full
import net.liftweb.http.js.JE.JsRaw
@ -640,16 +641,14 @@ This function returns an array of hyperlinks to all generated authorisation sub-
)
lazy val getConsentAuthorisation : OBPEndpoint = {
case "consents" :: consentId:: "authorisations" :: Nil JsonGet _ => {
case "consents" :: consentId :: "authorisations" :: Nil JsonGet _ => {
cc =>
for {
(_, callContext) <- authenticatedAccess(cc)
_ <- passesPsd2Aisp(callContext)
authorisations <- Future(Authorisations.authorisationProvider.vend.getAuthorizationByConsentId(consentId)) map {
unboxFullOrFail(_, callContext, s"$UnknownError ")
}
(challenges, callContext) <- NewStyle.function.getChallengesByConsentId(consentId, callContext)
} yield {
(JSONFactory_BERLIN_GROUP_1_3.AuthorisationJsonV13(authorisations.map(_.authorisationId)), HttpCode.`200`(callContext))
(JSONFactory_BERLIN_GROUP_1_3.AuthorisationJsonV13(challenges.map(_.challengeId)), HttpCode.`200`(callContext))
}
}
}
@ -751,13 +750,11 @@ This method returns the SCA status of a consent initiation's authorisation sub-r
_ <- Future(Consents.consentProvider.vend.getConsentByConsentId(consentId)) map {
unboxFullOrFail(_, callContext, s"$ConsentNotFound ($consentId)")
}
authorisation <- Future(Authorisations.authorisationProvider.vend.getAuthorizationByAuthorizationId(
authorisationId
)) map {
unboxFullOrFail(_, callContext, s"$AuthorisationNotFound Current AUTHORISATION_ID($authorisationId)")
}
(challenges, callContext) <- NewStyle.function.getChallengesByConsentId(consentId, callContext)
} yield {
(JSONFactory_BERLIN_GROUP_1_3.ScaStatusJsonV13(authorisation.scaStatus), HttpCode.`200`(callContext))
val challengeStatus = challenges.filter(_.challengeId == authorisationId)
.flatMap(_.scaStatus).headOption.map(_.toString).getOrElse("None")
(JSONFactory_BERLIN_GROUP_1_3.ScaStatusJsonV13(challengeStatus), HttpCode.`200`(callContext))
}
}
}

View File

@ -1016,6 +1016,17 @@ object NewStyle {
) map { i =>
(unboxFullOrFail(i._1, callContext, s"$InvalidChallengeTransactionRequestId Current transactionRequestId($transactionRequestId) ", 400), i._2)
}
}
def getChallengesByConsentId(
consentId: String,
callContext: Option[CallContext]
): OBPReturnType[List[ChallengeTrait]] = {
Connector.connector.vend.getChallengesByConsentId(
consentId: String,
callContext: Option[CallContext]
) map { i =>
(unboxFullOrFail(i._1, callContext, s"$InvalidChallengeTransactionRequestId Current transactionRequestId($consentId) ", 400), i._2)
}
}
def getChallenge(

View File

@ -408,6 +408,8 @@ trait Connector extends MdcLoggable {
def getChallengesByTransactionRequestId(transactionRequestId: String, callContext: Option[CallContext]): OBPReturnType[Box[List[ChallengeTrait]]] = Future{(Failure(setUnimplementedError), callContext)}
def getChallengesByConsentId(consentId: String, callContext: Option[CallContext]): OBPReturnType[Box[List[ChallengeTrait]]] = Future{(Failure(setUnimplementedError), callContext)}
def getChallenge(challengeId: String, callContext: Option[CallContext]): OBPReturnType[Box[ChallengeTrait]] = Future{(Failure(setUnimplementedError), callContext)}
//gets a particular bank handled by this connector

View File

@ -365,6 +365,7 @@ object ConnectorBuilderUtil {
"createChallengesC2",
"getChallenge",
"getChallengesByTransactionRequestId",
"getChallengesByConsentId",
"validateAndCheckIbanNumber",
"validateChallengeAnswerC2",
"getCounterpartyByIbanAndBankAccountId",

View File

@ -338,7 +338,10 @@ object LocalMappedConnector extends Connector with MdcLoggable {
}
override def getChallengesByTransactionRequestId(transactionRequestId: String, callContext: Option[CallContext]): OBPReturnType[Box[List[ChallengeTrait]]] =
Future {(Challenges.ChallengeProvider.vend.getChallengesByTransactionRequestId(transactionRequestId), callContext)}
Future {(Challenges.ChallengeProvider.vend.getChallengesByTransactionRequestId(transactionRequestId), callContext)}
override def getChallengesByConsentId(consentId: String, callContext: Option[CallContext]): OBPReturnType[Box[List[ChallengeTrait]]] =
Future {(Challenges.ChallengeProvider.vend.getChallengesByConsentId(consentId), callContext)}
override def getChallenge(challengeId: String, callContext: Option[CallContext]): OBPReturnType[Box[ChallengeTrait]] =

View File

@ -1,4 +1,4 @@
-- auto generated MS sql server procedures script, create on 2020-11-25T09:01:54Z
-- auto generated MS sql server procedures script, create on 2020-12-03T14:42:37Z
-- drop procedure obp_get_adapter_info
DROP PROCEDURE IF EXISTS obp_get_adapter_info;
@ -1416,6 +1416,134 @@ GO
-- drop procedure obp_get_challenges_by_consent_id
DROP PROCEDURE IF EXISTS obp_get_challenges_by_consent_id;
GO
-- create procedure obp_get_challenges_by_consent_id
CREATE PROCEDURE obp_get_challenges_by_consent_id
@outbound_json NVARCHAR(MAX),
@inbound_json NVARCHAR(MAX) OUT
AS
SET nocount on
-- replace the follow example to real logic
/*
this is example of parameter @outbound_json
N'{
"outboundAdapterCallContext":{
"correlationId":"1flssoftxq0cr1nssr68u0mioj",
"sessionId":"b4e0352a-9a0f-4bfa-b30b-9003aa467f50",
"consumerId":"7uy8a7e4-6d02-40e3-a129-0b2bf89de8uh",
"generalContext":[
{
"key":"CustomerNumber",
"value":"5987953"
}
],
"outboundAdapterAuthInfo":{
"userId":"9ca9a7e4-6d02-40e3-a129-0b2bf89de9b1",
"username":"felixsmith",
"linkedCustomers":[
{
"customerId":"7uy8a7e4-6d02-40e3-a129-0b2bf89de8uh",
"customerNumber":"5987953",
"legalName":"Eveline Tripman"
}
],
"userAuthContext":[
{
"key":"CustomerNumber",
"value":"5987953"
}
],
"authViews":[
{
"view":{
"id":"owner",
"name":"Owner",
"description":"This view is for the owner for the account."
},
"account":{
"id":"8ca8a7e4-6d02-40e3-a129-0b2bf89de9f0",
"accountRoutings":[
{
"scheme":"IBAN",
"address":"DE91 1000 0000 0123 4567 89"
}
],
"customerOwners":[
{
"bankId":"gh.29.uk",
"customerId":"7uy8a7e4-6d02-40e3-a129-0b2bf89de8uh",
"customerNumber":"5987953",
"legalName":"Eveline Tripman",
"dateOfBirth":"2018-03-09T00:00:00Z"
}
],
"userOwners":[
{
"userId":"9ca9a7e4-6d02-40e3-a129-0b2bf89de9b1",
"emailAddress":"felixsmith@example.com",
"name":"felixsmith"
}
]
}
}
]
}
},
"consentId":"no-example-provided"
}'
*/
-- return example value
SELECT @inbound_json = (
SELECT
N'{
"inboundAdapterCallContext":{
"correlationId":"1flssoftxq0cr1nssr68u0mioj",
"sessionId":"b4e0352a-9a0f-4bfa-b30b-9003aa467f50",
"generalContext":[
{
"key":"CustomerNumber",
"value":"5987953"
}
]
},
"status":{
"errorCode":"",
"backendMessages":[
{
"source":"String",
"status":"String",
"errorCode":"",
"text":"String"
}
]
},
"data":[
{
"challengeId":"123chaneid13-6d02-40e3-a129-0b2bf89de9f0",
"transactionRequestId":"8138a7e4-6d02-40e3-a129-0b2bf89de9f1",
"expectedAnswer":"string",
"expectedUserId":"string",
"salt":"string",
"successful":true,
"challengeType":"no-example-provided",
"consentId":"no-example-provided",
"scaMethod":"SMS",
"scaStatus":"received",
"authenticationMethodId":"string"
}
]
}'
);
GO
-- drop procedure obp_get_challenge
DROP PROCEDURE IF EXISTS obp_get_challenge;
GO

View File

@ -75,7 +75,7 @@ trait StoredProcedureConnector_vDec2019 extends Connector with MdcLoggable {
val connectorName = "stored_procedure_vDec2019"
//---------------- dynamic start -------------------please don't modify this line
// ---------- created on 2020-11-25T10:01:38Z
// ---------- created on 2020-12-03T15:42:13Z
messageDocs += getAdapterInfoDoc
def getAdapterInfoDoc = MessageDoc(
@ -461,6 +461,42 @@ trait StoredProcedureConnector_vDec2019 extends Connector with MdcLoggable {
response.map(convertToTuple[List[ChallengeCommons]](callContext))
}
messageDocs += getChallengesByConsentIdDoc
def getChallengesByConsentIdDoc = MessageDoc(
process = "obp.getChallengesByConsentId",
messageFormat = messageFormat,
description = "Get Challenges By Consent Id",
outboundTopic = None,
inboundTopic = None,
exampleOutboundMessage = (
OutBoundGetChallengesByConsentId(outboundAdapterCallContext=MessageDocsSwaggerDefinitions.outboundAdapterCallContext,
consentId=consentIdExample.value)
),
exampleInboundMessage = (
InBoundGetChallengesByConsentId(inboundAdapterCallContext=MessageDocsSwaggerDefinitions.inboundAdapterCallContext,
status=MessageDocsSwaggerDefinitions.inboundStatus,
data=List( ChallengeCommons(challengeId=challengeIdExample.value,
transactionRequestId=transactionRequestIdExample.value,
expectedAnswer="string",
expectedUserId="string",
salt="string",
successful=true,
challengeType=challengeTypeExample.value,
consentId=Some(consentIdExample.value),
scaMethod=Some(com.openbankproject.commons.model.enums.StrongCustomerAuthentication.SMS),
scaStatus=Some(com.openbankproject.commons.model.enums.StrongCustomerAuthenticationStatus.example),
authenticationMethodId=Some("string"))))
),
adapterImplementation = Some(AdapterImplementation("- Core", 1))
)
override def getChallengesByConsentId(consentId: String, callContext: Option[CallContext]): OBPReturnType[Box[List[ChallengeTrait]]] = {
import com.openbankproject.commons.dto.{InBoundGetChallengesByConsentId => InBound, OutBoundGetChallengesByConsentId => OutBound}
val req = OutBound(callContext.map(_.toOutboundAdapterCallContext).orNull, consentId)
val response: Future[Box[InBound]] = sendRequest[InBound]("obp_get_challenges_by_consent_id", req, callContext)
response.map(convertToTuple[List[ChallengeCommons]](callContext))
}
messageDocs += getChallengeDoc
def getChallengeDoc = MessageDoc(
process = "obp.getChallenge",
@ -6234,8 +6270,8 @@ trait StoredProcedureConnector_vDec2019 extends Connector with MdcLoggable {
response.map(convertToTuple[Boolean](callContext))
}
// ---------- created on 2020-11-25T10:01:38Z
//---------------- dynamic end ---------------------please don't modify this line
// ---------- created on 2020-12-03T15:42:13Z
//---------------- dynamic end ---------------------please don't modify this line
private val availableOperation = DynamicEntityOperation.values.map(it => s""""$it"""").mkString("[", ", ", "]")

View File

@ -39,4 +39,9 @@ object RemotedataChallenges extends ObpActorInit with ChallengeProvider {
override def getChallengesByTransactionRequestId(transactionRequestId: String): Box[List[ChallengeTrait]] = getValueFromFuture(
(actor ? cc.getChallengesByTransactionRequestId(transactionRequestId)).mapTo[Box[List[ChallengeTrait]]]
)
override def getChallengesByConsentId(consentId: String): Box[List[ChallengeTrait]] = getValueFromFuture(
(actor ? cc.getChallengesByConsentId(consentId)).mapTo[Box[List[ChallengeTrait]]]
)
}

View File

@ -30,6 +30,10 @@ class RemotedataChallengesActor extends Actor with ObpActorHelper with MdcLoggab
case cc.validateChallenge(challengeId: String, challengeAnswer: String, userId: Option[String])=>
logger.debug(s"validateChallenge($challengeId, $challengeAnswer, $userId)")
sender ! (mapper.validateChallenge(challengeId, challengeAnswer, userId))
case cc.getChallengesByConsentId(consentId: String)=>
logger.debug(s"validateChallenge($consentId)")
sender ! (mapper.getChallengesByConsentId(consentId))
case message => logger.warn("[AKKA ACTOR ERROR - REQUEST NOT RECOGNIZED] " + message)

View File

@ -24,6 +24,8 @@ trait ChallengeProvider {
def getChallengesByTransactionRequestId(transactionRequestId: String): Box[List[ChallengeTrait]]
def getChallengesByConsentId(consentId: String): Box[List[ChallengeTrait]]
/**
* There is another method: Connector.validateChallengeAnswer, it validate the challenge over Kafka.
* This method, will validate the answer in OBP side.
@ -47,6 +49,7 @@ class RemotedataChallengeProviderCaseClasses {
)
case class getChallenge(challengeId: String)
case class getChallengesByTransactionRequestId(transactionRequestId: String)
case class getChallengesByConsentId(consentId: String)
case class validateChallenge(challengeId: String, challengeAnswer: String, userId: Option[String])
}

View File

@ -44,6 +44,9 @@ object MappedChallengeProvider extends ChallengeProvider {
override def getChallengesByTransactionRequestId(transactionRequestId: String): Box[List[ChallengeTrait]] =
Full(MappedExpectedChallengeAnswer.findAll(By(MappedExpectedChallengeAnswer.mTransactionRequestId,transactionRequestId)))
override def getChallengesByConsentId(consentId: String): Box[List[ChallengeTrait]] =
Full(MappedExpectedChallengeAnswer.findAll(By(MappedExpectedChallengeAnswer.mConsentId,consentId)))
override def validateChallenge(
challengeId: String,
challengeAnswer: String,

View File

@ -245,18 +245,18 @@ class AccountInformationServiceAISApiTest extends BerlinGroupServerSetupV1_3 wit
responseStartConsentAuthorisation.body.extract[StartConsentAuthorisationJson].scaStatus should be ("received")
Then(s"We test the $getConsentAuthorisation")
val requestGetConsentAuthorisation = (V1_3_BG / "consents"/consentId /"authorisations" ).POST <@ (user1)
val requestGetConsentAuthorisation = (V1_3_BG / "consents"/consentId /"authorisations" ).GET<@ (user1)
val responseGetConsentAuthorisation = makeGetRequest(requestGetConsentAuthorisation)
responseGetConsentAuthorisation.code should be (200)
responseGetConsentAuthorisation.body.extract[AuthorisationJsonV13].authorisationIds.length > 0 should be (true)
Then(s"We test the $getConsentScaStatus")
val authorisationId = responseGetConsentAuthorisation.body.extract[AuthorisationJsonV13].authorisationIds.head
val requestGetConsentScaStatus = (V1_3_BG / "consents"/consentId /"authorisations"/authorisationId ).POST <@ (user1)
val requestGetConsentScaStatus = (V1_3_BG / "consents"/consentId /"authorisations"/authorisationId ).GET <@ (user1)
val responseGetConsentScaStatus = makeGetRequest(requestGetConsentScaStatus)
responseGetConsentScaStatus.code should be (200)
responseGetConsentScaStatus.body.extract[ScaStatusJsonV13].scaStatus should be ("received")
/*
Then(s"We test the $updateConsentsPsuData")
val updateConsentsPsuDataJsonBody = APIMethods_AccountInformationServiceAISApi
.resourceDocs
@ -267,7 +267,7 @@ class AccountInformationServiceAISApiTest extends BerlinGroupServerSetupV1_3 wit
val responseUpdateConsentsPsuData = makePutRequest(requestUpdateConsentsPsuData, write(updateConsentsPsuDataJsonBody))
responseUpdateConsentsPsuData.code should be (200)
responseUpdateConsentsPsuData.body.extract[PostConsentResponseJson].consentStatus should be ("received")
*/
}
}

View File

@ -1350,6 +1350,9 @@ case class InBoundGetChallenge(inboundAdapterCallContext: InboundAdapterCallCont
case class OutBoundGetChallengesByTransactionRequestId(outboundAdapterCallContext: OutboundAdapterCallContext, transactionRequestId: String) extends TopicTrait
case class InBoundGetChallengesByTransactionRequestId(inboundAdapterCallContext: InboundAdapterCallContext, status: Status, data: List[ChallengeCommons]) extends InBoundTrait[List[ChallengeCommons]]
case class OutBoundGetChallengesByConsentId(outboundAdapterCallContext: OutboundAdapterCallContext, consentId: String) extends TopicTrait
case class InBoundGetChallengesByConsentId(inboundAdapterCallContext: InboundAdapterCallContext, status: Status, data: List[ChallengeCommons]) extends InBoundTrait[List[ChallengeCommons]]
case class OutBoundGetCounterpartyByIbanAndBankAccountId(outboundAdapterCallContext: OutboundAdapterCallContext, iban: String, bankId: BankId, accountId: AccountId) extends TopicTrait
case class InBoundGetCounterpartyByIbanAndBankAccountId(inboundAdapterCallContext: InboundAdapterCallContext, status: Status, data: CounterpartyTraitCommons) extends InBoundTrait[CounterpartyTraitCommons]