REST API: expose OpenAPI schema and render it using Swagger UI

Fixes #609
This commit is contained in:
Nicola Murino
2021-11-21 09:32:51 +01:00
parent fb8f013ea7
commit 3d6b09e949
33 changed files with 244 additions and 51 deletions

View File

@@ -9,6 +9,7 @@ import (
"log"
"net"
"net/http"
"strings"
"time"
"github.com/go-chi/chi/v5"
@@ -37,20 +38,29 @@ var (
type httpdServer struct {
binding Binding
staticFilesPath string
openAPIPath string
enableWebAdmin bool
enableWebClient bool
renderOpenAPI bool
router *chi.Mux
tokenAuth *jwtauth.JWTAuth
signingPassphrase string
cors CorsConfig
}
func newHttpdServer(b Binding, staticFilesPath, signingPassphrase string, cors CorsConfig) *httpdServer {
func newHttpdServer(b Binding, staticFilesPath, signingPassphrase string, cors CorsConfig,
openAPIPath string,
) *httpdServer {
if openAPIPath == "" {
b.RenderOpenAPI = false
}
return &httpdServer{
binding: b,
staticFilesPath: staticFilesPath,
openAPIPath: openAPIPath,
enableWebAdmin: b.EnableWebAdmin,
enableWebClient: b.EnableWebClient,
renderOpenAPI: b.RenderOpenAPI,
signingPassphrase: signingPassphrase,
cors: cors,
}
@@ -940,6 +950,17 @@ func (s *httpdServer) redirectToWebPath(w http.ResponseWriter, r *http.Request,
}
}
func (s *httpdServer) isStaticFileURL(r *http.Request) bool {
var urlPath string
rctx := chi.RouteContext(r.Context())
if rctx != nil && rctx.RoutePath != "" {
urlPath = rctx.RoutePath
} else {
urlPath = r.URL.Path
}
return !strings.HasPrefix(urlPath, webOpenAPIPath) && !strings.HasPrefix(urlPath, webStaticFilesPath)
}
func (s *httpdServer) initializeRouter() {
s.tokenAuth = jwtauth.New(jwa.HS256.String(), getSigningKey(s.signingPassphrase), nil)
s.router = chi.NewRouter()
@@ -960,7 +981,8 @@ func (s *httpdServer) initializeRouter() {
s.router.Use(c.Handler)
}
s.router.Use(middleware.GetHead)
s.router.Use(middleware.StripSlashes)
// StripSlashes causes infinite redirects at the root path if used with http.FileServer
s.router.Use(middleware.Maybe(middleware.StripSlashes, s.isStaticFileURL))
s.router.NotFound(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
@@ -1135,6 +1157,13 @@ func (s *httpdServer) initializeRouter() {
router.With(checkHTTPUserPerm(sdk.WebClientSharesDisabled)).Delete(userSharesPath+"/{id}", deleteShare)
})
if s.renderOpenAPI {
s.router.Group(func(router chi.Router) {
router.Use(compressor.Handler)
fileServer(router, webOpenAPIPath, http.Dir(s.openAPIPath))
})
}
if s.enableWebAdmin || s.enableWebClient {
s.router.Group(func(router chi.Router) {
router.Use(compressor.Handler)