package route import ( "crypto/ecdsa" "net/http" "net/url" "strconv" "strings" "github.com/IceWhaleTech/CasaOS/codegen" "github.com/IceWhaleTech/CasaOS/pkg/config" "github.com/IceWhaleTech/CasaOS-Common/external" "github.com/IceWhaleTech/CasaOS-Common/utils/jwt" v2Route "github.com/IceWhaleTech/CasaOS/route/v2" "github.com/deepmap/oapi-codegen/pkg/middleware" "github.com/getkin/kin-openapi/openapi3" "github.com/getkin/kin-openapi/openapi3filter" "github.com/labstack/echo/v4" echo_middleware "github.com/labstack/echo/v4/middleware" ) var ( _swagger *openapi3.T V2APIPath string V2DocPath string ) func init() { swagger, err := codegen.GetSwagger() if err != nil { panic(err) } _swagger = swagger u, err := url.Parse(_swagger.Servers[0].URL) if err != nil { panic(err) } V2APIPath = strings.TrimRight(u.Path, "/") V2DocPath = "/doc" + V2APIPath } func InitV2Router() http.Handler { appManagement := v2Route.NewCasaOS() e := echo.New() e.Use((echo_middleware.CORSWithConfig(echo_middleware.CORSConfig{ AllowOrigins: []string{"*"}, AllowMethods: []string{echo.POST, echo.GET, echo.OPTIONS, echo.PUT, echo.DELETE}, AllowHeaders: []string{echo.HeaderAuthorization, echo.HeaderContentLength, echo.HeaderXCSRFToken, echo.HeaderContentType, echo.HeaderAccessControlAllowOrigin, echo.HeaderAccessControlAllowHeaders, echo.HeaderAccessControlAllowMethods, echo.HeaderConnection, echo.HeaderOrigin, echo.HeaderXRequestedWith}, ExposeHeaders: []string{echo.HeaderContentLength, echo.HeaderAccessControlAllowOrigin, echo.HeaderAccessControlAllowHeaders}, MaxAge: 172800, AllowCredentials: true, }))) e.Use(echo_middleware.Gzip()) e.Use(echo_middleware.Logger()) e.Use(echo_middleware.JWTWithConfig(echo_middleware.JWTConfig{ Skipper: func(c echo.Context) bool { return c.RealIP() == "::1" || c.RealIP() == "127.0.0.1" //return true }, ParseTokenFunc: func(token string, c echo.Context) (interface{}, error) { valid, claims, err := jwt.Validate(token, func() (*ecdsa.PublicKey, error) { return external.GetPublicKey(config.CommonInfo.RuntimePath) }) if err != nil || !valid { return nil, echo.ErrUnauthorized } c.Request().Header.Set("user_id", strconv.Itoa(claims.ID)) return claims, nil }, TokenLookupFuncs: []echo_middleware.ValuesExtractor{ func(c echo.Context) ([]string, error) { if len(c.Request().Header.Get(echo.HeaderAuthorization)) > 0 { return []string{c.Request().Header.Get(echo.HeaderAuthorization)}, nil } return []string{c.QueryParam("token")}, nil }, }, })) // e.Use(func(next echo.HandlerFunc) echo.HandlerFunc { // return func(c echo.Context) error { // switch c.Request().Header.Get(echo.HeaderContentType) { // case common.MIMEApplicationYAML: // in case request contains a compose content in YAML // return middleware.OapiRequestValidatorWithOptions(_swagger, &middleware.Options{ // Options: openapi3filter.Options{ // AuthenticationFunc: openapi3filter.NoopAuthenticationFunc, // // ExcludeRequestBody: true, // // ExcludeResponseBody: true, // }, // })(next)(c) // default: // return middleware.OapiRequestValidatorWithOptions(_swagger, &middleware.Options{ // Options: openapi3filter.Options{ // AuthenticationFunc: openapi3filter.NoopAuthenticationFunc, // }, // })(next)(c) // } // } // }) e.Use(middleware.OapiRequestValidatorWithOptions(_swagger, &middleware.Options{ Options: openapi3filter.Options{AuthenticationFunc: openapi3filter.NoopAuthenticationFunc}, })) codegen.RegisterHandlersWithBaseURL(e, appManagement, V2APIPath) return e } func InitV2DocRouter(docHTML string, docYAML string) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { if r.URL.Path == V2DocPath { if _, err := w.Write([]byte(docHTML)); err != nil { w.WriteHeader(http.StatusInternalServerError) } return } if r.URL.Path == V2DocPath+"/openapi.yaml" { if _, err := w.Write([]byte(docYAML)); err != nil { w.WriteHeader(http.StatusInternalServerError) } } }) }