mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Access control: Combine permissions through predefined roles (#33275)
* Access control: Combine permissions through predefined roles When certain permission is required for built-in role, instead of adding those permissions to the existing predefined roles, we need to have granular predefined roles with those permissions. * Better copy... * Adding and fixing tests * Remove duplicated permission
This commit is contained in:
parent
d66a5e65a4
commit
bf83fb80b7
@ -1,5 +1,159 @@
|
||||
package accesscontrol
|
||||
|
||||
import "github.com/grafana/grafana/pkg/models"
|
||||
|
||||
var ldapAdminReadRole = RoleDTO{
|
||||
Name: ldapAdminRead,
|
||||
Version: 1,
|
||||
Permissions: []Permission{
|
||||
{
|
||||
Action: ActionLDAPUsersRead,
|
||||
},
|
||||
{
|
||||
Action: ActionLDAPStatusRead,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var ldapAdminEditRole = RoleDTO{
|
||||
Name: ldapAdminEdit,
|
||||
Version: 1,
|
||||
Permissions: concat(ldapAdminReadRole.Permissions, []Permission{
|
||||
{
|
||||
Action: ActionLDAPUsersSync,
|
||||
},
|
||||
}),
|
||||
}
|
||||
|
||||
var orgsAdminReadRole = RoleDTO{
|
||||
Name: orgsAdminRead,
|
||||
Version: 1,
|
||||
Permissions: []Permission{
|
||||
{
|
||||
Action: ActionOrgUsersRead,
|
||||
Scope: ScopeOrgAllUsersAll,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var orgsAdminEditRole = RoleDTO{
|
||||
Name: orgsAdminEdit,
|
||||
Version: 1,
|
||||
Permissions: concat(orgsAdminReadRole.Permissions, []Permission{
|
||||
{
|
||||
Action: ActionOrgUsersAdd,
|
||||
Scope: ScopeOrgAllUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionOrgUsersRemove,
|
||||
Scope: ScopeOrgAllUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionOrgUsersRoleUpdate,
|
||||
Scope: ScopeOrgAllUsersAll,
|
||||
},
|
||||
}),
|
||||
}
|
||||
|
||||
var orgsCurrentReadRole = RoleDTO{
|
||||
Name: orgsCurrentRead,
|
||||
Version: 1,
|
||||
Permissions: []Permission{
|
||||
{
|
||||
Action: ActionOrgUsersRead,
|
||||
Scope: ScopeOrgCurrentUsersAll,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var orgsCurrentEditRole = RoleDTO{
|
||||
Name: orgsCurrentEdit,
|
||||
Version: 1,
|
||||
Permissions: concat(orgsCurrentReadRole.Permissions, []Permission{
|
||||
{
|
||||
Action: ActionOrgUsersAdd,
|
||||
Scope: ScopeOrgCurrentUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionOrgUsersRoleUpdate,
|
||||
Scope: ScopeOrgCurrentUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionOrgUsersRemove,
|
||||
Scope: ScopeOrgCurrentUsersAll,
|
||||
},
|
||||
}),
|
||||
}
|
||||
|
||||
var usersAdminReadRole = RoleDTO{
|
||||
Name: usersAdminRead,
|
||||
Version: 1,
|
||||
Permissions: []Permission{
|
||||
{
|
||||
Action: ActionUsersRead,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersTeamRead,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersAuthTokenList,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersQuotasList,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
var usersAdminEditRole = RoleDTO{
|
||||
Name: usersAdminEdit,
|
||||
Version: 1,
|
||||
Permissions: concat(usersAdminReadRole.Permissions, []Permission{
|
||||
{
|
||||
Action: ActionUsersPasswordUpdate,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersCreate,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersWrite,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersDelete,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersEnable,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersDisable,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersPermissionsUpdate,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersLogout,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersAuthTokenUpdate,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersQuotasUpdate,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
}),
|
||||
}
|
||||
|
||||
// PredefinedRoles provides a map of permission sets/roles which can be
|
||||
// assigned to a set of users. When adding a new resource protected by
|
||||
// Grafana access control the default permissions should be added to a
|
||||
@ -7,145 +161,59 @@ package accesscontrol
|
||||
// resource. PredefinedRoleGrants lists which organization roles are
|
||||
// assigned which predefined roles in this list.
|
||||
var PredefinedRoles = map[string]RoleDTO{
|
||||
// TODO: Add support for inheritance between the predefined roles to
|
||||
// make the admin ⊃ editor ⊃ viewer property hold.
|
||||
usersAdminRead: {
|
||||
Name: usersAdminRead,
|
||||
Version: 1,
|
||||
Permissions: []Permission{
|
||||
{
|
||||
Action: ActionUsersRead,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersTeamRead,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersAuthTokenList,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersQuotasList,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionOrgUsersRead,
|
||||
Scope: ScopeOrgAllUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionLDAPUsersRead,
|
||||
},
|
||||
{
|
||||
Action: ActionLDAPStatusRead,
|
||||
},
|
||||
},
|
||||
},
|
||||
usersAdminEdit: {
|
||||
Name: usersAdminEdit,
|
||||
Version: 1,
|
||||
Permissions: []Permission{
|
||||
{
|
||||
// Inherited from grafana:roles:users:admin:read
|
||||
Action: ActionUsersRead,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
// Inherited from grafana:roles:users:admin:read
|
||||
Action: ActionUsersTeamRead,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
// Inherited from grafana:roles:users:admin:read
|
||||
Action: ActionUsersAuthTokenList,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersPasswordUpdate,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersCreate,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersWrite,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersDelete,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersEnable,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersDisable,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersPermissionsUpdate,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersLogout,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersAuthTokenUpdate,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
// Inherited from grafana:roles:users:admin:read
|
||||
Action: ActionUsersQuotasList,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersQuotasUpdate,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
// Inherited from grafana:roles:users:admin:read
|
||||
Action: ActionOrgUsersRead,
|
||||
Scope: ScopeOrgAllUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionOrgUsersAdd,
|
||||
Scope: ScopeOrgAllUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionOrgUsersRemove,
|
||||
Scope: ScopeOrgAllUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionOrgUsersRoleUpdate,
|
||||
Scope: ScopeOrgAllUsersAll,
|
||||
},
|
||||
{
|
||||
// Inherited from grafana:roles:users:admin:read
|
||||
Action: ActionLDAPUsersRead,
|
||||
},
|
||||
{
|
||||
// Inherited from grafana:roles:users:admin:read
|
||||
Action: ActionLDAPStatusRead,
|
||||
},
|
||||
{
|
||||
Action: ActionLDAPUsersSync,
|
||||
},
|
||||
},
|
||||
},
|
||||
usersAdminRead: usersAdminReadRole,
|
||||
usersAdminEdit: usersAdminEditRole,
|
||||
|
||||
orgsAdminRead: orgsAdminReadRole,
|
||||
orgsAdminEdit: orgsAdminEditRole,
|
||||
|
||||
orgsCurrentRead: orgsCurrentReadRole,
|
||||
orgsCurrentEdit: orgsCurrentEditRole,
|
||||
|
||||
ldapAdminRead: ldapAdminReadRole,
|
||||
ldapAdminEdit: ldapAdminEditRole,
|
||||
}
|
||||
|
||||
const (
|
||||
usersAdminEdit = "grafana:roles:users:admin:edit"
|
||||
usersAdminRead = "grafana:roles:users:admin:read"
|
||||
|
||||
orgsAdminEdit = "grafana:roles:orgs:admin:edit"
|
||||
orgsAdminRead = "grafana:roles:orgs:admin:read"
|
||||
|
||||
orgsCurrentEdit = "grafana:roles:orgs:current:edit"
|
||||
orgsCurrentRead = "grafana:roles:orgs:current:read"
|
||||
|
||||
ldapAdminEdit = "grafana:roles:ldap:admin:edit"
|
||||
ldapAdminRead = "grafana:roles:ldap:admin:read"
|
||||
)
|
||||
|
||||
// PredefinedRoleGrants specifies which organization roles are assigned
|
||||
// to which set of PredefinedRoles by default. Alphabetically sorted.
|
||||
var PredefinedRoleGrants = map[string][]string{
|
||||
RoleGrafanaAdmin: {
|
||||
ldapAdminEdit,
|
||||
ldapAdminRead,
|
||||
orgsAdminEdit,
|
||||
orgsAdminRead,
|
||||
usersAdminEdit,
|
||||
usersAdminRead,
|
||||
},
|
||||
string(models.ROLE_ADMIN): {
|
||||
orgsCurrentEdit,
|
||||
orgsCurrentRead,
|
||||
},
|
||||
}
|
||||
|
||||
func concat(permissions ...[]Permission) []Permission {
|
||||
if permissions == nil {
|
||||
return nil
|
||||
}
|
||||
perms := make([]Permission, 0)
|
||||
for _, p := range permissions {
|
||||
pCopy := make([]Permission, 0, len(p))
|
||||
copy(pCopy, p)
|
||||
perms = append(perms, p...)
|
||||
}
|
||||
return perms
|
||||
}
|
||||
|
@ -33,3 +33,40 @@ func TestPredefinedRoleGrants(t *testing.T) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestConcat(t *testing.T) {
|
||||
perms1 := []Permission{
|
||||
{
|
||||
Action: "test",
|
||||
Scope: "test:*",
|
||||
},
|
||||
{
|
||||
Action: "test1",
|
||||
Scope: "test1:*",
|
||||
},
|
||||
}
|
||||
perms2 := []Permission{
|
||||
{
|
||||
Action: "test1",
|
||||
Scope: "*",
|
||||
},
|
||||
}
|
||||
|
||||
expected := []Permission{
|
||||
{
|
||||
Action: "test",
|
||||
Scope: "test:*",
|
||||
},
|
||||
{
|
||||
Action: "test1",
|
||||
Scope: "test1:*",
|
||||
},
|
||||
{
|
||||
Action: "test1",
|
||||
Scope: "*",
|
||||
},
|
||||
}
|
||||
|
||||
perms := concat(perms1, perms2)
|
||||
assert.ElementsMatch(t, perms, expected)
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user