mirror of
https://github.com/simon987/task_tracker.git
synced 2025-12-10 21:48:52 +00:00
Some work on permissions (lacks tests)
This commit is contained in:
@@ -145,7 +145,6 @@ func (api *WebAPI) AccountDetails(r *Request) {
|
||||
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"manager": manager,
|
||||
"session": sess,
|
||||
}).Trace("Account details request")
|
||||
|
||||
if manager == nil {
|
||||
|
||||
@@ -90,6 +90,8 @@ 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.POST("/task/create", LogRequestMiddleware(api.TaskCreate))
|
||||
api.router.GET("/task/get/:project", LogRequestMiddleware(api.TaskGetFromProject))
|
||||
|
||||
159
api/project.go
159
api/project.go
@@ -15,6 +15,7 @@ type CreateProjectRequest struct {
|
||||
Priority int64 `json:"priority"`
|
||||
Motd string `json:"motd"`
|
||||
Public bool `json:"public"`
|
||||
Hidden bool `json:"hidden"`
|
||||
}
|
||||
|
||||
type UpdateProjectRequest struct {
|
||||
@@ -24,6 +25,7 @@ type UpdateProjectRequest struct {
|
||||
Priority int64 `json:"priority"`
|
||||
Motd string `json:"motd"`
|
||||
Public bool `json:"public"`
|
||||
Hidden bool `json:"hidden"`
|
||||
}
|
||||
|
||||
type UpdateProjectResponse struct {
|
||||
@@ -55,8 +57,22 @@ type GetAssigneeStatsResponse struct {
|
||||
Assignees *[]storage.AssignedTasks `json:"assignees"`
|
||||
}
|
||||
|
||||
type WorkerRequestAccessResponse 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"`
|
||||
}
|
||||
|
||||
func (api *WebAPI) ProjectCreate(r *Request) {
|
||||
|
||||
sess := api.Session.StartFasthttp(r.Ctx)
|
||||
manager := sess.Get("manager")
|
||||
|
||||
createReq := &CreateProjectRequest{}
|
||||
err := json.Unmarshal(r.Ctx.Request.Body(), createReq)
|
||||
if err != nil {
|
||||
@@ -74,26 +90,10 @@ func (api *WebAPI) ProjectCreate(r *Request) {
|
||||
Priority: createReq.Priority,
|
||||
Motd: createReq.Motd,
|
||||
Public: createReq.Public,
|
||||
Hidden: createReq.Hidden,
|
||||
}
|
||||
|
||||
if isValidProject(project) {
|
||||
id, err := api.Database.SaveProject(project)
|
||||
|
||||
if err != nil {
|
||||
r.Json(CreateProjectResponse{
|
||||
Ok: false,
|
||||
Message: err.Error(),
|
||||
}, 500)
|
||||
} else {
|
||||
r.OkJson(CreateProjectResponse{
|
||||
Ok: true,
|
||||
Id: id,
|
||||
})
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"project": project,
|
||||
}).Debug("Created project")
|
||||
}
|
||||
} else {
|
||||
if !isValidProject(project) {
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"project": project,
|
||||
}).Warn("Invalid project")
|
||||
@@ -102,7 +102,36 @@ func (api *WebAPI) ProjectCreate(r *Request) {
|
||||
Ok: false,
|
||||
Message: "Invalid project",
|
||||
}, 400)
|
||||
return
|
||||
}
|
||||
|
||||
if !isProjectCreationAuthorized(project, manager) {
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"project": project,
|
||||
}).Warn("Unauthorized project creation")
|
||||
|
||||
r.Json(CreateProjectResponse{
|
||||
Ok: false,
|
||||
Message: "You are not permitted to create a project with this configuration",
|
||||
}, 400)
|
||||
return
|
||||
}
|
||||
|
||||
id, err := api.Database.SaveProject(project)
|
||||
if err != nil {
|
||||
r.Json(CreateProjectResponse{
|
||||
Ok: false,
|
||||
Message: err.Error(),
|
||||
}, 500)
|
||||
return
|
||||
}
|
||||
r.OkJson(CreateProjectResponse{
|
||||
Ok: true,
|
||||
Id: id,
|
||||
})
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"project": project,
|
||||
}).Debug("Created project")
|
||||
}
|
||||
|
||||
func (api *WebAPI) ProjectUpdate(r *Request) {
|
||||
@@ -133,6 +162,7 @@ func (api *WebAPI) ProjectUpdate(r *Request) {
|
||||
Priority: updateReq.Priority,
|
||||
Motd: updateReq.Motd,
|
||||
Public: updateReq.Public,
|
||||
Hidden: updateReq.Hidden,
|
||||
}
|
||||
|
||||
if isValidProject(project) {
|
||||
@@ -180,6 +210,38 @@ func isValidProject(project *storage.Project) bool {
|
||||
return true
|
||||
}
|
||||
|
||||
func isProjectCreationAuthorized(project *storage.Project, manager interface{}) bool {
|
||||
|
||||
return true
|
||||
if manager == nil {
|
||||
return false
|
||||
}
|
||||
|
||||
if project.Public && manager.(*storage.Manager).WebsiteAdmin {
|
||||
return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func isProjectUpdateAuthorized(project *storage.Project, manager interface{}, db *storage.Database) bool {
|
||||
|
||||
var man storage.Manager
|
||||
if manager != nil {
|
||||
man = manager.(storage.Manager)
|
||||
}
|
||||
|
||||
if man.WebsiteAdmin {
|
||||
return true
|
||||
}
|
||||
|
||||
role := db.ManagerHasRoleOn(&man, project.Id)
|
||||
if role&storage.ROLE_EDIT == 1 {
|
||||
return true
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
func (api *WebAPI) ProjectGet(r *Request) {
|
||||
|
||||
id, err := strconv.ParseInt(r.Ctx.UserValue("id").(string), 10, 64)
|
||||
@@ -230,3 +292,64 @@ func (api *WebAPI) ProjectGetAssigneeStats(r *Request) {
|
||||
Assignees: stats,
|
||||
})
|
||||
}
|
||||
|
||||
func (api *WebAPI) ProjectGetAccessRequests(r *Request) {
|
||||
|
||||
sess := api.Session.StartFasthttp(r.Ctx)
|
||||
manager := sess.Get("manager")
|
||||
|
||||
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.ManagerHasRoleOn(manager.(*storage.Manager), 1)&
|
||||
storage.ROLE_MANAGE_ACCESS == 0 {
|
||||
r.Json(ProjectGetAccessRequestsResponse{
|
||||
Ok: false,
|
||||
Message: "Unauthorized",
|
||||
}, 403)
|
||||
return
|
||||
}
|
||||
requests := api.Database.GetAllAccessRequests(id)
|
||||
|
||||
r.OkJson(ProjectGetAccessRequestsResponse{
|
||||
Ok: true,
|
||||
Requests: requests,
|
||||
})
|
||||
}
|
||||
|
||||
func (api *WebAPI) WorkerRequestAccess(r *Request) {
|
||||
|
||||
id, err := strconv.ParseInt(r.Ctx.UserValue("id").(string), 10, 64)
|
||||
handleErr(err, r) //todo handle invalid id
|
||||
|
||||
worker, err := api.validateSignature(r)
|
||||
if err != nil {
|
||||
r.Json(WorkerRequestAccessResponse{
|
||||
Ok: false,
|
||||
Message: err.Error(),
|
||||
}, 401)
|
||||
}
|
||||
|
||||
res := api.Database.SaveAccessRequest(worker, id)
|
||||
|
||||
if res {
|
||||
r.OkJson(WorkerRequestAccessResponse{
|
||||
Ok: true,
|
||||
})
|
||||
} else {
|
||||
r.Json(WorkerRequestAccessResponse{
|
||||
Ok: false,
|
||||
Message: "Project is public, you already have " +
|
||||
"an active request or you already have access to this project",
|
||||
}, 400)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -177,6 +177,10 @@ func (api WebAPI) validateSignature(r *Request) (*storage.Worker, error) {
|
||||
widStr := string(r.Ctx.Request.Header.Peek("X-Worker-Id"))
|
||||
signature := r.Ctx.Request.Header.Peek("X-Signature")
|
||||
|
||||
if widStr == "" {
|
||||
return nil, errors.New("worker id not specified")
|
||||
}
|
||||
|
||||
wid, err := strconv.ParseInt(widStr, 10, 64)
|
||||
if err != nil {
|
||||
logrus.WithError(err).WithFields(logrus.Fields{
|
||||
|
||||
@@ -58,11 +58,9 @@ func (api *WebAPI) WorkerCreate(r *Request) {
|
||||
return
|
||||
}
|
||||
|
||||
identity := getIdentity(r)
|
||||
if !canCreateWorker(r, workerReq, identity) {
|
||||
if !canCreateWorker(r, workerReq) {
|
||||
|
||||
logrus.WithFields(logrus.Fields{
|
||||
"identity": identity,
|
||||
"createWorkerRequest": workerReq,
|
||||
}).Warn("Failed CreateWorkerRequest")
|
||||
|
||||
@@ -73,7 +71,7 @@ func (api *WebAPI) WorkerCreate(r *Request) {
|
||||
return
|
||||
}
|
||||
|
||||
worker, err := api.workerCreate(workerReq, getIdentity(r))
|
||||
worker, err := api.workerCreate(workerReq)
|
||||
if err != nil {
|
||||
handleErr(err, r)
|
||||
} else {
|
||||
@@ -185,7 +183,7 @@ func (api *WebAPI) WorkerUpdate(r *Request) {
|
||||
r.Json(GetTaskResponse{
|
||||
Ok: false,
|
||||
Message: err.Error(),
|
||||
}, 403)
|
||||
}, 401)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -224,24 +222,23 @@ func (api *WebAPI) GetAllWorkerStats(r *Request) {
|
||||
})
|
||||
}
|
||||
|
||||
func (api *WebAPI) workerCreate(request *CreateWorkerRequest, identity *storage.Identity) (*storage.Worker, error) {
|
||||
func (api *WebAPI) workerCreate(request *CreateWorkerRequest) (*storage.Worker, error) {
|
||||
|
||||
if request.Alias == "" {
|
||||
request.Alias = "default_alias"
|
||||
}
|
||||
|
||||
worker := storage.Worker{
|
||||
Created: time.Now().Unix(),
|
||||
Identity: identity,
|
||||
Secret: makeSecret(),
|
||||
Alias: request.Alias,
|
||||
Created: time.Now().Unix(),
|
||||
Secret: makeSecret(),
|
||||
Alias: request.Alias,
|
||||
}
|
||||
|
||||
api.Database.SaveWorker(&worker)
|
||||
return &worker, nil
|
||||
}
|
||||
|
||||
func canCreateWorker(r *Request, cwr *CreateWorkerRequest, identity *storage.Identity) bool {
|
||||
func canCreateWorker(r *Request, cwr *CreateWorkerRequest) bool {
|
||||
|
||||
if cwr.Alias == "unassigned" {
|
||||
//Reserved alias
|
||||
@@ -260,13 +257,3 @@ func makeSecret() []byte {
|
||||
|
||||
return secret
|
||||
}
|
||||
|
||||
func getIdentity(r *Request) *storage.Identity {
|
||||
|
||||
identity := storage.Identity{
|
||||
RemoteAddr: r.Ctx.RemoteAddr().String(),
|
||||
UserAgent: string(r.Ctx.UserAgent()),
|
||||
}
|
||||
|
||||
return &identity
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user