Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(pollux): update storage for static resources to be wrapped in an envelope #1283

Merged
Original file line number Diff line number Diff line change
Expand Up @@ -9,24 +9,15 @@ import org.hyperledger.identus.iam.authentication.apikey.ApiKeyEndpointSecurityL
import org.hyperledger.identus.iam.authentication.oidc.JwtCredentials
import org.hyperledger.identus.iam.authentication.oidc.JwtSecurityLogic.jwtAuthHeader
import org.hyperledger.identus.pollux.credentialschema.http.{
CredentialSchemaDidUrlResponse,
CredentialSchemaInput,
CredentialSchemaResponse,
CredentialSchemaResponsePage,
FilterInput
}
import sttp.apispec.{ExternalDocumentation, Tag}
import sttp.model.StatusCode
import sttp.tapir.{
endpoint,
extractFromRequest,
path,
query,
statusCode,
stringToPath,
Endpoint,
EndpointInput,
PublicEndpoint
}
import sttp.tapir.*
import sttp.tapir.json.zio.{jsonBody, schemaForZioJsonValue}
import zio.json.ast.Json

Expand Down Expand Up @@ -66,7 +57,42 @@ object SchemaRegistryEndpoints {

val tag = Tag(name = tagName, description = Option(tagDescription), externalDocs = Option(tagExternalDocumentation))

val createSchemaEndpoint: Endpoint[
val createSchemaDidUrlEndpoint: Endpoint[
(ApiKeyCredentials, JwtCredentials),
(RequestContext, CredentialSchemaInput),
ErrorResponse,
CredentialSchemaDidUrlResponse,
Any
] =
endpoint.post
.securityIn(apiKeyHeader)
.securityIn(jwtAuthHeader)
.in(extractFromRequest[RequestContext](RequestContext.apply))
.in("schema-registry" / "schemas" / "did-url")
.in(
jsonBody[CredentialSchemaInput]
.description(
"JSON object required for the credential schema creation"
)
)
.out(
statusCode(StatusCode.Created)
.description(
"The new credential schema record is successfully created"
)
)
.out(jsonBody[CredentialSchemaDidUrlResponse])
.description("Credential schema record")
.errorOut(basicFailureAndNotFoundAndForbidden)
.name("createSchema")
.summary("Publish new schema to the schema registry, did url resolvable")
.description(
"Create the new credential schema record with metadata and internal JSON Schema on behalf of Cloud Agent. " +
"The credential schema will be signed by the keys of Cloud Agent and issued by the DID that corresponds to it."
)
.tag(tagName)

val createSchemaHttpUrlEndpoint: Endpoint[
(ApiKeyCredentials, JwtCredentials),
(RequestContext, CredentialSchemaInput),
ErrorResponse,
Expand Down Expand Up @@ -94,7 +120,7 @@ object SchemaRegistryEndpoints {
.description("Credential schema record")
.errorOut(basicFailureAndNotFoundAndForbidden)
.name("createSchema")
.summary("Publish new schema to the schema registry")
.summary("Publish new schema to the schema registry, http url resolvable")
.description(
"Create the new credential schema record with metadata and internal JSON Schema on behalf of Cloud Agent. " +
"The credential schema will be signed by the keys of Cloud Agent and issued by the DID that corresponds to it."
Expand All @@ -103,19 +129,19 @@ object SchemaRegistryEndpoints {

val updateSchemaEndpoint: Endpoint[
(ApiKeyCredentials, JwtCredentials),
(RequestContext, String, UUID, CredentialSchemaInput),
(RequestContext, UUID, CredentialSchemaInput),
ErrorResponse,
CredentialSchemaResponse,
CredentialSchemaResponse | CredentialSchemaDidUrlResponse,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does it make sense to unpack the DIDURLResponse and use CredentialSchemaResponse everywhere?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why do you mean by unpack? I did not get it

Any
] =
endpoint.put
.securityIn(apiKeyHeader)
.securityIn(jwtAuthHeader)
.in(extractFromRequest[RequestContext](RequestContext.apply))
.in(
"schema-registry" /
path[String]("author").description(CredentialSchemaResponse.annotations.author.description) /
path[UUID]("id").description(CredentialSchemaResponse.annotations.id.description)
"schema-registry" / "schemas" / path[UUID]("id").description(
CredentialSchemaResponse.annotations.id.description
)
)
.in(
jsonBody[CredentialSchemaInput]
Expand All @@ -129,7 +155,18 @@ object SchemaRegistryEndpoints {
"The credential schema record is successfully updated"
)
)
.out(jsonBody[CredentialSchemaResponse])
.out(
oneOf[CredentialSchemaResponse | CredentialSchemaDidUrlResponse](
oneOfVariant(
jsonBody[CredentialSchemaResponse].description("CredentialSchema found by `guid`, resolvable by HTTP URL")
),
oneOfVariant(
jsonBody[CredentialSchemaDidUrlResponse].description(
"CredentialSchema found by `guid`, resolvable by DID URL"
)
)
)
)
.description("Credential schema record")
.errorOut(basicFailureAndNotFoundAndForbidden)
.name("updateSchema")
Expand All @@ -143,7 +180,7 @@ object SchemaRegistryEndpoints {
val getSchemaByIdEndpoint: PublicEndpoint[
(RequestContext, UUID),
ErrorResponse,
CredentialSchemaResponse,
CredentialSchemaResponse | CredentialSchemaDidUrlResponse,
Any
] =
endpoint.get
Expand All @@ -153,7 +190,18 @@ object SchemaRegistryEndpoints {
"Globally unique identifier of the credential schema record"
)
)
.out(jsonBody[CredentialSchemaResponse].description("CredentialSchema found by `guid`"))
.out(
oneOf[CredentialSchemaResponse | CredentialSchemaDidUrlResponse](
oneOfVariant(
jsonBody[CredentialSchemaResponse].description("CredentialSchema found by `guid`, resolvable by HTTP URL")
),
oneOfVariant(
jsonBody[CredentialSchemaDidUrlResponse].description(
"CredentialSchema found by `guid`, resolvable by DID URL"
)
)
)
)
.errorOut(basicFailuresAndNotFound)
.name("getSchemaById")
.summary("Fetch the schema from the registry by `guid`")
Expand Down Expand Up @@ -184,6 +232,7 @@ object SchemaRegistryEndpoints {

private val credentialSchemaFilterInput: EndpointInput[FilterInput] = EndpointInput.derived[FilterInput]
private val paginationInput: EndpointInput[PaginationInput] = EndpointInput.derived[PaginationInput]

val lookupSchemasByQueryEndpoint: Endpoint[
(ApiKeyCredentials, JwtCredentials),
(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,18 +9,21 @@ import org.hyperledger.identus.pollux.credentialschema.http.{CredentialSchemaInp
import org.hyperledger.identus.pollux.credentialschema.SchemaRegistryEndpoints.*
import org.hyperledger.identus.shared.models.WalletAccessContext
import org.hyperledger.identus.LogUtils.*
import org.hyperledger.identus.agent.server.config.AppConfig
import sttp.tapir.ztapir.*
import zio.*

import java.util.UUID

class SchemaRegistryServerEndpoints(
config: AppConfig,
credentialSchemaController: CredentialSchemaController,
authenticator: Authenticator[BaseEntity],
authorizer: Authorizer[BaseEntity]
) {
val createSchemaServerEndpoint: ZServerEndpoint[Any, Any] =
createSchemaEndpoint

val createSchemaHttpUrlServerEndpoint: ZServerEndpoint[Any, Any] =
createSchemaHttpUrlEndpoint
.zServerSecurityLogic(SecurityLogic.authorizeWalletAccessWith(_)(authenticator, authorizer))
.serverLogic { wac =>
{ case (ctx: RequestContext, schemaInput: CredentialSchemaInput) =>
Expand All @@ -31,13 +34,25 @@ class SchemaRegistryServerEndpoints(
}
}

val createSchemaDidUrlServerEndpoint: ZServerEndpoint[Any, Any] =
createSchemaDidUrlEndpoint
.zServerSecurityLogic(SecurityLogic.authorizeWalletAccessWith(_)(authenticator, authorizer))
.serverLogic { wac => {
case (ctx: RequestContext, schemaInput: CredentialSchemaInput) =>
credentialSchemaController
.createSchemaDidUrl(config, schemaInput)(ctx)
.provideSomeLayer(ZLayer.succeed(wac))
.logTrace(ctx)
}
}

val updateSchemaServerEndpoint: ZServerEndpoint[Any, Any] =
updateSchemaEndpoint
.zServerSecurityLogic(SecurityLogic.authorizeWalletAccessWith(_)(authenticator, authorizer))
.serverLogic { wac =>
{ case (ctx: RequestContext, author: String, id: UUID, schemaInput: CredentialSchemaInput) =>
{ case (ctx: RequestContext, id: UUID, schemaInput: CredentialSchemaInput) =>
credentialSchemaController
.updateSchema(author, id, schemaInput)(ctx)
.updateSchema(config, id, schemaInput)(ctx)
.provideSomeLayer(ZLayer.succeed(wac))
.logTrace(ctx)
}
Expand All @@ -47,7 +62,7 @@ class SchemaRegistryServerEndpoints(
getSchemaByIdEndpoint
.zServerLogic { case (ctx: RequestContext, guid: UUID) =>
credentialSchemaController
.getSchemaByGuid(guid)(ctx)
.getSchemaByGuid(config, guid)(ctx)
.logTrace(ctx)
}

Expand All @@ -66,7 +81,8 @@ class SchemaRegistryServerEndpoints(
.lookupSchemas(
filter,
paginationInput.toPagination,
order
order,
config
)(ctx)
.provideSomeLayer(ZLayer.succeed(wac))
.logTrace(ctx)
Expand All @@ -75,20 +91,23 @@ class SchemaRegistryServerEndpoints(

val all: List[ZServerEndpoint[Any, Any]] =
List(
createSchemaServerEndpoint,
updateSchemaServerEndpoint,
createSchemaHttpUrlServerEndpoint,
createSchemaDidUrlServerEndpoint,
updateSchemaServerEndpoint, // TODO: get back to it, see if changes are needed
getSchemaByIdServerEndpoint,
getRawSchemaByIdServerEndpoint,
lookupSchemasByQueryServerEndpoint
)
}

object SchemaRegistryServerEndpoints {
def all: URIO[CredentialSchemaController & DefaultAuthenticator, List[ZServerEndpoint[Any, Any]]] = {
def all: URIO[CredentialSchemaController & DefaultAuthenticator & AppConfig, List[ZServerEndpoint[Any, Any]]] = {
for {
authenticator <- ZIO.service[DefaultAuthenticator]
config <- ZIO.service[AppConfig]
schemaRegistryService <- ZIO.service[CredentialSchemaController]
schemaRegistryEndpoints = new SchemaRegistryServerEndpoints(
config,
schemaRegistryService,
authenticator,
authenticator
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
package org.hyperledger.identus.pollux.credentialschema.controller

import org.hyperledger.identus.agent.server.config.AppConfig
import org.hyperledger.identus.api.http.*
import org.hyperledger.identus.api.http.model.{Order, Pagination}
import org.hyperledger.identus.pollux.credentialschema.http.{
CredentialSchemaDidUrlResponse,
CredentialSchemaInput,
CredentialSchemaResponse,
CredentialSchemaResponsePage,
Expand All @@ -20,13 +22,17 @@ trait CredentialSchemaController {
rc: RequestContext
): ZIO[WalletAccessContext, ErrorResponse, CredentialSchemaResponse]

def updateSchema(author: String, id: UUID, in: CredentialSchemaInput)(implicit
def createSchemaDidUrl(config: AppConfig, in: CredentialSchemaInput)(implicit
rc: RequestContext
): ZIO[WalletAccessContext, ErrorResponse, CredentialSchemaResponse]
): ZIO[WalletAccessContext, ErrorResponse, CredentialSchemaDidUrlResponse]

def updateSchema(config: AppConfig, id: UUID, in: CredentialSchemaInput)(implicit
rc: RequestContext
): ZIO[WalletAccessContext, ErrorResponse, CredentialSchemaResponse | CredentialSchemaDidUrlResponse]

def getSchemaByGuid(id: UUID)(implicit
def getSchemaByGuid(config: AppConfig, id: UUID)(implicit
rc: RequestContext
): IO[ErrorResponse, CredentialSchemaResponse]
): IO[ErrorResponse, CredentialSchemaResponse | CredentialSchemaDidUrlResponse]

def getSchemaJsonByGuid(id: UUID)(implicit
rc: RequestContext
Expand All @@ -39,7 +45,8 @@ trait CredentialSchemaController {
def lookupSchemas(
filter: FilterInput,
pagination: Pagination,
order: Option[Order]
order: Option[Order],
config: AppConfig
)(implicit
rc: RequestContext
): ZIO[WalletAccessContext, ErrorResponse, CredentialSchemaResponsePage]
Expand Down
Loading
Loading