feat: create new swagger package

This commit is contained in:
Derrick Hammer 2024-02-17 03:05:22 -05:00
parent 3b9f4bbe3d
commit 24694ecbae
Signed by: pcfreak30
GPG Key ID: C997C339BE476FF2
4 changed files with 74 additions and 58 deletions

View File

View File

@ -5,14 +5,12 @@ import (
"context" "context"
"crypto/ed25519" "crypto/ed25519"
"crypto/rand" "crypto/rand"
"embed"
_ "embed" _ "embed"
"encoding/base64" "encoding/base64"
"encoding/hex" "encoding/hex"
"errors" "errors"
"fmt" "fmt"
"io" "io"
"io/fs"
"math" "math"
"mime/multipart" "mime/multipart"
"net/http" "net/http"
@ -21,12 +19,12 @@ import (
"strings" "strings"
"time" "time"
"git.lumeweb.com/LumeWeb/portal/api/swagger"
"git.lumeweb.com/LumeWeb/portal/metadata" "git.lumeweb.com/LumeWeb/portal/metadata"
"git.lumeweb.com/LumeWeb/portal/storage" "git.lumeweb.com/LumeWeb/portal/storage"
"github.com/getkin/kin-openapi/openapi3"
"git.lumeweb.com/LumeWeb/libs5-go/encoding" "git.lumeweb.com/LumeWeb/libs5-go/encoding"
s5libmetadata "git.lumeweb.com/LumeWeb/libs5-go/metadata" s5libmetadata "git.lumeweb.com/LumeWeb/libs5-go/metadata"
"git.lumeweb.com/LumeWeb/libs5-go/node" "git.lumeweb.com/LumeWeb/libs5-go/node"
@ -60,12 +58,7 @@ var (
) )
//go:embed swagger.yaml //go:embed swagger.yaml
var spec []byte var swagSpec []byte
//go:generate go run generate.go
//go:embed embed
var swagfs embed.FS
type S5API struct { type S5API struct {
config *viper.Viper config *viper.Viper
@ -143,7 +136,7 @@ func (s S5API) Stop(ctx context.Context) error {
return nil return nil
} }
func (s *S5API) Routes() *httprouter.Router { func (s *S5API) Routes() (*httprouter.Router, error) {
authMiddlewareOpts := middleware.AuthMiddlewareOptions{ authMiddlewareOpts := middleware.AuthMiddlewareOptions{
Identity: s.identity, Identity: s.identity,
Accounts: s.accounts, Accounts: s.accounts,
@ -161,38 +154,8 @@ func (s *S5API) Routes() *httprouter.Router {
tusCors := BuildTusCors() tusCors := BuildTusCors()
loader := openapi3.NewLoader()
doc, err := loader.LoadFromData(spec)
if err != nil {
panic(err)
}
if err = doc.Validate(loader.Context); err != nil {
panic(err)
}
jsonDoc, err := doc.MarshalJSON()
if err != nil {
panic(err)
}
wrappedTusHandler := middleware.ApplyMiddlewares(tusOptionsHandler, tusCors, authMw) wrappedTusHandler := middleware.ApplyMiddlewares(tusOptionsHandler, tusCors, authMw)
swaggerFiles, _ := fs.Sub(swagfs, "embed")
swaggerServ := http.FileServer(http.FS(swaggerFiles))
swaggerHandler := func(c jape.Context) {
swaggerServ.ServeHTTP(c.ResponseWriter, c.Request)
}
swaggerStrip := func(next http.Handler) http.Handler {
return http.StripPrefix("/swagger", next)
}
swaggerRedirect := func(jc jape.Context) {
http.Redirect(jc.ResponseWriter, jc.Request, "/swagger/", http.StatusMovedPermanently)
}
routes := map[string]jape.Handler{ routes := map[string]jape.Handler{
// Account API // Account API
"GET /s5/account/register": s.accountRegisterChallenge, "GET /s5/account/register": s.accountRegisterChallenge,
@ -232,20 +195,14 @@ func (s *S5API) Routes() *httprouter.Router {
"GET /s5/registry": middleware.ApplyMiddlewares(s.registryQuery, authMw), "GET /s5/registry": middleware.ApplyMiddlewares(s.registryQuery, authMw),
"POST /s5/registry": middleware.ApplyMiddlewares(s.registrySet, authMw), "POST /s5/registry": middleware.ApplyMiddlewares(s.registrySet, authMw),
"GET /s5/registry/subscription": middleware.ApplyMiddlewares(s.registrySubscription, authMw), "GET /s5/registry/subscription": middleware.ApplyMiddlewares(s.registrySubscription, authMw),
"GET /swagger.json": byteHandler(jsonDoc),
"GET /swagger": swaggerRedirect,
"GET /swagger/*path": middleware.ApplyMiddlewares(swaggerHandler, swaggerStrip),
} }
return s.protocol.Node().Services().HTTP().GetHttpRouter(routes) routes, err := swagger.Swagger(swagSpec, routes)
if err != nil {
return nil, err
} }
func byteHandler(b []byte) jape.Handler { return s.protocol.Node().Services().HTTP().GetHttpRouter(routes), nil
return func(c jape.Context) {
c.ResponseWriter.Header().Set("Content-Type", "application/json")
c.ResponseWriter.Write(b)
}
} }
type s5TusJwtResponseWriter struct { type s5TusJwtResponseWriter struct {

View File

@ -108,10 +108,4 @@ func main() {
if _, err := newinitFile.Write(newInit); err != nil { if _, err := newinitFile.Write(newInit); err != nil {
log.Fatalf("unable to write to swagger-initializer.js: %v", err) log.Fatalf("unable to write to swagger-initializer.js: %v", err)
} }
newcv, err := os.Create("current_version.txt")
if err != nil {
log.Fatalf("can't update current_version.txt: %v", err)
}
defer newcv.Close()
newcv.WriteString(tag)
} }

65
api/swagger/swagger.go Normal file
View File

@ -0,0 +1,65 @@
package swagger
import (
"embed"
"io/fs"
"net/http"
"git.lumeweb.com/LumeWeb/portal/api/middleware"
"go.sia.tech/jape"
"github.com/getkin/kin-openapi/openapi3"
)
//go:generate go run generate.go
//go:embed embed
var swagfs embed.FS
func byteHandler(b []byte) jape.Handler {
return func(c jape.Context) {
c.ResponseWriter.Header().Set("Content-Type", "application/json")
c.ResponseWriter.Write(b)
}
}
func Swagger(spec []byte, routes map[string]jape.Handler) (map[string]jape.Handler, error) {
loader := openapi3.NewLoader()
doc, err := loader.LoadFromData(spec)
if err != nil {
return nil, err
}
if err = doc.Validate(loader.Context); err != nil {
return nil, err
}
jsonDoc, err := doc.MarshalJSON()
if err != nil {
return nil, err
}
swaggerFiles, _ := fs.Sub(swagfs, "embed")
swaggerServ := http.FileServer(http.FS(swaggerFiles))
handler := func(c jape.Context) {
swaggerServ.ServeHTTP(c.ResponseWriter, c.Request)
}
strip := func(next http.Handler) http.Handler {
return http.StripPrefix("/swagger", next)
}
redirect := func(jc jape.Context) {
http.Redirect(jc.ResponseWriter, jc.Request, "/swagger/", http.StatusMovedPermanently)
}
swagRoutes := map[string]jape.Handler{
"GET /swagger.json": byteHandler(jsonDoc),
"GET /swagger": redirect,
"GET /swagger/*path": middleware.ApplyMiddlewares(handler, strip),
}
return middleware.MergeRoutes(routes, swagRoutes), nil
}