mirror of
https://github.com/simon987/task_tracker.git
synced 2025-04-20 02:26:46 +00:00
rework worker permissions
This commit is contained in:
parent
e079fc8497
commit
8784b536d3
@ -80,9 +80,6 @@ func New() *WebAPI {
|
|||||||
api.router.GET("/worker/get/:id", LogRequestMiddleware(api.WorkerGet))
|
api.router.GET("/worker/get/:id", LogRequestMiddleware(api.WorkerGet))
|
||||||
api.router.GET("/worker/stats", LogRequestMiddleware(api.GetAllWorkerStats))
|
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.POST("/project/create", LogRequestMiddleware(api.ProjectCreate))
|
||||||
api.router.GET("/project/get/:id", LogRequestMiddleware(api.ProjectGet))
|
api.router.GET("/project/get/:id", LogRequestMiddleware(api.ProjectGet))
|
||||||
api.router.POST("/project/update/:id", LogRequestMiddleware(api.ProjectUpdate))
|
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-between/:id", LogRequestMiddleware(api.GetSnapshotsBetween))
|
||||||
api.router.GET("/project/monitoring/:id", LogRequestMiddleware(api.GetNSnapshots))
|
api.router.GET("/project/monitoring/:id", LogRequestMiddleware(api.GetNSnapshots))
|
||||||
api.router.GET("/project/assignees/:id", LogRequestMiddleware(api.ProjectGetAssigneeStats))
|
api.router.GET("/project/assignees/:id", LogRequestMiddleware(api.ProjectGetAssigneeStats))
|
||||||
api.router.GET("/project/requests/:id", LogRequestMiddleware(api.ProjectGetAccessRequests))
|
api.router.GET("/project/accesses/:id", LogRequestMiddleware(api.ProjectGetWorkerAccesses))
|
||||||
api.router.GET("/project/request_access/:id", LogRequestMiddleware(api.WorkerRequestAccess))
|
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.POST("/task/create", LogRequestMiddleware(api.TaskCreate))
|
||||||
api.router.GET("/task/get/:project", LogRequestMiddleware(api.TaskGetFromProject))
|
api.router.GET("/task/get/:project", LogRequestMiddleware(api.TaskGetFromProject))
|
||||||
|
118
api/project.go
118
api/project.go
@ -59,7 +59,7 @@ type GetAssigneeStatsResponse struct {
|
|||||||
Assignees *[]storage.AssignedTasks `json:"assignees"`
|
Assignees *[]storage.AssignedTasks `json:"assignees"`
|
||||||
}
|
}
|
||||||
|
|
||||||
type WorkerRequestAccessResponse struct {
|
type WorkerAccessRequestResponse struct {
|
||||||
Ok bool `json:"ok"`
|
Ok bool `json:"ok"`
|
||||||
Message string `json:"message,omitempty"`
|
Message string `json:"message,omitempty"`
|
||||||
}
|
}
|
||||||
@ -67,7 +67,7 @@ type WorkerRequestAccessResponse struct {
|
|||||||
type ProjectGetAccessRequestsResponse struct {
|
type ProjectGetAccessRequestsResponse struct {
|
||||||
Ok bool `json:"ok"`
|
Ok bool `json:"ok"`
|
||||||
Message string `json:"message,omitempty"`
|
Message string `json:"message,omitempty"`
|
||||||
Requests *[]storage.Worker `json:"requests,omitempty"`
|
Accesses *[]storage.WorkerAccess `json:"accesses,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *WebAPI) ProjectCreate(r *Request) {
|
func (api *WebAPI) ProjectCreate(r *Request) {
|
||||||
@ -187,7 +187,7 @@ func (api *WebAPI) ProjectUpdate(r *Request) {
|
|||||||
sess := api.Session.StartFasthttp(r.Ctx)
|
sess := api.Session.StartFasthttp(r.Ctx)
|
||||||
manager := sess.Get("manager")
|
manager := sess.Get("manager")
|
||||||
|
|
||||||
if !isProjectUpdateAuthorized(project, manager, api.Database) {
|
if !isActionAuthorized(project.Id, manager, storage.ROLE_EDIT, api.Database) {
|
||||||
r.Json(CreateProjectResponse{
|
r.Json(CreateProjectResponse{
|
||||||
Ok: false,
|
Ok: false,
|
||||||
Message: "Unauthorized",
|
Message: "Unauthorized",
|
||||||
@ -245,7 +245,8 @@ func isProjectCreationAuthorized(project *storage.Project, manager interface{})
|
|||||||
return true
|
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 {
|
if manager == nil {
|
||||||
return false
|
return false
|
||||||
@ -255,8 +256,8 @@ func isProjectUpdateAuthorized(project *storage.Project, manager interface{}, db
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
role := db.GetManagerRoleOn(manager.(*storage.Manager), project.Id)
|
role := db.GetManagerRoleOn(manager.(*storage.Manager), project)
|
||||||
if role&storage.ROLE_EDIT == 1 {
|
if role&requiredRole != 0 {
|
||||||
return true
|
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)
|
sess := api.Session.StartFasthttp(r.Ctx)
|
||||||
manager := sess.Get("manager")
|
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)
|
id, err := strconv.ParseInt(r.Ctx.UserValue("id").(string), 10, 64)
|
||||||
handleErr(err, r) //todo handle invalid id
|
handleErr(err, r) //todo handle invalid id
|
||||||
|
|
||||||
if manager == nil {
|
if !isActionAuthorized(id, manager, storage.ROLE_MANAGE_ACCESS, api.Database) {
|
||||||
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 {
|
|
||||||
r.Json(ProjectGetAccessRequestsResponse{
|
r.Json(ProjectGetAccessRequestsResponse{
|
||||||
Ok: false,
|
Ok: false,
|
||||||
Message: "Unauthorized",
|
Message: "Unauthorized",
|
||||||
}, 403)
|
}, 403)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
requests := api.Database.GetAllAccessRequests(id)
|
accesses := api.Database.GetAllAccesses(id)
|
||||||
|
|
||||||
r.OkJson(ProjectGetAccessRequestsResponse{
|
r.OkJson(ProjectGetAccessRequestsResponse{
|
||||||
Ok: true,
|
Ok: true,
|
||||||
Requests: requests,
|
Accesses: accesses,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
func (api *WebAPI) WorkerRequestAccess(r *Request) {
|
func (api *WebAPI) WorkerRequestAccess(r *Request) {
|
||||||
|
|
||||||
id, err := strconv.ParseInt(r.Ctx.UserValue("id").(string), 10, 64)
|
req := &WorkerAccessRequest{}
|
||||||
handleErr(err, r) //todo handle invalid id
|
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)
|
worker, err := api.validateSignature(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.Json(WorkerRequestAccessResponse{
|
r.Json(WorkerAccessRequestResponse{
|
||||||
Ok: false,
|
Ok: false,
|
||||||
Message: err.Error(),
|
Message: err.Error(),
|
||||||
}, 401)
|
}, 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 {
|
if res {
|
||||||
r.OkJson(WorkerRequestAccessResponse{
|
r.OkJson(WorkerAccessRequestResponse{
|
||||||
Ok: true,
|
Ok: true,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
r.Json(WorkerRequestAccessResponse{
|
r.Json(WorkerAccessRequestResponse{
|
||||||
Ok: false,
|
Ok: false,
|
||||||
Message: "Project is public, you already have " +
|
Message: "Project is public, you already have " +
|
||||||
"an active request or you already have access to this project",
|
"an active request or you already have access to this project",
|
||||||
}, 400)
|
}, 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",
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
13
api/task.go
13
api/task.go
@ -49,8 +49,17 @@ type GetTaskResponse struct {
|
|||||||
|
|
||||||
func (api *WebAPI) TaskCreate(r *Request) {
|
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{}
|
createReq := &CreateTaskRequest{}
|
||||||
err := json.Unmarshal(r.Ctx.Request.Body(), createReq)
|
err = json.Unmarshal(r.Ctx.Request.Body(), createReq)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
r.Json(CreateProjectResponse{
|
r.Json(CreateProjectResponse{
|
||||||
Ok: false,
|
Ok: false,
|
||||||
@ -74,7 +83,7 @@ func (api *WebAPI) TaskCreate(r *Request) {
|
|||||||
createReq.Hash64 = int64(siphash.Hash(1, 2, []byte(createReq.UniqueString)))
|
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 {
|
if err != nil {
|
||||||
r.Json(CreateTaskResponse{
|
r.Json(CreateTaskResponse{
|
||||||
|
@ -9,10 +9,6 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
type CreateWorkerRequest struct {
|
|
||||||
Alias string `json:"alias"`
|
|
||||||
}
|
|
||||||
|
|
||||||
type UpdateWorkerRequest struct {
|
type UpdateWorkerRequest struct {
|
||||||
Alias string `json:"alias"`
|
Alias string `json:"alias"`
|
||||||
}
|
}
|
||||||
@ -22,6 +18,10 @@ type UpdateWorkerResponse struct {
|
|||||||
Message string `json:"message,omitempty"`
|
Message string `json:"message,omitempty"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type CreateWorkerRequest struct {
|
||||||
|
Alias string `json:"alias"`
|
||||||
|
}
|
||||||
|
|
||||||
type CreateWorkerResponse struct {
|
type CreateWorkerResponse struct {
|
||||||
Ok bool `json:"ok"`
|
Ok bool `json:"ok"`
|
||||||
Message string `json:"message,omitempty"`
|
Message string `json:"message,omitempty"`
|
||||||
@ -34,22 +34,25 @@ type GetWorkerResponse struct {
|
|||||||
Worker *storage.Worker `json:"worker,omitempty"`
|
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 {
|
type GetAllWorkerStatsResponse struct {
|
||||||
Ok bool `json:"ok"`
|
Ok bool `json:"ok"`
|
||||||
Message string `json:"message,omitempty"`
|
Message string `json:"message,omitempty"`
|
||||||
Stats *[]storage.WorkerStats `json:"stats"`
|
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) WorkerCreate(r *Request) {
|
||||||
|
|
||||||
workerReq := &CreateWorkerRequest{}
|
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) {
|
func (api *WebAPI) WorkerUpdate(r *Request) {
|
||||||
|
|
||||||
worker, err := api.validateSignature(r)
|
worker, err := api.validateSignature(r)
|
||||||
|
17
schema.sql
17
schema.sql
@ -1,6 +1,6 @@
|
|||||||
DROP TABLE IF EXISTS worker, project, task, log_entry,
|
DROP TABLE IF EXISTS worker, project, task, log_entry,
|
||||||
worker_has_access_to_project, manager, manager_has_role_on_project, project_monitoring_snapshot,
|
worker_access, manager, manager_has_role_on_project, project_monitoring_snapshot,
|
||||||
worker_verifies_task, worker_requests_access_to_project;
|
worker_verifies_task;
|
||||||
DROP TYPE IF EXISTS status;
|
DROP TYPE IF EXISTS status;
|
||||||
DROP TYPE IF EXISTS log_level;
|
DROP TYPE IF EXISTS log_level;
|
||||||
|
|
||||||
@ -28,10 +28,13 @@ CREATE TABLE project
|
|||||||
motd TEXT NOT NULL
|
motd TEXT NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE worker_has_access_to_project
|
CREATE TABLE worker_access
|
||||||
(
|
(
|
||||||
worker INTEGER REFERENCES worker (id),
|
worker INTEGER REFERENCES worker (id),
|
||||||
project INTEGER REFERENCES project (id),
|
project INTEGER REFERENCES project (id),
|
||||||
|
role_assign boolean,
|
||||||
|
role_submit boolean,
|
||||||
|
request boolean,
|
||||||
primary key (worker, project)
|
primary key (worker, project)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -79,7 +82,7 @@ CREATE TABLE manager
|
|||||||
CREATE TABLE manager_has_role_on_project
|
CREATE TABLE manager_has_role_on_project
|
||||||
(
|
(
|
||||||
manager INTEGER REFERENCES manager (id) NOT NULL,
|
manager INTEGER REFERENCES manager (id) NOT NULL,
|
||||||
role SMALLINT NOT NULl,
|
role SMALLINT NOT NULL,
|
||||||
project INTEGER REFERENCES project (id) NOT NULL
|
project INTEGER REFERENCES project (id) NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -94,12 +97,6 @@ CREATE TABLE project_monitoring_snapshot
|
|||||||
timestamp INT NOT NULL
|
timestamp INT NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE worker_requests_access_to_project
|
|
||||||
(
|
|
||||||
worker INT REFERENCES worker (id) NOT NULL,
|
|
||||||
project INT REFERENCES project (id) NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION on_task_delete_proc() RETURNS TRIGGER AS
|
CREATE OR REPLACE FUNCTION on_task_delete_proc() RETURNS TRIGGER AS
|
||||||
$$
|
$$
|
||||||
DECLARE
|
DECLARE
|
||||||
|
@ -30,7 +30,7 @@ func (database *Database) MakeProjectSnapshots() {
|
|||||||
WHERE task.project = project.id AND status = 1 AND wvt.task IS NULL),
|
WHERE task.project = project.id AND status = 1 AND wvt.task IS NULL),
|
||||||
(SELECT COUNT(*) FROM task WHERE task.project = project.id AND status = 2),
|
(SELECT COUNT(*) FROM task WHERE task.project = project.id AND status = 2),
|
||||||
closed_task_count,
|
closed_task_count,
|
||||||
(SELECT COUNT(*) FROM worker_has_access_to_project wa WHERE wa.project = project.id),
|
(SELECT COUNT(*) FROM worker_access wa WHERE wa.project = project.id),
|
||||||
(SELECT COUNT(*) FROM worker_verifies_task INNER JOIN task t on worker_verifies_task.task = t.id
|
(SELECT COUNT(*) FROM worker_verifies_task INNER JOIN task t on worker_verifies_task.task = t.id
|
||||||
WHERE t.project = project.id),
|
WHERE t.project = project.id),
|
||||||
extract(epoch from now() at time zone 'utc')
|
extract(epoch from now() at time zone 'utc')
|
||||||
|
@ -2,6 +2,7 @@ package storage
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"database/sql"
|
"database/sql"
|
||||||
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
"github.com/Sirupsen/logrus"
|
"github.com/Sirupsen/logrus"
|
||||||
)
|
)
|
||||||
@ -35,15 +36,17 @@ const (
|
|||||||
TR_SKIP TaskResult = 2
|
TR_SKIP TaskResult = 2
|
||||||
)
|
)
|
||||||
|
|
||||||
func (database *Database) SaveTask(task *Task, project int64, hash64 int64) error {
|
func (database *Database) SaveTask(task *Task, project int64, hash64 int64, wid int64) error {
|
||||||
|
|
||||||
db := database.getDB()
|
db := database.getDB()
|
||||||
|
|
||||||
//TODO: For some reason it refuses to insert the 64-bit value unless I do that...
|
//TODO: For some reason it refuses to insert the 64-bit value unless I do that...
|
||||||
res, err := db.Exec(fmt.Sprintf(`
|
res, err := db.Exec(fmt.Sprintf(`
|
||||||
INSERT INTO task (project, max_retries, recipe, priority, max_assign_time, hash64,verification_count)
|
INSERT INTO task (project, max_retries, recipe, priority, max_assign_time, hash64,verification_count)
|
||||||
VALUES ($1,$2,$3,$4,$5,NULLIF(%d, 0),$6)`, hash64),
|
SELECT $1,$2,$3,$4,$5,NULLIF(%d, 0),$6 FROM worker_access
|
||||||
project, task.MaxRetries, task.Recipe, task.Priority, task.MaxAssignTime, task.VerificationCount)
|
WHERE role_submit AND worker=$7 AND project=$1`, hash64),
|
||||||
|
project, task.MaxRetries, task.Recipe, task.Priority, task.MaxAssignTime, task.VerificationCount,
|
||||||
|
wid)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithError(err).WithFields(logrus.Fields{
|
logrus.WithError(err).WithFields(logrus.Fields{
|
||||||
"task": task,
|
"task": task,
|
||||||
@ -59,6 +62,10 @@ func (database *Database) SaveTask(task *Task, project int64, hash64 int64) erro
|
|||||||
"task": task,
|
"task": task,
|
||||||
}).Trace("Database.saveTask INSERT task")
|
}).Trace("Database.saveTask INSERT task")
|
||||||
|
|
||||||
|
if rowsAffected == 0 {
|
||||||
|
return errors.New("unauthorized task submit")
|
||||||
|
}
|
||||||
|
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -77,7 +84,7 @@ func (database *Database) GetTask(worker *Worker) *Task {
|
|||||||
LEFT JOIN worker_verifies_task wvt on task.id = wvt.task AND wvt.worker=$1
|
LEFT JOIN worker_verifies_task wvt on task.id = wvt.task AND wvt.worker=$1
|
||||||
WHERE assignee IS NULL AND task.status=1
|
WHERE assignee IS NULL AND task.status=1
|
||||||
AND (project.public OR EXISTS (
|
AND (project.public OR EXISTS (
|
||||||
SELECT 1 FROM worker_has_access_to_project a WHERE a.worker=$1 AND a.project=project.id
|
SELECT a.role_assign FROM worker_access a WHERE a.worker=$1 AND a.project=project.id
|
||||||
))
|
))
|
||||||
AND wvt.task IS NULL
|
AND wvt.task IS NULL
|
||||||
ORDER BY project.priority DESC, task.priority DESC
|
ORDER BY project.priority DESC, task.priority DESC
|
||||||
@ -179,8 +186,8 @@ func (database *Database) GetTaskFromProject(worker *Worker, projectId int64) *T
|
|||||||
INNER JOIN project project on task.project = project.id
|
INNER JOIN project project on task.project = project.id
|
||||||
LEFT JOIN worker_verifies_task wvt on task.id = wvt.task AND wvt.worker=$1
|
LEFT JOIN worker_verifies_task wvt on task.id = wvt.task AND wvt.worker=$1
|
||||||
WHERE assignee IS NULL AND project.id=$2 AND status=1
|
WHERE assignee IS NULL AND project.id=$2 AND status=1
|
||||||
AND (project.public OR EXISTS (
|
AND (project.public OR (
|
||||||
SELECT 1 FROM worker_has_access_to_project a WHERE a.worker=$1 AND a.project=$2
|
SELECT a.role_assign FROM worker_access a WHERE a.worker=$1 AND a.project=$2
|
||||||
))
|
))
|
||||||
AND wvt.task IS NULL
|
AND wvt.task IS NULL
|
||||||
ORDER BY task.priority DESC
|
ORDER BY task.priority DESC
|
||||||
|
@ -16,11 +16,20 @@ type WorkerStats struct {
|
|||||||
ClosedTaskCount int64 `json:"closed_task_count"`
|
ClosedTaskCount int64 `json:"closed_task_count"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type WorkerAccess struct {
|
||||||
|
Submit bool `json:"submit"`
|
||||||
|
Assign bool `json:"assign"`
|
||||||
|
Request bool `json:"request"`
|
||||||
|
Worker Worker `json:"worker"`
|
||||||
|
Project int64 `json:"project"`
|
||||||
|
}
|
||||||
|
|
||||||
func (database *Database) SaveWorker(worker *Worker) {
|
func (database *Database) SaveWorker(worker *Worker) {
|
||||||
|
|
||||||
db := database.getDB()
|
db := database.getDB()
|
||||||
|
|
||||||
row := db.QueryRow("INSERT INTO worker (created, secret, alias) VALUES ($1,$2,$3) RETURNING id",
|
row := db.QueryRow(`INSERT INTO worker (created, secret, alias)
|
||||||
|
VALUES ($1,$2,$3) RETURNING id`,
|
||||||
worker.Created, worker.Secret, worker.Alias)
|
worker.Created, worker.Secret, worker.Alias)
|
||||||
|
|
||||||
err := row.Scan(&worker.Id)
|
err := row.Scan(&worker.Id)
|
||||||
@ -56,14 +65,14 @@ func (database *Database) GetWorker(id int64) *Worker {
|
|||||||
func (database *Database) GrantAccess(workerId int64, projectId int64) bool {
|
func (database *Database) GrantAccess(workerId int64, projectId int64) bool {
|
||||||
|
|
||||||
db := database.getDB()
|
db := database.getDB()
|
||||||
res, err := db.Exec(`INSERT INTO worker_has_access_to_project (worker, project) VALUES ($1,$2)
|
res, err := db.Exec(`UPDATE worker_access SET
|
||||||
ON CONFLICT DO NOTHING`,
|
request=FALSE WHERE worker=$1 AND project=$2`,
|
||||||
workerId, projectId)
|
workerId, projectId)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logrus.WithFields(logrus.Fields{
|
logrus.WithFields(logrus.Fields{
|
||||||
"workerId": workerId,
|
"workerId": workerId,
|
||||||
"projectId": projectId,
|
"projectId": projectId,
|
||||||
}).WithError(err).Warn("Database.GrantAccess INSERT worker_hase_access_to_project")
|
}).WithError(err).Warn("Database.GrantAccess INSERT")
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,25 +82,7 @@ func (database *Database) GrantAccess(workerId int64, projectId int64) bool {
|
|||||||
"rowsAffected": rowsAffected,
|
"rowsAffected": rowsAffected,
|
||||||
"workerId": workerId,
|
"workerId": workerId,
|
||||||
"projectId": projectId,
|
"projectId": projectId,
|
||||||
}).Trace("Database.GrantAccess INSERT worker_has_access_to_project")
|
}).Trace("Database.GrantAccess INSERT")
|
||||||
|
|
||||||
return rowsAffected == 1
|
|
||||||
}
|
|
||||||
|
|
||||||
func (database *Database) RemoveAccess(workerId int64, projectId int64) bool {
|
|
||||||
|
|
||||||
db := database.getDB()
|
|
||||||
res, err := db.Exec(`DELETE FROM worker_has_access_to_project WHERE worker=$1 AND project=$2`,
|
|
||||||
workerId, projectId)
|
|
||||||
handleErr(err)
|
|
||||||
|
|
||||||
rowsAffected, _ := res.RowsAffected()
|
|
||||||
|
|
||||||
logrus.WithFields(logrus.Fields{
|
|
||||||
"rowsAffected": rowsAffected,
|
|
||||||
"workerId": workerId,
|
|
||||||
"projectId": projectId,
|
|
||||||
}).Trace("Database.RemoveAccess DELETE worker_has_access_to_project")
|
|
||||||
|
|
||||||
return rowsAffected == 1
|
return rowsAffected == 1
|
||||||
}
|
}
|
||||||
@ -113,14 +104,14 @@ func (database *Database) UpdateWorker(worker *Worker) bool {
|
|||||||
return rowsAffected == 1
|
return rowsAffected == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (database *Database) SaveAccessRequest(worker *Worker, projectId int64) bool {
|
func (database *Database) SaveAccessRequest(wa *WorkerAccess) bool {
|
||||||
|
|
||||||
db := database.getDB()
|
db := database.getDB()
|
||||||
|
|
||||||
res, err := db.Exec(`INSERT INTO worker_requests_access_to_project
|
res, err := db.Exec(`INSERT INTO worker_access(worker, project, role_assign,
|
||||||
SELECT $1, id FROM project WHERE id=$2 AND NOT project.public
|
role_submit, request)
|
||||||
AND NOT EXISTS(SELECT * FROM worker_has_access_to_project WHERE worker=$1 AND project=$2)`,
|
VALUES ($1,$2,$3,$4,TRUE)`,
|
||||||
worker.Id, projectId)
|
wa.Worker.Id, wa.Project, wa.Assign, wa.Submit)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return false
|
return false
|
||||||
}
|
}
|
||||||
@ -134,35 +125,12 @@ func (database *Database) SaveAccessRequest(worker *Worker, projectId int64) boo
|
|||||||
return rowsAffected == 1
|
return rowsAffected == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (database *Database) AcceptAccessRequest(worker *Worker, projectId int64) bool {
|
func (database *Database) AcceptAccessRequest(worker int64, projectId int64) bool {
|
||||||
|
|
||||||
db := database.getDB()
|
db := database.getDB()
|
||||||
|
|
||||||
res, err := db.Exec(`DELETE FROM worker_requests_access_to_project
|
res, err := db.Exec(`UPDATE worker_access SET request=FALSE
|
||||||
WHERE worker=$1 AND project=$2`)
|
WHERE worker=$1 AND project=$2`, worker, projectId)
|
||||||
handleErr(err)
|
|
||||||
|
|
||||||
rowsAffected, _ := res.RowsAffected()
|
|
||||||
if rowsAffected == 1 {
|
|
||||||
_, err := db.Exec(`INSERT INTO worker_has_access_to_project
|
|
||||||
(worker, project) VALUES ($1,$2)`,
|
|
||||||
worker.Id, projectId)
|
|
||||||
handleErr(err)
|
|
||||||
}
|
|
||||||
|
|
||||||
logrus.WithFields(logrus.Fields{
|
|
||||||
"rowsAffected": rowsAffected,
|
|
||||||
}).Trace("Database.AcceptAccessRequest")
|
|
||||||
|
|
||||||
return rowsAffected == 1
|
|
||||||
}
|
|
||||||
|
|
||||||
func (database *Database) RejectAccessRequest(worker *Worker, projectId int64) bool {
|
|
||||||
|
|
||||||
db := database.getDB()
|
|
||||||
|
|
||||||
res, err := db.Exec(`DELETE FROM worker_requests_access_to_project
|
|
||||||
WHERE worker=$1 AND project=$2`, worker.Id, projectId)
|
|
||||||
handleErr(err)
|
handleErr(err)
|
||||||
|
|
||||||
rowsAffected, _ := res.RowsAffected()
|
rowsAffected, _ := res.RowsAffected()
|
||||||
@ -174,22 +142,44 @@ func (database *Database) RejectAccessRequest(worker *Worker, projectId int64) b
|
|||||||
return rowsAffected == 1
|
return rowsAffected == 1
|
||||||
}
|
}
|
||||||
|
|
||||||
func (database *Database) GetAllAccessRequests(projectId int64) *[]Worker {
|
func (database *Database) RejectAccessRequest(workerId int64, projectId int64) bool {
|
||||||
|
|
||||||
|
db := database.getDB()
|
||||||
|
res, err := db.Exec(`DELETE FROM worker_access WHERE worker=$1 AND project=$2`,
|
||||||
|
workerId, projectId)
|
||||||
|
handleErr(err)
|
||||||
|
|
||||||
|
rowsAffected, _ := res.RowsAffected()
|
||||||
|
|
||||||
|
logrus.WithFields(logrus.Fields{
|
||||||
|
"rowsAffected": rowsAffected,
|
||||||
|
"workerId": workerId,
|
||||||
|
"projectId": projectId,
|
||||||
|
}).Trace("Database.RejectAccessRequest DELETE")
|
||||||
|
|
||||||
|
return rowsAffected == 1
|
||||||
|
}
|
||||||
|
|
||||||
|
func (database *Database) GetAllAccesses(projectId int64) *[]WorkerAccess {
|
||||||
|
|
||||||
db := database.getDB()
|
db := database.getDB()
|
||||||
|
|
||||||
rows, err := db.Query(`SELECT id, alias, created FROM worker_requests_access_to_project
|
rows, err := db.Query(`SELECT id, alias, created, role_assign, role_submit, request
|
||||||
INNER JOIN worker w on worker_requests_access_to_project.worker = w.id
|
FROM worker_access
|
||||||
WHERE project=$1`,
|
INNER JOIN worker w on worker_access.worker = w.id
|
||||||
|
WHERE project=$1 ORDER BY request, alias`,
|
||||||
projectId)
|
projectId)
|
||||||
handleErr(err)
|
handleErr(err)
|
||||||
|
|
||||||
requests := make([]Worker, 0)
|
requests := make([]WorkerAccess, 0)
|
||||||
|
|
||||||
for rows.Next() {
|
for rows.Next() {
|
||||||
w := Worker{}
|
wa := WorkerAccess{
|
||||||
_ = rows.Scan(&w.Id, &w.Alias, &w.Created)
|
Project: projectId,
|
||||||
requests = append(requests, w)
|
}
|
||||||
|
_ = rows.Scan(&wa.Worker.Id, &wa.Worker.Alias, &wa.Worker.Created,
|
||||||
|
&wa.Assign, &wa.Submit, &wa.Request)
|
||||||
|
requests = append(requests, wa)
|
||||||
}
|
}
|
||||||
|
|
||||||
return &requests
|
return &requests
|
||||||
|
@ -143,6 +143,40 @@ func TestInvalidCredentialsLogin(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRequireManageAccessRole(t *testing.T) {
|
||||||
|
|
||||||
|
user := getSessionCtx("testreqmanrole", "testreqmanrole", false)
|
||||||
|
|
||||||
|
pid := createProject(api.CreateProjectRequest{
|
||||||
|
GitRepo: "testRequireManageAccessRole",
|
||||||
|
CloneUrl: "testRequireManageAccessRole",
|
||||||
|
Name: "testRequireManageAccessRole",
|
||||||
|
Version: "testRequireManageAccessRole",
|
||||||
|
}, user).Id
|
||||||
|
|
||||||
|
w := genWid()
|
||||||
|
requestAccess(api.WorkerAccessRequest{
|
||||||
|
Submit: true,
|
||||||
|
Assign: true,
|
||||||
|
Project: pid,
|
||||||
|
}, w)
|
||||||
|
|
||||||
|
rGuest := acceptAccessRequest(pid, w.Id, nil)
|
||||||
|
rOtherUser := acceptAccessRequest(pid, w.Id, testUserCtx)
|
||||||
|
rUser := acceptAccessRequest(pid, w.Id, user)
|
||||||
|
|
||||||
|
if rGuest.Ok != false {
|
||||||
|
t.Error()
|
||||||
|
}
|
||||||
|
if rOtherUser.Ok != false {
|
||||||
|
t.Error()
|
||||||
|
}
|
||||||
|
if rUser.Ok != true {
|
||||||
|
t.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
func register(request *api.RegisterRequest) *api.RegisterResponse {
|
func register(request *api.RegisterRequest) *api.RegisterResponse {
|
||||||
|
|
||||||
r := Post("/register", request, nil, nil)
|
r := Post("/register", request, nil, nil)
|
||||||
|
@ -2,8 +2,6 @@ package test
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"github.com/simon987/task_tracker/api"
|
"github.com/simon987/task_tracker/api"
|
||||||
"github.com/simon987/task_tracker/config"
|
|
||||||
"github.com/simon987/task_tracker/storage"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
@ -29,24 +27,3 @@ func BenchmarkCreateTaskRemote(b *testing.B) {
|
|||||||
}, worker)
|
}, worker)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func BenchmarkCreateTask(b *testing.B) {
|
|
||||||
|
|
||||||
config.SetupConfig()
|
|
||||||
db := storage.Database{}
|
|
||||||
|
|
||||||
project, _ := db.SaveProject(&storage.Project{
|
|
||||||
Priority: 1,
|
|
||||||
Id: 1,
|
|
||||||
Version: "bmcreatetask",
|
|
||||||
Public: true,
|
|
||||||
Motd: "bmcreatetask",
|
|
||||||
Name: "BenchmarkCreateTask" + strconv.Itoa(b.N),
|
|
||||||
GitRepo: "benchmark_test" + strconv.Itoa(b.N),
|
|
||||||
})
|
|
||||||
|
|
||||||
b.ResetTimer()
|
|
||||||
for i := 0; i < b.N; i++ {
|
|
||||||
_ = db.SaveTask(&storage.Task{}, project, 0)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
@ -11,23 +11,29 @@ import (
|
|||||||
|
|
||||||
func TestCreateTaskValid(t *testing.T) {
|
func TestCreateTaskValid(t *testing.T) {
|
||||||
|
|
||||||
//Make sure there is always a project for id:1
|
pid := createProjectAsAdmin(api.CreateProjectRequest{
|
||||||
createProjectAsAdmin(api.CreateProjectRequest{
|
|
||||||
Name: "Some Test name",
|
Name: "Some Test name",
|
||||||
Version: "Test Version",
|
Version: "Test Version",
|
||||||
CloneUrl: "http://github.com/test/test",
|
CloneUrl: "http://github.com/test/test",
|
||||||
})
|
GitRepo: "Some git repo",
|
||||||
|
}).Id
|
||||||
|
|
||||||
worker := genWid()
|
worker := genWid()
|
||||||
|
requestAccess(api.WorkerAccessRequest{
|
||||||
|
Project: pid,
|
||||||
|
Submit: true,
|
||||||
|
Assign: false,
|
||||||
|
}, worker)
|
||||||
|
acceptAccessRequest(pid, worker.Id, testAdminCtx)
|
||||||
|
|
||||||
resp := createTask(api.CreateTaskRequest{
|
resp := createTask(api.CreateTaskRequest{
|
||||||
Project: 1,
|
Project: pid,
|
||||||
Recipe: "{}",
|
Recipe: "{}",
|
||||||
MaxRetries: 3,
|
MaxRetries: 3,
|
||||||
}, worker)
|
}, worker)
|
||||||
|
|
||||||
if resp.Ok != true {
|
if resp.Ok != true {
|
||||||
t.Fail()
|
t.Error()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -143,6 +149,12 @@ func TestCreateGetTask(t *testing.T) {
|
|||||||
})
|
})
|
||||||
|
|
||||||
worker := genWid()
|
worker := genWid()
|
||||||
|
requestAccess(api.WorkerAccessRequest{
|
||||||
|
Submit: true,
|
||||||
|
Assign: true,
|
||||||
|
Project: resp.Id,
|
||||||
|
}, worker)
|
||||||
|
acceptAccessRequest(resp.Id, worker.Id, testAdminCtx)
|
||||||
|
|
||||||
createTask(api.CreateTaskRequest{
|
createTask(api.CreateTaskRequest{
|
||||||
Project: resp.Id,
|
Project: resp.Id,
|
||||||
@ -211,6 +223,19 @@ func createTasks(prefix string) (int64, int64) {
|
|||||||
Public: true,
|
Public: true,
|
||||||
})
|
})
|
||||||
worker := genWid()
|
worker := genWid()
|
||||||
|
requestAccess(api.WorkerAccessRequest{
|
||||||
|
Submit: true,
|
||||||
|
Assign: false,
|
||||||
|
Project: highP.Id,
|
||||||
|
}, worker)
|
||||||
|
acceptAccessRequest(highP.Id, worker.Id, testAdminCtx)
|
||||||
|
requestAccess(api.WorkerAccessRequest{
|
||||||
|
Submit: true,
|
||||||
|
Assign: false,
|
||||||
|
Project: lowP.Id,
|
||||||
|
}, worker)
|
||||||
|
acceptAccessRequest(lowP.Id, worker.Id, testAdminCtx)
|
||||||
|
|
||||||
createTask(api.CreateTaskRequest{
|
createTask(api.CreateTaskRequest{
|
||||||
Project: lowP.Id,
|
Project: lowP.Id,
|
||||||
Recipe: "low1",
|
Recipe: "low1",
|
||||||
@ -303,6 +328,13 @@ func TestTaskNoAccess(t *testing.T) {
|
|||||||
Public: false,
|
Public: false,
|
||||||
}).Id
|
}).Id
|
||||||
|
|
||||||
|
requestAccess(api.WorkerAccessRequest{
|
||||||
|
Project: pid,
|
||||||
|
Assign: true,
|
||||||
|
Submit: true,
|
||||||
|
}, worker)
|
||||||
|
acceptAccessRequest(worker.Id, pid, testAdminCtx)
|
||||||
|
|
||||||
createResp := createTask(api.CreateTaskRequest{
|
createResp := createTask(api.CreateTaskRequest{
|
||||||
Project: pid,
|
Project: pid,
|
||||||
Priority: 1,
|
Priority: 1,
|
||||||
@ -315,8 +347,7 @@ func TestTaskNoAccess(t *testing.T) {
|
|||||||
t.Error()
|
t.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
grantAccess(worker.Id, pid)
|
rejectAccessRequest(pid, worker.Id, testAdminCtx)
|
||||||
removeAccess(worker.Id, pid)
|
|
||||||
|
|
||||||
tResp := getTaskFromProject(pid, worker)
|
tResp := getTaskFromProject(pid, worker)
|
||||||
|
|
||||||
@ -345,6 +376,13 @@ func TestTaskHasAccess(t *testing.T) {
|
|||||||
Public: false,
|
Public: false,
|
||||||
}).Id
|
}).Id
|
||||||
|
|
||||||
|
requestAccess(api.WorkerAccessRequest{
|
||||||
|
Submit: true,
|
||||||
|
Assign: true,
|
||||||
|
Project: pid,
|
||||||
|
}, worker)
|
||||||
|
acceptAccessRequest(worker.Id, pid, testAdminCtx)
|
||||||
|
|
||||||
createResp := createTask(api.CreateTaskRequest{
|
createResp := createTask(api.CreateTaskRequest{
|
||||||
Project: pid,
|
Project: pid,
|
||||||
Priority: 1,
|
Priority: 1,
|
||||||
@ -357,8 +395,6 @@ func TestTaskHasAccess(t *testing.T) {
|
|||||||
t.Error()
|
t.Error()
|
||||||
}
|
}
|
||||||
|
|
||||||
grantAccess(worker.Id, pid)
|
|
||||||
|
|
||||||
tResp := getTaskFromProject(pid, worker)
|
tResp := getTaskFromProject(pid, worker)
|
||||||
|
|
||||||
if tResp.Ok != true {
|
if tResp.Ok != true {
|
||||||
@ -392,6 +428,13 @@ func TestReleaseTaskSuccess(t *testing.T) {
|
|||||||
Public: true,
|
Public: true,
|
||||||
}).Id
|
}).Id
|
||||||
|
|
||||||
|
requestAccess(api.WorkerAccessRequest{
|
||||||
|
Project: pid,
|
||||||
|
Assign: true,
|
||||||
|
Submit: true,
|
||||||
|
}, worker)
|
||||||
|
acceptAccessRequest(pid, worker.Id, testAdminCtx)
|
||||||
|
|
||||||
createTask(api.CreateTaskRequest{
|
createTask(api.CreateTaskRequest{
|
||||||
Priority: 0,
|
Priority: 0,
|
||||||
Project: pid,
|
Project: pid,
|
||||||
@ -431,6 +474,12 @@ func TestCreateIntCollision(t *testing.T) {
|
|||||||
}).Id
|
}).Id
|
||||||
|
|
||||||
w := genWid()
|
w := genWid()
|
||||||
|
requestAccess(api.WorkerAccessRequest{
|
||||||
|
Project: pid,
|
||||||
|
Assign: true,
|
||||||
|
Submit: true,
|
||||||
|
}, w)
|
||||||
|
acceptAccessRequest(pid, w.Id, testAdminCtx)
|
||||||
|
|
||||||
if createTask(api.CreateTaskRequest{
|
if createTask(api.CreateTaskRequest{
|
||||||
Project: pid,
|
Project: pid,
|
||||||
@ -471,6 +520,12 @@ func TestCreateStringCollision(t *testing.T) {
|
|||||||
}).Id
|
}).Id
|
||||||
|
|
||||||
w := genWid()
|
w := genWid()
|
||||||
|
requestAccess(api.WorkerAccessRequest{
|
||||||
|
Project: pid,
|
||||||
|
Assign: true,
|
||||||
|
Submit: true,
|
||||||
|
}, w)
|
||||||
|
acceptAccessRequest(pid, w.Id, testAdminCtx)
|
||||||
|
|
||||||
if createTask(api.CreateTaskRequest{
|
if createTask(api.CreateTaskRequest{
|
||||||
Project: pid,
|
Project: pid,
|
||||||
@ -520,6 +575,12 @@ func TestCannotVerifySameTaskTwice(t *testing.T) {
|
|||||||
}).Id
|
}).Id
|
||||||
|
|
||||||
w := genWid()
|
w := genWid()
|
||||||
|
requestAccess(api.WorkerAccessRequest{
|
||||||
|
Project: pid,
|
||||||
|
Assign: true,
|
||||||
|
Submit: true,
|
||||||
|
}, w)
|
||||||
|
acceptAccessRequest(pid, w.Id, testAdminCtx)
|
||||||
|
|
||||||
createTask(api.CreateTaskRequest{
|
createTask(api.CreateTaskRequest{
|
||||||
VerificationCount: 2,
|
VerificationCount: 2,
|
||||||
@ -560,6 +621,24 @@ func TestVerification2(t *testing.T) {
|
|||||||
w := genWid()
|
w := genWid()
|
||||||
w2 := genWid()
|
w2 := genWid()
|
||||||
w3 := genWid()
|
w3 := genWid()
|
||||||
|
requestAccess(api.WorkerAccessRequest{
|
||||||
|
Project: pid,
|
||||||
|
Assign: true,
|
||||||
|
Submit: true,
|
||||||
|
}, w)
|
||||||
|
requestAccess(api.WorkerAccessRequest{
|
||||||
|
Project: pid,
|
||||||
|
Assign: true,
|
||||||
|
Submit: true,
|
||||||
|
}, w2)
|
||||||
|
requestAccess(api.WorkerAccessRequest{
|
||||||
|
Project: pid,
|
||||||
|
Assign: true,
|
||||||
|
Submit: true,
|
||||||
|
}, w3)
|
||||||
|
acceptAccessRequest(pid, w.Id, testAdminCtx)
|
||||||
|
acceptAccessRequest(pid, w2.Id, testAdminCtx)
|
||||||
|
acceptAccessRequest(pid, w3.Id, testAdminCtx)
|
||||||
|
|
||||||
createTask(api.CreateTaskRequest{
|
createTask(api.CreateTaskRequest{
|
||||||
VerificationCount: 2,
|
VerificationCount: 2,
|
||||||
@ -614,6 +693,12 @@ func TestReleaseTaskFail(t *testing.T) {
|
|||||||
}).Id
|
}).Id
|
||||||
|
|
||||||
w := genWid()
|
w := genWid()
|
||||||
|
requestAccess(api.WorkerAccessRequest{
|
||||||
|
Project: pid,
|
||||||
|
Assign: true,
|
||||||
|
Submit: true,
|
||||||
|
}, w)
|
||||||
|
acceptAccessRequest(pid, w.Id, testAdminCtx)
|
||||||
|
|
||||||
createTask(api.CreateTaskRequest{
|
createTask(api.CreateTaskRequest{
|
||||||
MaxRetries: 0,
|
MaxRetries: 0,
|
||||||
@ -657,6 +742,18 @@ func TestTaskChain(t *testing.T) {
|
|||||||
CloneUrl: "testtaskchain2",
|
CloneUrl: "testtaskchain2",
|
||||||
Chain: p1,
|
Chain: p1,
|
||||||
}).Id
|
}).Id
|
||||||
|
requestAccess(api.WorkerAccessRequest{
|
||||||
|
Project: p1,
|
||||||
|
Assign: true,
|
||||||
|
Submit: true,
|
||||||
|
}, w)
|
||||||
|
requestAccess(api.WorkerAccessRequest{
|
||||||
|
Project: p2,
|
||||||
|
Assign: true,
|
||||||
|
Submit: true,
|
||||||
|
}, w)
|
||||||
|
acceptAccessRequest(p1, w.Id, testAdminCtx)
|
||||||
|
acceptAccessRequest(p2, w.Id, testAdminCtx)
|
||||||
|
|
||||||
createTask(api.CreateTaskRequest{
|
createTask(api.CreateTaskRequest{
|
||||||
Project: p2,
|
Project: p2,
|
||||||
|
@ -64,79 +64,6 @@ func TestGetWorkerInvalid(t *testing.T) {
|
|||||||
t.Error()
|
t.Error()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func TestGrantAccessFailedProjectConstraint(t *testing.T) {
|
|
||||||
|
|
||||||
wid := genWid()
|
|
||||||
|
|
||||||
resp := grantAccess(wid.Id, 38274593)
|
|
||||||
|
|
||||||
if resp.Ok != false {
|
|
||||||
t.Error()
|
|
||||||
}
|
|
||||||
if len(resp.Message) <= 0 {
|
|
||||||
t.Error()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRemoveAccessFailedProjectConstraint(t *testing.T) {
|
|
||||||
|
|
||||||
worker := genWid()
|
|
||||||
|
|
||||||
resp := removeAccess(worker.Id, 38274593)
|
|
||||||
|
|
||||||
if resp.Ok != false {
|
|
||||||
t.Error()
|
|
||||||
}
|
|
||||||
if len(resp.Message) <= 0 {
|
|
||||||
t.Error()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestRemoveAccessFailedWorkerConstraint(t *testing.T) {
|
|
||||||
|
|
||||||
pid := createProjectAsAdmin(api.CreateProjectRequest{
|
|
||||||
Priority: 1,
|
|
||||||
GitRepo: "dfffffffffff",
|
|
||||||
CloneUrl: "fffffffffff23r",
|
|
||||||
Version: "f83w9rw",
|
|
||||||
Motd: "ddddddddd",
|
|
||||||
Name: "removeaccessfailedworkerconstraint",
|
|
||||||
Public: true,
|
|
||||||
}).Id
|
|
||||||
|
|
||||||
resp := removeAccess(0, pid)
|
|
||||||
|
|
||||||
if resp.Ok != false {
|
|
||||||
t.Error()
|
|
||||||
}
|
|
||||||
if len(resp.Message) <= 0 {
|
|
||||||
t.Error()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestGrantAccessFailedWorkerConstraint(t *testing.T) {
|
|
||||||
|
|
||||||
pid := createProjectAsAdmin(api.CreateProjectRequest{
|
|
||||||
Priority: 1,
|
|
||||||
GitRepo: "dfffffffffff1",
|
|
||||||
CloneUrl: "fffffffffff23r1",
|
|
||||||
Version: "f83w9rw1",
|
|
||||||
Motd: "ddddddddd1",
|
|
||||||
Name: "grantaccessfailedworkerconstraint",
|
|
||||||
Public: true,
|
|
||||||
}).Id
|
|
||||||
|
|
||||||
resp := removeAccess(0, pid)
|
|
||||||
|
|
||||||
if resp.Ok != false {
|
|
||||||
t.Error()
|
|
||||||
}
|
|
||||||
if len(resp.Message) <= 0 {
|
|
||||||
t.Error()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestUpdateAliasValid(t *testing.T) {
|
func TestUpdateAliasValid(t *testing.T) {
|
||||||
|
|
||||||
wid := genWid()
|
wid := genWid()
|
||||||
@ -169,7 +96,30 @@ func TestCreateWorkerAliasInvalid(t *testing.T) {
|
|||||||
if len(resp.Message) <= 0 {
|
if len(resp.Message) <= 0 {
|
||||||
t.Error()
|
t.Error()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestInvalidAccessRequest(t *testing.T) {
|
||||||
|
|
||||||
|
w := genWid()
|
||||||
|
pid := createProjectAsAdmin(api.CreateProjectRequest{
|
||||||
|
Name: "testinvalidaccessreq",
|
||||||
|
CloneUrl: "testinvalidaccessreq",
|
||||||
|
GitRepo: "testinvalidaccessreq",
|
||||||
|
}).Id
|
||||||
|
|
||||||
|
r := requestAccess(api.WorkerAccessRequest{
|
||||||
|
Submit: false,
|
||||||
|
Assign: false,
|
||||||
|
Project: pid,
|
||||||
|
}, w)
|
||||||
|
|
||||||
|
if r.Ok != false {
|
||||||
|
t.Error()
|
||||||
|
}
|
||||||
|
|
||||||
|
if len(r.Message) <= 0 {
|
||||||
|
t.Error()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func createWorker(req api.CreateWorkerRequest) (*api.CreateWorkerResponse, *http.Response) {
|
func createWorker(req api.CreateWorkerRequest) (*api.CreateWorkerResponse, *http.Response) {
|
||||||
@ -201,14 +151,11 @@ func genWid() *storage.Worker {
|
|||||||
return resp.Worker
|
return resp.Worker
|
||||||
}
|
}
|
||||||
|
|
||||||
func grantAccess(wid int64, project int64) *api.WorkerAccessResponse {
|
func requestAccess(req api.WorkerAccessRequest, w *storage.Worker) *api.WorkerAccessRequestResponse {
|
||||||
|
|
||||||
r := Post("/access/grant", api.WorkerAccessRequest{
|
r := Post(fmt.Sprintf("/project/request_access"), req, w, nil)
|
||||||
WorkerId: wid,
|
|
||||||
ProjectId: project,
|
|
||||||
}, nil, nil)
|
|
||||||
|
|
||||||
var resp *api.WorkerAccessResponse
|
var resp *api.WorkerAccessRequestResponse
|
||||||
data, _ := ioutil.ReadAll(r.Body)
|
data, _ := ioutil.ReadAll(r.Body)
|
||||||
err := json.Unmarshal(data, &resp)
|
err := json.Unmarshal(data, &resp)
|
||||||
handleErr(err)
|
handleErr(err)
|
||||||
@ -216,14 +163,25 @@ func grantAccess(wid int64, project int64) *api.WorkerAccessResponse {
|
|||||||
return resp
|
return resp
|
||||||
}
|
}
|
||||||
|
|
||||||
func removeAccess(wid int64, project int64) *api.WorkerAccessResponse {
|
func acceptAccessRequest(pid int64, wid int64, s *http.Client) *api.WorkerAccessRequestResponse {
|
||||||
|
|
||||||
r := Post("/access/remove", api.WorkerAccessRequest{
|
r := Post(fmt.Sprintf("/project/accept_request/%d/%d", pid, wid), nil,
|
||||||
WorkerId: wid,
|
nil, s)
|
||||||
ProjectId: project,
|
|
||||||
}, nil, nil)
|
|
||||||
|
|
||||||
var resp *api.WorkerAccessResponse
|
var resp *api.WorkerAccessRequestResponse
|
||||||
|
data, _ := ioutil.ReadAll(r.Body)
|
||||||
|
err := json.Unmarshal(data, &resp)
|
||||||
|
handleErr(err)
|
||||||
|
|
||||||
|
return resp
|
||||||
|
}
|
||||||
|
|
||||||
|
func rejectAccessRequest(pid int64, wid int64, s *http.Client) *api.WorkerAccessRequestResponse {
|
||||||
|
|
||||||
|
r := Post(fmt.Sprintf("/project/reject_request/%d/%d", pid, wid), nil,
|
||||||
|
nil, s)
|
||||||
|
|
||||||
|
var resp *api.WorkerAccessRequestResponse
|
||||||
data, _ := ioutil.ReadAll(r.Body)
|
data, _ := ioutil.ReadAll(r.Body)
|
||||||
err := json.Unmarshal(data, &resp)
|
err := json.Unmarshal(data, &resp)
|
||||||
handleErr(err)
|
handleErr(err)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
DROP TABLE IF EXISTS worker, project, task, log_entry,
|
DROP TABLE IF EXISTS worker, project, task, log_entry,
|
||||||
worker_has_access_to_project, manager, manager_has_role_on_project, project_monitoring_snapshot,
|
worker_access, manager, manager_has_role_on_project, project_monitoring_snapshot,
|
||||||
worker_verifies_task, worker_requests_access_to_project;
|
worker_verifies_task;
|
||||||
DROP TYPE IF EXISTS status;
|
DROP TYPE IF EXISTS status;
|
||||||
DROP TYPE IF EXISTS log_level;
|
DROP TYPE IF EXISTS log_level;
|
||||||
|
|
||||||
@ -28,10 +28,13 @@ CREATE TABLE project
|
|||||||
motd TEXT NOT NULL
|
motd TEXT NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE worker_has_access_to_project
|
CREATE TABLE worker_access
|
||||||
(
|
(
|
||||||
worker INTEGER REFERENCES worker (id),
|
worker INTEGER REFERENCES worker (id),
|
||||||
project INTEGER REFERENCES project (id),
|
project INTEGER REFERENCES project (id),
|
||||||
|
role_assign boolean,
|
||||||
|
role_submit boolean,
|
||||||
|
request boolean,
|
||||||
primary key (worker, project)
|
primary key (worker, project)
|
||||||
);
|
);
|
||||||
|
|
||||||
@ -81,7 +84,7 @@ CREATE TABLE manager_has_role_on_project
|
|||||||
manager INTEGER REFERENCES manager (id) NOT NULL,
|
manager INTEGER REFERENCES manager (id) NOT NULL,
|
||||||
role SMALLINT NOT NULL,
|
role SMALLINT NOT NULL,
|
||||||
project INTEGER REFERENCES project (id) NOT NULL,
|
project INTEGER REFERENCES project (id) NOT NULL,
|
||||||
primary key (manager, project)
|
PRIMARY KEY (manager, project)
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE project_monitoring_snapshot
|
CREATE TABLE project_monitoring_snapshot
|
||||||
@ -95,12 +98,6 @@ CREATE TABLE project_monitoring_snapshot
|
|||||||
timestamp INT NOT NULL
|
timestamp INT NOT NULL
|
||||||
);
|
);
|
||||||
|
|
||||||
CREATE TABLE worker_requests_access_to_project
|
|
||||||
(
|
|
||||||
worker INT REFERENCES worker (id) NOT NULL,
|
|
||||||
project INT REFERENCES project (id) NOT NULL
|
|
||||||
);
|
|
||||||
|
|
||||||
CREATE OR REPLACE FUNCTION on_task_delete_proc() RETURNS TRIGGER AS
|
CREATE OR REPLACE FUNCTION on_task_delete_proc() RETURNS TRIGGER AS
|
||||||
$$
|
$$
|
||||||
DECLARE
|
DECLARE
|
||||||
|
@ -65,8 +65,8 @@ export class ApiService {
|
|||||||
return this.http.get(this.url + `/worker/stats`, this.options)
|
return this.http.get(this.url + `/worker/stats`, this.options)
|
||||||
}
|
}
|
||||||
|
|
||||||
getProjectAccessRequests(project: number) {
|
getProjectAccess(project: number) {
|
||||||
return this.http.get(this.url + `/project/requests/${project}`)
|
return this.http.get(this.url + `/project/accesses/${project}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
getAllManagers() {
|
getAllManagers() {
|
||||||
@ -81,4 +81,12 @@ export class ApiService {
|
|||||||
return this.http.get(this.url + `/manager/demote/${managerId}`)
|
return this.http.get(this.url + `/manager/demote/${managerId}`)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
acceptWorkerAccessRequest(wid: number, pid: number) {
|
||||||
|
return this.http.post(this.url + `/project/accept_request/${pid}/${wid}`, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
rejectWorkerAccessRequest(wid: number, pid: number) {
|
||||||
|
return this.http.post(this.url + `/project/reject_request/${pid}/${wid}`, null)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
9
web/angular/src/app/models/worker-access.ts
Normal file
9
web/angular/src/app/models/worker-access.ts
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
import {Worker} from "./worker"
|
||||||
|
|
||||||
|
export interface WorkerAccess {
|
||||||
|
submit: boolean
|
||||||
|
assign: boolean
|
||||||
|
request: boolean
|
||||||
|
worker: Worker
|
||||||
|
project: number
|
||||||
|
}
|
@ -2,3 +2,7 @@
|
|||||||
button {
|
button {
|
||||||
margin-left: 15px;
|
margin-left: 15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.request {
|
||||||
|
color: #757575;
|
||||||
|
}
|
||||||
|
@ -11,19 +11,23 @@
|
|||||||
|
|
||||||
<mat-card-content>
|
<mat-card-content>
|
||||||
<mat-list *ngIf="!unauthorized">
|
<mat-list *ngIf="!unauthorized">
|
||||||
<mat-list-item *ngFor="let w of requests">
|
<mat-list-item *ngFor="let wa of accesses" [class.request]="wa.request">
|
||||||
<mat-icon mat-list-icon>person_add</mat-icon>
|
<mat-icon mat-list-icon *ngIf="wa.submit" [title]="'perms.assign'|translate">library_add</mat-icon>
|
||||||
<h4 mat-line>{{w.alias}}</h4>
|
<mat-icon mat-list-icon *ngIf="wa.assign" [title]="'perms.submit'|translate">get_app</mat-icon>
|
||||||
|
<h4 mat-line>{{wa.worker.alias}} {{wa.request ? ('perms.pending' | translate) : ''}}</h4>
|
||||||
<div mat-line>
|
<div mat-line>
|
||||||
Id=<span class="text-mono">{{w.id}}</span>, {{"perms.created" | translate}}
|
Id=<span class="text-mono">{{wa.worker.id}}</span>, {{"perms.created" | translate}}
|
||||||
<span
|
<span
|
||||||
class="text-mono">{{moment.unix(w.created).utc().format("UTC YYYY-MM-DD HH:mm:ss")}}</span>
|
class="text-mono">{{moment.unix(wa.worker.created).utc().format("UTC YYYY-MM-DD HH:mm:ss")}}</span>
|
||||||
</div>
|
</div>
|
||||||
<span style="flex: 1 1 auto;"></span>
|
<span style="flex: 1 1 auto;"></span>
|
||||||
<button mat-raised-button color="primary" [title]="'perms.grant' | translate">
|
<button mat-raised-button color="primary" [title]="'perms.grant' | translate"
|
||||||
|
*ngIf="wa.request" (click)="acceptRequest(wa)">
|
||||||
<mat-icon>check</mat-icon>
|
<mat-icon>check</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
<button mat-raised-button color="warn" [title]="'perms.reject' | translate">
|
<button mat-raised-button color="warn"
|
||||||
|
[title]="wa.request ? ('perms.reject'|translate) : ('perms.remove'|translate)"
|
||||||
|
(click)="rejectRequest(wa)">
|
||||||
<mat-icon>close</mat-icon>
|
<mat-icon>close</mat-icon>
|
||||||
</button>
|
</button>
|
||||||
</mat-list-item>
|
</mat-list-item>
|
||||||
|
@ -1,4 +1,3 @@
|
|||||||
import {Worker} from "../models/worker"
|
|
||||||
import {Component, OnInit} from '@angular/core';
|
import {Component, OnInit} from '@angular/core';
|
||||||
import {ApiService} from "../api.service";
|
import {ApiService} from "../api.service";
|
||||||
import {Project} from "../models/project";
|
import {Project} from "../models/project";
|
||||||
@ -7,6 +6,7 @@ import {MessengerService} from "../messenger.service";
|
|||||||
import {TranslateService} from "@ngx-translate/core";
|
import {TranslateService} from "@ngx-translate/core";
|
||||||
|
|
||||||
import * as moment from "moment"
|
import * as moment from "moment"
|
||||||
|
import {WorkerAccess} from "../models/worker-access";
|
||||||
|
|
||||||
@Component({
|
@Component({
|
||||||
selector: 'app-project-perms',
|
selector: 'app-project-perms',
|
||||||
@ -24,7 +24,7 @@ export class ProjectPermsComponent implements OnInit {
|
|||||||
|
|
||||||
project: Project;
|
project: Project;
|
||||||
private projectId: number;
|
private projectId: number;
|
||||||
requests: Worker[];
|
accesses: WorkerAccess[];
|
||||||
unauthorized: boolean = false;
|
unauthorized: boolean = false;
|
||||||
moment = moment;
|
moment = moment;
|
||||||
|
|
||||||
@ -32,20 +32,30 @@ export class ProjectPermsComponent implements OnInit {
|
|||||||
this.route.params.subscribe(params => {
|
this.route.params.subscribe(params => {
|
||||||
this.projectId = params["id"];
|
this.projectId = params["id"];
|
||||||
this.getProject();
|
this.getProject();
|
||||||
this.getProjectRequests();
|
this.getProjectAccesses();
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public acceptRequest(wa: WorkerAccess) {
|
||||||
|
this.apiService.acceptWorkerAccessRequest(wa.worker.id, this.projectId)
|
||||||
|
.subscribe(() => this.getProjectAccesses())
|
||||||
|
}
|
||||||
|
|
||||||
|
public rejectRequest(wa: WorkerAccess) {
|
||||||
|
this.apiService.rejectWorkerAccessRequest(wa.worker.id, this.projectId)
|
||||||
|
.subscribe(() => this.getProjectAccesses())
|
||||||
|
}
|
||||||
|
|
||||||
private getProject() {
|
private getProject() {
|
||||||
this.apiService.getProject(this.projectId).subscribe(data => {
|
this.apiService.getProject(this.projectId).subscribe(data => {
|
||||||
this.project = data["project"]
|
this.project = data["project"]
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private getProjectRequests() {
|
private getProjectAccesses() {
|
||||||
this.apiService.getProjectAccessRequests(this.projectId).subscribe(
|
this.apiService.getProjectAccess(this.projectId).subscribe(
|
||||||
data => {
|
data => {
|
||||||
this.requests = data["requests"]
|
this.accesses = data["accesses"]
|
||||||
},
|
},
|
||||||
error => {
|
error => {
|
||||||
if (error && (error.status == 401 || error.status == 403)) {
|
if (error && (error.status == 401 || error.status == 403)) {
|
||||||
@ -55,6 +65,6 @@ export class ProjectPermsComponent implements OnInit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public refresh() {
|
public refresh() {
|
||||||
this.getProjectRequests()
|
this.getProjectAccesses()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -103,7 +103,11 @@
|
|||||||
"created": "Created on",
|
"created": "Created on",
|
||||||
"grant": "Accept request",
|
"grant": "Accept request",
|
||||||
"reject": "Deny request",
|
"reject": "Deny request",
|
||||||
"refresh": "Refresh"
|
"remove": "Remove access",
|
||||||
|
"refresh": "Refresh",
|
||||||
|
"pending": "(Pending)",
|
||||||
|
"assign": "Assign",
|
||||||
|
"submit": "Submit"
|
||||||
},
|
},
|
||||||
"messenger": {
|
"messenger": {
|
||||||
"close": "Close",
|
"close": "Close",
|
||||||
|
@ -105,7 +105,11 @@
|
|||||||
"created": "Créé le",
|
"created": "Créé le",
|
||||||
"grant": "Accepter la requête",
|
"grant": "Accepter la requête",
|
||||||
"reject": "Rejeter la requête",
|
"reject": "Rejeter la requête",
|
||||||
"refresh": "Refraichir"
|
"remove": "Enlever l'accès",
|
||||||
|
"refresh": "Refraichir",
|
||||||
|
"pending": "(En attente)",
|
||||||
|
"assign": "Assigner",
|
||||||
|
"submit": "Soumettre"
|
||||||
},
|
},
|
||||||
"messenger": {
|
"messenger": {
|
||||||
"close": "Fermer",
|
"close": "Fermer",
|
||||||
|
Loading…
x
Reference in New Issue
Block a user