123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257 |
- package route
- import (
- "crypto/ecdsa"
- "log"
- "net/http"
- "net/url"
- "path"
- "path/filepath"
- "strconv"
- "strings"
- "github.com/IceWhaleTech/CasaOS/codegen"
- "github.com/IceWhaleTech/CasaOS/pkg/config"
- "github.com/IceWhaleTech/CasaOS/pkg/utils/file"
- "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
- V3FilePath 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
- V3FilePath = "/v3/file"
- }
- 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)
- }
- }
- })
- }
- func InitFile() http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- token := r.URL.Query().Get("token")
- if len(token) == 0 {
- w.Header().Set("Content-Type", "application/json")
- w.WriteHeader(http.StatusUnauthorized)
- w.Write([]byte(`{"message": "token not found"}`))
- return
- }
- valid, _, errs := jwt.Validate(token, func() (*ecdsa.PublicKey, error) { return external.GetPublicKey(config.CommonInfo.RuntimePath) })
- if errs != nil || !valid {
- w.Header().Set("Content-Type", "application/json")
- w.WriteHeader(http.StatusUnauthorized)
- w.Write([]byte(`{"message": "validation failure"}`))
- return
- }
- filePath := r.URL.Query().Get("path")
- fileName := path.Base(filePath)
- w.Header().Add("Content-Disposition", "attachment; filename*=utf-8''"+url.PathEscape(fileName))
- http.ServeFile(w, r, filePath)
- //http.ServeFile(w, r, filePath)
- })
- }
- func InitDir() http.Handler {
- return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
- token := r.URL.Query().Get("token")
- if len(token) == 0 {
- w.Header().Set("Content-Type", "application/json")
- w.WriteHeader(http.StatusUnauthorized)
- w.Write([]byte(`{"message": "token not found"}`))
- return
- }
- valid, _, errs := jwt.Validate(token, func() (*ecdsa.PublicKey, error) { return external.GetPublicKey(config.CommonInfo.RuntimePath) })
- if errs != nil || !valid {
- w.Header().Set("Content-Type", "application/json")
- w.WriteHeader(http.StatusUnauthorized)
- w.Write([]byte(`{"message": "validation failure"}`))
- return
- }
- t := r.URL.Query().Get("format")
- files := r.URL.Query().Get("files")
- if len(files) == 0 {
- // w.JSON(common_err.CLIENT_ERROR, model.Result{
- // Success: common_err.INVALID_PARAMS,
- // Message: common_err.GetMsg(common_err.INVALID_PARAMS),
- // })
- return
- }
- list := strings.Split(files, ",")
- for _, v := range list {
- if !file.Exists(v) {
- // c.JSON(common_err.SERVICE_ERROR, model.Result{
- // Success: common_err.FILE_DOES_NOT_EXIST,
- // Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
- // })
- return
- }
- }
- w.Header().Add("Content-Type", "application/octet-stream")
- w.Header().Add("Content-Transfer-Encoding", "binary")
- w.Header().Add("Cache-Control", "no-cache")
- // handles only single files not folders and multiple files
- // if len(list) == 1 {
- // filePath := list[0]
- // info, err := os.Stat(filePath)
- // if err != nil {
- // w.JSON(http.StatusOK, model.Result{
- // Success: common_err.FILE_DOES_NOT_EXIST,
- // Message: common_err.GetMsg(common_err.FILE_DOES_NOT_EXIST),
- // })
- //return
- // }
- //}
- extension, ar, err := file.GetCompressionAlgorithm(t)
- if err != nil {
- // w.JSON(common_err.CLIENT_ERROR, model.Result{
- // Success: common_err.INVALID_PARAMS,
- // Message: common_err.GetMsg(common_err.INVALID_PARAMS),
- // })
- return
- }
- err = ar.Create(w)
- if err != nil {
- // c.JSON(common_err.SERVICE_ERROR, model.Result{
- // Success: common_err.SERVICE_ERROR,
- // Message: common_err.GetMsg(common_err.SERVICE_ERROR),
- // Data: err.Error(),
- // })
- return
- }
- defer ar.Close()
- commonDir := file.CommonPrefix(filepath.Separator, list...)
- currentPath := filepath.Base(commonDir)
- name := "_" + currentPath
- name += extension
- w.Header().Add("Content-Disposition", "attachment; filename*=utf-8''"+url.PathEscape(name))
- for _, fname := range list {
- err = file.AddFile(ar, fname, commonDir)
- if err != nil {
- log.Printf("Failed to archive %s: %v", fname, err)
- }
- }
- })
- }
|