From d623285fcc27515b3ee4140ddc1cef48651deca8 Mon Sep 17 00:00:00 2001 From: Karl Persson Date: Wed, 17 Nov 2021 15:40:39 +0100 Subject: [PATCH] Access Control: Rename fixed roles (#41288) * Rename fixed roles * Update descriptions * Update docs for fixed roles and permissions Co-authored-by: Ieva Co-authored-by: Ursula Kallio <73951760+osg-grafana@users.noreply.github.com> --- .../fine-grained-access-control-references.md | 62 ++-- .../enterprise/access-control/permissions.md | 26 +- pkg/api/api.go | 1 - pkg/api/roles.go | 280 +++++++++--------- pkg/models/datasource.go | 1 + pkg/services/accesscontrol/roles.go | 187 ++++++------ pkg/services/accesscontrol/roles_test.go | 4 +- 7 files changed, 302 insertions(+), 259 deletions(-) diff --git a/docs/sources/enterprise/access-control/fine-grained-access-control-references.md b/docs/sources/enterprise/access-control/fine-grained-access-control-references.md index cfcefde765f..7feab2737ab 100644 --- a/docs/sources/enterprise/access-control/fine-grained-access-control-references.md +++ b/docs/sources/enterprise/access-control/fine-grained-access-control-references.md @@ -11,34 +11,40 @@ The reference information that follows complements conceptual information about ## Fine-grained access fixed roles -| Fixed roles | Permissions | Descriptions | -| ------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------- | -| `fixed:permissions:admin:read` | `roles:read`
`roles:list`
`roles.builtin:list` | Allows to list and get available roles and built-in role assignments. | -| `fixed:permissions:admin:edit` | All permissions from `fixed:permissions:admin:read` and
`roles:write`
`roles:delete`
`roles.builtin:add`
`roles.builtin:remove` | Allows every read action and in addition allows to create, change and delete custom roles and create or remove built-in role assignments. | -| `fixed:provisioning:admin` | `provisioning:reload` | Allow provisioning configurations to be reloaded. | -| `fixed:reporting:admin:read` | `reports:read`
`reports:send`
`reports.settings:read` | Allows to read reports and report settings. | -| `fixed:reporting:admin:edit` | All permissions from `fixed:reporting:admin:read` and
`reports.admin:write`
`reports:delete`
`reports.settings:write` | Allows every read action for reports and in addition allows to administer reports. | -| `fixed:users:admin:read` | `users.authtoken:list`
`users.quotas:list`
`users:read`
`users.teams:read` | Allows to list and get users and related information. | -| `fixed:users:admin:edit` | All permissions from `fixed:users:admin:read` and
`users.password:update`
`users:write`
`users:create`
`users:delete`
`users:enable`
`users:disable`
`users.permissions:update`
`users:logout`
`users.authtoken:update`
`users.quotas:update` | Allows every read action for users and in addition allows to administer users. | -| `fixed:users:org:read` | `org.users:read` | Allows to get user organizations. | -| `fixed:users:org:edit` | All permissions from `fixed:users:org:read` and
`org.users:add`
`org.users:remove`
`org.users.role:update` | Allows every read action for user organizations and in addition allows to administer user organizations. | -| `fixed:ldap:admin:read` | `ldap.user:read`
`ldap.status:read` | Allows to read LDAP information and status. | -| `fixed:ldap:admin:edit` | All permissions from `fixed:ldap:admin:read` and
`ldap.user:sync`
`ldap.config:reload` | Allows every read action for LDAP and in addition allows to administer LDAP. | -| `fixed:server:admin:read` | `server.stats:read` | Read server stats | -| `fixed:settings:admin:read` | `settings:read` | Read settings | -| `fixed:settings:admin:edit` | All permissions from `fixed:settings:admin:read` and
`settings:write` | Update settings | -| `fixed:datasources:editor:read` | `datasources:explore` | Allows to access the **Explore** tab | -| `fixed:datasources:admin` | `datasources:read`
`datasources:create`
`datasources:write`
`datasources:delete` | Allows to create, read, update, delete data sources. | -| `fixed:datasources:id:viewer` | `datasources.id:read` | Allows to read data source IDs. | -| `fixed:datasources:permissions:admin` | `datasources.permissions:create`
`datasources.permissions:read`
`datasources.permissions:delete`
`datasources.permissions:toggle` | Allows to create, read, delete, enable, or disable data source permissions | -| `fixed:licensing:viewer` | `licensing:read`
`licensing.reports:read` | Read licensing information and custom permission reports. | -| `fixed:licensing:editor` | All permissions from `fixed:licensing:viewer` and
`licensing:update`
`licensing:delete` | Read licensing information and custom permission reports, and update and delete the license token. | +| Fixed roles | Permissions | Descriptions | +| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| `fixed:roles:reader` | `roles:read`
`roles:list`
`roles.builtin:list` | Read all access control roles and built-in role assignments. | +| `fixed:roles:writer` | All permissions from `fixed:roles:reader` and
`roles:write`
`roles:delete`
`roles.builtin:add`
`roles.builtin:remove` | Create, read, update, or delete all roles and built-in role assignments. | +| `fixed:reports:reader` | `reports:read`
`reports:send`
`reports.settings:read` | Read all reports and shared report settings. | +| `fixed:reports:writer` | All permissions from `fixed:reports:reader` and
`reports.admin:write`
`reports:delete`
`reports.settings:write` | Create, read, update, or delete all reports and shared report settings. | +| `fixed:users:reader` | `users:read`
`users.quotas:list`
`users.authtoken:list`
`users.teams:read` | Read all users and their information, such as team memberships, authentication tokens, and quotas. | +| `fixed:users:writer` | All permissions from `fixed:users:reader` and
`users:write`
`users:create`
`users:delete`
`users:enable`
`users:disable`
`users.password:update`
`users.permissions:update`
`users:logout`
`users.authtoken:update`
`users.quotas:update` | 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. | +| `fixed:org.users:reader` | `org.users:read` | Read users within a single organization. | +| `fixed:org.users:writer` | All permissions from `fixed:org.users:reader` and
`org.users:add`
`org.users:remove`
`org.users.role:update` | 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. | +| `fixed:ldap:reader` | `ldap.user:read`
`ldap.status:read` | Read the LDAP configuration and LDAP status information. | +| `fixed:ldap:writer` | All permissions from `fixed:ldap:reader` and
`ldap.user:sync`
`ldap.config:reload` | Read and update the LDAP configuration, and read LDAP status information. | +| `fixed:stats:reader` | `server.stats:read` | Read Grafana instance statistics. | +| `fixed:settings:reader` | `settings:read` | Read Grafana instance settings. | +| `fixed:settings:writer` | All permissions from `fixed:settings:reader` and
`settings:write` | Read and update Grafana instance settings. | +| `fixed:datasources:explorer` | `datasources:explore` | Enable the Explore feature. Data source permissions still apply, you can only query data sources for which you have query permissions. | +| `fixed:datasources:reader` | `datasources:read`
`datasources:query` | Read and query data sources. | +| `fixed:datasources:writer` | All permissions from `fixed:datasources:reader` and
`datasources:create`
`datasources:write`
`datasources:delete` | Read, query, create, delete, or update a data source. | +| `fixed:datasources:id:reader` | `datasources.id:read` | Read the ID of a data source based on its name. | +| `fixed:datasources.permissions:reader` | `datasources.permissions:read` | Read data source permissions. | +| `fixed:datasources.permissions:writer` | All permissions from `fixed:datasources.permissions:reader` and
`datasources.permissions:create`
`datasources.permissions:delete`
`datasources.permissions:toggle` | Create, read, or delete permissions of a data source. | +| `fixed:licensing:reader` | `licensing:read`
`licensing.reports:read` | Read licensing information and licensing reports. | +| `fixed:licensing:writer` | All permissions from `fixed:licensing:viewer` and
`licensing:update`
`licensing:delete` | Read licensing information and licensing reports, update and delete the license token. | +| `fixed:provisioning:writer` | `provisioning:reload` | Reload provisioning. | +| `fixed:orgs:reader` | `orgs:read`
`orgs.quotas:read` | Read the organization and its quotas. | +| `fixed:orgs:writer` | All permissions from `fixed:orgs:reader` and
`orgs:write`
`orgs:delete`
`orgs.quotas:write` | Create, read, write, or delete an organization. Read or write its quotas. | +| `fixed:current.org:reader` | `orgs:read`
`orgs.quotas:read` | Read the current organization, such as its ID, name, address, or quotas. | +| `fixed:current.org:writer` | All permissions from `fixed:current.orgs:reader` and
`orgs:write`
`orgs.quotas:write`
`orgs.preferences:read`
`orgs.preferences:write` | Read the current organization, its quotas, or its preferences. Update the current organization properties, or its preferences. | ## Default built-in role assignments -| Built-in role | Associated role | Description | -| ------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | -| Grafana Admin | `fixed:permissions:admin:edit`
`fixed:permissions:admin:read`
`fixed:provisioning:admin`
`fixed:reporting:admin:edit`
`fixed:reporting:admin:read`
`fixed:users:admin:edit`
`fixed:users:admin:read`
`fixed:users:org:edit`
`fixed:users:org:read`
`fixed:ldap:admin:edit`
`fixed:ldap:admin:read`
`fixed:server:admin:read`
`fixed:settings:admin:read`
`fixed:settings:admin:edit`
`fixed:licensing:editor` | Default [Grafana server administrator]({{< relref "../../permissions/_index.md#grafana-server-admin-role" >}}) assignments. | -| Admin | `fixed:users:org:edit`
`fixed:users:org:read`
`fixed:reporting:admin:edit`
`fixed:reporting:admin:read`
`fixed:datasources:admin`
`fixed:datasources:permissions:admin` | Default [Grafana organization administrator]({{< relref "../../permissions/organization_roles.md" >}}) assignments. | -| Editor | `fixed:datasources:editor:read` | Default [Editor]({{< relref "../../permissions/organization_roles.md" >}}) assignments. | -| Viewer | `fixed:datasources:id:viewer` | Default [Viewer]({{< relref "../../permissions/organization_roles.md" >}}) assignments. | +| Built-in role | Associated role | Description | +| ------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------- | +| Grafana Admin | `fixed:roles:reader`
`fixed:roles:writer`
`fixed:users:reader`
`fixed:users:writer`
`fixed:org.users:reader`
`fixed:org.users:writer`
`fixed:ldap:reader`
`fixed:ldap:writer`
`fixed:stats:reader`
`fixed:settings:reader`
`fixed:settings:writer`
`fixed:provisioning:writer`
`fixed:orgs:reader`
`fixed:orgs:writer`
`fixed:licensing:reader`
`fixed:licensing:writer` | Default [Grafana server administrator]({{< relref "../../permissions/_index.md#grafana-server-admin-role" >}}) assignments. | +| Admin | `fixed:reports:reader`
`fixed:reports:writer`
`fixed:datasources:reader`
`fixed:datasources:writer`
`fixed:current.org:writer`
`fixed:datasources.permissions:reader`
`fixed:datasources.permissions:writer`
| Default [Grafana organization administrator]({{< relref "../../permissions/organization_roles.md" >}}) assignments. | +| Editor | `fixed:datasources:explorer` | Default [Editor]({{< relref "../../permissions/organization_roles.md" >}}) assignments. | +| Viewer | `fixed:datasources:id:reader` | Default [Viewer]({{< relref "../../permissions/organization_roles.md" >}}) assignments. | diff --git a/docs/sources/enterprise/access-control/permissions.md b/docs/sources/enterprise/access-control/permissions.md index ec28407b873..29e220ef47a 100644 --- a/docs/sources/enterprise/access-control/permissions.md +++ b/docs/sources/enterprise/access-control/permissions.md @@ -58,16 +58,25 @@ The following list contains fine-grained access control actions. | `org.users:add` | `users:*` | Add a user to an organization. | | `org.users:remove` | `users:*`
`users:id:*` | Remove a user from an organization. | | `org.users.role:update` | `users:*`
`users:id:*` | Update the organization role (`Viewer`, `Editor`, or `Admin`) of an organization. | -| `ldap.user:read` | n/a | Get a user via LDAP. | -| `ldap.user:sync` | n/a | Sync a user via LDAP. | +| `orgs:read` | `orgs:*`
`orgs:id:*` | Read one or more organizations. | +| `orgs:write` | `orgs:*`
`orgs:id:*` | Update one or more organizations. | +| `org:create` | n/a | Create an organization. | +| `orgs:delete` | `orgs:*`
`orgs:id:*` | Delete one or more organizations. | +| `orgs.quotas:read` | `orgs:*`
`orgs:id:*` | Read organization quotas. | +| `orgs.quotas:write` | `orgs:*`
`orgs:id:*` | Update organization quotas. | +| `orgs.preferences:read` | `orgs:*`
`orgs:id:*` | Read organization preferences. | +| `orgs.preferences:write` | `orgs:*`
`orgs:id:*` | Update organization preferences. | +| `ldap.user:read` | n/a | Read users via LDAP. | +| `ldap.user:sync` | n/a | Sync users via LDAP. | | `ldap.status:read` | n/a | Verify the availability of the LDAP server or servers. | | `ldap.config:reload` | n/a | Reload the LDAP configuration. | | `status:accesscontrol` | `services:accesscontrol` | Get access-control enabled status. | | `settings:read` | `settings:*`
`settings:auth.saml:*`
`settings:auth.saml:enabled` (property level) | Read the [Grafana configuration settings]({{< relref "../../administration/configuration/_index.md" >}}) | | `settings:write` | `settings:*`
`settings:auth.saml:*`
`settings:auth.saml:enabled` (property level) | Update any Grafana configuration settings that can be [updated at runtime]({{< relref "../../enterprise/settings-updates/_index.md" >}}). | -| `server.stats:read` | n/a | Read server stats | +| `server.stats:read` | n/a | Read Grafana instance statistics. | | `datasources:explore` | n/a | Enable access to the **Explore** tab. | | `datasources:read` | n/a
`datasources:*`
`datasources:id:*`
`datasources:uid:*`
`datasources:name:*` | List data sources. | +| `datasources:query` | n/a
`datasources:*`
`datasources:id:*` | Query data sources. | | `datasources.id:read` | `datasources:*`
`datasources:name:*` | Read data source IDs. | | `datasources:create` | n/a | Create data sources. | | `datasources:write` | `datasources:*`
`datasources:id:*` | Update data sources. | @@ -80,6 +89,7 @@ The following list contains fine-grained access control actions. | `licensing:update` | n/a | Update the license token. | | `licensing:delete` | n/a | Delete the license token. | | `licensing.reports:read` | n/a | Get custom permission reports. | +| `serviceaccounts:delete` | `serviceaccounts:*`
`serviceaccounts:id:*` | Delete one or more service accounts. | ## Scope definitions @@ -87,12 +97,14 @@ The following list contains fine-grained access control scopes. | Scopes | Descriptions | | ------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| `roles:*` | Restrict an action to a set of roles. For example, `roles:*` matches any role, `roles:uid:randomuid` matches only the role with UID `randomuid` | | `permissions:delegate` | The scope is only applicable for roles associated with the Access Control itself and indicates that you can delegate your permissions only, or a subset of it, by creating a new role or making an assignment. | -| `reports:*` | Restrict an action to a set of reports. For example, `reports:*` matches any report and `reports:id:1` matches the report with id `1`. | +| `roles:*`
`roles:uid:*` | Restrict an action to a set of roles. For example, `roles:*` matches any role and `roles:uid:randomuid` matches only the role whose UID is `randomuid`. | +| `reports:*`
`reports:id:*` | Restrict an action to a set of reports. For example, `reports:*` matches any report and `reports:id:1` matches the report whose ID is `1`. | | `services:accesscontrol` | Restrict an action to target only the fine-grained access control service. You can use this in conjunction with the `status:accesscontrol` actions. | -| `global:users:*` | Restrict an action to a set of global users. | -| `users:*` | Restrict an action to a set of users from an organization. | +| `global:users:*`
`global:users:id:*` | Restrict an action to a set of global users. For example, `global:users:*` matches any user and `global:users:id:1` matches the user whose ID is `1`. | +| `users:*`
`users:id:*` | Restrict an action to a set of users from an organization. For example, `users:*` matches any user and `users:id:1` matches the user whose ID is `1`. | +| `orgs:*`
`orgs:id:*` | Restrict an action to a set of organizations. For example, `orgs:*` matches any organization and `orgs:id:1` matches the organization whose ID is `1`. | | `settings:*` | Restrict an action to a subset of settings. For example, `settings:*` matches all settings, `settings:auth.saml:*` matches all SAML settings, and `settings:auth.saml:enabled` matches the enable property on the SAML settings. | | `provisioners:*` | Restrict an action to a set of provisioners. For example, `provisioners:*` matches any provisioner, and `provisioners:accesscontrol` matches the fine-grained access control [provisioner]({{< relref "./provisioning.md" >}}). | | `datasources:*`
`datasources:id:*`
`datasources:uid:*`
`datasources:name:*` | Restrict an action to a set of data sources. For example, `datasources:*` matches any data source, and `datasources:name:postgres` matches the data source named `postgres`. | +| `serviceaccounts:*`
`serviceaccounts:id:*` | Restrict an action to a set of service accounts. For example, `serviceaccounts:*` matches any service account and `serviceaccounts:id:1` matches the service account whose ID is `1`. | diff --git a/pkg/api/api.go b/pkg/api/api.go index 98557e7d6c6..d08edc1e550 100644 --- a/pkg/api/api.go +++ b/pkg/api/api.go @@ -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)) diff --git a/pkg/api/roles.go b/pkg/api/roles.go index 771084bd361..6f09f1de1c9 100644 --- a/pkg/api/roles.go +++ b/pkg/api/roles.go @@ -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 diff --git a/pkg/models/datasource.go b/pkg/models/datasource.go index 005c4a1bbde..9bd60f628ad 100644 --- a/pkg/models/datasource.go +++ b/pkg/models/datasource.go @@ -168,6 +168,7 @@ type DsPermissionType int const ( DsPermissionNoAccess DsPermissionType = iota DsPermissionQuery + DsPermissionRead ) func (p DsPermissionType) String() string { diff --git a/pkg/services/accesscontrol/roles.go b/pkg/services/accesscontrol/roles.go index 4a69a32da17..53442e3edd6 100644 --- a/pkg/services/accesscontrol/roles.go +++ b/pkg/services/accesscontrol/roles.go @@ -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, }, } ) diff --git a/pkg/services/accesscontrol/roles_test.go b/pkg/services/accesscontrol/roles_test.go index 7df69ecd3f5..9c0eec44e6b 100644 --- a/pkg/services/accesscontrol/roles_test.go +++ b/pkg/services/accesscontrol/roles_test.go @@ -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,