Access Control: Rename fixed roles (#41288)

* Rename fixed roles
* Update descriptions
* Update docs for fixed roles and permissions

Co-authored-by: Ieva <ieva.vasiljeva@grafana.com>
Co-authored-by: Ursula Kallio <73951760+osg-grafana@users.noreply.github.com>
This commit is contained in:
Karl Persson
2021-11-17 15:40:39 +01:00
committed by GitHub
co-authored by Ieva Ursula Kallio
parent d76cea45b5
commit d623285fcc
7 changed files with 302 additions and 259 deletions
-1
View File
@@ -166,7 +166,6 @@ func (hs *HTTPServer) registerRoutes() {
userRoute.Post("/revoke-auth-token", bind(models.RevokeAuthTokenCmd{}), routing.Wrap(hs.RevokeUserAuthToken))
}, reqSignedInNoAnonymous)
// users (admin permission required)
apiRoute.Group("/users", func(usersRoute routing.RouteRegister) {
userIDScope := ac.Scope("global", "users", "id", ac.Parameter(":id"))
usersRoute.Get("/", authorize(reqGrafanaAdmin, ac.EvalPermission(ac.ActionUsersRead, ac.ScopeGlobalUsersAll)), routing.Wrap(hs.searchUsersService.SearchUsers))
+146 -134
View File
@@ -44,145 +44,157 @@ var (
// grants to organization roles ("Viewer", "Editor", "Admin") or "Grafana Admin"
// that HTTPServer needs
func (hs *HTTPServer) declareFixedRoles() error {
registrations := []accesscontrol.RoleRegistration{
{
Role: accesscontrol.RoleDTO{
Version: 1,
Name: "fixed:provisioning:admin",
Description: "Reload provisioning configurations",
Permissions: []accesscontrol.Permission{
{
Action: ActionProvisioningReload,
Scope: ScopeProvisionersAll,
},
provisioningWriterRole := accesscontrol.RoleRegistration{
Role: accesscontrol.RoleDTO{
Version: 2,
Name: "fixed:provisioning:writer",
DisplayName: "Provisioning writer",
Description: "Reload provisioning.",
Permissions: []accesscontrol.Permission{
{
Action: ActionProvisioningReload,
Scope: ScopeProvisionersAll,
},
},
Grants: []string{accesscontrol.RoleGrafanaAdmin},
},
{
Role: accesscontrol.RoleDTO{
Version: 1,
Name: "fixed:datasources:admin",
Description: "Gives access to create, read, update, delete datasources",
Permissions: []accesscontrol.Permission{
{
Action: ActionDatasourcesRead,
Scope: ScopeDatasourcesAll,
},
{
Action: ActionDatasourcesWrite,
Scope: ScopeDatasourcesAll,
},
{
Action: ActionDatasourcesCreate,
},
{
Action: ActionDatasourcesDelete,
Scope: ScopeDatasourcesAll,
},
{
Action: ActionDatasourcesQuery,
Scope: ScopeDatasourcesAll,
},
},
},
Grants: []string{string(models.ROLE_ADMIN)},
},
{
Role: accesscontrol.RoleDTO{
Version: 2,
Name: "fixed:datasources:id:viewer",
Description: "Gives access to read datasources ID",
Permissions: []accesscontrol.Permission{
{
Action: ActionDatasourcesIDRead,
Scope: ScopeDatasourcesAll,
},
},
},
Grants: []string{string(models.ROLE_VIEWER)},
},
{
Role: accesscontrol.RoleDTO{
Version: 1,
Name: "fixed:datasources:compatibility:querier",
Description: "Query data sources when data source permissions are not in use",
Permissions: []accesscontrol.Permission{
{Action: ActionDatasourcesQuery},
},
},
Grants: []string{string(models.ROLE_VIEWER)},
},
{
Role: accesscontrol.RoleDTO{
Version: 2,
Name: "fixed:current:org:reader",
Description: "Read current organization and its quotas.",
Permissions: []accesscontrol.Permission{
{
Action: ActionOrgsRead,
},
{
Action: ActionOrgsQuotasRead,
},
},
},
Grants: []string{string(models.ROLE_VIEWER)},
},
{
Role: accesscontrol.RoleDTO{
Version: 2,
Name: "fixed:current:org:writer",
Description: "Read current organization, its quotas, and its preferences. Write current organization and its preferences.",
Permissions: []accesscontrol.Permission{
{
Action: ActionOrgsRead,
},
{
Action: ActionOrgsQuotasRead,
},
{
Action: ActionOrgsPreferencesRead,
},
{
Action: ActionOrgsWrite,
},
{
Action: ActionOrgsPreferencesWrite,
},
},
},
Grants: []string{string(models.ROLE_ADMIN)},
},
{
Role: accesscontrol.RoleDTO{
Version: 2,
Name: "fixed:orgs:writer",
Description: "Create, read, write, or delete an organization. Read or write an organization's quotas.",
Permissions: []accesscontrol.Permission{
{Action: ActionOrgsCreate},
{
Action: ActionOrgsRead,
},
{
Action: ActionOrgsWrite,
},
{
Action: ActionOrgsDelete,
},
{
Action: ActionOrgsQuotasRead,
},
{
Action: ActionOrgsQuotasWrite,
},
},
},
Grants: []string{accesscontrol.RoleGrafanaAdmin},
},
Grants: []string{accesscontrol.RoleGrafanaAdmin},
}
return hs.AccessControl.DeclareFixedRoles(registrations...)
datasourcesReaderRole := accesscontrol.RoleRegistration{
Role: accesscontrol.RoleDTO{
Version: 2,
Name: "fixed:datasources:reader",
DisplayName: "Data source reader",
Description: "Read and query all data sources.",
Permissions: []accesscontrol.Permission{
{
Action: ActionDatasourcesRead,
Scope: ScopeDatasourcesAll,
},
{
Action: ActionDatasourcesQuery,
Scope: ScopeDatasourcesAll,
},
},
},
Grants: []string{string(models.ROLE_ADMIN)},
}
datasourcesWriterRole := accesscontrol.RoleRegistration{
Role: accesscontrol.RoleDTO{
Version: 2,
Name: "fixed:datasources:writer",
DisplayName: "Data source writer",
Description: "Create, update, delete, read, or query data sources.",
Permissions: accesscontrol.ConcatPermissions(datasourcesReaderRole.Role.Permissions, []accesscontrol.Permission{
{
Action: ActionDatasourcesWrite,
Scope: ScopeDatasourcesAll,
},
{
Action: ActionDatasourcesCreate,
},
{
Action: ActionDatasourcesDelete,
Scope: ScopeDatasourcesAll,
},
}),
},
Grants: []string{string(models.ROLE_ADMIN)},
}
datasourcesIdReaderRole := accesscontrol.RoleRegistration{
Role: accesscontrol.RoleDTO{
Version: 3,
Name: "fixed:datasources.id:reader",
DisplayName: "Data source ID reader",
Description: "Read the ID of a data source based on its name.",
Permissions: []accesscontrol.Permission{
{
Action: ActionDatasourcesIDRead,
Scope: ScopeDatasourcesAll,
},
},
},
Grants: []string{string(models.ROLE_VIEWER)},
}
datasourcesCompatibilityReaderRole := accesscontrol.RoleRegistration{
Role: accesscontrol.RoleDTO{
Version: 2,
Name: "fixed:datasources:compatibility:querier",
DisplayName: "Data source compatibility querier",
Description: "Only used for open source compatibility. Query data sources.",
Permissions: []accesscontrol.Permission{
{Action: ActionDatasourcesQuery},
},
},
Grants: []string{string(models.ROLE_VIEWER)},
}
currentOrgReaderRole := accesscontrol.RoleRegistration{
Role: accesscontrol.RoleDTO{
Version: 3,
Name: "fixed:current.org:reader",
DisplayName: "Current Organization reader",
Description: "Read the current organization, such as its ID, name, address, or quotas.",
Permissions: []accesscontrol.Permission{
{Action: ActionOrgsRead},
{Action: ActionOrgsQuotasRead},
},
},
Grants: []string{string(models.ROLE_VIEWER)},
}
currentOrgWriterRole := accesscontrol.RoleRegistration{
Role: accesscontrol.RoleDTO{
Version: 3,
Name: "fixed:current.org:writer",
DisplayName: "Current Organization writer",
Description: "Read the current organization, its quotas, or its preferences. Update the current organization properties, or its preferences.",
Permissions: accesscontrol.ConcatPermissions(currentOrgReaderRole.Role.Permissions, []accesscontrol.Permission{
{Action: ActionOrgsPreferencesRead},
{Action: ActionOrgsWrite},
{Action: ActionOrgsPreferencesWrite},
}),
},
Grants: []string{string(models.ROLE_ADMIN)},
}
orgReaderRole := accesscontrol.RoleRegistration{
Role: accesscontrol.RoleDTO{
Version: 1,
Name: "fixed:orgs:reader",
DisplayName: "Organization reader",
Description: "Read the organization and its quotas.",
Permissions: []accesscontrol.Permission{
{Action: ActionOrgsRead},
{Action: ActionOrgsQuotasRead},
},
},
Grants: []string{string(accesscontrol.RoleGrafanaAdmin)},
}
orgWriterRole := accesscontrol.RoleRegistration{
Role: accesscontrol.RoleDTO{
Version: 3,
Name: "fixed:orgs:writer",
DisplayName: "Organization writer",
Description: "Create, read, write, or delete an organization. Read or write an organization's quotas.",
Permissions: accesscontrol.ConcatPermissions(orgReaderRole.Role.Permissions, []accesscontrol.Permission{
{Action: ActionOrgsCreate},
{Action: ActionOrgsWrite},
{Action: ActionOrgsDelete},
{Action: ActionOrgsQuotasWrite},
}),
},
Grants: []string{string(accesscontrol.RoleGrafanaAdmin)},
}
return hs.AccessControl.DeclareFixedRoles(
provisioningWriterRole, datasourcesReaderRole, datasourcesWriterRole, datasourcesIdReaderRole,
datasourcesCompatibilityReaderRole, currentOrgReaderRole, currentOrgWriterRole, orgReaderRole, orgWriterRole,
)
}
// Evaluators
+1
View File
@@ -168,6 +168,7 @@ type DsPermissionType int
const (
DsPermissionNoAccess DsPermissionType = iota
DsPermissionQuery
DsPermissionRead
)
func (p DsPermissionType) String() string {
+100 -87
View File
@@ -15,9 +15,11 @@ type RoleRegistry interface {
// Roles definition
var (
datasourcesEditorReadRole = RoleDTO{
Version: 1,
Name: datasourcesEditorRead,
datasourcesExplorerRole = RoleDTO{
Version: 2,
Name: datasourcesExplorer,
DisplayName: "Data source explorer",
Description: "Enable the Explore feature. Data source permissions still apply; you can only query data sources for which you have query permissions.",
Permissions: []Permission{
{
Action: ActionDatasourcesExplore,
@@ -25,9 +27,11 @@ var (
},
}
ldapAdminReadRole = RoleDTO{
Name: ldapAdminRead,
Version: 1,
ldapReaderRole = RoleDTO{
Name: ldapReader,
DisplayName: "LDAP reader",
Description: "Read LDAP configuration and status.",
Version: 2,
Permissions: []Permission{
{
Action: ActionLDAPUsersRead,
@@ -38,10 +42,12 @@ var (
},
}
ldapAdminEditRole = RoleDTO{
Name: ldapAdminEdit,
Version: 2,
Permissions: ConcatPermissions(ldapAdminReadRole.Permissions, []Permission{
ldapWriterRole = RoleDTO{
Name: ldapWriter,
DisplayName: "LDAP writer",
Description: "Read and update LDAP configuration and read LDAP status.",
Version: 3,
Permissions: ConcatPermissions(ldapReaderRole.Permissions, []Permission{
{
Action: ActionLDAPUsersSync,
},
@@ -51,42 +57,12 @@ var (
}),
}
serverAdminReadRole = RoleDTO{
Version: 1,
Name: serverAdminRead,
Permissions: []Permission{
{
Action: ActionServerStatsRead,
},
},
}
settingsAdminReadRole = RoleDTO{
Version: 2,
Name: settingsAdminRead,
Permissions: []Permission{
{
Action: ActionSettingsRead,
Scope: ScopeSettingsAll,
},
},
}
usersOrgReadRole = RoleDTO{
Name: usersOrgRead,
Version: 1,
Permissions: []Permission{
{
Action: ActionOrgUsersRead,
Scope: ScopeUsersAll,
},
},
}
usersOrgEditRole = RoleDTO{
Name: usersOrgEdit,
Version: 1,
Permissions: ConcatPermissions(usersOrgReadRole.Permissions, []Permission{
orgUsersWriterRole = RoleDTO{
Name: orgUsersWriter,
DisplayName: "Organization user writer",
Description: "Within a single organization, add a user, invite a user, read information about a user and their role, remove a user from that organization, or change the role of a user.",
Version: 2,
Permissions: ConcatPermissions(orgUsersReaderRole.Permissions, []Permission{
{
Action: ActionOrgUsersAdd,
Scope: ScopeUsersAll,
@@ -102,9 +78,49 @@ var (
}),
}
usersAdminReadRole = RoleDTO{
Name: usersAdminRead,
Version: 1,
orgUsersReaderRole = RoleDTO{
Name: orgUsersReader,
DisplayName: "Organization user reader",
Description: "Read users within a single organization.",
Version: 2,
Permissions: []Permission{
{
Action: ActionOrgUsersRead,
Scope: ScopeUsersAll,
},
},
}
settingsReaderRole = RoleDTO{
Version: 3,
DisplayName: "Setting reader",
Description: "Read Grafana instance settings.",
Name: settingsReader,
Permissions: []Permission{
{
Action: ActionSettingsRead,
Scope: ScopeSettingsAll,
},
},
}
statsReaderRole = RoleDTO{
Version: 2,
Name: statsReader,
DisplayName: "Statistics reader",
Description: "Read Grafana instance statistics.",
Permissions: []Permission{
{
Action: ActionServerStatsRead,
},
},
}
usersReaderRole = RoleDTO{
Name: usersReader,
DisplayName: "User reader",
Description: "Read all users and their information, such as team memberships, authentication tokens, and quotas.",
Version: 2,
Permissions: []Permission{
{
Action: ActionUsersRead,
@@ -125,10 +141,12 @@ var (
},
}
usersAdminEditRole = RoleDTO{
Name: usersAdminEdit,
Version: 1,
Permissions: ConcatPermissions(usersAdminReadRole.Permissions, []Permission{
usersWriterRole = RoleDTO{
Name: usersWriter,
DisplayName: "User writer",
Description: "Read and update all attributes and settings for all users in Grafana: update user information, read user information, create or enable or disable a user, make a user a Grafana administrator, sign out a user, update a user’s authentication token, or update quotas for all users.",
Version: 2,
Permissions: ConcatPermissions(usersReaderRole.Permissions, []Permission{
{
Action: ActionUsersPasswordUpdate,
Scope: ScopeGlobalUsersAll,
@@ -174,20 +192,15 @@ var (
// Role names definitions
const (
datasourcesEditorRead = "fixed:datasources:editor:read"
serverAdminRead = "fixed:server:admin:read"
settingsAdminRead = "fixed:settings:admin:read"
usersAdminEdit = "fixed:users:admin:edit"
usersAdminRead = "fixed:users:admin:read"
usersOrgEdit = "fixed:users:org:edit"
usersOrgRead = "fixed:users:org:read"
ldapAdminEdit = "fixed:ldap:admin:edit"
ldapAdminRead = "fixed:ldap:admin:read"
datasourcesExplorer = "fixed:datasources:explorer"
ldapReader = "fixed:ldap:reader"
ldapWriter = "fixed:ldap:writer"
orgUsersReader = "fixed:org.users:reader"
orgUsersWriter = "fixed:org.users:writer"
settingsReader = "fixed:settings:reader"
statsReader = "fixed:stats:reader"
usersReader = "fixed:users:reader"
usersWriter = "fixed:users:writer"
)
var (
@@ -198,36 +211,36 @@ var (
// resource. FixedRoleGrants lists which built-in roles are
// assigned which fixed roles in this list.
FixedRoles = map[string]RoleDTO{
datasourcesEditorRead: datasourcesEditorReadRole,
usersAdminEdit: usersAdminEditRole,
usersAdminRead: usersAdminReadRole,
usersOrgEdit: usersOrgEditRole,
usersOrgRead: usersOrgReadRole,
ldapAdminEdit: ldapAdminEditRole,
ldapAdminRead: ldapAdminReadRole,
serverAdminRead: serverAdminReadRole,
settingsAdminRead: settingsAdminReadRole,
datasourcesExplorer: datasourcesExplorerRole,
ldapReader: ldapReaderRole,
ldapWriter: ldapWriterRole,
orgUsersReader: orgUsersReaderRole,
orgUsersWriter: orgUsersWriterRole,
settingsReader: settingsReaderRole,
statsReader: statsReaderRole,
usersReader: usersReaderRole,
usersWriter: usersWriterRole,
}
// FixedRoleGrants specifies which built-in roles are assigned
// to which set of FixedRoles by default. Alphabetically sorted.
FixedRoleGrants = map[string][]string{
RoleGrafanaAdmin: {
ldapAdminEdit,
ldapAdminRead,
serverAdminRead,
settingsAdminRead,
usersAdminEdit,
usersAdminRead,
usersOrgEdit,
usersOrgRead,
ldapReader,
ldapWriter,
orgUsersReader,
orgUsersWriter,
settingsReader,
statsReader,
usersReader,
usersWriter,
},
string(models.ROLE_ADMIN): {
usersOrgEdit,
usersOrgRead,
orgUsersReader,
orgUsersWriter,
},
string(models.ROLE_EDITOR): {
datasourcesEditorRead,
datasourcesExplorer,
},
}
)
+2 -2
View File
@@ -8,7 +8,7 @@ import (
"github.com/stretchr/testify/assert"
)
func TestPredefinedRoles(t *testing.T) {
func TestFixedRoles(t *testing.T) {
for name, role := range FixedRoles {
assert.Truef(t,
strings.HasPrefix(name, "fixed:"),
@@ -19,7 +19,7 @@ func TestPredefinedRoles(t *testing.T) {
}
}
func TestPredefinedRoleGrants(t *testing.T) {
func TestFixedRoleGrants(t *testing.T) {
for _, grants := range FixedRoleGrants {
// Check grants list is sorted
assert.True(t,