mirror of
https://github.com/simon987/task_tracker.git
synced 2025-12-10 21:48:52 +00:00
Cleanup api responses
This commit is contained in:
106
api/auth.go
106
api/auth.go
@@ -7,55 +7,13 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const MinPasswordLength = 8
|
||||
const MinUsernameLength = 3
|
||||
const MaxUsernameLength = 16
|
||||
|
||||
type LoginRequest struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
type LoginResponse struct {
|
||||
Ok bool `json:"ok"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Manager *storage.Manager `json:"manager"`
|
||||
}
|
||||
|
||||
type RegisterRequest struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
type AccountDetails struct {
|
||||
LoggedIn bool `json:"logged_in"`
|
||||
Manager *storage.Manager `json:"manager,omitempty"`
|
||||
}
|
||||
|
||||
type GetAllManagersResponse struct {
|
||||
Ok bool `json:"ok"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Managers *[]storage.Manager `json:"managers"`
|
||||
}
|
||||
|
||||
func (r *RegisterRequest) isValid() bool {
|
||||
return MinUsernameLength <= len(r.Username) &&
|
||||
len(r.Username) <= MaxUsernameLength &&
|
||||
MinPasswordLength <= len(r.Password)
|
||||
}
|
||||
|
||||
type RegisterResponse struct {
|
||||
Ok bool `json:"ok"`
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
func (api *WebAPI) Login(r *Request) {
|
||||
|
||||
req := &LoginRequest{}
|
||||
err := json.Unmarshal(r.Ctx.Request.Body(), req)
|
||||
|
||||
if err != nil {
|
||||
r.Json(LoginResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Could not parse request",
|
||||
}, 400)
|
||||
@@ -68,7 +26,7 @@ func (api *WebAPI) Login(r *Request) {
|
||||
"username": req.Username,
|
||||
}).Warning("Login attempt")
|
||||
|
||||
r.Json(LoginResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Invalid username/password",
|
||||
}, 403)
|
||||
@@ -78,9 +36,11 @@ func (api *WebAPI) Login(r *Request) {
|
||||
sess := api.Session.StartFasthttp(r.Ctx)
|
||||
sess.Set("manager", manager)
|
||||
|
||||
r.OkJson(LoginResponse{
|
||||
Manager: manager,
|
||||
Ok: true,
|
||||
r.OkJson(JsonResponse{
|
||||
Content: LoginResponse{
|
||||
Manager: manager,
|
||||
},
|
||||
Ok: true,
|
||||
})
|
||||
|
||||
logrus.WithFields(logrus.Fields{
|
||||
@@ -101,7 +61,7 @@ func (api *WebAPI) Register(r *Request) {
|
||||
err := json.Unmarshal(r.Ctx.Request.Body(), req)
|
||||
|
||||
if err != nil {
|
||||
r.Json(LoginResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Could not parse request",
|
||||
}, 400)
|
||||
@@ -109,7 +69,7 @@ func (api *WebAPI) Register(r *Request) {
|
||||
}
|
||||
|
||||
if !req.isValid() {
|
||||
r.Json(LoginResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Invalid register request",
|
||||
}, 400)
|
||||
@@ -126,7 +86,7 @@ func (api *WebAPI) Register(r *Request) {
|
||||
"username": string(manager.Username),
|
||||
}).Warning("Register attempt")
|
||||
|
||||
r.Json(LoginResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: err.Error(),
|
||||
}, 400)
|
||||
@@ -136,7 +96,7 @@ func (api *WebAPI) Register(r *Request) {
|
||||
sess := api.Session.StartFasthttp(r.Ctx)
|
||||
sess.Set("manager", manager)
|
||||
|
||||
r.OkJson(RegisterResponse{
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: true,
|
||||
})
|
||||
|
||||
@@ -145,7 +105,7 @@ func (api *WebAPI) Register(r *Request) {
|
||||
}).Info("Registered")
|
||||
}
|
||||
|
||||
func (api *WebAPI) AccountDetails(r *Request) {
|
||||
func (api *WebAPI) GetAccountDetails(r *Request) {
|
||||
|
||||
sess := api.Session.StartFasthttp(r.Ctx)
|
||||
manager := sess.Get("manager")
|
||||
@@ -155,35 +115,43 @@ func (api *WebAPI) AccountDetails(r *Request) {
|
||||
}).Trace("Account details request")
|
||||
|
||||
if manager == nil {
|
||||
r.OkJson(AccountDetails{
|
||||
LoggedIn: false,
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: false,
|
||||
Content: GetAccountDetailsResponse{
|
||||
LoggedIn: false,
|
||||
},
|
||||
})
|
||||
} else {
|
||||
r.OkJson(AccountDetails{
|
||||
LoggedIn: true,
|
||||
Manager: manager.(*storage.Manager),
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: true,
|
||||
Content: GetAccountDetailsResponse{
|
||||
LoggedIn: true,
|
||||
Manager: manager.(*storage.Manager),
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (api *WebAPI) GetAllManagers(r *Request) {
|
||||
func (api *WebAPI) GetManagerList(r *Request) {
|
||||
|
||||
sess := api.Session.StartFasthttp(r.Ctx)
|
||||
manager := sess.Get("manager")
|
||||
|
||||
if manager == nil {
|
||||
r.Json(GetAllManagersResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Unauthorized",
|
||||
}, 401)
|
||||
return
|
||||
}
|
||||
|
||||
managers := api.Database.GetAllManagers()
|
||||
managers := api.Database.GetManagerList()
|
||||
|
||||
r.OkJson(GetAllManagersResponse{
|
||||
Ok: true,
|
||||
Managers: managers,
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: true,
|
||||
Content: GetManagerListResponse{
|
||||
Managers: managers,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -191,7 +159,7 @@ func (api *WebAPI) PromoteManager(r *Request) {
|
||||
|
||||
id, err := strconv.ParseInt(r.Ctx.UserValue("id").(string), 10, 64)
|
||||
if err != nil || id <= 0 {
|
||||
r.Json(CreateProjectResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Invalid manager id",
|
||||
}, 400)
|
||||
@@ -202,7 +170,7 @@ func (api *WebAPI) PromoteManager(r *Request) {
|
||||
manager := sess.Get("manager")
|
||||
|
||||
if !manager.(*storage.Manager).WebsiteAdmin || manager.(*storage.Manager).Id == id {
|
||||
r.Json(GetAllManagersResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Unauthorized",
|
||||
}, 401)
|
||||
@@ -210,7 +178,7 @@ func (api *WebAPI) PromoteManager(r *Request) {
|
||||
}
|
||||
|
||||
if !manager.(*storage.Manager).WebsiteAdmin {
|
||||
r.Json(GetAllManagersResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Unauthorized",
|
||||
}, 403)
|
||||
@@ -229,7 +197,7 @@ func (api *WebAPI) DemoteManager(r *Request) {
|
||||
|
||||
id, err := strconv.ParseInt(r.Ctx.UserValue("id").(string), 10, 64)
|
||||
if err != nil || id <= 0 {
|
||||
r.Json(CreateProjectResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Invalid manager id",
|
||||
}, 400)
|
||||
@@ -240,7 +208,7 @@ func (api *WebAPI) DemoteManager(r *Request) {
|
||||
manager := sess.Get("manager")
|
||||
|
||||
if manager == nil {
|
||||
r.Json(GetAllManagersResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Unauthorized",
|
||||
}, 401)
|
||||
@@ -248,7 +216,7 @@ func (api *WebAPI) DemoteManager(r *Request) {
|
||||
}
|
||||
|
||||
if !manager.(*storage.Manager).WebsiteAdmin || manager.(*storage.Manager).Id == id {
|
||||
r.Json(GetAllManagersResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Unauthorized",
|
||||
}, 403)
|
||||
|
||||
12
api/error.go
12
api/error.go
@@ -5,21 +5,17 @@ import (
|
||||
"runtime/debug"
|
||||
)
|
||||
|
||||
type ErrorResponse struct {
|
||||
Message string `json:"message"`
|
||||
StackTrace string `json:"stack_trace"`
|
||||
|
||||
}
|
||||
|
||||
func handleErr(err error, r *Request) {
|
||||
|
||||
if err != nil {
|
||||
logrus.Error(err.Error())
|
||||
//debug.PrintStack()
|
||||
|
||||
r.Json(ErrorResponse{
|
||||
r.Json(JsonResponse{
|
||||
Message: err.Error(),
|
||||
StackTrace: string(debug.Stack()),
|
||||
Content: ErrorResponse{
|
||||
StackTrace: string(debug.Stack()),
|
||||
},
|
||||
}, 500)
|
||||
}
|
||||
}
|
||||
|
||||
30
api/git.go
30
api/git.go
@@ -14,36 +14,6 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
type GitPayload struct {
|
||||
Ref string `json:"ref"`
|
||||
Before string `json:"before"`
|
||||
After string `json:"after"`
|
||||
Repository struct {
|
||||
Id int64 `json:"id"`
|
||||
Owner struct {
|
||||
Id int64 `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Login string `json:"login"`
|
||||
FullName string `json:"full_name"`
|
||||
Email string `json:"email"`
|
||||
} `json:"owner"`
|
||||
Name string `json:"name"`
|
||||
FullName string `json:"full_name"`
|
||||
Private bool `json:"private"`
|
||||
Fork bool `json:"fork"`
|
||||
Size int64 `json:"size"`
|
||||
HtmlUrl string `json:"html_url"`
|
||||
SshUrl string `json:"ssh_url"`
|
||||
CloneUrl string `json:"clone_url"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
} `json:"repository"`
|
||||
}
|
||||
|
||||
func (g GitPayload) String() string {
|
||||
jsonBytes, _ := json.Marshal(g)
|
||||
return string(jsonBytes)
|
||||
}
|
||||
|
||||
func (api *WebAPI) ReceiveGitWebHook(r *Request) {
|
||||
|
||||
if !signatureValid(r) {
|
||||
|
||||
@@ -10,7 +10,7 @@ type Request struct {
|
||||
Ctx *fasthttp.RequestCtx
|
||||
}
|
||||
|
||||
func (r *Request) OkJson(object interface{}) {
|
||||
func (r *Request) OkJson(object JsonResponse) {
|
||||
|
||||
resp, err := json.Marshal(object)
|
||||
handleErr(err, r)
|
||||
@@ -20,7 +20,7 @@ func (r *Request) OkJson(object interface{}) {
|
||||
handleErr(err, r)
|
||||
}
|
||||
|
||||
func (r *Request) Json(object interface{}, code int) {
|
||||
func (r *Request) Json(object JsonResponse, code int) {
|
||||
|
||||
resp, err := json.Marshal(object)
|
||||
if err != nil {
|
||||
|
||||
55
api/log.go
55
api/log.go
@@ -5,36 +5,10 @@ import (
|
||||
"errors"
|
||||
"github.com/Sirupsen/logrus"
|
||||
"github.com/simon987/task_tracker/config"
|
||||
"github.com/simon987/task_tracker/storage"
|
||||
"github.com/valyala/fasthttp"
|
||||
"time"
|
||||
)
|
||||
|
||||
type RequestHandler func(*Request)
|
||||
|
||||
type GetLogRequest struct {
|
||||
Level storage.LogLevel `json:"level"`
|
||||
Since int64 `json:"since"`
|
||||
}
|
||||
|
||||
type LogRequest struct {
|
||||
Scope string `json:"scope"`
|
||||
Message string `json:"Message"`
|
||||
TimeStamp int64 `json:"timestamp"`
|
||||
worker *storage.Worker
|
||||
}
|
||||
|
||||
type GetLogResponse struct {
|
||||
Ok bool `json:"ok"`
|
||||
Message string `json:"message"`
|
||||
Logs *[]storage.LogEntry `json:"logs"`
|
||||
}
|
||||
|
||||
type LogResponse struct {
|
||||
Ok bool `json:"ok"`
|
||||
Message string `json:"message"`
|
||||
}
|
||||
|
||||
func (e *LogRequest) Time() time.Time {
|
||||
|
||||
t := time.Unix(e.TimeStamp, 0)
|
||||
@@ -94,7 +68,7 @@ func (api *WebAPI) LogTrace(r *Request) {
|
||||
|
||||
entry, err := api.parseLogEntry(r)
|
||||
if err != nil {
|
||||
r.Json(LogResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Could not parse request",
|
||||
}, 400)
|
||||
@@ -111,7 +85,7 @@ func (api *WebAPI) LogInfo(r *Request) {
|
||||
|
||||
entry, err := api.parseLogEntry(r)
|
||||
if err != nil {
|
||||
r.Json(LogResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Could not parse request",
|
||||
}, 400)
|
||||
@@ -128,7 +102,7 @@ func (api *WebAPI) LogWarn(r *Request) {
|
||||
|
||||
entry, err := api.parseLogEntry(r)
|
||||
if err != nil {
|
||||
r.Json(LogResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Could not parse request",
|
||||
}, 400)
|
||||
@@ -145,7 +119,7 @@ func (api *WebAPI) LogError(r *Request) {
|
||||
|
||||
entry, err := api.parseLogEntry(r)
|
||||
if err != nil {
|
||||
r.Json(LogResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Could not parse request",
|
||||
}, 400)
|
||||
@@ -163,7 +137,7 @@ func (api *WebAPI) GetLog(r *Request) {
|
||||
req := &GetLogRequest{}
|
||||
err := json.Unmarshal(r.Ctx.Request.Body(), req)
|
||||
if err != nil {
|
||||
r.Json(GetLogResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Could not parse request",
|
||||
}, 400)
|
||||
@@ -178,27 +152,20 @@ func (api *WebAPI) GetLog(r *Request) {
|
||||
"logCount": len(*logs),
|
||||
}).Trace("Get log request")
|
||||
|
||||
r.OkJson(GetLogResponse{
|
||||
Ok: true,
|
||||
Logs: logs,
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: true,
|
||||
Content: GetLogResponse{
|
||||
Logs: logs,
|
||||
},
|
||||
})
|
||||
} else {
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"getLogRequest": req,
|
||||
}).Warn("Invalid log request")
|
||||
|
||||
r.Json(GetLogResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Invalid log request",
|
||||
}, 400)
|
||||
}
|
||||
}
|
||||
|
||||
func (r GetLogRequest) isValid() bool {
|
||||
|
||||
if r.Since <= 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
44
api/main.go
44
api/main.go
@@ -20,10 +20,7 @@ type WebAPI struct {
|
||||
Cron *cron.Cron
|
||||
}
|
||||
|
||||
type Info struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
type RequestHandler func(*Request)
|
||||
|
||||
var info = Info{
|
||||
Name: "task_tracker",
|
||||
@@ -31,7 +28,10 @@ var info = Info{
|
||||
}
|
||||
|
||||
func Index(r *Request) {
|
||||
r.OkJson(info)
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: true,
|
||||
Content: info,
|
||||
})
|
||||
}
|
||||
|
||||
func (api *WebAPI) setupMonitoring() {
|
||||
@@ -75,27 +75,27 @@ func New() *WebAPI {
|
||||
api.router.POST("/log/warn", LogRequestMiddleware(api.LogWarn))
|
||||
api.router.POST("/log/error", LogRequestMiddleware(api.LogError))
|
||||
|
||||
api.router.POST("/worker/create", LogRequestMiddleware(api.WorkerCreate))
|
||||
api.router.POST("/worker/update", LogRequestMiddleware(api.WorkerUpdate))
|
||||
api.router.GET("/worker/get/:id", LogRequestMiddleware(api.WorkerGet))
|
||||
api.router.POST("/worker/create", LogRequestMiddleware(api.CreateWorker))
|
||||
api.router.POST("/worker/update", LogRequestMiddleware(api.UpdateWorker))
|
||||
api.router.GET("/worker/get/:id", LogRequestMiddleware(api.GetWorker))
|
||||
api.router.GET("/worker/stats", LogRequestMiddleware(api.GetAllWorkerStats))
|
||||
|
||||
api.router.POST("/project/create", LogRequestMiddleware(api.ProjectCreate))
|
||||
api.router.GET("/project/get/:id", LogRequestMiddleware(api.ProjectGet))
|
||||
api.router.POST("/project/update/:id", LogRequestMiddleware(api.ProjectUpdate))
|
||||
api.router.GET("/project/list", LogRequestMiddleware(api.ProjectGetAllProjects))
|
||||
api.router.GET("/project/monitoring-between/:id", LogRequestMiddleware(api.GetSnapshotsBetween))
|
||||
api.router.POST("/project/create", LogRequestMiddleware(api.CreateProject))
|
||||
api.router.GET("/project/get/:id", LogRequestMiddleware(api.GetProject))
|
||||
api.router.POST("/project/update/:id", LogRequestMiddleware(api.UpdateProject))
|
||||
api.router.GET("/project/list", LogRequestMiddleware(api.GetProjectList))
|
||||
api.router.GET("/project/monitoring-between/:id", LogRequestMiddleware(api.GetSnapshotsWithinRange))
|
||||
api.router.GET("/project/monitoring/:id", LogRequestMiddleware(api.GetNSnapshots))
|
||||
api.router.GET("/project/assignees/:id", LogRequestMiddleware(api.ProjectGetAssigneeStats))
|
||||
api.router.GET("/project/accesses/:id", LogRequestMiddleware(api.ProjectGetWorkerAccesses))
|
||||
api.router.POST("/project/request_access", LogRequestMiddleware(api.WorkerRequestAccess))
|
||||
api.router.GET("/project/assignees/:id", LogRequestMiddleware(api.GetAssigneeStatsForProject))
|
||||
api.router.GET("/project/accesses/:id", LogRequestMiddleware(api.GetWorkerAccessListForProject))
|
||||
api.router.POST("/project/request_access", LogRequestMiddleware(api.CreateWorkerAccess))
|
||||
api.router.POST("/project/accept_request/:id/:wid", LogRequestMiddleware(api.AcceptAccessRequest))
|
||||
api.router.POST("/project/reject_request/:id/:wid", LogRequestMiddleware(api.RejectAccessRequest))
|
||||
|
||||
api.router.POST("/task/create", LogRequestMiddleware(api.TaskCreate))
|
||||
api.router.GET("/task/get/:project", LogRequestMiddleware(api.TaskGetFromProject))
|
||||
api.router.GET("/task/get", LogRequestMiddleware(api.TaskGet))
|
||||
api.router.POST("/task/release", LogRequestMiddleware(api.TaskRelease))
|
||||
api.router.POST("/task/create", LogRequestMiddleware(api.SubmitTask))
|
||||
api.router.GET("/task/get/:project", LogRequestMiddleware(api.GetTaskFromProject))
|
||||
api.router.GET("/task/get", LogRequestMiddleware(api.GetTask))
|
||||
api.router.POST("/task/release", LogRequestMiddleware(api.ReleaseTask))
|
||||
|
||||
api.router.POST("/git/receivehook", LogRequestMiddleware(api.ReceiveGitWebHook))
|
||||
|
||||
@@ -104,8 +104,8 @@ func New() *WebAPI {
|
||||
api.router.POST("/register", LogRequestMiddleware(api.Register))
|
||||
api.router.POST("/login", LogRequestMiddleware(api.Login))
|
||||
api.router.GET("/logout", LogRequestMiddleware(api.Logout))
|
||||
api.router.GET("/account", LogRequestMiddleware(api.AccountDetails))
|
||||
api.router.GET("/manager/list", LogRequestMiddleware(api.GetAllManagers))
|
||||
api.router.GET("/account", LogRequestMiddleware(api.GetAccountDetails))
|
||||
api.router.GET("/manager/list", LogRequestMiddleware(api.GetManagerList))
|
||||
api.router.GET("/manager/promote/:id", LogRequestMiddleware(api.PromoteManager))
|
||||
api.router.GET("/manager/demote/:id", LogRequestMiddleware(api.DemoteManager))
|
||||
|
||||
|
||||
269
api/models.go
Normal file
269
api/models.go
Normal file
@@ -0,0 +1,269 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"encoding/json"
|
||||
"github.com/simon987/task_tracker/storage"
|
||||
)
|
||||
|
||||
const (
|
||||
MinPasswordLength = 8
|
||||
MinUsernameLength = 3
|
||||
MaxUsernameLength = 16
|
||||
)
|
||||
|
||||
type JsonResponse struct {
|
||||
Ok bool `json:"ok"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Content interface{} `json:"content,omitempty"`
|
||||
}
|
||||
|
||||
type GitPayload struct {
|
||||
Ref string `json:"ref"`
|
||||
Before string `json:"before"`
|
||||
After string `json:"after"`
|
||||
Repository struct {
|
||||
Id int64 `json:"id"`
|
||||
Owner struct {
|
||||
Id int64 `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Login string `json:"login"`
|
||||
FullName string `json:"full_name"`
|
||||
Email string `json:"email"`
|
||||
} `json:"owner"`
|
||||
Name string `json:"name"`
|
||||
FullName string `json:"full_name"`
|
||||
Private bool `json:"private"`
|
||||
Fork bool `json:"fork"`
|
||||
Size int64 `json:"size"`
|
||||
HtmlUrl string `json:"html_url"`
|
||||
SshUrl string `json:"ssh_url"`
|
||||
CloneUrl string `json:"clone_url"`
|
||||
DefaultBranch string `json:"default_branch"`
|
||||
} `json:"repository"`
|
||||
}
|
||||
|
||||
func (g GitPayload) String() string {
|
||||
jsonBytes, _ := json.Marshal(g)
|
||||
return string(jsonBytes)
|
||||
}
|
||||
|
||||
type ErrorResponse struct {
|
||||
Message string `json:"message"`
|
||||
StackTrace string `json:"stack_trace"`
|
||||
}
|
||||
|
||||
type LoginRequest struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
type LoginResponse struct {
|
||||
Manager *storage.Manager `json:"manager"`
|
||||
}
|
||||
|
||||
type RegisterRequest struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password"`
|
||||
}
|
||||
|
||||
func (r *RegisterRequest) isValid() bool {
|
||||
return MinUsernameLength <= len(r.Username) &&
|
||||
len(r.Username) <= MaxUsernameLength &&
|
||||
MinPasswordLength <= len(r.Password)
|
||||
}
|
||||
|
||||
type GetAccountDetailsResponse struct {
|
||||
LoggedIn bool `json:"logged_in"`
|
||||
Manager *storage.Manager `json:"manager,omitempty"`
|
||||
}
|
||||
|
||||
type GetManagerListResponse struct {
|
||||
Managers *[]storage.Manager `json:"managers"`
|
||||
}
|
||||
|
||||
type GetLogRequest struct {
|
||||
Level storage.LogLevel `json:"level"`
|
||||
Since int64 `json:"since"`
|
||||
}
|
||||
|
||||
func (r GetLogRequest) isValid() bool {
|
||||
|
||||
if r.Since <= 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
type LogRequest struct {
|
||||
Scope string `json:"scope"`
|
||||
Message string `json:"Message"`
|
||||
TimeStamp int64 `json:"timestamp"`
|
||||
worker *storage.Worker
|
||||
}
|
||||
|
||||
type GetLogResponse struct {
|
||||
Logs *[]storage.LogEntry `json:"logs"`
|
||||
}
|
||||
|
||||
type GetSnapshotsResponse struct {
|
||||
Snapshots *[]storage.ProjectMonitoringSnapshot `json:"snapshots,omitempty"`
|
||||
}
|
||||
|
||||
type CreateProjectRequest struct {
|
||||
Name string `json:"name"`
|
||||
CloneUrl string `json:"clone_url"`
|
||||
GitRepo string `json:"git_repo"`
|
||||
Version string `json:"version"`
|
||||
Priority int64 `json:"priority"`
|
||||
Motd string `json:"motd"`
|
||||
Public bool `json:"public"`
|
||||
Hidden bool `json:"hidden"`
|
||||
Chain int64 `json:"chain"`
|
||||
}
|
||||
|
||||
func (req *CreateProjectRequest) isValid() bool {
|
||||
if len(req.Name) <= 0 {
|
||||
return false
|
||||
}
|
||||
if req.Priority < 0 {
|
||||
return false
|
||||
}
|
||||
if req.Hidden && req.Public {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
type UpdateProjectRequest struct {
|
||||
Name string `json:"name"`
|
||||
CloneUrl string `json:"clone_url"`
|
||||
GitRepo string `json:"git_repo"`
|
||||
Priority int64 `json:"priority"`
|
||||
Motd string `json:"motd"`
|
||||
Public bool `json:"public"`
|
||||
Hidden bool `json:"hidden"`
|
||||
Chain int64 `json:"chain"`
|
||||
}
|
||||
|
||||
func (req *UpdateProjectRequest) isValid() bool {
|
||||
if len(req.Name) <= 0 {
|
||||
return false
|
||||
}
|
||||
if req.Priority < 0 {
|
||||
return false
|
||||
}
|
||||
if req.Hidden && req.Public {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
type CreateProjectResponse struct {
|
||||
Id int64 `json:"id,omitempty"`
|
||||
}
|
||||
|
||||
type GetProjectResponse struct {
|
||||
Project *storage.Project `json:"project,omitempty"`
|
||||
}
|
||||
|
||||
type GetProjectListResponse struct {
|
||||
Projects *[]storage.Project `json:"projects,omitempty"`
|
||||
}
|
||||
|
||||
type GetAssigneeStatsForProjectResponse struct {
|
||||
Assignees *[]storage.AssignedTasks `json:"assignees"`
|
||||
}
|
||||
|
||||
type GetWorkerAccessListForProjectResponse struct {
|
||||
Accesses *[]storage.WorkerAccess `json:"accesses,omitempty"`
|
||||
}
|
||||
|
||||
type SubmitTaskRequest struct {
|
||||
Project int64 `json:"project"`
|
||||
MaxRetries int64 `json:"max_retries"`
|
||||
Recipe string `json:"recipe"`
|
||||
Priority int64 `json:"priority"`
|
||||
MaxAssignTime int64 `json:"max_assign_time"`
|
||||
Hash64 int64 `json:"hash_u64"`
|
||||
UniqueString string `json:"unique_string"`
|
||||
VerificationCount int64 `json:"verification_count"`
|
||||
}
|
||||
|
||||
func (req *SubmitTaskRequest) IsValid() bool {
|
||||
if req.MaxRetries < 0 {
|
||||
return false
|
||||
}
|
||||
if len(req.Recipe) <= 0 {
|
||||
return false
|
||||
}
|
||||
if req.Hash64 != 0 && req.UniqueString != "" {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
type ReleaseTaskRequest struct {
|
||||
TaskId int64 `json:"task_id"`
|
||||
Result storage.TaskResult `json:"result"`
|
||||
Verification int64 `json:"verification"`
|
||||
}
|
||||
|
||||
type ReleaseTaskResponse struct {
|
||||
Updated bool `json:"updated"`
|
||||
}
|
||||
|
||||
type CreateTaskResponse struct {
|
||||
}
|
||||
|
||||
type GetTaskResponse struct {
|
||||
Task *storage.Task `json:"task,omitempty"`
|
||||
}
|
||||
|
||||
type UpdateWorkerRequest struct {
|
||||
Alias string `json:"alias"`
|
||||
}
|
||||
|
||||
type CreateWorkerRequest struct {
|
||||
Alias string `json:"alias"`
|
||||
}
|
||||
|
||||
func (req *CreateWorkerRequest) isValid() bool {
|
||||
if req.Alias == "unassigned" {
|
||||
//Reserved alias
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
type CreateWorkerResponse struct {
|
||||
Worker *storage.Worker `json:"worker,omitempty"`
|
||||
}
|
||||
|
||||
type GetWorkerResponse struct {
|
||||
Worker *storage.Worker `json:"worker,omitempty"`
|
||||
}
|
||||
|
||||
type GetAllWorkerStatsResponse struct {
|
||||
Stats *[]storage.WorkerStats `json:"stats"`
|
||||
}
|
||||
|
||||
type CreateWorkerAccessRequest struct {
|
||||
Assign bool `json:"assign"`
|
||||
Submit bool `json:"submit"`
|
||||
Project int64 `json:"project"`
|
||||
}
|
||||
|
||||
func (w *CreateWorkerAccessRequest) isValid() bool {
|
||||
if !w.Assign && !w.Submit {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
type Info struct {
|
||||
Name string `json:"name"`
|
||||
Version string `json:"version"`
|
||||
}
|
||||
@@ -1,24 +1,17 @@
|
||||
package api
|
||||
|
||||
import (
|
||||
"github.com/simon987/task_tracker/storage"
|
||||
"math"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type MonitoringSnapshotResponse struct {
|
||||
Ok bool `json:"ok"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Snapshots *[]storage.ProjectMonitoringSnapshot `json:"snapshots,omitempty"`
|
||||
}
|
||||
|
||||
func (api *WebAPI) GetSnapshotsBetween(r *Request) {
|
||||
func (api *WebAPI) GetSnapshotsWithinRange(r *Request) {
|
||||
|
||||
id, err := strconv.ParseInt(r.Ctx.UserValue("id").(string), 10, 64)
|
||||
from := r.Ctx.Request.URI().QueryArgs().GetUintOrZero("from")
|
||||
to := r.Ctx.Request.URI().QueryArgs().GetUintOrZero("to")
|
||||
if err != nil || id <= 0 || from <= 0 || to <= 0 || from >= math.MaxInt32 || to >= math.MaxInt32 {
|
||||
r.Json(MonitoringSnapshotResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Invalid request",
|
||||
}, 400)
|
||||
@@ -26,9 +19,11 @@ func (api *WebAPI) GetSnapshotsBetween(r *Request) {
|
||||
}
|
||||
|
||||
snapshots := api.Database.GetMonitoringSnapshotsBetween(id, from, to)
|
||||
r.OkJson(MonitoringSnapshotResponse{
|
||||
Ok: true,
|
||||
Snapshots: snapshots,
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: true,
|
||||
Content: GetSnapshotsResponse{
|
||||
Snapshots: snapshots,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -37,7 +32,7 @@ func (api *WebAPI) GetNSnapshots(r *Request) {
|
||||
id, err := strconv.ParseInt(r.Ctx.UserValue("id").(string), 10, 64)
|
||||
count := r.Ctx.Request.URI().QueryArgs().GetUintOrZero("count")
|
||||
if err != nil || id <= 0 || count <= 0 || count >= 1000 {
|
||||
r.Json(MonitoringSnapshotResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Invalid request",
|
||||
}, 400)
|
||||
@@ -45,8 +40,10 @@ func (api *WebAPI) GetNSnapshots(r *Request) {
|
||||
}
|
||||
|
||||
snapshots := api.Database.GetNMonitoringSnapshots(id, count)
|
||||
r.OkJson(MonitoringSnapshotResponse{
|
||||
Ok: true,
|
||||
Snapshots: snapshots,
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: true,
|
||||
Content: GetSnapshotsResponse{
|
||||
Snapshots: snapshots,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
256
api/project.go
256
api/project.go
@@ -7,70 +7,41 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type CreateProjectRequest struct {
|
||||
Name string `json:"name"`
|
||||
CloneUrl string `json:"clone_url"`
|
||||
GitRepo string `json:"git_repo"`
|
||||
Version string `json:"version"`
|
||||
Priority int64 `json:"priority"`
|
||||
Motd string `json:"motd"`
|
||||
Public bool `json:"public"`
|
||||
Hidden bool `json:"hidden"`
|
||||
Chain int64 `json:"chain"`
|
||||
func (api *WebAPI) GetProject(r *Request) {
|
||||
|
||||
id, err := strconv.ParseInt(r.Ctx.UserValue("id").(string), 10, 64)
|
||||
handleErr(err, r) //todo handle invalid id
|
||||
|
||||
sess := api.Session.StartFasthttp(r.Ctx)
|
||||
manager := sess.Get("manager")
|
||||
|
||||
project := api.Database.GetProject(id)
|
||||
|
||||
if project == nil {
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Project not found",
|
||||
}, 404)
|
||||
return
|
||||
}
|
||||
|
||||
if !isProjectReadAuthorized(project, manager, api.Database) {
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Unauthorized",
|
||||
}, 403)
|
||||
return
|
||||
}
|
||||
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: true,
|
||||
Content: GetProjectResponse{
|
||||
Project: project,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
type UpdateProjectRequest struct {
|
||||
Name string `json:"name"`
|
||||
CloneUrl string `json:"clone_url"`
|
||||
GitRepo string `json:"git_repo"`
|
||||
Priority int64 `json:"priority"`
|
||||
Motd string `json:"motd"`
|
||||
Public bool `json:"public"`
|
||||
Hidden bool `json:"hidden"`
|
||||
Chain int64 `json:"chain"`
|
||||
}
|
||||
|
||||
type UpdateProjectResponse struct {
|
||||
Ok bool `json:"ok"`
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
type CreateProjectResponse struct {
|
||||
Ok bool `json:"ok"`
|
||||
Id int64 `json:"id,omitempty"`
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
type GetProjectResponse struct {
|
||||
Ok bool `json:"ok"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Project *storage.Project `json:"project,omitempty"`
|
||||
}
|
||||
|
||||
type GetAllProjectsResponse struct {
|
||||
Ok bool `json:"ok"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Projects *[]storage.Project `json:"projects,omitempty"`
|
||||
}
|
||||
|
||||
type GetAssigneeStatsResponse struct {
|
||||
Ok bool `json:"ok"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Assignees *[]storage.AssignedTasks `json:"assignees"`
|
||||
}
|
||||
|
||||
type WorkerAccessRequestResponse struct {
|
||||
Ok bool `json:"ok"`
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
type ProjectGetAccessRequestsResponse struct {
|
||||
Ok bool `json:"ok"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Accesses *[]storage.WorkerAccess `json:"accesses,omitempty"`
|
||||
}
|
||||
|
||||
func (api *WebAPI) ProjectCreate(r *Request) {
|
||||
func (api *WebAPI) CreateProject(r *Request) {
|
||||
|
||||
sess := api.Session.StartFasthttp(r.Ctx)
|
||||
manager := sess.Get("manager")
|
||||
@@ -78,7 +49,7 @@ func (api *WebAPI) ProjectCreate(r *Request) {
|
||||
createReq := &CreateProjectRequest{}
|
||||
err := json.Unmarshal(r.Ctx.Request.Body(), createReq)
|
||||
if err != nil {
|
||||
r.Json(CreateProjectResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Could not parse request",
|
||||
}, 400)
|
||||
@@ -96,12 +67,12 @@ func (api *WebAPI) ProjectCreate(r *Request) {
|
||||
Chain: createReq.Chain,
|
||||
}
|
||||
|
||||
if !isValidProject(project) {
|
||||
if !createReq.isValid() {
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"project": project,
|
||||
}).Warn("Invalid project")
|
||||
|
||||
r.Json(CreateProjectResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Invalid project",
|
||||
}, 400)
|
||||
@@ -113,7 +84,7 @@ func (api *WebAPI) ProjectCreate(r *Request) {
|
||||
"project": project,
|
||||
}).Warn("Unauthorized project creation")
|
||||
|
||||
r.Json(CreateProjectResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "You are not permitted to create a project with this configuration",
|
||||
}, 400)
|
||||
@@ -122,7 +93,7 @@ func (api *WebAPI) ProjectCreate(r *Request) {
|
||||
|
||||
id, err := api.Database.SaveProject(project)
|
||||
if err != nil {
|
||||
r.Json(CreateProjectResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: err.Error(),
|
||||
}, 500)
|
||||
@@ -131,20 +102,22 @@ func (api *WebAPI) ProjectCreate(r *Request) {
|
||||
|
||||
api.Database.SetManagerRoleOn(manager.(*storage.Manager), id,
|
||||
storage.ROLE_MANAGE_ACCESS|storage.ROLE_READ|storage.ROLE_EDIT)
|
||||
r.OkJson(CreateProjectResponse{
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: true,
|
||||
Id: id,
|
||||
Content: CreateProjectResponse{
|
||||
Id: id,
|
||||
},
|
||||
})
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"project": project,
|
||||
}).Debug("Created project")
|
||||
}
|
||||
|
||||
func (api *WebAPI) ProjectUpdate(r *Request) {
|
||||
func (api *WebAPI) UpdateProject(r *Request) {
|
||||
|
||||
id, err := strconv.ParseInt(r.Ctx.UserValue("id").(string), 10, 64)
|
||||
if err != nil || id <= 0 {
|
||||
r.Json(CreateProjectResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Invalid project id",
|
||||
}, 400)
|
||||
@@ -154,12 +127,21 @@ func (api *WebAPI) ProjectUpdate(r *Request) {
|
||||
updateReq := &UpdateProjectRequest{}
|
||||
err = json.Unmarshal(r.Ctx.Request.Body(), updateReq)
|
||||
if err != nil {
|
||||
r.Json(CreateProjectResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Could not parse request",
|
||||
}, 400)
|
||||
return
|
||||
}
|
||||
|
||||
if !updateReq.isValid() {
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Invalid request",
|
||||
}, 400)
|
||||
return
|
||||
}
|
||||
|
||||
project := &storage.Project{
|
||||
Id: id,
|
||||
Name: updateReq.Name,
|
||||
@@ -171,24 +153,11 @@ func (api *WebAPI) ProjectUpdate(r *Request) {
|
||||
Hidden: updateReq.Hidden,
|
||||
Chain: updateReq.Chain,
|
||||
}
|
||||
|
||||
if !isValidProject(project) {
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"project": project,
|
||||
}).Warn("Invalid project")
|
||||
|
||||
r.Json(CreateProjectResponse{
|
||||
Ok: false,
|
||||
Message: "Invalid project",
|
||||
}, 400)
|
||||
return
|
||||
}
|
||||
|
||||
sess := api.Session.StartFasthttp(r.Ctx)
|
||||
manager := sess.Get("manager")
|
||||
|
||||
if !isActionAuthorized(project.Id, manager, storage.ROLE_EDIT, api.Database) {
|
||||
r.Json(CreateProjectResponse{
|
||||
if !isActionOnProjectAuthorized(project.Id, manager, storage.ROLE_EDIT, api.Database) {
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Unauthorized",
|
||||
}, 403)
|
||||
@@ -200,7 +169,7 @@ func (api *WebAPI) ProjectUpdate(r *Request) {
|
||||
|
||||
err = api.Database.UpdateProject(project)
|
||||
if err != nil {
|
||||
r.Json(CreateProjectResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: err.Error(),
|
||||
}, 500)
|
||||
@@ -209,7 +178,7 @@ func (api *WebAPI) ProjectUpdate(r *Request) {
|
||||
"project": project,
|
||||
}).Warn("Error during project update")
|
||||
} else {
|
||||
r.OkJson(UpdateProjectResponse{
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: true,
|
||||
})
|
||||
|
||||
@@ -219,20 +188,6 @@ func (api *WebAPI) ProjectUpdate(r *Request) {
|
||||
}
|
||||
}
|
||||
|
||||
func isValidProject(project *storage.Project) bool {
|
||||
if len(project.Name) <= 0 {
|
||||
return false
|
||||
}
|
||||
if project.Priority < 0 {
|
||||
return false
|
||||
}
|
||||
if project.Hidden && project.Public {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func isProjectCreationAuthorized(project *storage.Project, manager interface{}) bool {
|
||||
|
||||
if manager == nil {
|
||||
@@ -245,7 +200,7 @@ func isProjectCreationAuthorized(project *storage.Project, manager interface{})
|
||||
return true
|
||||
}
|
||||
|
||||
func isActionAuthorized(project int64, manager interface{},
|
||||
func isActionOnProjectAuthorized(project int64, manager interface{},
|
||||
requiredRole storage.ManagerRole, db *storage.Database) bool {
|
||||
|
||||
if manager == nil {
|
||||
@@ -283,39 +238,7 @@ func isProjectReadAuthorized(project *storage.Project, manager interface{}, db *
|
||||
return false
|
||||
}
|
||||
|
||||
func (api *WebAPI) ProjectGet(r *Request) {
|
||||
|
||||
id, err := strconv.ParseInt(r.Ctx.UserValue("id").(string), 10, 64)
|
||||
handleErr(err, r) //todo handle invalid id
|
||||
|
||||
sess := api.Session.StartFasthttp(r.Ctx)
|
||||
manager := sess.Get("manager")
|
||||
|
||||
project := api.Database.GetProject(id)
|
||||
|
||||
if project == nil {
|
||||
r.Json(GetProjectResponse{
|
||||
Ok: false,
|
||||
Message: "Project not found",
|
||||
}, 404)
|
||||
return
|
||||
}
|
||||
|
||||
if !isProjectReadAuthorized(project, manager, api.Database) {
|
||||
r.Json(GetProjectResponse{
|
||||
Ok: false,
|
||||
Message: "Unauthorized",
|
||||
}, 403)
|
||||
return
|
||||
}
|
||||
|
||||
r.OkJson(GetProjectResponse{
|
||||
Ok: true,
|
||||
Project: project,
|
||||
})
|
||||
}
|
||||
|
||||
func (api *WebAPI) ProjectGetAllProjects(r *Request) {
|
||||
func (api *WebAPI) GetProjectList(r *Request) {
|
||||
|
||||
sess := api.Session.StartFasthttp(r.Ctx)
|
||||
manager := sess.Get("manager")
|
||||
@@ -329,26 +252,30 @@ func (api *WebAPI) ProjectGetAllProjects(r *Request) {
|
||||
|
||||
projects := api.Database.GetAllProjects(id)
|
||||
|
||||
r.OkJson(GetAllProjectsResponse{
|
||||
Ok: true,
|
||||
Projects: projects,
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: true,
|
||||
Content: GetProjectListResponse{
|
||||
Projects: projects,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (api *WebAPI) ProjectGetAssigneeStats(r *Request) {
|
||||
func (api *WebAPI) GetAssigneeStatsForProject(r *Request) {
|
||||
|
||||
id, err := strconv.ParseInt(r.Ctx.UserValue("id").(string), 10, 64)
|
||||
handleErr(err, r) //todo handle invalid id
|
||||
|
||||
stats := api.Database.GetAssigneeStats(id, 16)
|
||||
|
||||
r.OkJson(GetAssigneeStatsResponse{
|
||||
Ok: true,
|
||||
Assignees: stats,
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: true,
|
||||
Content: GetAssigneeStatsForProjectResponse{
|
||||
Assignees: stats,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (api *WebAPI) ProjectGetWorkerAccesses(r *Request) {
|
||||
func (api *WebAPI) GetWorkerAccessListForProject(r *Request) {
|
||||
|
||||
sess := api.Session.StartFasthttp(r.Ctx)
|
||||
manager := sess.Get("manager")
|
||||
@@ -356,8 +283,8 @@ func (api *WebAPI) ProjectGetWorkerAccesses(r *Request) {
|
||||
id, err := strconv.ParseInt(r.Ctx.UserValue("id").(string), 10, 64)
|
||||
handleErr(err, r) //todo handle invalid id
|
||||
|
||||
if !isActionAuthorized(id, manager, storage.ROLE_MANAGE_ACCESS, api.Database) {
|
||||
r.Json(ProjectGetAccessRequestsResponse{
|
||||
if !isActionOnProjectAuthorized(id, manager, storage.ROLE_MANAGE_ACCESS, api.Database) {
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Unauthorized",
|
||||
}, 403)
|
||||
@@ -365,18 +292,20 @@ func (api *WebAPI) ProjectGetWorkerAccesses(r *Request) {
|
||||
}
|
||||
accesses := api.Database.GetAllAccesses(id)
|
||||
|
||||
r.OkJson(ProjectGetAccessRequestsResponse{
|
||||
Ok: true,
|
||||
Accesses: accesses,
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: true,
|
||||
Content: GetWorkerAccessListForProjectResponse{
|
||||
Accesses: accesses,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
func (api *WebAPI) WorkerRequestAccess(r *Request) {
|
||||
func (api *WebAPI) CreateWorkerAccess(r *Request) {
|
||||
|
||||
req := &WorkerAccessRequest{}
|
||||
req := &CreateWorkerAccessRequest{}
|
||||
err := json.Unmarshal(r.Ctx.Request.Body(), req)
|
||||
if err != nil {
|
||||
r.Json(WorkerAccessRequestResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Could not parse request",
|
||||
}, 400)
|
||||
@@ -384,7 +313,7 @@ func (api *WebAPI) WorkerRequestAccess(r *Request) {
|
||||
}
|
||||
|
||||
if !req.isValid() {
|
||||
r.Json(WorkerAccessRequestResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Invalid request",
|
||||
}, 400)
|
||||
@@ -393,10 +322,11 @@ func (api *WebAPI) WorkerRequestAccess(r *Request) {
|
||||
|
||||
worker, err := api.validateSignature(r)
|
||||
if err != nil {
|
||||
r.Json(WorkerAccessRequestResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: err.Error(),
|
||||
}, 401)
|
||||
return
|
||||
}
|
||||
|
||||
res := api.Database.SaveAccessRequest(&storage.WorkerAccess{
|
||||
@@ -407,11 +337,11 @@ func (api *WebAPI) WorkerRequestAccess(r *Request) {
|
||||
})
|
||||
|
||||
if res {
|
||||
r.OkJson(WorkerAccessRequestResponse{
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: true,
|
||||
})
|
||||
} else {
|
||||
r.Json(WorkerAccessRequestResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Project is public, you already have " +
|
||||
"an active request or you already have access to this project",
|
||||
@@ -430,8 +360,8 @@ func (api *WebAPI) AcceptAccessRequest(r *Request) {
|
||||
sess := api.Session.StartFasthttp(r.Ctx)
|
||||
manager := sess.Get("manager")
|
||||
|
||||
if !isActionAuthorized(pid, manager, storage.ROLE_MANAGE_ACCESS, api.Database) {
|
||||
r.Json(WorkerAccessRequestResponse{
|
||||
if !isActionOnProjectAuthorized(pid, manager, storage.ROLE_MANAGE_ACCESS, api.Database) {
|
||||
r.Json(JsonResponse{
|
||||
Message: "Unauthorized",
|
||||
Ok: false,
|
||||
}, 403)
|
||||
@@ -441,11 +371,11 @@ func (api *WebAPI) AcceptAccessRequest(r *Request) {
|
||||
ok := api.Database.AcceptAccessRequest(wid, pid)
|
||||
|
||||
if ok {
|
||||
r.OkJson(WorkerAccessRequestResponse{
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: true,
|
||||
})
|
||||
} else {
|
||||
r.OkJson(WorkerAccessRequestResponse{
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Worker did not have access to this project",
|
||||
})
|
||||
@@ -463,11 +393,11 @@ func (api *WebAPI) RejectAccessRequest(r *Request) {
|
||||
ok := api.Database.RejectAccessRequest(wid, pid)
|
||||
|
||||
if ok {
|
||||
r.OkJson(WorkerAccessRequestResponse{
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: true,
|
||||
})
|
||||
} else {
|
||||
r.OkJson(WorkerAccessRequestResponse{
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Worker did not have access to this project",
|
||||
})
|
||||
|
||||
141
api/task.go
141
api/task.go
@@ -13,55 +13,21 @@ import (
|
||||
"strconv"
|
||||
)
|
||||
|
||||
type CreateTaskRequest struct {
|
||||
Project int64 `json:"project"`
|
||||
MaxRetries int64 `json:"max_retries"`
|
||||
Recipe string `json:"recipe"`
|
||||
Priority int64 `json:"priority"`
|
||||
MaxAssignTime int64 `json:"max_assign_time"`
|
||||
Hash64 int64 `json:"hash_u64"`
|
||||
UniqueString string `json:"unique_string"`
|
||||
VerificationCount int64 `json:"verification_count"`
|
||||
}
|
||||
|
||||
type ReleaseTaskRequest struct {
|
||||
TaskId int64 `json:"task_id"`
|
||||
Result storage.TaskResult `json:"result"`
|
||||
Verification int64 `json:"verification"`
|
||||
}
|
||||
|
||||
type ReleaseTaskResponse struct {
|
||||
Ok bool `json:"ok"`
|
||||
Updated bool `json:"updated"`
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
type CreateTaskResponse struct {
|
||||
Ok bool `json:"ok"`
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
type GetTaskResponse struct {
|
||||
Ok bool `json:"ok"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Task *storage.Task `json:"task,omitempty"`
|
||||
}
|
||||
|
||||
func (api *WebAPI) TaskCreate(r *Request) {
|
||||
func (api *WebAPI) SubmitTask(r *Request) {
|
||||
|
||||
worker, err := api.validateSignature(r)
|
||||
if worker == nil {
|
||||
r.Json(CreateProjectResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: err.Error(),
|
||||
}, 401)
|
||||
return
|
||||
}
|
||||
|
||||
createReq := &CreateTaskRequest{}
|
||||
createReq := &SubmitTaskRequest{}
|
||||
err = json.Unmarshal(r.Ctx.Request.Body(), createReq)
|
||||
if err != nil {
|
||||
r.Json(CreateProjectResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Could not parse request",
|
||||
}, 400)
|
||||
@@ -76,56 +42,41 @@ func (api *WebAPI) TaskCreate(r *Request) {
|
||||
VerificationCount: createReq.VerificationCount,
|
||||
}
|
||||
|
||||
if createReq.IsValid() && isTaskValid(task) {
|
||||
|
||||
if createReq.UniqueString != "" {
|
||||
//TODO: Load key from config
|
||||
createReq.Hash64 = int64(siphash.Hash(1, 2, []byte(createReq.UniqueString)))
|
||||
}
|
||||
|
||||
err := api.Database.SaveTask(task, createReq.Project, createReq.Hash64, worker.Id)
|
||||
|
||||
if err != nil {
|
||||
r.Json(CreateTaskResponse{
|
||||
Ok: false,
|
||||
Message: err.Error(),
|
||||
}, 400)
|
||||
} else {
|
||||
r.OkJson(CreateTaskResponse{
|
||||
Ok: true,
|
||||
})
|
||||
}
|
||||
} else {
|
||||
if !createReq.IsValid() {
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"task": task,
|
||||
}).Warn("Invalid task")
|
||||
r.Json(CreateTaskResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Invalid task",
|
||||
}, 400)
|
||||
return
|
||||
}
|
||||
|
||||
if createReq.UniqueString != "" {
|
||||
//TODO: Load key from config
|
||||
createReq.Hash64 = int64(siphash.Hash(1, 2, []byte(createReq.UniqueString)))
|
||||
}
|
||||
|
||||
err = api.Database.SaveTask(task, createReq.Project, createReq.Hash64, worker.Id)
|
||||
|
||||
if err != nil {
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: err.Error(),
|
||||
}, 400)
|
||||
} else {
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: true,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (req *CreateTaskRequest) IsValid() bool {
|
||||
return req.Hash64 == 0 || req.UniqueString == ""
|
||||
}
|
||||
|
||||
func isTaskValid(task *storage.Task) bool {
|
||||
if task.MaxRetries < 0 {
|
||||
return false
|
||||
}
|
||||
if len(task.Recipe) <= 0 {
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func (api *WebAPI) TaskGetFromProject(r *Request) {
|
||||
func (api *WebAPI) GetTaskFromProject(r *Request) {
|
||||
|
||||
worker, err := api.validateSignature(r)
|
||||
if err != nil {
|
||||
r.Json(GetTaskResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: err.Error(),
|
||||
}, 403)
|
||||
@@ -138,26 +89,28 @@ func (api *WebAPI) TaskGetFromProject(r *Request) {
|
||||
|
||||
if task == nil {
|
||||
|
||||
r.OkJson(GetTaskResponse{
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "No task available",
|
||||
})
|
||||
|
||||
} else {
|
||||
|
||||
r.OkJson(GetTaskResponse{
|
||||
Ok: true,
|
||||
Task: task,
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: true,
|
||||
Content: GetTaskResponse{
|
||||
Task: task,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
func (api *WebAPI) TaskGet(r *Request) {
|
||||
func (api *WebAPI) GetTask(r *Request) {
|
||||
|
||||
worker, err := api.validateSignature(r)
|
||||
if err != nil {
|
||||
r.Json(GetTaskResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: err.Error(),
|
||||
}, 403)
|
||||
@@ -167,16 +120,18 @@ func (api *WebAPI) TaskGet(r *Request) {
|
||||
task := api.Database.GetTask(worker)
|
||||
if task == nil {
|
||||
|
||||
r.OkJson(GetTaskResponse{
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "No task available",
|
||||
})
|
||||
|
||||
} else {
|
||||
|
||||
r.OkJson(GetTaskResponse{
|
||||
Ok: true,
|
||||
Task: task,
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: true,
|
||||
Content: GetTaskResponse{
|
||||
Task: task,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -236,11 +191,11 @@ func (api WebAPI) validateSignature(r *Request) (*storage.Worker, error) {
|
||||
return worker, nil
|
||||
}
|
||||
|
||||
func (api *WebAPI) TaskRelease(r *Request) {
|
||||
func (api *WebAPI) ReleaseTask(r *Request) {
|
||||
|
||||
worker, err := api.validateSignature(r)
|
||||
if err != nil {
|
||||
r.Json(GetTaskResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: err.Error(),
|
||||
}, 403)
|
||||
@@ -250,16 +205,18 @@ func (api *WebAPI) TaskRelease(r *Request) {
|
||||
req := &ReleaseTaskRequest{}
|
||||
err = json.Unmarshal(r.Ctx.Request.Body(), req)
|
||||
if err != nil {
|
||||
r.Json(CreateProjectResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Could not parse request",
|
||||
}, 400)
|
||||
}
|
||||
res := api.Database.ReleaseTask(req.TaskId, worker.Id, req.Result, req.Verification)
|
||||
|
||||
response := ReleaseTaskResponse{
|
||||
Updated: res,
|
||||
Ok: true,
|
||||
response := JsonResponse{
|
||||
Ok: true,
|
||||
Content: ReleaseTaskResponse{
|
||||
Updated: res,
|
||||
},
|
||||
}
|
||||
|
||||
if !res {
|
||||
|
||||
102
api/worker.go
102
api/worker.go
@@ -9,51 +9,7 @@ import (
|
||||
"time"
|
||||
)
|
||||
|
||||
type UpdateWorkerRequest struct {
|
||||
Alias string `json:"alias"`
|
||||
}
|
||||
|
||||
type UpdateWorkerResponse struct {
|
||||
Ok bool `json:"ok"`
|
||||
Message string `json:"message,omitempty"`
|
||||
}
|
||||
|
||||
type CreateWorkerRequest struct {
|
||||
Alias string `json:"alias"`
|
||||
}
|
||||
|
||||
type CreateWorkerResponse struct {
|
||||
Ok bool `json:"ok"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Worker *storage.Worker `json:"worker,omitempty"`
|
||||
}
|
||||
|
||||
type GetWorkerResponse struct {
|
||||
Ok bool `json:"ok"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Worker *storage.Worker `json:"worker,omitempty"`
|
||||
}
|
||||
|
||||
type GetAllWorkerStatsResponse struct {
|
||||
Ok bool `json:"ok"`
|
||||
Message string `json:"message,omitempty"`
|
||||
Stats *[]storage.WorkerStats `json:"stats"`
|
||||
}
|
||||
|
||||
type WorkerAccessRequest struct {
|
||||
Assign bool `json:"assign"`
|
||||
Submit bool `json:"submit"`
|
||||
Project int64 `json:"project"`
|
||||
}
|
||||
|
||||
func (w *WorkerAccessRequest) isValid() bool {
|
||||
if !w.Assign && !w.Submit {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func (api *WebAPI) WorkerCreate(r *Request) {
|
||||
func (api *WebAPI) CreateWorker(r *Request) {
|
||||
|
||||
workerReq := &CreateWorkerRequest{}
|
||||
err := json.Unmarshal(r.Ctx.Request.Body(), workerReq)
|
||||
@@ -61,13 +17,13 @@ func (api *WebAPI) WorkerCreate(r *Request) {
|
||||
return
|
||||
}
|
||||
|
||||
if !canCreateWorker(r, workerReq) {
|
||||
if !workerReq.isValid() {
|
||||
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"createWorkerRequest": workerReq,
|
||||
}).Warn("Failed CreateWorkerRequest")
|
||||
|
||||
r.Json(CreateWorkerResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "You are now allowed to create a worker",
|
||||
}, 403)
|
||||
@@ -78,14 +34,16 @@ func (api *WebAPI) WorkerCreate(r *Request) {
|
||||
if err != nil {
|
||||
handleErr(err, r)
|
||||
} else {
|
||||
r.OkJson(CreateWorkerResponse{
|
||||
Ok: true,
|
||||
Worker: worker,
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: true,
|
||||
Content: CreateWorkerResponse{
|
||||
Worker: worker,
|
||||
},
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func (api *WebAPI) WorkerGet(r *Request) {
|
||||
func (api *WebAPI) GetWorker(r *Request) {
|
||||
|
||||
id, err := strconv.ParseInt(r.Ctx.UserValue("id").(string), 10, 64)
|
||||
if err != nil {
|
||||
@@ -93,7 +51,7 @@ func (api *WebAPI) WorkerGet(r *Request) {
|
||||
"id": id,
|
||||
}).Warn("Invalid worker id")
|
||||
|
||||
r.Json(GetWorkerResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: err.Error(),
|
||||
}, 400)
|
||||
@@ -103,7 +61,7 @@ func (api *WebAPI) WorkerGet(r *Request) {
|
||||
"id": id,
|
||||
}).Warn("Invalid worker id")
|
||||
|
||||
r.Json(GetWorkerResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Invalid worker id",
|
||||
}, 400)
|
||||
@@ -116,23 +74,25 @@ func (api *WebAPI) WorkerGet(r *Request) {
|
||||
|
||||
worker.Secret = nil
|
||||
|
||||
r.OkJson(GetWorkerResponse{
|
||||
Ok: true,
|
||||
Worker: worker,
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: true,
|
||||
Content: GetWorkerResponse{
|
||||
Worker: worker,
|
||||
},
|
||||
})
|
||||
} else {
|
||||
r.Json(GetWorkerResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Worker not found",
|
||||
}, 404)
|
||||
}
|
||||
}
|
||||
|
||||
func (api *WebAPI) WorkerUpdate(r *Request) {
|
||||
func (api *WebAPI) UpdateWorker(r *Request) {
|
||||
|
||||
worker, err := api.validateSignature(r)
|
||||
if err != nil {
|
||||
r.Json(GetTaskResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: err.Error(),
|
||||
}, 401)
|
||||
@@ -142,7 +102,7 @@ func (api *WebAPI) WorkerUpdate(r *Request) {
|
||||
req := &UpdateWorkerRequest{}
|
||||
err = json.Unmarshal(r.Ctx.Request.Body(), req)
|
||||
if err != nil {
|
||||
r.Json(GetTaskResponse{
|
||||
r.Json(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Could not parse request",
|
||||
}, 400)
|
||||
@@ -153,11 +113,11 @@ func (api *WebAPI) WorkerUpdate(r *Request) {
|
||||
ok := api.Database.UpdateWorker(worker)
|
||||
|
||||
if ok {
|
||||
r.OkJson(UpdateWorkerResponse{
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: true,
|
||||
})
|
||||
} else {
|
||||
r.OkJson(UpdateWorkerResponse{
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: false,
|
||||
Message: "Could not update worker",
|
||||
})
|
||||
@@ -168,9 +128,11 @@ func (api *WebAPI) GetAllWorkerStats(r *Request) {
|
||||
|
||||
stats := api.Database.GetAllWorkerStats()
|
||||
|
||||
r.OkJson(GetAllWorkerStatsResponse{
|
||||
Ok: true,
|
||||
Stats: stats,
|
||||
r.OkJson(JsonResponse{
|
||||
Ok: true,
|
||||
Content: GetAllWorkerStatsResponse{
|
||||
Stats: stats,
|
||||
},
|
||||
})
|
||||
}
|
||||
|
||||
@@ -190,16 +152,6 @@ func (api *WebAPI) workerCreate(request *CreateWorkerRequest) (*storage.Worker,
|
||||
return &worker, nil
|
||||
}
|
||||
|
||||
func canCreateWorker(r *Request, cwr *CreateWorkerRequest) bool {
|
||||
|
||||
if cwr.Alias == "unassigned" {
|
||||
//Reserved alias
|
||||
return false
|
||||
}
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func makeSecret() []byte {
|
||||
|
||||
secret := make([]byte, 32)
|
||||
|
||||
Reference in New Issue
Block a user