rework worker permissions

This commit is contained in:
simon987
2019-02-16 16:18:28 -05:00
parent e079fc8497
commit 8784b536d3
20 changed files with 454 additions and 328 deletions

View File

@@ -80,9 +80,6 @@ func New() *WebAPI {
api.router.GET("/worker/get/:id", LogRequestMiddleware(api.WorkerGet))
api.router.GET("/worker/stats", LogRequestMiddleware(api.GetAllWorkerStats))
api.router.POST("/access/grant", LogRequestMiddleware(api.WorkerGrantAccess))
api.router.POST("/access/remove", LogRequestMiddleware(api.WorkerRemoveAccess))
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))
@@ -90,8 +87,10 @@ func New() *WebAPI {
api.router.GET("/project/monitoring-between/:id", LogRequestMiddleware(api.GetSnapshotsBetween))
api.router.GET("/project/monitoring/:id", LogRequestMiddleware(api.GetNSnapshots))
api.router.GET("/project/assignees/:id", LogRequestMiddleware(api.ProjectGetAssigneeStats))
api.router.GET("/project/requests/:id", LogRequestMiddleware(api.ProjectGetAccessRequests))
api.router.GET("/project/request_access/:id", LogRequestMiddleware(api.WorkerRequestAccess))
api.router.GET("/project/accesses/:id", LogRequestMiddleware(api.ProjectGetWorkerAccesses))
api.router.POST("/project/request_access", LogRequestMiddleware(api.WorkerRequestAccess))
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))

View File

