Skip to content

Commit

Permalink
OpenAPI for Verifier endpoint (eu-digital-identity-wallet#176)
Browse files Browse the repository at this point in the history
OpenAPI doesn't include wallet related endpoints
  • Loading branch information
dzarras authored Jul 25, 2024
1 parent 80ab719 commit 8a627fc
Show file tree
Hide file tree
Showing 12 changed files with 1,289 additions and 47 deletions.
6 changes: 6 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,8 @@ The Verifier API, supports two operations:
* [Initialize Transaction](src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/port/input/InitTransaction.kt), where Verifier may define whether it wants to request a SIOP or OpenID4VP or combined request
* [Get Wallet response](src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/port/input/GetWalletResponse.kt), where Verifier receives depending on the request an `id_token`, `vp_token`, or an error

An Open API v3 specification of these operations is available [here](src/main/resources/public/openapi.json).

The Wallet API, provides the following main operations
* [Get Request Object](src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/port/input/GetRequestObject.kt) according JWT Secured Authorization Request
* [Get Presentation Definition](src/main/kotlin/eu/europa/ec/eudi/verifier/endpoint/port/input/GetPresentationDefinition.kt) according to OpenId4VP in case of using `presentation_definition_uri`
Expand Down Expand Up @@ -279,6 +281,8 @@ curl -X POST -H "Content-type: application/json" -d '{
}
```

You can also try it out in [Swagger UI](http://localhost:8080/swagger-ui#/verifier%20api/initializeTransaction).

### Get authorization request

- _Method_: GET
Expand Down Expand Up @@ -387,6 +391,8 @@ curl http://localhost:8080/ui/presentations/5N6E7VZsmwXOGLz1Xlfi96MoyZVC3FZxwdAu

**Returns:** The wallet submitted response as JSON.

You can also try it out in [Swagger UI](http://localhost:8080/swagger-ui#/verifier%20api/getWalletResponse).

## Configuration

The Verifier Endpoint application can be configured using the following *environment* variables:
Expand Down
4 changes: 4 additions & 0 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,10 @@ dependencies {
implementation(libs.bouncy.castle)
implementation(libs.arrow.core)
implementation(libs.arrow.fx.coroutines)
implementation("org.springframework.boot:spring-boot-starter-thymeleaf")
implementation("org.webjars:webjars-locator-core")
implementation(libs.swagger.ui)

testImplementation(kotlin("test"))
testImplementation(libs.kotlinx.coroutines.test)
testImplementation("org.springframework.boot:spring-boot-starter-test")
Expand Down
3 changes: 2 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ arrow = "1.2.4"
sonarqube = "5.0.0.4638"
dependencycheck = "10.0.3"
jacoco = "0.8.11"

swaggerUi = "5.17.14"

[libraries]
kotlinx-coroutines-test = { module = "org.jetbrains.kotlinx:kotlinx-coroutines-test", version.ref = "coroutines" }
Expand All @@ -25,6 +25,7 @@ presentation-exchange = { module = "eu.europa.ec.eudi:eudi-lib-jvm-presentation-
bouncy-castle = { module = "org.bouncycastle:bcpkix-jdk18on", version.ref = "bouncyCastle" }
arrow-core = { module = "io.arrow-kt:arrow-core", version.ref = "arrow" }
arrow-fx-coroutines = { module = "io.arrow-kt:arrow-fx-coroutines", version.ref = "arrow" }
swagger-ui = { module = "org.webjars:swagger-ui", version.ref = "swaggerUi" }

[plugins]
foojay-resolver-convention = { id = "org.gradle.toolchains.foojay-resolver-convention", version.ref = "foojay" }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ import eu.europa.ec.eudi.verifier.endpoint.EmbedOptionEnum.ByReference
import eu.europa.ec.eudi.verifier.endpoint.EmbedOptionEnum.ByValue
import eu.europa.ec.eudi.verifier.endpoint.adapter.input.timer.ScheduleTimeoutPresentations
import eu.europa.ec.eudi.verifier.endpoint.adapter.input.web.StaticContent
import eu.europa.ec.eudi.verifier.endpoint.adapter.input.web.SwaggerUi
import eu.europa.ec.eudi.verifier.endpoint.adapter.input.web.VerifierApi
import eu.europa.ec.eudi.verifier.endpoint.adapter.input.web.WalletApi
import eu.europa.ec.eudi.verifier.endpoint.adapter.out.cfg.GenerateRequestIdNimbus
Expand Down Expand Up @@ -147,7 +148,14 @@ internal fun beans(clock: Clock) = beans {
)
val verifierApi = VerifierApi(ref(), ref())
val staticContent = StaticContent()
walletApi.route.and(verifierApi.route).and(staticContent.route)
val swaggerUi = SwaggerUi(
publicResourcesBasePath = env.getRequiredProperty("spring.webflux.static-path-pattern").removeSuffix("/**"),
webJarResourcesBasePath = env.getRequiredProperty("spring.webflux.webjars-path-pattern").removeSuffix("/**"),
)
walletApi.route
.and(verifierApi.route)
.and(staticContent.route)
.and(swaggerUi.route)
}

//
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,10 @@ import org.springframework.context.ApplicationContextInitializer
import org.springframework.context.support.BeanDefinitionDsl
import org.springframework.context.support.GenericApplicationContext
import org.springframework.scheduling.annotation.EnableScheduling
import org.springframework.security.config.annotation.web.reactive.EnableWebFluxSecurity
import org.springframework.web.reactive.config.EnableWebFlux
import java.time.Clock

@EnableScheduling
@EnableWebFlux
@EnableWebFluxSecurity
@SpringBootApplication(proxyBeanMethods = false)
@SpringBootApplication
class VerifierApplication

internal fun BeanDefinitionDsl.initializer(): ApplicationContextInitializer<GenericApplicationContext> =
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright (c) 2023 European Commission
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package eu.europa.ec.eudi.verifier.endpoint.adapter.input.web

import org.slf4j.LoggerFactory
import org.springframework.http.HttpStatus
import org.springframework.http.MediaType
import org.springframework.web.reactive.function.server.RouterFunction
import org.springframework.web.reactive.function.server.ServerResponse
import org.springframework.web.reactive.function.server.coRouter
import org.springframework.web.reactive.function.server.renderAndAwait

private val log = LoggerFactory.getLogger(SwaggerUi::class.java)

/**
* Web adapter for displaying the Swagger UI.
*
* @param publicResourcesBasePath base path for accessing public resources
* @param webJarResourcesBasePath base path for accessing web jar resources
* @property route the routes handled by this web adapter
*/
internal class SwaggerUi(
private val publicResourcesBasePath: String,
private val webJarResourcesBasePath: String,
) {
val route: RouterFunction<ServerResponse> = coRouter {
(GET("") or GET("/")) {
log.info("Redirecting to {}", SWAGGER_UI)
ServerResponse.status(HttpStatus.TEMPORARY_REDIRECT)
.renderAndAwait("redirect:$SWAGGER_UI")
}

GET(SWAGGER_UI, contentType(MediaType.ALL) and accept(MediaType.TEXT_HTML)) {
log.info("Displaying Swagger UI")
ServerResponse.ok()
.contentType(MediaType.TEXT_HTML)
.renderAndAwait(
name = "swagger-ui",
model = mapOf(
"publicResourcesBasePath" to publicResourcesBasePath,
"webJarResourcesBasePath" to webJarResourcesBasePath,
),
)
}
}

companion object {
const val SWAGGER_UI = "/swagger-ui"
}
}
2 changes: 2 additions & 0 deletions src/main/resources/application.properties
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ logging.level.org.springframework.boot.actuate.endpoint.web=DEBUG
management.endpoints.enabled-by-default=true
server.error.includeStacktrace=ALWAYS
server.port=8080
spring.webflux.static-path-pattern=/public/**
spring.webflux.webjars-path-pattern=/webjars/**

#
# Verifier options
Expand Down
Loading

0 comments on commit 8a627fc

Please sign in to comment.