feat: admin can all

This commit is contained in:
Denis Gukov 2023-09-17 16:15:44 +02:00
parent b31033323a
commit d3923f18b3
12 changed files with 73 additions and 25 deletions

View File

@ -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)

View File

@ -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
}

View File

@ -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)

View File

@ -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,
})

View File

@ -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)

View File

@ -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
}

View File

@ -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

View File

@ -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)

View File

@ -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").

View File

@ -314,11 +314,14 @@
v-on="on"
>
<v-list-item-icon>
<v-icon>mdi-account</v-icon>
<v-icon :color="user.admin ? 'red' : ''">mdi-account</v-icon>
</v-list-item-icon>
<v-list-item-content>
<v-list-item-title>{{ user.name }}</v-list-item-title>
<v-list-item-title>
{{ user.name }}
<v-chip v-if="user.admin" small color="red" class="ml-1">admin</v-chip>
</v-list-item-title>
</v-list-item-content>
</v-list-item>
</template>
@ -366,6 +369,7 @@
:projectId="projectId"
:userPermissions="userRole.permissions"
:userId="user ? user.id : null"
:isAdmin="user ? user.admin : false"
></router-view>
</v-main>

View File

@ -18,6 +18,7 @@ export default {
projectId: Number,
userId: Number,
userPermissions: Number,
isAdmin: Boolean,
},
data() {
@ -51,6 +52,9 @@ export default {
},
can(permission) {
if (this.isAdmin) {
return true;
}
// eslint-disable-next-line no-bitwise
return (this.userPermissions & permission) === permission;
},

View File

@ -8,7 +8,7 @@
<div class="project-settings-form">
<div style="height: 300px;">
<ProjectForm item-id="new" ref="editForm" @save="onSave" :demo-project="true" />
<ProjectForm item-id="new" ref="editForm" @save="onSave" :demo-project="demoProject" />
</div>
<div class="text-right">