@@ -59,15 +59,15 @@ type GetAssigneeStatsResponse struct {
Assignees *[]storage.AssignedTasks `json:"assignees"`
}
type WorkerRequestAccessResponse struct {
type WorkerAccessRequestResponse struct {
Ok bool `json:"ok"`
Message string `json:"message,omitempty"`
}
type ProjectGetAccessRequestsResponse struct {
Ok bool `json:"ok"`
Message string `json:"message,omitempty"`
Requests *[]storage.Worker `json:"requests,omitempty"`
Ok bool `json:"ok"`
Message string `json:"message,omitempty"`
Accesses *[]storage.WorkerAccess `json:"accesses,omitempty"`
}
func (api *WebAPI) ProjectCreate(r *Request) {
@@ -187,7 +187,7 @@ func (api *WebAPI) ProjectUpdate(r *Request) {
sess := api.Session.StartFasthttp(r.Ctx)
manager := sess.Get("manager")
if !isProjectUpdateAuthorized(project, manager, api.Database) {
if !isActionAuthorized(project.Id, manager, storage.ROLE_EDIT, api.Database) {
r.Json(CreateProjectResponse{
Ok: false,
Message: "Unauthorized",
@@ -245,7 +245,8 @@ func isProjectCreationAuthorized(project *storage.Project, manager interface{})
return true
}
func isProjectUpdateAuthorized(project *storage.Project, manager interface{}, db *storage.Database) bool {
func isActionAuthorized(project int64, manager interface{},
requiredRole storage.ManagerRole, db *storage.Database) bool {
if manager == nil {
return false
@@ -255,8 +256,8 @@ func isProjectUpdateAuthorized(project *storage.Project, manager interface{}, db
return true
}
role := db.GetManagerRoleOn(manager.(*storage.Manager), project.Id)
if role&storage.ROLE_EDIT == 1 {
role := db.GetManagerRoleOn(manager.(*storage.Manager), project)
if role&requiredRole != 0 {
return true
}
@@ -347,7 +348,7 @@ func (api *WebAPI) ProjectGetAssigneeStats(r *Request) {
})
}
func (api *WebAPI) ProjectGetAccessRequests(r *Request) {
func (api *WebAPI) ProjectGetWorkerAccesses(r *Request) {
sess := api.Session.StartFasthttp(r.Ctx)
manager := sess.Get("manager")
@@ -355,55 +356,120 @@ func (api *WebAPI) ProjectGetAccessRequests(r *Request) {
id, err := strconv.ParseInt(r.Ctx.UserValue("id").(string), 10, 64)
handleErr(err, r) //todo handle invalid id
if manager == nil {
r.Json(ProjectGetAccessRequestsResponse{
Ok: false,
Message: "Unauthorized",
}, 401)
return
}
if !manager.(*storage.Manager).WebsiteAdmin &&
api.Database.GetManagerRoleOn(manager.(*storage.Manager), 1)&
storage.ROLE_MANAGE_ACCESS == 0 {
if !isActionAuthorized(id, manager, storage.ROLE_MANAGE_ACCESS, api.Database) {
r.Json(ProjectGetAccessRequestsResponse{
Ok: false,
Message: "Unauthorized",
}, 403)
return
}
requests := api.Database.GetAllAccessRequests(id)
accesses := api.Database.GetAllAccesses(id)
r.OkJson(ProjectGetAccessRequestsResponse{
Ok: true,
Requests: requests,
Accesses: accesses,
})
}
func (api *WebAPI) WorkerRequestAccess(r *Request) {
id, err := strconv.ParseInt(r.Ctx.UserValue("id").(string), 10, 64)
handleErr(err, r) //todo handle invalid id
req := &WorkerAccessRequest{}
err := json.Unmarshal(r.Ctx.Request.Body(), req)
if err != nil {
r.Json(WorkerAccessRequestResponse{
Ok: false,
Message: "Could not parse request",
}, 400)
return
}
if !req.isValid() {
r.Json(WorkerAccessRequestResponse{
Ok: false,
Message: "Invalid request",
}, 400)
return
}
worker, err := api.validateSignature(r)
if err != nil {
r.Json(WorkerRequestAccessResponse{
r.Json(WorkerAccessRequestResponse{
Ok: false,
Message: err.Error(),
}, 401)
}
res := api.Database.SaveAccessRequest(worker, id)
res := api.Database.SaveAccessRequest(&storage.WorkerAccess{
Worker: *worker,
Submit: req.Submit,
Assign: req.Assign,
Project: req.Project,
})
if res {
r.OkJson(WorkerRequestAccessResponse{
r.OkJson(WorkerAccessRequestResponse{
Ok: true,
})
} else {
r.Json(WorkerRequestAccessResponse{
r.Json(WorkerAccessRequestResponse{
Ok: false,
Message: "Project is public, you already have " +
"an active request or you already have access to this project",
}, 400)
}
}
func (api *WebAPI) AcceptAccessRequest(r *Request) {
pid, err := strconv.ParseInt(r.Ctx.UserValue("id").(string), 10, 64)
handleErr(err, r) //todo handle invalid id
wid, err := strconv.ParseInt(r.Ctx.UserValue("wid").(string), 10, 64)
handleErr(err, r) //todo handle invalid id
sess := api.Session.StartFasthttp(r.Ctx)
manager := sess.Get("manager")
if !isActionAuthorized(pid, manager, storage.ROLE_MANAGE_ACCESS, api.Database) {
r.Json(WorkerAccessRequestResponse{
Message: "Unauthorized",
Ok: false,
}, 403)
return
}
ok := api.Database.AcceptAccessRequest(wid, pid)
if ok {
r.OkJson(WorkerAccessRequestResponse{
Ok: true,
})
} else {
r.OkJson(WorkerAccessRequestResponse{
Ok: false,
Message: "Worker did not have access to this project",
})
}
}
func (api *WebAPI) RejectAccessRequest(r *Request) {
pid, err := strconv.ParseInt(r.Ctx.UserValue("id").(string), 10, 64)
handleErr(err, r) //todo handle invalid id
wid, err := strconv.ParseInt(r.Ctx.UserValue("wid").(string), 10, 64)
handleErr(err, r) //todo handle invalid id
ok := api.Database.RejectAccessRequest(wid, pid)
if ok {
r.OkJson(WorkerAccessRequestResponse{
Ok: true,
})
} else {
r.OkJson(WorkerAccessRequestResponse{
Ok: false,
Message: "Worker did not have access to this project",
})
}
}

View File

@@ -49,8 +49,17 @@ type GetTaskResponse struct {
func (api *WebAPI) TaskCreate(r *Request) {
worker, err := api.validateSignature(r)
if worker == nil {
r.Json(CreateProjectResponse{
Ok: false,
Message: err.Error(),
}, 401)
return
}
createReq := &CreateTaskRequest{}
err := json.Unmarshal(r.Ctx.Request.Body(), createReq)
err = json.Unmarshal(r.Ctx.Request.Body(), createReq)
if err != nil {
r.Json(CreateProjectResponse{
Ok: false,
@@ -74,7 +83,7 @@ func (api *WebAPI) TaskCreate(r *Request) {
createReq.Hash64 = int64(siphash.Hash(1, 2, []byte(createReq.UniqueString)))
}
err := api.Database.SaveTask(task, createReq.Project, createReq.Hash64)
err := api.Database.SaveTask(task, createReq.Project, createReq.Hash64, worker.Id)
if err != nil {
r.Json(CreateTaskResponse{

View File

@@ -9,10 +9,6 @@ import (
"time"
)
type CreateWorkerRequest struct {
Alias string `json:"alias"`
}
type UpdateWorkerRequest struct {
Alias string `json:"alias"`
}
@@ -22,6 +18,10 @@ type UpdateWorkerResponse struct {
Message string `json:"message,omitempty"`
}
type CreateWorkerRequest struct {
Alias string `json:"alias"`
}
type CreateWorkerResponse struct {
Ok bool `json:"ok"`
Message string `json:"message,omitempty"`
@@ -34,22 +34,25 @@ type GetWorkerResponse struct {
Worker *storage.Worker `json:"worker,omitempty"`
}
type WorkerAccessRequest struct {
WorkerId int64 `json:"worker_id"`
ProjectId int64 `json:"project_id"`
}
type WorkerAccessResponse struct {
Ok bool `json:"ok"`
Message string `json:"message"`
}
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) {
workerReq := &CreateWorkerRequest{}
@@ -125,57 +128,6 @@ func (api *WebAPI) WorkerGet(r *Request) {
}
}
func (api *WebAPI) WorkerGrantAccess(r *Request) {
req := &WorkerAccessRequest{}
err := json.Unmarshal(r.Ctx.Request.Body(), req)
if err != nil {
r.Json(GetTaskResponse{
Ok: false,
Message: "Could not parse request",
}, 400)
return
}
ok := api.Database.GrantAccess(req.WorkerId, req.ProjectId)
if ok {
r.OkJson(WorkerAccessResponse{
Ok: true,
})
} else {
r.OkJson(WorkerAccessResponse{
Ok: false,
Message: "Worker already has access to this project",
})
}
}
func (api *WebAPI) WorkerRemoveAccess(r *Request) {
req := &WorkerAccessRequest{}
err := json.Unmarshal(r.Ctx.Request.Body(), req)
if err != nil {
r.Json(GetTaskResponse{
Ok: false,
Message: "Could not parse request",
}, 400)
return
}
ok := api.Database.RemoveAccess(req.WorkerId, req.ProjectId)
if ok {
r.OkJson(WorkerAccessResponse{
Ok: true,
})
} else {
r.OkJson(WorkerAccessResponse{
Ok: false,
Message: "Worker did not have access to this project",
})
}
}
func (api *WebAPI) WorkerUpdate(r *Request) {
worker, err := api.validateSignature(r)