From 0ef9d8a3955f64f9e156feaf7a3eef0b1bb56c82 Mon Sep 17 00:00:00 2001 From: Adrien YHUEL Date: Wed, 4 Dec 2024 11:50:16 +0100 Subject: [PATCH] feat: :sparkles: Add ability to extend or replace existing servers in the OpenAPI spec --- README.md | 2 ++ openapi.go | 38 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 40 insertions(+) diff --git a/README.md b/README.md index a0da3c3..6134389 100644 --- a/README.md +++ b/README.md @@ -52,6 +52,8 @@ Reports any errors as a `{openapi.error}` [placeholder](https://caddyserver.com/ | `validate_servers` | Enable server validation. Accepts `true`, `false` or just the directive which enables validation. Default is `true`. | | `log_error` | Toggles error logging. Default is `false` | | `check` | Enable validation of the request parameters; include one or more of the following directives in the body:`req_params`, `req_body` and `resp_body`. `resp_body` only validates `application/json` payload. Note that validating the request body will implicitly set `req_params` | +| `additional_servers` | List of servers to add to openapi spec for request validation | +| `replace_servers` | Make additional_servers replace existing servers in OpenAPI spec | Errors are reported in the following [placeholders](https://caddyserver.com/docs/caddyfile/concepts#placeholders). You can use them in other [directives](https://caddyserver.com/docs/caddyfile/directives) like [`respond`](https://caddyserver.com/docs/caddyfile/directives/respond) diff --git a/openapi.go b/openapi.go index 3864508..02b9d13 100644 --- a/openapi.go +++ b/openapi.go @@ -33,6 +33,8 @@ const ( TOKEN_LOG_ERROR = "log_error" TOKEN_VALIDATE_SERVERS = "validate_servers" TOKEN_CHECK = "check" + TOKEN_ADD_SERVERS = "additional_servers" + TOKEN_REPLACE_SERVERS = "replace_servers" VALUE_REQ_PARAMS = "req_params" VALUE_REQ_BODY = "req_body" VALUE_RESP_BODY = "resp_body" @@ -57,6 +59,15 @@ type OpenAPI struct { // Enable server validation ValidateServers bool `json:"valid_servers,omitempty"` + // A list of additional servers to be considered valid when + // when performing the request validation. The additional servers + // are added to the servers in the OpenAPI specification. + // Default is empty list + AdditionalServers []string `json:"additional_servers,omitempty"` + + // Make AdditionalServers replace existing servers in spec + ReplaceServers bool `json:"replace_servers,omitempty"` + oas *openapi3.T router routers.Router @@ -125,6 +136,20 @@ func (oapi *OpenAPI) Provision(ctx caddy.Context) error { } if oapi.ValidateServers { + + if oapi.ReplaceServers && len(oapi.AdditionalServers) != 0 { + oas.Servers = make([]*openapi3.Server, 0) + } + + for i, s := range oapi.AdditionalServers { + server := &openapi3.Server{ + URL: s, + Description: fmt.Sprintf("Additional server: %d", i), + Variables: make(map[string]*openapi3.ServerVariable), + } + oas.Servers = append(oas.Servers, server) + } + oapi.log("List of servers") for _, s := range oas.Servers { oapi.log(fmt.Sprintf("- %s #%s", s.URL, s.Description)) @@ -171,6 +196,8 @@ func (oapi *OpenAPI) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { oapi.LogError = false oapi.ValidateServers = true oapi.Check = nil + oapi.AdditionalServers = make([]string, 0) + oapi.ReplaceServers = false // Skip the openapi directive d.Next() @@ -229,6 +256,17 @@ func (oapi *OpenAPI) UnmarshalCaddyfile(d *caddyfile.Dispenser) error { return err } + case TOKEN_ADD_SERVERS: + oapi.AdditionalServers = d.RemainingArgs() + + case TOKEN_REPLACE_SERVERS: + if d.NextArg() { + b, err := strconv.ParseBool(d.Val()) + if nil == err { + oapi.ReplaceServers = b + } + } + default: return d.Errf("unrecognized subdirective: '%s'", token) }