diff --git a/api/project.go b/api/project.go index 1b9552a..0381162 100644 --- a/api/project.go +++ b/api/project.go @@ -86,7 +86,7 @@ func (api *WebAPI) CreateProject(r *Request) { return } - if !isProjectCreationAuthorized(project, manager) { + if !api.isProjectCreationAuthorized(project, manager) { logrus.WithFields(logrus.Fields{ "project": project, }).Warn("Unauthorized project creation") @@ -175,9 +175,14 @@ func (api *WebAPI) UpdateProject(r *Request) { Ok: false, Message: "Unauthorized", }, 403) - logrus.WithError(err).WithFields(logrus.Fields{ - "project": project, - }).Warn("Unauthorized project update") + return + } + + if project.Chain != 0 && !isActionOnProjectAuthorized(project.Chain, manager, storage.RoleEdit, api.Database) { + r.Json(JsonResponse{ + Ok: false, + Message: "Unauthorized (You need RoleEdit on the project you wish to chain tasks to)", + }, 403) return } @@ -202,7 +207,7 @@ func (api *WebAPI) UpdateProject(r *Request) { } } -func isProjectCreationAuthorized(project *storage.Project, manager interface{}) bool { +func (api *WebAPI) isProjectCreationAuthorized(project *storage.Project, manager interface{}) bool { if manager == nil { return false @@ -211,6 +216,19 @@ func isProjectCreationAuthorized(project *storage.Project, manager interface{}) if project.Public && !manager.(*storage.Manager).WebsiteAdmin { return false } + + if project.Chain != 0 { + chainsTo := api.Database.GetProject(project.Chain) + if chainsTo == nil { + return false + } + + if !isActionOnProjectAuthorized(chainsTo.Id, manager.(*storage.Manager), + storage.RoleEdit, api.Database) { + return false + } + } + return true } diff --git a/test/api_project_test.go b/test/api_project_test.go index 0cc02c6..a5e9959 100644 --- a/test/api_project_test.go +++ b/test/api_project_test.go @@ -542,6 +542,78 @@ func TestGetWebhookRequiresRole(t *testing.T) { } } +func TestTaskChainCreateRequiresRole(t *testing.T) { + + testUser := getAccountDetails(testUserCtx).Content.Manager + + p1 := createProjectAsAdmin(api.CreateProjectRequest{ + Name: "testtaskchainrequiresrole", + CloneUrl: "testtaskchainrequiresrole", + }).Content.Id + + resp := createProject(api.CreateProjectRequest{ + Name: "testtaskchainrequiresrole1", + CloneUrl: "testtaskchainrequiresrole1", + Chain: p1, + }, testUserCtx) + + if resp.Ok != false { + t.Error() + } + if len(resp.Message) <= 0 { + t.Error() + } + + setRoleOnProject(api.SetManagerRoleOnProjectRequest{ + Manager: testUser.Id, + Role: storage.RoleEdit, + }, p1, testAdminCtx) + + resp2 := createProject(api.CreateProjectRequest{ + Name: "testtaskchainrequiresrole1", + CloneUrl: "testtaskchainrequiresrole1", + Chain: p1, + }, testUserCtx) + + if resp2.Ok != true { + t.Error() + } +} + +func TestTaskChainUpdateRequiresRole(t *testing.T) { + + p1 := createProjectAsAdmin(api.CreateProjectRequest{ + Name: "testtaskchainrequiresroleupdate", + CloneUrl: "testtaskchainrequiresroleupdate", + }).Content.Id + + p2Resp := createProject(api.CreateProjectRequest{ + Name: "testtaskchainrequiresrole1update", + CloneUrl: "testtaskchainrequiresrole1update", + }, testUserCtx) + + p2 := getProjectAsAdmin(p2Resp.Content.Id).Content.Project + + resp := updateProject(api.UpdateProjectRequest{ + Chain: p1, + Name: p2.Name, + CloneUrl: p2.CloneUrl, + Public: p2.Public, + Hidden: p2.Hidden, + GitRepo: p2.GitRepo, + Paused: p2.Paused, + Priority: p2.Priority, + Motd: p2.Motd, + }, p2.Id, testUserCtx) + + if resp.Ok != false { + t.Error() + } + if len(resp.Message) <= 0 { + t.Error() + } +} + func createProjectAsAdmin(req api.CreateProjectRequest) CreateProjectAR { return createProject(req, testAdminCtx) }