From b522169832dd5eee2bc2a30047db1edc02d116a0 Mon Sep 17 00:00:00 2001 From: Denis Gukov Date: Sat, 26 Aug 2023 18:48:16 +0200 Subject: [PATCH] test: check role permissions --- api/projects/project.go | 34 +++++++++++++--------------------- db/ProjectUser.go | 12 ++++++++++-- db/ProjectUser_test.go | 15 +++++++++++++++ 3 files changed, 38 insertions(+), 23 deletions(-) create mode 100644 db/ProjectUser_test.go diff --git a/api/projects/project.go b/api/projects/project.go index 9a407550..866a14af 100644 --- a/api/projects/project.go +++ b/api/projects/project.go @@ -24,7 +24,7 @@ func ProjectMiddleware(next http.Handler) http.Handler { } // check if user in project's team - _, err = helpers.Store(r).GetProjectUser(projectID, user.ID) + projectUser, err := helpers.Store(r).GetProjectUser(projectID, user.ID) if err != nil { helpers.WriteError(w, err) @@ -38,6 +38,7 @@ func ProjectMiddleware(next http.Handler) http.Handler { return } + context.Set(r, "projectUserRole", projectUser.Role) context.Set(r, "project", project) next.ServeHTTP(w, r) }) @@ -47,27 +48,12 @@ func ProjectMiddleware(next http.Handler) http.Handler { func GetMustCanMiddlewareFor(permissions db.ProjectUserPermission) mux.MiddlewareFunc { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { - project := context.Get(r, "project").(db.Project) user := context.Get(r, "user").(*db.User) + projectUserRole := context.Get(r, "projectUserRole").(db.ProjectUserRole) - if !user.Admin { - // check if user in project's team - projectUser, err := helpers.Store(r).GetProjectUser(project.ID, user.ID) - - if err == db.ErrNotFound { - w.WriteHeader(http.StatusForbidden) - return - } - - if err != nil { - helpers.WriteError(w, err) - return - } - - if r.Method != "GET" && r.Method != "HEAD" && !projectUser.Can(permissions) { - w.WriteHeader(http.StatusForbidden) - return - } + if !user.Admin && r.Method != "GET" && r.Method != "HEAD" && !projectUserRole.Can(permissions) { + w.WriteHeader(http.StatusForbidden) + return } next.ServeHTTP(w, r) @@ -77,7 +63,13 @@ func GetMustCanMiddlewareFor(permissions db.ProjectUserPermission) mux.Middlewar // GetProject returns a project details func GetProject(w http.ResponseWriter, r *http.Request) { - helpers.WriteJSON(w, http.StatusOK, context.Get(r, "project")) + var project struct { + db.Project + UserPermissions db.ProjectUserPermission `json:"userPermissions"` + } + project.Project = context.Get(r, "project").(db.Project) + project.UserPermissions = context.Get(r, "projectUserRole").(db.ProjectUserRole).GetPermissions() + helpers.WriteJSON(w, http.StatusOK, project) } // UpdateProject saves updated project details to the database diff --git a/db/ProjectUser.go b/db/ProjectUser.go index 6b561abe..ce768170 100644 --- a/db/ProjectUser.go +++ b/db/ProjectUser.go @@ -19,7 +19,7 @@ const ( ) var rolePermissions = map[ProjectUserRole]ProjectUserPermission{ - ProjectOwner: CanRunProjectTasks | CanUpdateProject | CanManageProjectResources, + ProjectOwner: CanRunProjectTasks | CanManageProjectResources | CanUpdateProject, ProjectManager: CanRunProjectTasks | CanManageProjectResources, ProjectTaskRunner: CanRunProjectTasks, ProjectGuest: 0, @@ -39,5 +39,13 @@ type ProjectUser struct { func (u *ProjectUser) Can(permissions ProjectUserPermission) bool { userPermissions := rolePermissions[u.Role] - return (userPermissions & userPermissions) == permissions + return (userPermissions & permissions) == permissions +} + +func (r ProjectUserRole) Can(permissions ProjectUserPermission) bool { + return (rolePermissions[r] & permissions) == permissions +} + +func (r ProjectUserRole) GetPermissions() ProjectUserPermission { + return rolePermissions[r] } diff --git a/db/ProjectUser_test.go b/db/ProjectUser_test.go new file mode 100644 index 00000000..08be5e95 --- /dev/null +++ b/db/ProjectUser_test.go @@ -0,0 +1,15 @@ +package db + +import ( + "testing" +) + +func TestProjectUsers_RoleCan(t *testing.T) { + if !ProjectManager.Can(CanManageProjectResources) { + t.Fatal() + } + + if ProjectManager.Can(CanUpdateProject) { + t.Fatal() + } +}