From 030a257efa89f5fc473549dc17657160fda0b26b Mon Sep 17 00:00:00 2001 From: bvoiturier Date: Tue, 20 Dec 2022 22:08:09 +0100 Subject: [PATCH] feat(prism-agent): add 'GET /present-proof/presentations/{id}' endpoint (#282) --- .../api/http/prism-agent-openapi-spec.yaml | 25 ++++++++++++ .../PresentProofApiMarshallerImpl.scala | 3 ++ .../http/model/OASDomainModelHelper.scala | 24 ++++++++++++ .../service/PresentProofApiServiceImpl.scala | 38 ++++++++++--------- 4 files changed, 72 insertions(+), 18 deletions(-) diff --git a/prism-agent/service/api/http/prism-agent-openapi-spec.yaml b/prism-agent/service/api/http/prism-agent-openapi-spec.yaml index c967857724..3a45ab5aa9 100644 --- a/prism-agent/service/api/http/prism-agent-openapi-spec.yaml +++ b/prism-agent/service/api/http/prism-agent-openapi-spec.yaml @@ -794,6 +794,31 @@ paths: application/json: schema: $ref: "./castor/schemas.yaml#/components/schemas/ErrorResponse" + get: + tags: [ "Present Proof" ] + operationId: getPresentation + parameters: + - in: path + name: id + schema: + type: string + required: true + description: Unique identifier of the presentation + example: "06e126d1-fa44-4882-a243-1e326fbe21db" + summary: Returns an existing presentation record by id. + responses: + "200": + description: Presentation state record + content: + application/json: + schema: + $ref: "./pollux/schemas.yaml#/components/schemas/PresentationStatus" + "404": + description: There is no presentation record matching the given 'id'. + content: + application/json: + schema: + $ref: "./castor/schemas.yaml#/components/schemas/ErrorResponse" # ---------------------------------- # Connect diff --git a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/http/marshaller/PresentProofApiMarshallerImpl.scala b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/http/marshaller/PresentProofApiMarshallerImpl.scala index 9171bc15f5..5eaedbe4fb 100644 --- a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/http/marshaller/PresentProofApiMarshallerImpl.scala +++ b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/http/marshaller/PresentProofApiMarshallerImpl.scala @@ -15,6 +15,9 @@ object PresentProofApiMarshallerImpl extends JsonSupport { implicit def fromEntityUnmarshallerRequestPresentationInput: FromEntityUnmarshaller[RequestPresentationInput] = summon[RootJsonFormat[RequestPresentationInput]] + implicit def toEntityMarshallerPresentationStatus: ToEntityMarshaller[PresentationStatus] = + summon[RootJsonFormat[PresentationStatus]] + implicit def toEntityMarshallerPresentationStatusarray: ToEntityMarshaller[Seq[PresentationStatus]] = summon[RootJsonFormat[Seq[PresentationStatus]]] implicit def toEntityMarshallerRequestPresentationOutput: ToEntityMarshaller[RequestPresentationOutput] = diff --git a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/http/model/OASDomainModelHelper.scala b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/http/model/OASDomainModelHelper.scala index d2986f72ae..3f5b679aeb 100644 --- a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/http/model/OASDomainModelHelper.scala +++ b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/http/model/OASDomainModelHelper.scala @@ -38,6 +38,7 @@ import io.iohk.atala.castor.core.model.did.{LongFormPrismDID, PrismDID} import java.util.UUID import io.iohk.atala.connect.core.model.ConnectionRecord.Role +import io.iohk.atala.agent.openapi.model.PresentationStatus trait OASDomainModelHelper { @@ -145,6 +146,29 @@ trait OASDomainModelHelper { ) } + extension (domain: polluxdomain.PresentationRecord) { + def toOAS: PresentationStatus = { + val connectionId = domain.connectionId + val data = domain.presentationData match + case Some(p) => + p.attachments.head.data match { + case Base64(data) => + val base64Decoded = new String(java.util.Base64.getDecoder().decode(data)).drop(1).dropRight(1) + println(s"Base64decode:\n\n ${base64Decoded} \n\n") + Seq(base64Decoded) + case any => ??? + } + case None => Seq.empty + PresentationStatus( + presentationId = domain.id.toString, + status = domain.protocolState.toString, + proofs = Seq.empty, + data = data, + connectionId = connectionId + ) + } + } + extension (str: String) { def toUUID: ZIO[Any, InvalidPayload, UUID] = ZIO diff --git a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/http/service/PresentProofApiServiceImpl.scala b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/http/service/PresentProofApiServiceImpl.scala index 12def6a8bc..92701f72d8 100644 --- a/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/http/service/PresentProofApiServiceImpl.scala +++ b/prism-agent/service/server/src/main/scala/io/iohk/atala/agent/server/http/service/PresentProofApiServiceImpl.scala @@ -85,25 +85,9 @@ class PresentProofApiServiceImpl( records <- presentationService .getPresentationRecords() .mapError(HttpServiceError.DomainError[PresentationError].apply) + } yield records - presentationStatus = records.map { record => - val connectionId = record.connectionId - val data = record.presentationData match - case Some(p) => - p.attachments.head.data match { - case Base64(data) => - val base64Decoded = new String(java.util.Base64.getDecoder().decode(data)).drop(1).dropRight(1) - println(s"Base64decode:\n\n ${base64Decoded} \n\n") - Seq(base64Decoded) - case any => ??? - } - case None => Seq.empty - - PresentationStatus(record.id.toString, record.protocolState.toString, Seq.empty, data, connectionId) - } - } yield presentationStatus - - onZioSuccess(result.mapError(_.toOAS).either) { + onZioSuccess(result.mapBoth(_.toOAS, _.map(_.toOAS)).either) { case Left(error) => complete(error.status -> error) case Right(results) => { @@ -112,6 +96,24 @@ class PresentProofApiServiceImpl( } } + def getPresentation(id: String)(implicit + toEntityMarshallerPresentationStatus: ToEntityMarshaller[PresentationStatus], + toEntityMarshallerErrorResponse: ToEntityMarshaller[ErrorResponse] + ): Route = { + val result = for { + presentationId <- id.toUUID + outcome <- presentationService + .getPresentationRecord(presentationId) + .mapError(HttpServiceError.DomainError[PresentationError].apply) + } yield outcome + + onZioSuccess(result.mapBoth(_.toOAS, _.map(_.toOAS)).either) { + case Left(error) => complete(error.status -> error) + case Right(Some(result)) => getPresentation200(result) + case Right(None) => getPresentation404(notFoundErrorResponse(Some("Presentation record not found"))) + } + } + override def updatePresentation(id: String, requestPresentationAction: RequestPresentationAction)(implicit toEntityMarshallerErrorResponse: ToEntityMarshaller[ErrorResponse] ): Route = {