diff --git a/app/utils/http.ts b/app/utils/http.ts index 5053da59..16a1581c 100644 --- a/app/utils/http.ts +++ b/app/utils/http.ts @@ -43,6 +43,7 @@ service.interceptors.request.use(config => { service.interceptors.response.use( (response: any) => { + // const isExecReq = /api-nebula\/db\/(exec|batchExec)$/.test(response.config?.url); if (response.data?.data?.data) { response.data.data = response.data.data.data; diff --git a/server-v2/api/studio/internal/common/utils.go b/server-v2/api/studio/internal/common/utils.go index bdc527d4..a269dd46 100644 --- a/server-v2/api/studio/internal/common/utils.go +++ b/server-v2/api/studio/internal/common/utils.go @@ -7,13 +7,12 @@ import ( var ( ReserveRequestRoutes = []string{ - "/api-nebula/db/disconnect", + "/api-nebula/db/", "/api/files", "/api/import-tasks", } ReserveResponseRoutes = []string{ - "/api-nebula/db/connect", - "/api-nebula/db/disconnect", + "/api-nebula/db/", "/api/import-tasks", } IgnoreHandlerBodyPatterns = []*regexp.Regexp{ diff --git a/server-v2/api/studio/internal/handler/gateway/disonnecthandler.go b/server-v2/api/studio/internal/handler/gateway/disonnecthandler.go index c8f02d91..11759674 100644 --- a/server-v2/api/studio/internal/handler/gateway/disonnecthandler.go +++ b/server-v2/api/studio/internal/handler/gateway/disonnecthandler.go @@ -4,30 +4,14 @@ package gateway import ( "net/http" - "github.com/vesoft-inc/go-pkg/validator" - "github.com/vesoft-inc/nebula-studio/server-v2/api/studio/pkg/ecode" - "github.com/vesoft-inc/nebula-studio/server-v2/api/studio/internal/logic/gateway" "github.com/vesoft-inc/nebula-studio/server-v2/api/studio/internal/svc" - "github.com/vesoft-inc/nebula-studio/server-v2/api/studio/internal/types" - "github.com/zeromicro/go-zero/rest/httpx" ) func DisonnectHandler(svcCtx *svc.ServiceContext) http.HandlerFunc { return func(w http.ResponseWriter, r *http.Request) { - var req types.DisconnectDBParams - if err := httpx.Parse(r, &req); err != nil { - err = ecode.WithCode(ecode.ErrParam, err) - svcCtx.ResponseHandler.Handle(w, r, nil, err) - return - } - if err := validator.Struct(req); err != nil { - svcCtx.ResponseHandler.Handle(w, r, nil, err) - return - } - l := gateway.NewDisonnectLogic(r.Context(), svcCtx) - data, err := l.Disonnect(req) + data, err := l.Disonnect() svcCtx.ResponseHandler.Handle(w, r, data, err) } } diff --git a/server-v2/api/studio/internal/logic/gateway/disonnectlogic.go b/server-v2/api/studio/internal/logic/gateway/disonnectlogic.go index 085e4a36..ef652258 100644 --- a/server-v2/api/studio/internal/logic/gateway/disonnectlogic.go +++ b/server-v2/api/studio/internal/logic/gateway/disonnectlogic.go @@ -24,6 +24,6 @@ func NewDisonnectLogic(ctx context.Context, svcCtx *svc.ServiceContext) Disonnec } } -func (l *DisonnectLogic) Disonnect(req types.DisconnectDBParams) (*types.AnyResponse, error) { - return service.NewGatewayService(l.ctx, l.svcCtx).DisconnectDB(&req) +func (l *DisonnectLogic) Disonnect() (*types.AnyResponse, error) { + return service.NewGatewayService(l.ctx, l.svcCtx).DisconnectDB() } diff --git a/server-v2/api/studio/internal/service/gateway.go b/server-v2/api/studio/internal/service/gateway.go index 9104b458..2237d318 100644 --- a/server-v2/api/studio/internal/service/gateway.go +++ b/server-v2/api/studio/internal/service/gateway.go @@ -24,7 +24,7 @@ type ( ExecNGQL(request *types.ExecNGQLParams) (*types.AnyResponse, error) BatchExecNGQL(request *types.BatchExecNGQLParams) (*types.AnyResponse, error) ConnectDB(request *types.ConnectDBParams) (*types.ConnectDBResult, error) - DisconnectDB(request *types.DisconnectDBParams) (*types.AnyResponse, error) + DisconnectDB() (*types.AnyResponse, error) } gatewayService struct { @@ -74,7 +74,7 @@ func (s *gatewayService) ConnectDB(request *types.ConnectDBParams) (*types.Conne }, nil } -func (s *gatewayService) DisconnectDB(request *types.DisconnectDBParams) (*types.AnyResponse, error) { +func (s *gatewayService) DisconnectDB() (*types.AnyResponse, error) { httpReq, _ := middleware.GetRequest(s.ctx) httpRes, _ := middleware.GetResponseWriter(s.ctx) @@ -90,20 +90,45 @@ func (s *gatewayService) DisconnectDB(request *types.DisconnectDBParams) (*types } func (s *gatewayService) ExecNGQL(request *types.ExecNGQLParams) (*types.AnyResponse, error) { - execute, _, err := dao.Execute(request.NSID, request.Gql, request.ParamList) + httpReq, _ := middleware.GetRequest(s.ctx) + NSIDCookie, NSIDErr := httpReq.Cookie(auth.NSIDName) + if NSIDErr != nil { + return nil, ecode.WithSessionMessage(NSIDErr) + } + + execute, _, err := dao.Execute(NSIDCookie.Value, request.Gql, request.ParamList) if err != nil { - return nil, ecode.WithCode(ecode.ErrInternalServer, err, "exec failed") + // TODO: common middleware should handle this + subErrMsgStr := []string{ + "session expired", + "connection refused", + "broken pipe", + "an existing connection was forcibly closed", + "Token is expired", + } + for _, subErrMsg := range subErrMsgStr { + if strings.Contains(err.Error(), subErrMsg) { + return nil, ecode.WithSessionMessage(err) + } + } + return nil, ecode.WithErrorMessage(ecode.ErrInternalServer, err, "execute failed") } + return &types.AnyResponse{Data: execute}, nil } func (s *gatewayService) BatchExecNGQL(request *types.BatchExecNGQLParams) (*types.AnyResponse, error) { - data := make([]map[string]interface{}, 0) + httpReq, _ := middleware.GetRequest(s.ctx) + NSIDCookie, NSIDErr := httpReq.Cookie(auth.NSIDName) + if NSIDErr != nil { + return nil, ecode.WithSessionMessage(NSIDErr) + } - NSID := request.NSID + NSID := NSIDCookie.Value gqls := request.Gqls paramList := request.ParamList + data := make([]map[string]interface{}, 0) for _, gql := range gqls { execute, _, err := dao.Execute(NSID, gql, make([]string, 0)) gqlRes := map[string]interface{}{"gql": gql, "data": execute} diff --git a/server-v2/api/studio/internal/service/import.go b/server-v2/api/studio/internal/service/import.go index 0d9c0a0c..d44bb8dc 100644 --- a/server-v2/api/studio/internal/service/import.go +++ b/server-v2/api/studio/internal/service/import.go @@ -18,6 +18,7 @@ import ( "github.com/vesoft-inc/nebula-studio/server-v2/api/studio/internal/service/importer" "github.com/vesoft-inc/nebula-studio/server-v2/api/studio/internal/svc" "github.com/vesoft-inc/nebula-studio/server-v2/api/studio/internal/types" + "github.com/vesoft-inc/nebula-studio/server-v2/api/studio/pkg/auth" "github.com/vesoft-inc/nebula-studio/server-v2/api/studio/pkg/ecode" "github.com/vesoft-inc/nebula-studio/server-v2/api/studio/pkg/utils" "github.com/zeromicro/go-zero/core/logx" @@ -151,7 +152,9 @@ func (i *importService) CreateImportTask(req *types.CreateImportTaskRequest) (*t } func (i *importService) StopImportTask(req *types.StopImportTaskRequest) error { - return importer.StopImportTask(req.Id, req.Address+":"+req.Port, req.Username) + auth := i.ctx.Value(auth.CtxKeyUserInfo{}).(*auth.AuthData) + host := fmt.Sprintf("%s:%d", auth.Address, auth.Port) + return importer.StopImportTask(req.Id, host, auth.Username) } func (i *importService) DownloadConfig(req *types.DownloadConfigsRequest) error { @@ -201,15 +204,21 @@ func (i *importService) DownloadLogs(req *types.DownloadLogsRequest) error { } func (i *importService) DeleteImportTask(req *types.DeleteImportTaskRequest) error { - return importer.DeleteImportTask(i.svcCtx.Config.File.TasksDir, req.Id, req.Address+":"+req.Port, req.Username) + auth := i.ctx.Value(auth.CtxKeyUserInfo{}).(*auth.AuthData) + host := fmt.Sprintf("%s:%d", auth.Address, auth.Port) + return importer.DeleteImportTask(i.svcCtx.Config.File.TasksDir, req.Id, host, auth.Username) } func (i *importService) GetImportTask(req *types.GetImportTaskRequest) (*types.GetImportTaskData, error) { - return importer.GetImportTask(i.svcCtx.Config.File.TasksDir, req.Id, req.Address+":"+req.Port, req.Username) + auth := i.ctx.Value(auth.CtxKeyUserInfo{}).(*auth.AuthData) + host := fmt.Sprintf("%s:%d", auth.Address, auth.Port) + return importer.GetImportTask(i.svcCtx.Config.File.TasksDir, req.Id, host, auth.Username) } func (i *importService) GetManyImportTask(req *types.GetManyImportTaskRequest) (*types.GetManyImportTaskData, error) { - return importer.GetManyImportTask(i.svcCtx.Config.File.TasksDir, req.Address+":"+req.Port, req.Username, req.Page, req.PageSize) + auth := i.ctx.Value(auth.CtxKeyUserInfo{}).(*auth.AuthData) + host := fmt.Sprintf("%s:%d", auth.Address, auth.Port) + return importer.GetManyImportTask(i.svcCtx.Config.File.TasksDir, host, auth.Username, req.Page, req.PageSize) } // GetImportTaskLogNames :Get all log file's name of a task diff --git a/server-v2/api/studio/internal/types/types.go b/server-v2/api/studio/internal/types/types.go index 5196306a..8e98bbae 100644 --- a/server-v2/api/studio/internal/types/types.go +++ b/server-v2/api/studio/internal/types/types.go @@ -8,19 +8,16 @@ type GetHealth struct { type ExecNGQLParams struct { Gql string `json:"gql"` ParamList []string `json:"paramList,optional"` - NSID string `form:"NSID"` } type BatchExecNGQLParams struct { Gqls []string `json:"gqls"` ParamList []string `json:"paramList,optional"` - NSID string `form:"NSID"` } type ConnectDBParams struct { Address string `json:"address"` Port int `json:"port"` - NebulaVersion string `form:"nebulaVersion,optional"` Authorization string `header:"Authorization"` } @@ -28,10 +25,6 @@ type ConnectDBResult struct { Version string `json:"version"` } -type DisconnectDBParams struct { - NSID string `form:"NSID,optional"` -} - type AnyResponse struct { Data interface{} `json:"data"` } @@ -127,7 +120,7 @@ type ImportTaskEdge struct { Name string `json:"name" validate:"required"` SrcVID ImportTaskEdgeID `json:"srcVID" validate:"required"` DstVID ImportTaskEdgeID `json:"dstVID" validate:"required"` - Rank ImportTaskEdgeRank `json:"rank,optional"` + Rank ImportTaskEdgeRank `json:"rank, optional"` Props []ImportTaskEdgeProp `json:"props" validate:"required"` } @@ -141,8 +134,8 @@ type ImportTaskFile struct { Path string `json:"path" validate:"required"` FailDataPath string `json:"failDataPath" validate:"required"` BatchSize int `json:"batchSize,optional"` - Limit int `json:"limit,optional"` - InOrder bool `json:"inOrder,optional"` + Limit int `json:"limit, optional"` + InOrder bool `json:"inOrder, optional"` Type string `json:"type" validate:"required"` CSV ImportTaskCSV `json:"csv" validate:"required"` Schema ImportTaskSchema `json:"schema" validate:"required"` @@ -166,10 +159,7 @@ type CreateImportTaskData struct { } type GetImportTaskRequest struct { - Id string `path:"id" validate:"required"` - Address string `form:"address"` - Username string `form:"username"` - Port string `form:"port"` + Id string `path:"id" validate:"required"` } type GetImportTaskData struct { @@ -196,11 +186,8 @@ type ImportTaskStats struct { } type GetManyImportTaskRequest struct { - Address string `form:"address"` - Username string `form:"username"` - Port string `form:"port"` - Page int `form:"page,default=1"` - PageSize int `form:"pageSize,default=100"` + Page int `form:"page,default=1"` + PageSize int `form:"pageSize,default=100"` } type GetManyImportTaskData struct { @@ -220,7 +207,7 @@ type GetManyImportTaskLogData struct { } type GetImportTaskLogNamesRequest struct { - Id string `path:"id" validate:"required"` + Id string `path:"id" validate:"required""` } type GetImportTaskLogNamesData struct { @@ -228,17 +215,11 @@ type GetImportTaskLogNamesData struct { } type DeleteImportTaskRequest struct { - Id string `path:"id"` - Address string `form:"address"` - Username string `form:"username"` - Port string `form:"port"` + Id string `path:"id"` } type StopImportTaskRequest struct { - Id string `path:"id"` - Address string `form:"address"` - Port string `form:"port"` - Username string `form:"username"` + Id string `path:"id"` } type DownloadLogsRequest struct { diff --git a/server-v2/api/studio/pkg/auth/authorize.go b/server-v2/api/studio/pkg/auth/authorize.go index 70444273..6b87069f 100644 --- a/server-v2/api/studio/pkg/auth/authorize.go +++ b/server-v2/api/studio/pkg/auth/authorize.go @@ -1,6 +1,7 @@ package auth import ( + "context" "encoding/base64" "errors" "fmt" @@ -26,6 +27,7 @@ type ( Address string `json:"address"` Port int `json:"port"` Username string `json:"username"` + Password string `json:"password"` } authClaims struct { @@ -110,6 +112,7 @@ func ParseConnectDBParams(params *types.ConnectDBParams, config *config.Config) Address: params.Address, Port: params.Port, Username: username, + Password: password, }, config, ) @@ -124,17 +127,8 @@ func AuthMiddlewareWithCtx(svcCtx *svc.ServiceContext) rest.Middleware { return } - NSIDCookie, NSIDErr := r.Cookie(NSIDName) - if NSIDErr == nil { - // Add NSID to request query - utils.AddQueryParams(r, map[string]string{"NSID": NSIDCookie.Value}) - } - tokenCookie, tokenErr := r.Cookie(TokenName) - if NSIDErr != nil { - svcCtx.ResponseHandler.Handle(w, r, nil, ecode.WithSessionMessage(NSIDErr)) - return - } else if tokenErr != nil { + if tokenErr != nil { svcCtx.ResponseHandler.Handle(w, r, nil, ecode.WithSessionMessage(tokenErr)) return } @@ -145,12 +139,13 @@ func AuthMiddlewareWithCtx(svcCtx *svc.ServiceContext) rest.Middleware { return } - // Add address|port|username to request query - utils.AddQueryParams(r, map[string]string{ - "address": auth.Address, - "port": fmt.Sprintf("%d", auth.Port), - "username": auth.Username, - }) + /** + * Add auth to request context + * + * Get auth from context: + * auth := s.ctx.Value(auth.CtxKeyUserInfo{}).(*auth.AuthData) + */ + r = r.WithContext(context.WithValue(r.Context(), CtxKeyUserInfo{}, auth)) next(w, r) } diff --git a/server-v2/api/studio/pkg/ecode/codes.go b/server-v2/api/studio/pkg/ecode/codes.go index 37feb4ca..59b64246 100644 --- a/server-v2/api/studio/pkg/ecode/codes.go +++ b/server-v2/api/studio/pkg/ecode/codes.go @@ -52,6 +52,11 @@ func WithSessionMessage(err error, formatWithArgs ...interface{}) error { return WithCode(ErrSessionWithMessage, err, formatWithArgs...) } +func WithErrorMessage(c *ErrCode, err error, formatWithArgs ...interface{}) error { + ErrWithMessage := newErrCode(c.GetCode(), PlatformCode, 1, fmt.Sprintf("%s::%s", c.GetMessage(), err.Error())) + return WithCode(ErrWithMessage, err, formatWithArgs...) +} + func WithForbidden(err error, formatWithArgs ...interface{}) error { return WithCode(ErrForbidden, err, formatWithArgs...) } diff --git a/server-v2/api/studio/restapi/gateway.api b/server-v2/api/studio/restapi/gateway.api index baee6de6..ce724fa6 100644 --- a/server-v2/api/studio/restapi/gateway.api +++ b/server-v2/api/studio/restapi/gateway.api @@ -4,25 +4,19 @@ type ( ExecNGQLParams { Gql string `json:"gql"` ParamList []string `json:"paramList,optional"` - NSID string `form:"NSID"` } BatchExecNGQLParams { Gqls []string `json:"gqls"` ParamList []string `json:"paramList,optional"` - NSID string `form:"NSID"` } ConnectDBParams { Address string `json:"address"` Port int `json:"port"` - NebulaVersion string `form:"nebulaVersion,optional"` Authorization string `header:"Authorization"` } ConnectDBResult { Version string `json:"version"` } - DisconnectDBParams { - NSID string `form:"NSID,optional"` - } AnyResponse { Data interface{} `json:"data"` } @@ -55,5 +49,5 @@ service studio-api { @doc "Disonnect DB" @handler Disonnect - post /disconnect(DisconnectDBParams) returns (AnyResponse) + post /disconnect returns (AnyResponse) } \ No newline at end of file diff --git a/server-v2/api/studio/restapi/import.api b/server-v2/api/studio/restapi/import.api index 785b06aa..ab2bf849 100644 --- a/server-v2/api/studio/restapi/import.api +++ b/server-v2/api/studio/restapi/import.api @@ -115,10 +115,7 @@ type ( } GetImportTaskRequest { - Id string `path:"id" validate:"required"` - Address string `form:"address"` - Username string `form:"username"` - Port string `form:"port"` + Id string `path:"id" validate:"required"` } GetImportTaskData { @@ -145,11 +142,8 @@ type ( } GetManyImportTaskRequest { - Address string `form:"address"` - Username string `form:"username"` - Port string `form:"port"` - Page int `form:"page,default=1"` - PageSize int `form:"pageSize,default=100"` + Page int `form:"page,default=1"` + PageSize int `form:"pageSize,default=100"` } GetManyImportTaskData { @@ -177,17 +171,11 @@ type ( } DeleteImportTaskRequest { - Id string `path:"id"` - Address string `form:"address"` - Username string `form:"username"` - Port string `form:"port"` + Id string `path:"id"` } StopImportTaskRequest { - Id string `path:"id"` - Address string `form:"address"` - Port string `form:"port"` - Username string `form:"username"` + Id string `path:"id"` } DownloadLogsRequest {