-
Notifications
You must be signed in to change notification settings - Fork 26
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
feat: add presentation-exchange endpoints (#1365)
Signed-off-by: Pat Losoponkul <pat.losoponkul@iohk.io>
- Loading branch information
patlo-iog
authored
Sep 19, 2024
1 parent
c18385c
commit 49f7ab3
Showing
61 changed files
with
614 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
3 changes: 1 addition & 2 deletions
3
castor/src/main/scala/org/hyperledger/identus/castor/core/model/did/PublicKey.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
File renamed without changes.
3 changes: 1 addition & 2 deletions
3
...er/src/main/scala/org/hyperledger/identus/didcomm/controller/DIDCommControllerError.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
97 changes: 97 additions & 0 deletions
97
...er/src/main/scala/org/hyperledger/identus/pollux/prex/PresentationExchangeEndpoints.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
package org.hyperledger.identus.pollux.prex | ||
|
||
import org.hyperledger.identus.api.http.{EndpointOutputs, ErrorResponse, RequestContext} | ||
import org.hyperledger.identus.api.http.model.PaginationInput | ||
import org.hyperledger.identus.iam.authentication.apikey.ApiKeyCredentials | ||
import org.hyperledger.identus.iam.authentication.apikey.ApiKeyEndpointSecurityLogic.apiKeyHeader | ||
import org.hyperledger.identus.iam.authentication.oidc.JwtCredentials | ||
import org.hyperledger.identus.iam.authentication.oidc.JwtSecurityLogic.jwtAuthHeader | ||
import org.hyperledger.identus.pollux.prex.http.{CreatePresentationDefinition, PresentationDefinitionPage} | ||
import org.hyperledger.identus.pollux.prex.http.PresentationExchangeTapirSchemas.given | ||
import sttp.apispec.Tag | ||
import sttp.model.StatusCode | ||
import sttp.tapir.* | ||
import sttp.tapir.json.zio.jsonBody | ||
|
||
import java.util.UUID | ||
|
||
object PresentationExchangeEndpoints { | ||
|
||
private val tagName = "Presentation Exchange" | ||
private val tagDescription = | ||
s""" | ||
|The __${tagName}__ endpoints offers a way to manage resources related to [presentation exchange protocol](https://identity.foundation/presentation-exchange/spec/v2.1.1/). | ||
| | ||
|The verifier can create the resources such as `presentation-definition` that can be publicly referenced | ||
|in various protocols such as [OpenID for Verificable Presentation](https://openid.net/specs/openid-4-verifiable-presentations-1_0.html). | ||
|""".stripMargin | ||
|
||
val tag = Tag(tagName, Some(tagDescription)) | ||
|
||
private val paginationInput: EndpointInput[PaginationInput] = EndpointInput.derived[PaginationInput] | ||
|
||
private val baseEndpoint = endpoint | ||
.tag(tagName) | ||
.in("presentation-exchange") | ||
.in(extractFromRequest[RequestContext](RequestContext.apply)) | ||
|
||
private val basePrivateEndpoint = baseEndpoint | ||
.securityIn(apiKeyHeader) | ||
.securityIn(jwtAuthHeader) | ||
|
||
val getPresentationDefinition: Endpoint[ | ||
Unit, | ||
(RequestContext, UUID), | ||
ErrorResponse, | ||
PresentationDefinition, | ||
Any | ||
] = | ||
baseEndpoint.get | ||
.in("presentation-definitions" / path[UUID]("id")) | ||
.out(statusCode(StatusCode.Ok).description("Presentation Definition retrieved successfully")) | ||
.out(jsonBody[PresentationDefinition]) | ||
.errorOut(EndpointOutputs.basicFailuresAndNotFound) | ||
.name("getPresentationDefinition") | ||
.summary("Get a presentation-definition") | ||
|
||
val listPresentationDefinition: Endpoint[ | ||
(ApiKeyCredentials, JwtCredentials), | ||
(RequestContext, PaginationInput), | ||
ErrorResponse, | ||
PresentationDefinitionPage, | ||
Any, | ||
] = | ||
basePrivateEndpoint.get | ||
.in("presentation-definitions") | ||
.in(paginationInput) | ||
.out(statusCode(StatusCode.Ok).description("Presentation Definitions retrieved successfully")) | ||
.out(jsonBody[PresentationDefinitionPage]) | ||
.errorOut(EndpointOutputs.basicFailuresAndForbidden) | ||
.name("listPresentationDefinition") | ||
.summary("List all presentation-definitions") | ||
.description( | ||
"""List all `presentation-definitions` in the wallet. | ||
|Return a paginated items ordered by created timestamp.""".stripMargin | ||
) | ||
|
||
val createPresentationDefinition: Endpoint[ | ||
(ApiKeyCredentials, JwtCredentials), | ||
(RequestContext, CreatePresentationDefinition), | ||
ErrorResponse, | ||
PresentationDefinition, | ||
Any | ||
] = | ||
basePrivateEndpoint.post | ||
.in("presentation-definitions") | ||
.in(jsonBody[CreatePresentationDefinition]) | ||
.out(statusCode(StatusCode.Created).description("Presentation Definition created successfully")) | ||
.out(jsonBody[PresentationDefinition]) | ||
.errorOut(EndpointOutputs.basicFailureAndNotFoundAndForbidden) | ||
.name("createPresentationDefinition") | ||
.summary("Create a new presentation-definition") | ||
.description( | ||
"""Create a `presentation-definition` object according to the [presentation exchange protocol](https://identity.foundation/presentation-exchange/spec/v2.1.1/). | ||
|The `POST` endpoint is restricted to the owner of the wallet. The `presentation-definition` object, however can be referenced by publicly by `id` returned in the response.""".stripMargin | ||
) | ||
|
||
} |
61 changes: 61 additions & 0 deletions
61
.../main/scala/org/hyperledger/identus/pollux/prex/PresentationExchangeServerEndpoints.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
package org.hyperledger.identus.pollux.prex | ||
|
||
import org.hyperledger.identus.agent.walletapi.model.BaseEntity | ||
import org.hyperledger.identus.iam.authentication.{Authenticator, Authorizer, DefaultAuthenticator, SecurityLogic} | ||
import org.hyperledger.identus.pollux.prex.controller.PresentationExchangeController | ||
import org.hyperledger.identus.LogUtils.* | ||
import sttp.tapir.ztapir.* | ||
import zio.* | ||
|
||
class PresentationExchangeServerEndpoints( | ||
controller: PresentationExchangeController, | ||
authenticator: Authenticator[BaseEntity], | ||
authorizer: Authorizer[BaseEntity] | ||
) { | ||
|
||
private val getPresentationDefinitionServerEndpoint: ZServerEndpoint[Any, Any] = | ||
PresentationExchangeEndpoints.getPresentationDefinition | ||
.zServerLogic { case (rc, id) => | ||
controller.getPresentationDefinition(id).logTrace(rc) | ||
} | ||
|
||
private val listPresentationDefinitionServerEndpoint: ZServerEndpoint[Any, Any] = | ||
PresentationExchangeEndpoints.listPresentationDefinition | ||
.zServerSecurityLogic(SecurityLogic.authorizeWalletAccessWith(_)(authenticator, authorizer)) | ||
.serverLogic { wac => | ||
{ case (rc, pagination) => | ||
controller | ||
.listPresentationDefinition(pagination)(rc) | ||
.provideSomeLayer(ZLayer.succeed(wac)) | ||
.logTrace(rc) | ||
} | ||
} | ||
|
||
private val createPresentationDefinitionServerEndpoint: ZServerEndpoint[Any, Any] = | ||
PresentationExchangeEndpoints.createPresentationDefinition | ||
.zServerSecurityLogic(SecurityLogic.authorizeWalletAccessWith(_)(authenticator, authorizer)) | ||
.serverLogic { wac => | ||
{ case (rc, pd) => | ||
controller | ||
.createPresentationDefinition(pd) | ||
.provideSomeLayer(ZLayer.succeed(wac)) | ||
.logTrace(rc) | ||
} | ||
} | ||
|
||
val all: List[ZServerEndpoint[Any, Any]] = List( | ||
getPresentationDefinitionServerEndpoint, | ||
listPresentationDefinitionServerEndpoint, | ||
createPresentationDefinitionServerEndpoint | ||
) | ||
} | ||
|
||
object PresentationExchangeServerEndpoints { | ||
def all: URIO[DefaultAuthenticator & PresentationExchangeController, List[ZServerEndpoint[Any, Any]]] = { | ||
for { | ||
controller <- ZIO.service[PresentationExchangeController] | ||
authenticator <- ZIO.service[DefaultAuthenticator] | ||
endpoints = PresentationExchangeServerEndpoints(controller, authenticator, authenticator) | ||
} yield endpoints.all | ||
} | ||
} |
62 changes: 62 additions & 0 deletions
62
...scala/org/hyperledger/identus/pollux/prex/controller/PresentationExchangeController.scala
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,62 @@ | ||
package org.hyperledger.identus.pollux.prex.controller | ||
|
||
import org.hyperledger.identus.api.http.{ErrorResponse, RequestContext} | ||
import org.hyperledger.identus.api.http.model.{CollectionStats, PaginationInput} | ||
import org.hyperledger.identus.api.util.PaginationUtils | ||
import org.hyperledger.identus.pollux.core.service.PresentationExchangeService | ||
import org.hyperledger.identus.pollux.prex.http.{CreatePresentationDefinition, PresentationDefinitionPage} | ||
import org.hyperledger.identus.pollux.prex.PresentationDefinition | ||
import org.hyperledger.identus.shared.models.WalletAccessContext | ||
import zio.* | ||
|
||
import java.util.UUID | ||
import scala.language.implicitConversions | ||
|
||
trait PresentationExchangeController { | ||
def createPresentationDefinition( | ||
cpd: CreatePresentationDefinition | ||
): ZIO[WalletAccessContext, ErrorResponse, PresentationDefinition] | ||
|
||
def getPresentationDefinition(id: UUID): IO[ErrorResponse, PresentationDefinition] | ||
|
||
def listPresentationDefinition(paginationInput: PaginationInput)(implicit | ||
rc: RequestContext | ||
): ZIO[WalletAccessContext, ErrorResponse, PresentationDefinitionPage] | ||
} | ||
|
||
class PresentationExchangeControllerImpl(service: PresentationExchangeService) extends PresentationExchangeController { | ||
|
||
override def createPresentationDefinition( | ||
cpd: CreatePresentationDefinition | ||
): ZIO[WalletAccessContext, ErrorResponse, PresentationDefinition] = { | ||
val pd: PresentationDefinition = cpd | ||
service.createPresentationDefinititon(pd).as(pd) | ||
} | ||
|
||
override def getPresentationDefinition(id: UUID): IO[ErrorResponse, PresentationDefinition] = | ||
service.getPresentationDefinition(id) | ||
|
||
override def listPresentationDefinition( | ||
paginationInput: PaginationInput | ||
)(implicit rc: RequestContext): ZIO[WalletAccessContext, ErrorResponse, PresentationDefinitionPage] = { | ||
val uri = rc.request.uri | ||
val pagination = paginationInput.toPagination | ||
for { | ||
pageResult <- service.listPresentationDefinition(offset = paginationInput.offset, limit = paginationInput.limit) | ||
(items, totalCount) = pageResult | ||
stats = CollectionStats(totalCount = totalCount, filteredCount = totalCount) | ||
} yield PresentationDefinitionPage( | ||
self = uri.toString(), | ||
pageOf = PaginationUtils.composePageOfUri(uri).toString, | ||
next = PaginationUtils.composeNextUri(uri, items, pagination, stats).map(_.toString), | ||
previous = PaginationUtils.composePreviousUri(uri, items, pagination, stats).map(_.toString), | ||
contents = items, | ||
) | ||
} | ||
|
||
} | ||
|
||
object PresentationExchangeControllerImpl { | ||
def layer: URLayer[PresentationExchangeService, PresentationExchangeController] = | ||
ZLayer.fromFunction(PresentationExchangeControllerImpl(_)) | ||
} |
Oops, something went wrong.