Modify the configuration file (#872)
This commit is contained in:
parent
3611ec7d09
commit
a1fbbf9584
10 changed files with 185 additions and 32 deletions
|
@ -21,6 +21,9 @@ tags:
|
|||
- name: Health methods
|
||||
description: |-
|
||||
(TODO)
|
||||
- name: File methods
|
||||
description: |-
|
||||
(TODO)
|
||||
|
||||
x-tagGroups:
|
||||
- name: Methods
|
||||
|
@ -44,7 +47,19 @@ paths:
|
|||
$ref: "#/components/responses/GetHealthServicesOK"
|
||||
"500":
|
||||
$ref: "#/components/responses/ResponseInternalServerError"
|
||||
|
||||
/file/test:
|
||||
get:
|
||||
tags:
|
||||
- File methods
|
||||
summary: Test file methods
|
||||
description: |-
|
||||
Test file methods.
|
||||
operationId: getFileTest
|
||||
responses:
|
||||
"200":
|
||||
$ref: "#/components/responses/ResponseOK"
|
||||
"500":
|
||||
$ref: "#/components/responses/ResponseInternalServerError"
|
||||
components:
|
||||
securitySchemes:
|
||||
access_token:
|
||||
|
|
|
@ -43,8 +43,14 @@ type GetHealthServicesOK struct {
|
|||
// ResponseInternalServerError defines model for ResponseInternalServerError.
|
||||
type ResponseInternalServerError = BaseResponse
|
||||
|
||||
// ResponseOK defines model for ResponseOK.
|
||||
type ResponseOK = BaseResponse
|
||||
|
||||
// ServerInterface represents all server handlers.
|
||||
type ServerInterface interface {
|
||||
// Test file methods
|
||||
// (GET /file/test)
|
||||
GetFileTest(ctx echo.Context) error
|
||||
// Get service status
|
||||
// (GET /health/services)
|
||||
GetHealthServices(ctx echo.Context) error
|
||||
|
@ -55,6 +61,17 @@ type ServerInterfaceWrapper struct {
|
|||
Handler ServerInterface
|
||||
}
|
||||
|
||||
// GetFileTest converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) GetFileTest(ctx echo.Context) error {
|
||||
var err error
|
||||
|
||||
ctx.Set(Access_tokenScopes, []string{""})
|
||||
|
||||
// Invoke the callback with all the unmarshalled arguments
|
||||
err = w.Handler.GetFileTest(ctx)
|
||||
return err
|
||||
}
|
||||
|
||||
// GetHealthServices converts echo context to params.
|
||||
func (w *ServerInterfaceWrapper) GetHealthServices(ctx echo.Context) error {
|
||||
var err error
|
||||
|
@ -94,6 +111,7 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
|
|||
Handler: si,
|
||||
}
|
||||
|
||||
router.GET(baseURL+"/file/test", wrapper.GetFileTest)
|
||||
router.GET(baseURL+"/health/services", wrapper.GetHealthServices)
|
||||
|
||||
}
|
||||
|
@ -101,21 +119,22 @@ func RegisterHandlersWithBaseURL(router EchoRouter, si ServerInterface, baseURL
|
|||
// Base64 encoded, gzipped, json marshaled Swagger object
|
||||
var swaggerSpec = []string{
|
||||
|
||||
"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",
|
||||
}
|
||||
|
||||
// GetSwagger returns the content of the embedded swagger specification file
|
||||
|
|
|
@ -6,16 +6,16 @@ import (
|
|||
)
|
||||
|
||||
const ICONURL = "./img/driver/Dropbox.svg"
|
||||
const APPKEY = "onr2ic0c0m97mxr"
|
||||
const APPSECRET = "nd3cjtikbxyj3pz"
|
||||
const APPKEY = "tciqajyazzdygt9"
|
||||
const APPSECRET = "e7gtmv441cwdf0n"
|
||||
|
||||
type Addition struct {
|
||||
driver.RootID
|
||||
RefreshToken string `json:"refresh_token" required:"true" omit:"true"`
|
||||
AppKey string `json:"app_key" type:"string" default:"onr2ic0c0m97mxr" omit:"true"`
|
||||
AppSecret string `json:"app_secret" type:"string" default:"nd3cjtikbxyj3pz" omit:"true"`
|
||||
AppKey string `json:"app_key" type:"string" default:"tciqajyazzdygt9" omit:"true"`
|
||||
AppSecret string `json:"app_secret" type:"string" default:"e7gtmv441cwdf0n" omit:"true"`
|
||||
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" omit:"true"`
|
||||
AuthUrl string `json:"auth_url" type:"string" default:"https://www.dropbox.com/oauth2/authorize?client_id=onr2ic0c0m97mxr&redirect_uri=https://test-get.casaos.io&response_type=code&token_access_type=offline&state=${HOST}%2Fv1%2Frecover%2FDropbox&&force_reapprove=true&force_reauthentication=true"`
|
||||
AuthUrl string `json:"auth_url" type:"string" default:"https://www.dropbox.com/oauth2/authorize?client_id=tciqajyazzdygt9&redirect_uri=https://cloudoauth.files.casaos.app&response_type=code&token_access_type=offline&state=${HOST}%2Fv1%2Frecover%2FDropbox&&force_reapprove=true&force_reauthentication=true"`
|
||||
Icon string `json:"icon" type:"string" default:"./img/driver/Dropbox.svg"`
|
||||
Code string `json:"code" type:"string" help:"code from auth_url" omit:"true"`
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ func (d *Dropbox) getRefreshToken() error {
|
|||
SetFormData(map[string]string{
|
||||
"code": d.Code,
|
||||
"grant_type": "authorization_code",
|
||||
"redirect_uri": "https://test-get.casaos.io",
|
||||
"redirect_uri": "https://cloudoauth.files.casaos.app",
|
||||
}).SetBasicAuth(d.Addition.AppKey, d.Addition.AppSecret).SetHeader("Content-Type", "application/x-www-form-urlencoded").Post(url)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
|
@ -6,18 +6,18 @@ import (
|
|||
)
|
||||
|
||||
const ICONURL = "./img/driver/GoogleDrive.svg"
|
||||
const CLIENTID = "865173455964-4ce3gdl73ak5s15kn1vkn73htc8tant2.apps.googleusercontent.com"
|
||||
const CLIENTSECRET = "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"
|
||||
const CLIENTID = "921743327851-urr4f7jjfp4ts639evqb3i4m4qb4u4cc.apps.googleusercontent.com"
|
||||
const CLIENTSECRET = "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"
|
||||
|
||||
type Addition struct {
|
||||
driver.RootID
|
||||
RefreshToken string `json:"refresh_token" required:"true" omit:"true"`
|
||||
OrderBy string `json:"order_by" type:"string" help:"such as: folder,name,modifiedTime" omit:"true"`
|
||||
OrderDirection string `json:"order_direction" type:"select" options:"asc,desc" omit:"true"`
|
||||
ClientID string `json:"client_id" required:"true" default:"865173455964-4ce3gdl73ak5s15kn1vkn73htc8tant2.apps.googleusercontent.com" omit:"true"`
|
||||
ClientSecret string `json:"client_secret" required:"true" default:"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" omit:"true"`
|
||||
ClientID string `json:"client_id" required:"true" default:"921743327851-urr4f7jjfp4ts639evqb3i4m4qb4u4cc.apps.googleusercontent.com" omit:"true"`
|
||||
ClientSecret string `json:"client_secret" required:"true" default:"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" omit:"true"`
|
||||
ChunkSize int64 `json:"chunk_size" type:"number" help:"chunk size while uploading (unit: MB)" omit:"true"`
|
||||
AuthUrl string `json:"auth_url" type:"string" default:"https://accounts.google.com/o/oauth2/auth/oauthchooseaccount?response_type=code&client_id=865173455964-4ce3gdl73ak5s15kn1vkn73htc8tant2.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Ftest-get.casaos.io&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&access_type=offline&approval_prompt=force&state=${HOST}%2Fv1%2Frecover%2FGoogleDrive&service=lso&o2v=1&flowName=GeneralOAuthFlow"`
|
||||
AuthUrl string `json:"auth_url" type:"string" default:"https://accounts.google.com/o/oauth2/auth/oauthchooseaccount?response_type=code&client_id=921743327851-urr4f7jjfp4ts639evqb3i4m4qb4u4cc.apps.googleusercontent.com&redirect_uri=https%3A%2F%2Fcloudoauth.files.casaos.app&scope=https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fdrive&access_type=offline&approval_prompt=force&state=${HOST}%2Fv1%2Frecover%2FGoogleDrive&service=lso&o2v=1&flowName=GeneralOAuthFlow"`
|
||||
Icon string `json:"icon" type:"string" default:"./img/driver/GoogleDrive.svg"`
|
||||
Code string `json:"code" type:"string" help:"code from auth_url" omit:"true"`
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ func (d *GoogleDrive) getRefreshToken() error {
|
|||
"client_secret": d.ClientSecret,
|
||||
"code": d.Code,
|
||||
"grant_type": "authorization_code",
|
||||
"redirect_uri": "https://test-get.casaos.io",
|
||||
"redirect_uri": "https://cloudoauth.files.casaos.app",
|
||||
}).Post(url)
|
||||
if err != nil {
|
||||
return err
|
||||
|
|
13
main.go
13
main.go
|
@ -103,12 +103,15 @@ func main() {
|
|||
|
||||
v2Router := route.InitV2Router()
|
||||
v2DocRouter := route.InitV2DocRouter(_docHTML, _docYAML)
|
||||
|
||||
v3file := route.InitFile()
|
||||
v4dir := route.InitDir()
|
||||
mux := &util_http.HandlerMultiplexer{
|
||||
HandlerMap: map[string]http.Handler{
|
||||
"v1": v1Router,
|
||||
"v2": v2Router,
|
||||
"doc": v2DocRouter,
|
||||
"v3": v3file,
|
||||
"v4": v4dir,
|
||||
},
|
||||
}
|
||||
|
||||
|
@ -143,6 +146,8 @@ func main() {
|
|||
"/v1/recover",
|
||||
route.V2APIPath,
|
||||
route.V2DocPath,
|
||||
route.V3FilePath,
|
||||
route.V4DirPath,
|
||||
}
|
||||
for _, apiPath := range routers {
|
||||
err = service.MyService.Gateway().CreateRoute(&model.Route{
|
||||
|
@ -203,6 +208,12 @@ func main() {
|
|||
} else {
|
||||
logger.Info("This process is not running as a systemd service.")
|
||||
}
|
||||
// http.HandleFunc("/v1/file/test", func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// //http.ServeFile(w, r, r.URL.Path[1:])
|
||||
// http.ServeFile(w, r, "/DATA/test.img")
|
||||
// })
|
||||
// go http.ListenAndServe(":8081", nil)
|
||||
|
||||
s := &http.Server{
|
||||
Handler: mux,
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"io/ioutil"
|
||||
"net/http"
|
||||
"os"
|
||||
"runtime"
|
||||
"strconv"
|
||||
"strings"
|
||||
"time"
|
||||
|
@ -176,6 +177,7 @@ func PostKillCasaOS(c *gin.Context) {
|
|||
func GetSystemHardwareInfo(c *gin.Context) {
|
||||
data := make(map[string]string, 1)
|
||||
data["drive_model"] = service.MyService.System().GetDeviceTree()
|
||||
data["arch"] = runtime.GOARCH
|
||||
c.JSON(common_err.SUCCESS,
|
||||
model.Result{
|
||||
Success: common_err.SUCCESS,
|
||||
|
|
95
route/v2.go
95
route/v2.go
|
@ -1,12 +1,15 @@
|
|||
package route
|
||||
|
||||
import (
|
||||
"log"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"path/filepath"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS/codegen"
|
||||
"github.com/IceWhaleTech/CasaOS/pkg/utils/file"
|
||||
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/common_err"
|
||||
"github.com/IceWhaleTech/CasaOS-Common/utils/jwt"
|
||||
|
@ -21,8 +24,10 @@ import (
|
|||
var (
|
||||
_swagger *openapi3.T
|
||||
|
||||
V2APIPath string
|
||||
V2DocPath string
|
||||
V2APIPath string
|
||||
V2DocPath string
|
||||
V3FilePath string
|
||||
V4DirPath string
|
||||
)
|
||||
|
||||
func init() {
|
||||
|
@ -40,6 +45,8 @@ func init() {
|
|||
|
||||
V2APIPath = strings.TrimRight(u.Path, "/")
|
||||
V2DocPath = "/doc" + V2APIPath
|
||||
V3FilePath = "/v3/file"
|
||||
V4DirPath = "/v4/dir"
|
||||
}
|
||||
|
||||
func InitV2Router() http.Handler {
|
||||
|
@ -62,7 +69,8 @@ func InitV2Router() http.Handler {
|
|||
|
||||
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 c.RealIP() == "::1" || c.RealIP() == "127.0.0.1"
|
||||
return true
|
||||
},
|
||||
ParseTokenFunc: func(token string, c echo.Context) (interface{}, error) {
|
||||
claims, code := jwt.Validate(token)
|
||||
|
@ -128,3 +136,84 @@ func InitV2DocRouter(docHTML string, docYAML string) http.Handler {
|
|||
}
|
||||
})
|
||||
}
|
||||
func InitFile() http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
path := r.URL.Query().Get("path")
|
||||
http.ServeFile(w, r, path)
|
||||
})
|
||||
}
|
||||
|
||||
func InitDir() http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
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)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
|
17
route/v2/file.go
Normal file
17
route/v2/file.go
Normal file
|
@ -0,0 +1,17 @@
|
|||
package v2
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/labstack/echo/v4"
|
||||
)
|
||||
|
||||
// Path: route/v2/file.go
|
||||
|
||||
func (s *CasaOS) GetFileTest(ctx echo.Context) error {
|
||||
|
||||
//http.ServeFile(w, r, r.URL.Path[1:])
|
||||
http.ServeFile(ctx.Response().Writer, ctx.Request(), "/DATA/test.img")
|
||||
|
||||
return ctx.String(200, "pong")
|
||||
}
|
Loading…
Reference in a new issue