zio-http icon indicating copy to clipboard operation
zio-http copied to clipboard

Simplistic implementation of OpenAPI security block for Auth

Open gzoller opened this issue 11 months ago • 1 comments

When generating the OpenAPI spec from Endpoints using OpenAPIGen.fromEndpoints() there currently is no apparent way to generate the "security" block for per-Endpoint Auth for OpenAPI. Endpoint has an authType field, which doesn't quite to line up 1-to-1 with the OpenAPI spec values for security, however it does include 3 common schemes: BasicAuth, BearerAuth, and DigestAuth. The authType field (AuthType) has some other defined values, such as Custom and Or (not sure what that is), that don't have an apparent map into an OpenApi value. OAuth is notably missing here.

This PR tweaks the OpenAPI gen code to generate the "security" block is one of these 3 auth schemes is specified on an Endpoint using (for exmaple) ".auth(AuthType.Bearer)". This auth type must match the defined scheme. Example below.

Note this PR does not attempt to auto-generate the components.securitySchemes block of OpenAPI. This must be done manually or via a new PR.

  val bearerAuthScheme = OpenAPI.SecurityScheme.Http(
    scheme = "bearer",
    bearerFormat = Some("JWT"), // Optional: specify the token format
    description = Some(Doc.p("Use a Bearer token for authentication."))
  )

  val hello_endpoint = Endpoint(RoutePattern.GET / "hello" ?? (Doc.p("Say hello to the people") + authHeaderDoc))
    .out[String](MediaType.text.plain, Doc.p("Just a hello message")) // force plaintext response, not JSON
    .auth[AuthType.Bearer](AuthType.Bearer). // <<< This will trigger the security block generation

  val openAPI_basic = OpenAPIGen.fromEndpoints(title = "Library API", version = "1.0", hello_endpoint)
  // Not clean, yet not terrible either...at least it's not hand-tooled JSON
  val openAPI = openAPI_basic
          .copy(
            components = Some(Components(
              securitySchemes = ListMap(Key.fromString("BearerAuth").get -> ReferenceOr.Or(bearerAuthScheme)),
              schemas = openAPIFirst.components.get.schemas
              ))
          )

gzoller avatar Dec 12 '24 06:12 gzoller

CLA assistant check
All committers have signed the CLA.

CLAassistant avatar Dec 12 '24 06:12 CLAassistant