diff --git a/api/events.go b/api/events.go
index d392ef41..b14a8371 100644
--- a/api/events.go
+++ b/api/events.go
@@ -8,7 +8,7 @@ import (
"github.com/gorilla/context"
)
-//nolint: gocyclo
+// nolint: gocyclo
func getEvents(w http.ResponseWriter, r *http.Request, limit int) {
user := context.Get(r, "user").(*db.User)
projectObj, exists := context.GetOk(r, "project")
@@ -19,7 +19,9 @@ func getEvents(w http.ResponseWriter, r *http.Request, limit int) {
if exists {
project := projectObj.(db.Project)
- _, err = helpers.Store(r).GetProjectUser(project.ID, user.ID)
+ if !user.Admin { // check permissions to view events
+ _, err = helpers.Store(r).GetProjectUser(project.ID, user.ID)
+ }
if err != nil {
helpers.WriteError(w, err)
diff --git a/api/projects/project.go b/api/projects/project.go
index 6dcadede..d3c01a8d 100644
--- a/api/projects/project.go
+++ b/api/projects/project.go
@@ -26,7 +26,7 @@ func ProjectMiddleware(next http.Handler) http.Handler {
// check if user in project's team
projectUser, err := helpers.Store(r).GetProjectUser(projectID, user.ID)
- if err != nil {
+ if !user.Admin && err != nil {
helpers.WriteError(w, err)
return
}
diff --git a/api/projects/projects.go b/api/projects/projects.go
index 83f3f3e4..a3c219c1 100644
--- a/api/projects/projects.go
+++ b/api/projects/projects.go
@@ -14,7 +14,13 @@ import (
func GetProjects(w http.ResponseWriter, r *http.Request) {
user := context.Get(r, "user").(*db.User)
- projects, err := helpers.Store(r).GetProjects(user.ID)
+ var err error
+ var projects []db.Project
+ if user.Admin {
+ projects, err = helpers.Store(r).GetAllProjects()
+ } else {
+ projects, err = helpers.Store(r).GetProjects(user.ID)
+ }
if err != nil {
helpers.WriteError(w, err)
diff --git a/api/projects/users.go b/api/projects/users.go
index c185e604..46415cdc 100644
--- a/api/projects/users.go
+++ b/api/projects/users.go
@@ -1,6 +1,7 @@
package projects
import (
+ "fmt"
"github.com/ansible-semaphore/semaphore/api/helpers"
"github.com/ansible-semaphore/semaphore/db"
"net/http"
@@ -108,24 +109,30 @@ func AddUser(w http.ResponseWriter, r *http.Request) {
// RemoveUser removes a user from a project team
func RemoveUser(w http.ResponseWriter, r *http.Request) {
project := context.Get(r, "project").(db.Project)
- projectUser := context.Get(r, "projectUser").(db.User)
+ me := context.Get(r, "user").(*db.User) // logged in user
+ targetUser := context.Get(r, "projectUser").(db.User) // target user
+ targetUserRole := context.Get(r, "projectUserRole").(db.ProjectUserRole)
- err := helpers.Store(r).DeleteProjectUser(project.ID, projectUser.ID)
+ if !me.Admin && targetUser.ID == me.ID && targetUserRole == db.ProjectOwner {
+ helpers.WriteError(w, fmt.Errorf("owner can not left the project"))
+ return
+ }
+
+ err := helpers.Store(r).DeleteProjectUser(project.ID, targetUser.ID)
if err != nil {
helpers.WriteError(w, err)
return
}
- user := context.Get(r, "user").(*db.User)
objType := db.EventUser
- desc := "User ID " + strconv.Itoa(projectUser.ID) + " removed from team"
+ desc := "User ID " + strconv.Itoa(targetUser.ID) + " removed from team"
_, err = helpers.Store(r).CreateEvent(db.Event{
- UserID: &user.ID,
+ UserID: &me.ID,
ProjectID: &project.ID,
ObjectType: &objType,
- ObjectID: &projectUser.ID,
+ ObjectID: &targetUser.ID,
Description: &desc,
})
@@ -138,7 +145,14 @@ func RemoveUser(w http.ResponseWriter, r *http.Request) {
func UpdateUser(w http.ResponseWriter, r *http.Request) {
project := context.Get(r, "project").(db.Project)
- user := context.Get(r, "projectUser").(db.User)
+ me := context.Get(r, "user").(*db.User) // logged in user
+ targetUser := context.Get(r, "projectUser").(db.User)
+ targetUserRole := context.Get(r, "projectUserRole").(db.ProjectUserRole)
+
+ if !me.Admin && targetUser.ID == me.ID && targetUserRole == db.ProjectOwner {
+ helpers.WriteError(w, fmt.Errorf("owner can not change his role in the project"))
+ return
+ }
var projectUser struct {
Role db.ProjectUserRole `json:"role"`
@@ -154,7 +168,7 @@ func UpdateUser(w http.ResponseWriter, r *http.Request) {
}
err := helpers.Store(r).UpdateProjectUser(db.ProjectUser{
- UserID: user.ID,
+ UserID: targetUser.ID,
ProjectID: project.ID,
Role: projectUser.Role,
})
diff --git a/api/users.go b/api/users.go
index 5146dcdc..7b488a1d 100644
--- a/api/users.go
+++ b/api/users.go
@@ -73,7 +73,7 @@ func getUserMiddleware(next http.Handler) http.Handler {
}
func updateUser(w http.ResponseWriter, r *http.Request) {
- oldUser := context.Get(r, "_user").(db.User)
+ targetUser := context.Get(r, "_user").(db.User)
editor := context.Get(r, "user").(*db.User)
var user db.UserWithPwd
@@ -81,25 +81,25 @@ func updateUser(w http.ResponseWriter, r *http.Request) {
return
}
- if !editor.Admin && editor.ID != oldUser.ID {
+ if !editor.Admin && editor.ID != targetUser.ID {
log.Warn(editor.Username + " is not permitted to edit users")
w.WriteHeader(http.StatusUnauthorized)
return
}
- if editor.ID == oldUser.ID && oldUser.Admin != user.Admin {
+ if editor.ID == targetUser.ID && targetUser.Admin != user.Admin {
log.Warn("User can't edit his own role")
w.WriteHeader(http.StatusUnauthorized)
return
}
- if oldUser.External && oldUser.Username != user.Username {
+ if targetUser.External && targetUser.Username != user.Username {
log.Warn("Username is not editable for external users")
w.WriteHeader(http.StatusBadRequest)
return
}
- user.ID = oldUser.ID
+ user.ID = targetUser.ID
if err := helpers.Store(r).UpdateUser(user); err != nil {
log.Error(err.Error())
w.WriteHeader(http.StatusBadRequest)
diff --git a/db/ProjectUser.go b/db/ProjectUser.go
index a5a75714..7977e15c 100644
--- a/db/ProjectUser.go
+++ b/db/ProjectUser.go
@@ -7,6 +7,7 @@ const (
ProjectManager ProjectUserRole = "manager"
ProjectTaskRunner ProjectUserRole = "task_runner"
ProjectGuest ProjectUserRole = "guest"
+ ProjectNone ProjectUserRole = ""
)
type ProjectUserPermission int
@@ -37,11 +38,6 @@ type ProjectUser struct {
Role ProjectUserRole `db:"role" json:"role"`
}
-func (u *ProjectUser) Can(permissions ProjectUserPermission) bool {
- userPermissions := rolePermissions[u.Role]
- return (userPermissions & permissions) == permissions
-}
-
func (r ProjectUserRole) Can(permissions ProjectUserPermission) bool {
return (rolePermissions[r] & permissions) == permissions
}
diff --git a/db/Store.go b/db/Store.go
index 22d41cb2..fedb67ad 100644
--- a/db/Store.go
+++ b/db/Store.go
@@ -143,6 +143,7 @@ type Store interface {
GetUserByLoginOrEmail(login string, email string) (User, error)
GetProject(projectID int) (Project, error)
+ GetAllProjects() ([]Project, error)
GetProjects(userID int) ([]Project, error)
CreateProject(project Project) (Project, error)
DeleteProject(projectID int) error
diff --git a/db/bolt/project.go b/db/bolt/project.go
index b36c0e20..45156808 100644
--- a/db/bolt/project.go
+++ b/db/bolt/project.go
@@ -17,6 +17,12 @@ func (d *BoltDb) CreateProject(project db.Project) (db.Project, error) {
return newProject.(db.Project), nil
}
+func (d *BoltDb) GetAllProjects() (projects []db.Project, err error) {
+ err = d.getObjects(0, db.ProjectProps, db.RetrieveQueryParams{}, nil, &projects)
+
+ return
+}
+
func (d *BoltDb) GetProjects(userID int) (projects []db.Project, err error) {
projects = make([]db.Project, 0)
diff --git a/db/sql/project.go b/db/sql/project.go
index 63e36e1e..4f787402 100644
--- a/db/sql/project.go
+++ b/db/sql/project.go
@@ -23,6 +23,21 @@ func (d *SqlDb) CreateProject(project db.Project) (newProject db.Project, err er
return
}
+func (d *SqlDb) GetAllProjects() (projects []db.Project, err error) {
+ query, args, err := squirrel.Select("p.*").
+ From("project as p").
+ OrderBy("p.name").
+ ToSql()
+
+ if err != nil {
+ return
+ }
+
+ _, err = d.selectAll(&projects, query, args...)
+
+ return
+}
+
func (d *SqlDb) GetProjects(userID int) (projects []db.Project, err error) {
query, args, err := squirrel.Select("p.*").
From("project as p").
diff --git a/web/src/App.vue b/web/src/App.vue
index 7e6c1d0e..353c22a8 100644
--- a/web/src/App.vue
+++ b/web/src/App.vue
@@ -314,11 +314,14 @@
v-on="on"
>