[MM-28717] Refactor applyMultiRoleFilters to use sq builder (#15500)
* Refactor apply multi role filters and add role filters to get all profiles * Add some tests * Fix tests * Fix lint * Trigger CI * Rename param to make more sense * Tie get filtered user stats to usermanagement read users * Dont filter out other system roles when searching for team members or team admins only filter out system admins * add new permissions * add migration * fix test * remove system roles as default permissions * implement changes discussed with dennis * add read only and fix i18n * use model consts instead of strings * turn the permissions into pseudo constants * Update read only default permissions Co-authored-by: Mattermod <mattermod@users.noreply.github.com> Co-authored-by: Hossein Ahmadian-Yazdi <hyazdi1997@gmail.com>
Этот коммит содержится в:
коммит произвёл
GitHub
родитель
1d15900f84
Коммит
c9a4a475d3
70
api4/role.go
70
api4/role.go
@@ -10,6 +10,24 @@ import (
|
||||
"github.com/mattermost/mattermost-server/v5/model"
|
||||
)
|
||||
|
||||
var allowedPermissions = []string{
|
||||
model.PERMISSION_CREATE_TEAM.Id,
|
||||
model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id,
|
||||
model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id,
|
||||
model.PERMISSION_MANAGE_SLASH_COMMANDS.Id,
|
||||
model.PERMISSION_MANAGE_OAUTH.Id,
|
||||
model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH.Id,
|
||||
model.PERMISSION_CREATE_EMOJIS.Id,
|
||||
model.PERMISSION_DELETE_EMOJIS.Id,
|
||||
model.PERMISSION_EDIT_OTHERS_POSTS.Id,
|
||||
}
|
||||
|
||||
var notAllowedPermissions = []string{
|
||||
model.PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_SYSTEM_ROLES.Id,
|
||||
model.PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_SYSTEM_ROLES.Id,
|
||||
model.PERMISSION_MANAGE_ROLES.Id,
|
||||
}
|
||||
|
||||
func (api *API) InitRole() {
|
||||
api.BaseRoutes.Roles.Handle("/{role_id:[A-Za-z0-9]+}", api.ApiSessionRequiredTrustRequester(getRole)).Methods("GET")
|
||||
api.BaseRoutes.Roles.Handle("/name/{role_name:[a-z0-9_]+}", api.ApiSessionRequiredTrustRequester(getRoleByName)).Methods("GET")
|
||||
@@ -92,22 +110,17 @@ func patchRole(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
auditRec.AddMeta("role", oldRole)
|
||||
|
||||
if oldRole.Name == model.SYSTEM_ADMIN_ROLE_ID {
|
||||
c.Err = model.NewAppError("Api4.PatchRoles", "api.roles.patch_roles.admin_role.error", nil, "", http.StatusNotImplemented)
|
||||
return
|
||||
}
|
||||
|
||||
isGuest := oldRole.Name == model.SYSTEM_GUEST_ROLE_ID || oldRole.Name == model.TEAM_GUEST_ROLE_ID || oldRole.Name == model.CHANNEL_GUEST_ROLE_ID
|
||||
if c.App.Srv().License() == nil && patch.Permissions != nil {
|
||||
if oldRole.Name == "system_guest" || oldRole.Name == "team_guest" || oldRole.Name == "channel_guest" {
|
||||
if isGuest {
|
||||
c.Err = model.NewAppError("Api4.PatchRoles", "api.roles.patch_roles.license.error", nil, "", http.StatusNotImplemented)
|
||||
return
|
||||
}
|
||||
allowedPermissions := []string{
|
||||
model.PERMISSION_CREATE_TEAM.Id,
|
||||
model.PERMISSION_MANAGE_INCOMING_WEBHOOKS.Id,
|
||||
model.PERMISSION_MANAGE_OUTGOING_WEBHOOKS.Id,
|
||||
model.PERMISSION_MANAGE_SLASH_COMMANDS.Id,
|
||||
model.PERMISSION_MANAGE_OAUTH.Id,
|
||||
model.PERMISSION_MANAGE_SYSTEM_WIDE_OAUTH.Id,
|
||||
model.PERMISSION_CREATE_EMOJIS.Id,
|
||||
model.PERMISSION_DELETE_EMOJIS.Id,
|
||||
model.PERMISSION_EDIT_OTHERS_POSTS.Id,
|
||||
}
|
||||
|
||||
changedPermissions := model.PermissionsChangedByPatch(oldRole, patch)
|
||||
for _, permission := range changedPermissions {
|
||||
@@ -125,14 +138,39 @@ func patchRole(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
if c.App.Srv().License() != nil && (oldRole.Name == "system_guest" || oldRole.Name == "team_guest" || oldRole.Name == "channel_guest") && !*c.App.Srv().License().Features.GuestAccountsPermissions {
|
||||
if patch.Permissions != nil {
|
||||
deltaPermissions := model.PermissionsChangedByPatch(oldRole, patch)
|
||||
|
||||
for _, permission := range deltaPermissions {
|
||||
notAllowed := false
|
||||
for _, notAllowedPermission := range notAllowedPermissions {
|
||||
if permission == notAllowedPermission {
|
||||
notAllowed = true
|
||||
}
|
||||
}
|
||||
|
||||
if notAllowed {
|
||||
c.Err = model.NewAppError("Api4.PatchRoles", "api.roles.patch_roles.not_allowed_permission.error", nil, "Cannot add or remove permission: "+permission, http.StatusNotImplemented)
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if c.App.Srv().License() != nil && isGuest && !*c.App.Srv().License().Features.GuestAccountsPermissions {
|
||||
c.Err = model.NewAppError("Api4.PatchRoles", "api.roles.patch_roles.license.error", nil, "", http.StatusNotImplemented)
|
||||
return
|
||||
}
|
||||
|
||||
if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_PERMISSIONS) {
|
||||
c.SetPermissionError(model.PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_PERMISSIONS)
|
||||
return
|
||||
if oldRole.Name == model.TEAM_ADMIN_ROLE_ID || oldRole.Name == model.CHANNEL_ADMIN_ROLE_ID || oldRole.Name == model.SYSTEM_USER_ROLE_ID || oldRole.Name == model.TEAM_USER_ROLE_ID || oldRole.Name == model.CHANNEL_USER_ROLE_ID || oldRole.Name == model.SYSTEM_GUEST_ROLE_ID || oldRole.Name == model.TEAM_GUEST_ROLE_ID || oldRole.Name == model.CHANNEL_GUEST_ROLE_ID {
|
||||
if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_PERMISSIONS) {
|
||||
c.SetPermissionError(model.PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_PERMISSIONS)
|
||||
return
|
||||
}
|
||||
} else {
|
||||
if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_SYSTEM_ROLES) {
|
||||
c.SetPermissionError(model.PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_SYSTEM_ROLES)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
role, err := c.App.PatchRole(oldRole, patch)
|
||||
|
||||
@@ -177,6 +177,43 @@ func TestPatchRole(t *testing.T) {
|
||||
Permissions: &[]string{"manage_system", "create_public_channel", "manage_incoming_webhooks", "manage_outgoing_webhooks"},
|
||||
}
|
||||
|
||||
th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
|
||||
|
||||
// Cannot edit a system admin
|
||||
adminRole, err := th.App.Srv().Store.Role().GetByName("system_admin")
|
||||
assert.Nil(t, err)
|
||||
defer th.App.Srv().Store.Job().Delete(adminRole.Id)
|
||||
|
||||
_, resp := client.PatchRole(adminRole.Id, patch)
|
||||
CheckNotImplementedStatus(t, resp)
|
||||
|
||||
// Cannot give other roles read / write to system roles or manage roles because only system admin can do these actions
|
||||
systemManager, err := th.App.Srv().Store.Role().GetByName("system_manager")
|
||||
assert.Nil(t, err)
|
||||
defer th.App.Srv().Store.Job().Delete(systemManager.Id)
|
||||
|
||||
patchWriteSystemRoles := &model.RolePatch{
|
||||
Permissions: &[]string{model.PERMISSION_SYSCONSOLE_WRITE_USERMANAGEMENT_SYSTEM_ROLES.Id},
|
||||
}
|
||||
|
||||
_, resp = client.PatchRole(systemManager.Id, patchWriteSystemRoles)
|
||||
CheckNotImplementedStatus(t, resp)
|
||||
|
||||
patchReadSystemRoles := &model.RolePatch{
|
||||
Permissions: &[]string{model.PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_SYSTEM_ROLES.Id},
|
||||
}
|
||||
|
||||
_, resp = client.PatchRole(systemManager.Id, patchReadSystemRoles)
|
||||
CheckNotImplementedStatus(t, resp)
|
||||
|
||||
patchManageRoles := &model.RolePatch{
|
||||
Permissions: &[]string{model.PERMISSION_MANAGE_ROLES.Id},
|
||||
}
|
||||
|
||||
_, resp = client.PatchRole(systemManager.Id, patchManageRoles)
|
||||
CheckNotImplementedStatus(t, resp)
|
||||
})
|
||||
|
||||
th.TestForSystemAdminAndLocal(t, func(t *testing.T, client *model.Client4) {
|
||||
received, resp := client.PatchRole(role.Id, patch)
|
||||
CheckNoError(t, resp)
|
||||
|
||||
@@ -585,8 +585,8 @@ func getFilteredUsersStats(c *Context, w http.ResponseWriter, r *http.Request) {
|
||||
TeamRoles: teamRoles,
|
||||
}
|
||||
|
||||
if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_MANAGE_SYSTEM) {
|
||||
c.SetPermissionError(model.PERMISSION_MANAGE_SYSTEM)
|
||||
if !c.App.SessionHasPermissionTo(*c.App.Session(), model.PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_USERS) {
|
||||
c.SetPermissionError(model.PERMISSION_SYSCONSOLE_READ_USERMANAGEMENT_USERS)
|
||||
return
|
||||
}
|
||||
|
||||
|
||||
Ссылка в новой задаче
Block a user