mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
RBAC: Make RBAC action names more consistent (#49730)
* update action names * correctly retrieve teams for signed in user * remove test * undo swagger changes * undo swagger changes pt2 * add migration from old action names to the new ones * rename from list to read * linting * also update alertign actions * fix migration
This commit is contained in:
@@ -79,7 +79,7 @@ Query Parameters:
|
||||
| roles:read | roles:\* |
|
||||
|
||||
#### Example request
|
||||
|
||||
|
||||
```http
|
||||
GET /api/access-control/roles
|
||||
Accept: application/json
|
||||
@@ -180,13 +180,13 @@ Content-Type: application/json; charset=UTF-8
|
||||
|
||||
#### JSON body schema
|
||||
|
||||
| Field Name | Date Type | Required | Description |
|
||||
| Field Name | Date Type | Required | Description |
|
||||
| ----------- | ---------- | -------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| uid | string | No | UID of the role. If not present, the UID will be automatically created for you and returned in response. Refer to the [Custom roles]({{< relref "../../enterprise/access-control/about-rbac/#custom-roles" >}}) for more information. |
|
||||
| global | boolean | No | A flag indicating if the role is global or not. If set to `false`, the default org ID of the authenticated user will be used from the request. |
|
||||
| version | number | No | Version of the role. If not present, version 0 will be assigned to the role and returned in the response. Refer to the [Custom roles]({{< relref "../../enterprise/access-control/about-rbac/#custom-roles" >}}) for more information. |
|
||||
| name | string | Yes | Name of the role. Refer to [Custom roles]({{< relref "../../enterprise/access-control/about-rbac/#custom-roles" >}}) for more information. |
|
||||
| description | string | No | Description of the role. |
|
||||
| description | string | No | Description of the role. |
|
||||
| displayName | string | No | Display name of the role, visible in the UI. |
|
||||
| group | string | No | The group name the role belongs to. |
|
||||
| hidden | boolean | No | Specify whether the role is hidden or not. If set to `true`, then the role does not show in the role picker. It will not be listed by API endpoints unless explicitly specified. |
|
||||
@@ -489,7 +489,7 @@ Query Parameters:
|
||||
`permissions:type:delegate` scope ensures that users can only unassign roles which have same, or a subset of permissions which the user has.
|
||||
For example, if a user does not have required permissions for creating users, they won't be able to unassign a role which will allow to do that. This is done to prevent escalation of privileges.
|
||||
|
||||
| Action | Scope |
|
||||
| Action | Scope |
|
||||
| ------------------ | ------------------------- |
|
||||
| users.roles:remove | permissions:type:delegate |
|
||||
|
||||
@@ -537,7 +537,7 @@ Lists the permissions that a given user has.
|
||||
|
||||
#### Required permissions
|
||||
|
||||
`permissions:type:delegate` scope ensures that users can only assign or unassign roles which have same, or a subset of permissions which the user has.
|
||||
`permissions:type:delegate` scope ensures that users can only assign or unassign roles which have same, or a subset of permissions which the user has.
|
||||
For example, if a user does not have required permissions for creating users, they won't be able to assign or unassign a role which will allow to do that. This is done to prevent escalation of privileges.
|
||||
|
||||
| Action | Scope |
|
||||
@@ -763,7 +763,7 @@ Query Parameters:
|
||||
#### JSON body schema
|
||||
|
||||
| Field Name | Date Type | Required | Description |
|
||||
| ------------- | --------- | -------- | -------------------------------------------------------------- |
|
||||
| ------------- | --------- | -------- | -------------------------------------------------------------- |
|
||||
| roleUids | list | Yes | List of role UIDs. |
|
||||
| includeHidden | boolean | No | Specify whether the hidden role assignments should be updated. |
|
||||
|
||||
|
||||
@@ -380,9 +380,9 @@ Change password for a specific user.
|
||||
|
||||
## Logout User
|
||||
|
||||
`POST /api/admin/users/:id/logout`
|
||||
|
||||
Logout user revokes all auth tokens (devices) for the user. User of issued auth tokens (devices) will no longer be logged in
|
||||
`POST /api/admin/users/:id/logout`
|
||||
|
||||
Logout user revokes all auth tokens (devices) for the user. User of issued auth tokens (devices) will no longer be logged in
|
||||
and will be required to authenticate again upon next activity.
|
||||
|
||||
Only works with Basic Authentication (username and password). See [introduction](http://docs.grafana.org/http_api/admin/#admin-api) for an explanation.
|
||||
@@ -413,9 +413,9 @@ Only works with Basic Authentication (username and password). See [introduction]
|
||||
|
||||
## Reload provisioning configurations
|
||||
|
||||
`POST /api/admin/provisioning/dashboards/reload`
|
||||
|
||||
`POST /api/admin/provisioning/datasources/reload`
|
||||
`POST /api/admin/provisioning/dashboards/reload`
|
||||
|
||||
`POST /api/admin/provisioning/datasources/reload`
|
||||
|
||||
`POST /api/admin/provisioning/plugins/reload`
|
||||
|
||||
@@ -516,7 +516,7 @@ See note in the [introduction]({{< ref "#admin-api" >}}) for an explanation.
|
||||
|
||||
| Action | Scope |
|
||||
| -------------------- | --------------- |
|
||||
| users.authtoken:list | global.users:\* |
|
||||
| users.authtoken:read | global.users:\* |
|
||||
|
||||
**Example Request**:
|
||||
|
||||
@@ -573,9 +573,9 @@ Only works with Basic Authentication (username and password). See [introduction]
|
||||
|
||||
See note in the [introduction]({{< ref "#admin-api" >}}) for an explanation.
|
||||
|
||||
| Action | Scope |
|
||||
| ---------------------- | --------------- |
|
||||
| users.authtoken:update | global.users:\* |
|
||||
| Action | Scope |
|
||||
| --------------------- | --------------- |
|
||||
| users.authtoken:write | global.users:\* |
|
||||
|
||||
**Example Request**:
|
||||
|
||||
|
||||
@@ -71,9 +71,9 @@ Manually ask license issuer for a new token.
|
||||
See note in the [introduction]({{< ref "#enterprise-license-api" >}}) for an explanation.
|
||||
|
||||
| Action | Scope |
|
||||
| ---------------- | ----- |
|
||||
| licensing:update | n/a |
|
||||
|
||||
| --------------- | ----- |
|
||||
| licensing:write | n/a |
|
||||
|
||||
### Examples
|
||||
|
||||
**Example request:**
|
||||
|
||||
@@ -149,9 +149,9 @@ Content-Type: application/json
|
||||
```
|
||||
|
||||
### Delete user in current organization
|
||||
|
||||
`DELETE /api/org/users/:userId`
|
||||
|
||||
|
||||
`DELETE /api/org/users/:userId`
|
||||
|
||||
**Required permissions**
|
||||
|
||||
See note in the [introduction]({{< ref "#organization-api" >}}) for an explanation.
|
||||
@@ -605,9 +605,9 @@ Only works with Basic Authentication (username and password), see [introduction]
|
||||
|
||||
See note in the [introduction]({{< ref "#organization-api" >}}) for an explanation.
|
||||
|
||||
| Action | Scope |
|
||||
| --------------------- | -------- |
|
||||
| org.users.role:update | users:\* |
|
||||
| Action | Scope |
|
||||
| --------------- | -------- |
|
||||
| org.users:write | users:\* |
|
||||
|
||||
**Example Request**:
|
||||
|
||||
|
||||
@@ -140,9 +140,9 @@ Content-Type: application/json
|
||||
Content-Type: application/json
|
||||
Authorization: Basic YWRtaW46YWRtaW4=
|
||||
```
|
||||
|
||||
Requires basic authentication and that the authenticated user is a Grafana Admin.
|
||||
|
||||
|
||||
Requires basic authentication and that the authenticated user is a Grafana Admin.
|
||||
|
||||
**Example Response**:
|
||||
|
||||
```http
|
||||
@@ -241,9 +241,9 @@ Content-Type: application/json
|
||||
**Example Response**:
|
||||
|
||||
```http
|
||||
Content-Type: application/json
|
||||
|
||||
```
|
||||
HTTP/1.1 200
|
||||
Content-Type: application/json
|
||||
|
||||
```
|
||||
|
||||
## User
|
||||
@@ -280,9 +280,9 @@ Content-Type: application/json
|
||||
**Example Request**:
|
||||
|
||||
```http
|
||||
Accept: application/json
|
||||
Content-Type: application/json
|
||||
Authorization: Basic YWRtaW46YWRtaW4=
|
||||
PUT /api/user/password HTTP/1.1
|
||||
Accept: application/json
|
||||
Content-Type: application/json
|
||||
Authorization: Basic YWRtaW46YWRtaW4=
|
||||
|
||||
```
|
||||
@@ -318,9 +318,10 @@ Content-Type: application/json
|
||||
```http
|
||||
POST /api/users/7/using/2 HTTP/1.1
|
||||
Authorization: Basic YWRtaW46YWRtaW4=
|
||||
|
||||
**Example Response**:
|
||||
|
||||
```
|
||||
|
||||
**Example Response**:
|
||||
|
||||
```http
|
||||
HTTP/1.1 200
|
||||
Content-Type: application/json
|
||||
|
||||
@@ -91,9 +91,9 @@ To learn more about the permissions you can grant for each resource, refer to [R
|
||||
|
||||
If you are a Grafana Enterprise customer, you can create custom roles to manage user permissions in a way that meets your security requirements.
|
||||
|
||||
Custom roles contain unique combinations of permissions _actions_ and _scopes_. An action defines the action a use can perform on a Grafana resource. For example, the `teams.roles:list` action allows a user to see a list of roles associated with each team.
|
||||
Custom roles contain unique combinations of permissions _actions_ and _scopes_. An action defines the action a use can perform on a Grafana resource. For example, the `teams.roles:read` action allows a user to see a list of roles associated with each team.
|
||||
|
||||
A scope describes where an action can be performed. For example, the `teams:id:1` scope restricts the user's action to the team with ID `1`. When paired with the `teams.roles:list` action, this permission prohibits the user from viewing the roles for teams other than team `1`.
|
||||
A scope describes where an action can be performed. For example, the `teams:id:1` scope restricts the user's action to the team with ID `1`. When paired with the `teams.roles:read` action, this permission prohibits the user from viewing the roles for teams other than team `1`.
|
||||
|
||||
Consider creating a custom role when fixed roles do not meet your permissions requirements.
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ The following list contains role-based access control actions.
|
||||
| `alert.instances.external:write` | `datasources:*`<br>`datasources:uid:*` | Manage alerts and silences in data sources that support alerting. |
|
||||
| `alert.instances:create` | n/a | Create silences in the current organization. |
|
||||
| `alert.instances:read` | n/a | Read alerts and silences in the current organization. |
|
||||
| `alert.instances:update` | n/a | Update and expire silences in the current organization. |
|
||||
| `alert.instances:write` | n/a | Update and expire silences in the current organization. |
|
||||
| `alert.notifications.external:read` | `datasources:*`<br>`datasources:uid:*` | Read templates, contact points, notification policies, and mute timings in data sources that support alerting. |
|
||||
| `alert.notifications.external:write` | `datasources:*`<br>`datasources:uid:*` | Manage templates, contact points, notification policies, and mute timings in data sources that support alerting. |
|
||||
| `alert.notifications:write` | n/a | Manage templates, contact points, notification policies, and mute timings in the current organization. |
|
||||
@@ -37,7 +37,7 @@ The following list contains role-based access control actions.
|
||||
| `alert.rules:create` | `folders:*`<br>`folders:uid:*` | Create Grafana alert rules in a folder. Combine this permission with `folders:read` in a scope that includes the folder and `datasources:query` in the scope of data sources the user can query. |
|
||||
| `alert.rules:delete` | `folders:*`<br>`folders:uid:*` | Delete Grafana alert rules in a folder. Combine this permission with `folders:read` in a scope that includes the folder and `datasources:query` in the scope of data sources the user can query. |
|
||||
| `alert.rules:read` | `folders:*`<br>`folders:uid:*` | Read Grafana alert rules in a folder. Combine this permission with `folders:read` in a scope that includes the folder and `datasources:query` in the scope of data sources the user can query. |
|
||||
| `alert.rules:update` | `folders:*`<br>`folders:uid:*` | Update Grafana alert rules in a folder. Combine this permission with `folders:read` in a scope that includes the folder and `datasources:query` in the scope of data sources the user can query. |
|
||||
| `alert.rules:write` | `folders:*`<br>`folders:uid:*` | Update Grafana alert rules in a folder. Combine this permission with `folders:read` in a scope that includes the folder and `datasources:query` in the scope of data sources the user can query. |
|
||||
| `annotations:create` | `annotations:*`<br>`annotations:type:*` | Create annotations. |
|
||||
| `annotations:delete` | `annotations:*`<br>`annotations:type:*` | Delete annotations. |
|
||||
| `annotations:read` | `annotations:*`<br>`annotations:type:*` | Read annotations and annotation tags. |
|
||||
@@ -73,8 +73,8 @@ The following list contains role-based access control actions.
|
||||
| `licensing.reports:read` | n/a | Get custom permission reports. |
|
||||
| `licensing:delete` | n/a | Delete the license token. |
|
||||
| `licensing:read` | n/a | Read licensing information. |
|
||||
| `licensing:update` | n/a | Update the license token. |
|
||||
| `org.users.role:update` | `users:*` <br> `users:id:*` | Update the organization role (`Viewer`, `Editor`, or `Admin`) of an organization. |
|
||||
| `licensing:write` | n/a | Update the license token. |
|
||||
| `org.users:write` | `users:*` <br> `users:id:*` | Update the organization role (`Viewer`, `Editor`, or `Admin`) of a user. |
|
||||
| `org.users:add` | `users:*` | Add a user to an organization. |
|
||||
| `org.users:read` | `users:*` <br> `users:id:*` | Get user profiles within an organization. |
|
||||
| `org.users:remove` | `users:*` <br> `users:id:*` | Remove a user from an organization. |
|
||||
@@ -87,16 +87,15 @@ The following list contains role-based access control actions.
|
||||
| `orgs:read` | `orgs:*` <br> `orgs:id:*` | Read one or more organizations. |
|
||||
| `orgs:write` | `orgs:*` <br> `orgs:id:*` | Update one or more organizations. |
|
||||
| `provisioning:reload` | `provisioners:*` | Reload provisioning files. To find the exact scope for specific provisioner, see [Scope definitions]({{< relref "#scope-definitions" >}}). |
|
||||
| `reports.admin:create` | n/a | Create reports. |
|
||||
| `reports.admin:write` | `reports:*` <br> `reports:id:*` | Update reports. |
|
||||
| `reports:create` | n/a | Create reports. |
|
||||
| `reports:write` | `reports:*` <br> `reports:id:*` | Update reports. |
|
||||
| `reports.settings:read` | n/a | Read report settings. |
|
||||
| `reports.settings:write` | n/a | Update report settings. |
|
||||
| `reports:delete` | `reports:*` <br> `reports:id:*` | Delete reports. |
|
||||
| `reports:read` | `reports:*` | List all available reports or get a specific report. |
|
||||
| `reports:send` | `reports:*` | Send a report email. |
|
||||
| `roles:delete` | `permissions:type:delegate` | Delete a custom role. |
|
||||
| `roles:list` | `roles:*` | List available roles without permissions. |
|
||||
| `roles:read` | `roles:*` <br> `roles:uid:*` | Read a specific role with its permissions. |
|
||||
| `roles:read` | `roles:*` <br> `roles:uid:*` | List roles and read a specific with its permissions. |
|
||||
| `roles:write` | `permissions:type:delegate` | Create or update a custom role. |
|
||||
| `roles:write` | `permissions:type:escalate` | Reset basic roles to their default permissions. |
|
||||
| `server.stats:read` | n/a | Read Grafana instance statistics. |
|
||||
@@ -106,23 +105,22 @@ The following list contains role-based access control actions.
|
||||
| `teams.permissions:read` | `teams:*`<br>`teams:id:*` | Read members and External Group Synchronization setup for teams. |
|
||||
| `teams.permissions:write` | `teams:*`<br>`teams:id:*` | Add, remove and update members and manage External Group Synchronization setup for teams. |
|
||||
| `teams.roles:add` | `permissions:type:delegate` | Assign a role to a team. |
|
||||
| `teams.roles:list` | `teams:*` | List roles assigned directly to a team. |
|
||||
| `teams.roles:read` | `teams:*` | List roles assigned directly to a team. |
|
||||
| `teams.roles:remove` | `permissions:type:delegate` | Unassign a role from a team. |
|
||||
| `teams:create` | n/a | Create teams. |
|
||||
| `teams:delete` | `teams:*`<br>`teams:id:*` | Delete one or more teams. |
|
||||
| `teams:read` | `teams:*`<br>`teams:id:*` | Read one or more teams and team preferences. |
|
||||
| `teams:write` | `teams:*`<br>`teams:id:*` | Update one or more teams and team preferences. |
|
||||
| `users.authtoken:list` | `global.users:*` <br> `global.users:id:*` | List authentication tokens that are assigned to a user. |
|
||||
| `users.authtoken:update` | `global.users:*` <br> `global.users:id:*` | Update authentication tokens that are assigned to a user. |
|
||||
| `users.password:update` | `global.users:*` <br> `global.users:id:*` | Update a user’s password. |
|
||||
| `users.permissions:list` | `users:*` | List permissions of a user. |
|
||||
| `users.permissions:update` | `global.users:*` <br> `global.users:id:*` | Update a user’s organization-level permissions. |
|
||||
| `users.quotas:list` | `global.users:*` <br> `global.users:id:*` | List a user’s quotas. |
|
||||
| `users.quotas:update` | `global.users:*` <br> `global.users:id:*` | Update a user’s quotas. |
|
||||
| `users.authtoken:read` | `global.users:*` <br> `global.users:id:*` | List authentication tokens that are assigned to a user. |
|
||||
| `users.authtoken:write` | `global.users:*` <br> `global.users:id:*` | Update authentication tokens that are assigned to a user. |
|
||||
| `users.password:write` | `global.users:*` <br> `global.users:id:*` | Update a user’s password. |
|
||||
| `users.permissions:read` | `users:*` | List permissions of a user. |
|
||||
| `users.permissions:write` | `global.users:*` <br> `global.users:id:*` | Update a user’s organization-level permissions. |
|
||||
| `users.quotas:read` | `global.users:*` <br> `global.users:id:*` | List a user’s quotas. |
|
||||
| `users.quotas:write` | `global.users:*` <br> `global.users:id:*` | Update a user’s quotas. |
|
||||
| `users.roles:add` | `permissions:type:delegate` | Assign a role to a user. |
|
||||
| `users.roles:list` | `users:*` | List roles assigned directly to a user. |
|
||||
| `users.roles:read` | `users:*` | List roles assigned directly to a user. |
|
||||
| `users.roles:remove` | `permissions:type:delegate` | Unassign a role from a user. |
|
||||
| `users.teams:read` | `global.users:*` <br> `global.users:id:*` | Read a user’s teams. |
|
||||
| `users:create` | n/a | Create a user. |
|
||||
| `users:delete` | `global.users:*` <br> `global.users:id:*` | Delete a user. |
|
||||
| `users:disable` | `global.users:*` <br> `global.users:id:*` | Disable a user. |
|
||||
|
||||
@@ -65,7 +65,7 @@ curl --location --request GET '<grafana_url>/api/access-control/roles/qQui_LCMk'
|
||||
"created": "2021-05-17T20:49:18+02:00"
|
||||
},
|
||||
{
|
||||
"action": "org.users.role:update",
|
||||
"action": "org.users:write",
|
||||
"scope": "users:*",
|
||||
"updated": "2021-05-17T20:49:18+02:00",
|
||||
"created": "2021-05-17T20:49:18+02:00"
|
||||
@@ -178,7 +178,7 @@ roles:
|
||||
- name: 'fixed:org.users:writer'
|
||||
global: true
|
||||
permissions:
|
||||
- action: 'org.users.role:update'
|
||||
- action: 'org.users:write'
|
||||
scope: 'users:*'
|
||||
state: 'absent'
|
||||
- action: 'org.users:add'
|
||||
@@ -283,7 +283,7 @@ roles:
|
||||
global: true
|
||||
permissions:
|
||||
# Permissions to remove
|
||||
- action: 'teams.roles:list'
|
||||
- action: 'teams.roles:read'
|
||||
scope: 'teams:*'
|
||||
state: 'absent'
|
||||
- action: 'teams.roles:remove'
|
||||
|
||||
@@ -173,7 +173,6 @@ roles:
|
||||
|
||||
| action | scope |
|
||||
| -------------- | --------------------------- |
|
||||
| `roles:list` | `roles:*` |
|
||||
| `roles:read` | `roles:*` |
|
||||
| `roles:write` | `permissions:type:delegate` |
|
||||
| `roles:delete` | `permissions:type:delegate` |
|
||||
@@ -204,12 +203,12 @@ roles:
|
||||
|
||||
- Add the following permissions to the `basic:viewer` role, using provisioning or the [RBAC HTTP API]({{< relref "../../developers/http_api/access_control.md#update-a-role" >}}):
|
||||
|
||||
| Action | Scope |
|
||||
| ---------------------- | ------------------------------- |
|
||||
| `reports.admin:create` | n/a |
|
||||
| `reports.admin:write` | `reports:*` <br> `reports:id:*` |
|
||||
| `reports:read` | `reports:*` |
|
||||
| `reports:send` | `reports:*` |
|
||||
| Action | Scope |
|
||||
| ---------------- | ------------------------------- |
|
||||
| `reports:create` | n/a |
|
||||
| `reports:write` | `reports:*` <br> `reports:id:*` |
|
||||
| `reports:read` | `reports:*` |
|
||||
| `reports:send` | `reports:*` |
|
||||
|
||||
### Prevent a Grafana Admin from creating and inviting users
|
||||
|
||||
|
||||
@@ -24,59 +24,59 @@ The following tables list permissions associated with basic and fixed roles.
|
||||
|
||||
## Fixed role definitions
|
||||
|
||||
| Fixed role | Permissions | Description |
|
||||
| -------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `fixed:alerting.instances:editor` | All permissions from `fixed:alerting.instances:reader` and<br> `alert.instances:create`<br>`alert.instances:update` for organization scope <br> `alert.instances.external:write` for scope `datasources:*` | Create, update and expire all silences in the organization produced by Grafana, Mimir, and Loki.[\*](#alerting-roles) |
|
||||
| `fixed:alerting.instances:reader` | `alert.instances:read` for organization scope <br> `alert.instances.external:read` for scope `datasources:*` | Read all alerts and silences in the organization produced by Grafana Alerts and Mimir and Loki alerts and silences.[\*](#alerting-roles) |
|
||||
| `fixed:alerting.notifications:editor` | All permissions from `fixed:alerting.notifications:reader` and<br>`alert.notifications:write`for organization scope<br>`alert.notifications.external:read` for scope `datasources:*` | Create, update, and delete contact points, templates, mute timings and notification policies for Grafana and external Alertmanager.[\*](#alerting-roles) |
|
||||
| `fixed:alerting.notifications:reader` | `alert.notifications:read` for organization scope<br>`alert.notifications.external:read` for scope `datasources:*` | Read all Grafana and Alertmanager contact points, templates, and notification policies.[\*](#alerting-roles) |
|
||||
| `fixed:alerting.rules:editor` | All permissions from `fixed:alerting.rules:reader` and <br> `alert.rule:create` <br> `alert.rule:update` <br> `alert.rule:delete` for scope `folders:*` <br> `alert.rules.external:write` for scope `datasources:*` | Create, update, and delete all\* Grafana, Mimir, and Loki alert rules.[\*](#alerting-roles) |
|
||||
| `fixed:alerting.rules:reader` | `alert.rule:read` for scope `folders:*` <br> `alert.rules.external:read` for scope `datasources:*` | Read all\* Grafana, Mimir, and Loki alert rules.[\*](#alerting-roles) |
|
||||
| `fixed:alerting:editor` | All permissions from `fixed:alerting.rules:editor` <br>`fixed:alerting.instances:editor`<br>`fixed:alerting.notifications:editor` | Create, update, and delete Grafana, Mimir, Loki and Alertmanager alert rules\*, silences, contact points, templates, mute timings, and notification policies.[\*](#alerting-roles) |
|
||||
| `fixed:alerting:reader` | All permissions from `fixed:alerting.rules:reader` <br>`fixed:alerting.instances:reader`<br>`fixed:alerting.notifications:reader` | Read-only permissions for all Grafana, Mimir, Loki and Alertmanager alert rules\*, alerts, contact points, and notification policies.[\*](#alerting-roles) |
|
||||
| `fixed:annotations.dashboard:writer` | `annotations:write` <br>`annotations.create`<br> `annotations:delete` for scope `annotations:type:dashboard` | Create, update and delete dashboard annotations and annotation tags. |
|
||||
| `fixed:annotations:reader` | `annotations:read` for scopes `annotations:type:*` | Read all annotations and annotation tags. |
|
||||
| `fixed:annotations:writer` | All permissions from `fixed:annotations:reader` <br>`annotations:write` <br>`annotations.create`<br> `annotations:delete` for scope `annotations:type:*` | Read, create, update and delete all annotations and annotation tags. |
|
||||
| `fixed:apikeys:reader` | `apikeys:read` for scope `apikeys:*` | Read all api keys. |
|
||||
| `fixed:apikeys:writer` | All permissions from `fixed:apikeys:reader` and <br> `apikeys:create` <br> `apikeys:delete` for scope `apikeys:*` | Read, create, delete all api keys. |
|
||||
| `fixed:dashboards.permissions:reader` | `dashboards.permissions:read` | Read all dashboard permissions. |
|
||||
| `fixed:dashboards.permissions:writer` | All permissions from `fixed:dashboards.permissions:reader` and <br>`dashboards.permissions:write` | Read and update all dashboard permissions. |
|
||||
| `fixed:dashboards:creator` | `dashboards:create`<br>`folders:read` | Create dashboards. |
|
||||
| `fixed:dashboards:reader` | `dashboards:read` | Read all dashboards. |
|
||||
| `fixed:dashboards:writer` | All permissions from `fixed:dashboards:reader` and <br>`dashboards:write`<br>`dashboards:edit`<br>`dashboards:delete`<br>`dashboards:create`<br>`dashboards.permissions:read`<br>`dashboards.permissions:write` | Read, create, update, and delete all dashboards. |
|
||||
| `fixed:datasources.permissions:reader` | `datasources.permissions:read` | Read data source permissions. |
|
||||
| `fixed:datasources.permissions:writer` | All permissions from `fixed:datasources.permissions:reader` and <br>`datasources.permissions:write` | Create, read, or delete permissions of a data source. |
|
||||
| `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:id:reader` | `datasources.id:read` | Read the ID of a data source based on its name. |
|
||||
| `fixed:datasources:reader` | `datasources:read`<br>`datasources:query` | Read and query data sources. |
|
||||
| `fixed:datasources:writer` | All permissions from `fixed:datasources:reader` and <br>`datasources:create`<br>`datasources:write`<br>`datasources:delete` | Read, query, create, delete, or update a data source. |
|
||||
| `fixed:folders.permissions:reader` | `folders.permissions:read` | Read all folder permissions. |
|
||||
| `fixed:folders.permissions:writer` | All permissions from `fixed:folders.permissions:reader` and <br>`folders.permissions:write` | Read and update all folder permissions. |
|
||||
| `fixed:folders:creator` | `folders:create` | Create folders. |
|
||||
| `fixed:folders:reader` | `folders:read`<br>`dashboards:read` | Read all folders and dashboards. |
|
||||
| `fixed:folders:writer` | All permissions from `fixed:dashboards:writer` and <br>`folders:read`<br>`folders:write`<br>`folders:create`<br>`folders:delete`<br>`folders.permissions:read`<br>`folders.permissions:write` | Read, create, update, and delete all folders and dashboards. |
|
||||
| `fixed:ldap:reader` | `ldap.user:read`<br>`ldap.status:read` | Read the LDAP configuration and LDAP status information. |
|
||||
| `fixed:ldap:writer` | All permissions from `fixed:ldap:reader` and <br>`ldap.user:sync`<br>`ldap.config:reload` | Read and update the LDAP configuration, and read LDAP status information. |
|
||||
| `fixed:licensing:reader` | `licensing:read`<br>`licensing.reports:read` | Read licensing information and licensing reports. |
|
||||
| `fixed:licensing:writer` | All permissions from `fixed:licensing:viewer` and <br>`licensing:update`<br>`licensing:delete` | Read licensing information and licensing reports, update and delete the license token. |
|
||||
| `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 <br>`org.users:add`<br>`org.users:remove`<br>`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:organization:maintainer` | All permissions from `fixed:organization:reader` and <br> `orgs:write`<br>`orgs:create`<br>`orgs:delete`<br>`orgs.quotas:write` | Create, read, write, or delete an organization. Read or write its quotas. This role needs to be assigned globally. |
|
||||
| `fixed:organization:reader` | `orgs:read`<br>`orgs.quotas:read` | Read an organization and its quotas. |
|
||||
| `fixed:organization:writer` | All permissions from `fixed:organization:reader` and <br> `orgs:write`<br>`orgs.preferences:read`<br>`orgs.preferences:write` | Read an organization, its quotas, or its preferences. Update organization properties, or its preferences. |
|
||||
| `fixed:provisioning:writer` | `provisioning:reload` | Reload provisioning. |
|
||||
| `fixed:reports:reader` | `reports:read`<br>`reports:send`<br>`reports.settings:read` | Read all reports and shared report settings. |
|
||||
| `fixed:reports:writer` | All permissions from `fixed:reports:reader` and <br>`reports.admin:write`<br>`reports:delete`<br>`reports.settings:write` | Create, read, update, or delete all reports and shared report settings. |
|
||||
| `fixed:roles:reader` | `roles:read`<br>`roles:list`<br>`teams.roles:list`<br>`users.roles:list`<br>`users.permissions:list` | Read all access control roles, roles and permissions assigned to users, teams. |
|
||||
| `fixed:roles:writer` | All permissions from `fixed:roles:reader` and <br>`roles:write`<br>`roles:delete`<br>`teams.roles:add`<br>`teams.roles:remove`<br>`users.roles:add`<br>`users.roles:remove` | Create, read, update, or delete all roles, assign or unassign roles to users, teams. |
|
||||
| `fixed:roles:resetter` | `roles:write` with scope `permissions:type:escalate` | Reset basic roles to their default. |
|
||||
| `fixed:settings:reader` | `settings:read` | Read Grafana instance settings. |
|
||||
| `fixed:settings:writer` | All permissions from `fixed:settings:reader` and<br>`settings:write` | Read and update Grafana instance settings. |
|
||||
| `fixed:stats:reader` | `server.stats:read` | Read Grafana instance statistics. |
|
||||
| `fixed:teams:creator` | `teams:create`<br>`org.users:read` | Create a team and list organization users (required to manage the created team). |
|
||||
| `fixed:teams:writer` | `teams:create`<br>`teams:delete`<br>`teams:read`<br>`teams:write`<br>`teams.permissions:read`<br>`teams.permissions:write` | Create, read, update and delete teams and manage team memberships. |
|
||||
| `fixed:users:reader` | `users:read`<br>`users.quotas:list`<br>`users.authtoken:list`<br>`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 <br>`users:write`<br>`users:create`<br>`users:delete`<br>`users:enable`<br>`users:disable`<br>`users.password:update`<br>`users.permissions:update`<br>`users:logout`<br>`users.authtoken:update`<br>`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 role | Permissions | Description |
|
||||
| -------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `fixed:alerting.instances:editor` | All permissions from `fixed:alerting.instances:reader` and<br> `alert.instances:create`<br>`alert.instances:write` for organization scope <br> `alert.instances.external:write` for scope `datasources:*` | Create, update and expire all silences in the organization produced by Grafana, Mimir, and Loki.[\*](#alerting-roles) |
|
||||
| `fixed:alerting.instances:reader` | `alert.instances:read` for organization scope <br> `alert.instances.external:read` for scope `datasources:*` | Read all alerts and silences in the organization produced by Grafana Alerts and Mimir and Loki alerts and silences.[\*](#alerting-roles) |
|
||||
| `fixed:alerting.notifications:editor` | All permissions from `fixed:alerting.notifications:reader` and<br>`alert.notifications:write`for organization scope<br>`alert.notifications.external:read` for scope `datasources:*` | Create, update, and delete contact points, templates, mute timings and notification policies for Grafana and external Alertmanager.[\*](#alerting-roles) |
|
||||
| `fixed:alerting.notifications:reader` | `alert.notifications:read` for organization scope<br>`alert.notifications.external:read` for scope `datasources:*` | Read all Grafana and Alertmanager contact points, templates, and notification policies.[\*](#alerting-roles) |
|
||||
| `fixed:alerting.rules:editor` | All permissions from `fixed:alerting.rules:reader` and <br> `alert.rule:create` <br> `alert.rule:update` <br> `alert.rule:delete` for scope `folders:*` <br> `alert.rules.external:write` for scope `datasources:*` | Create, update, and delete all\* Grafana, Mimir, and Loki alert rules.[\*](#alerting-roles) |
|
||||
| `fixed:alerting.rules:reader` | `alert.rule:read` for scope `folders:*` <br> `alert.rules.external:read` for scope `datasources:*` | Read all\* Grafana, Mimir, and Loki alert rules.[\*](#alerting-roles) |
|
||||
| `fixed:alerting:editor` | All permissions from `fixed:alerting.rules:editor` <br>`fixed:alerting.instances:editor`<br>`fixed:alerting.notifications:editor` | Create, update, and delete Grafana, Mimir, Loki and Alertmanager alert rules\*, silences, contact points, templates, mute timings, and notification policies.[\*](#alerting-roles) |
|
||||
| `fixed:alerting:reader` | All permissions from `fixed:alerting.rules:reader` <br>`fixed:alerting.instances:reader`<br>`fixed:alerting.notifications:reader` | Read-only permissions for all Grafana, Mimir, Loki and Alertmanager alert rules\*, alerts, contact points, and notification policies.[\*](#alerting-roles) |
|
||||
| `fixed:annotations.dashboard:writer` | `annotations:write` <br>`annotations.create`<br> `annotations:delete` for scope `annotations:type:dashboard` | Create, update and delete dashboard annotations and annotation tags. |
|
||||
| `fixed:annotations:reader` | `annotations:read` for scopes `annotations:type:*` | Read all annotations and annotation tags. |
|
||||
| `fixed:annotations:writer` | All permissions from `fixed:annotations:reader` <br>`annotations:write` <br>`annotations.create`<br> `annotations:delete` for scope `annotations:type:*` | Read, create, update and delete all annotations and annotation tags. |
|
||||
| `fixed:apikeys:reader` | `apikeys:read` for scope `apikeys:*` | Read all api keys. |
|
||||
| `fixed:apikeys:writer` | All permissions from `fixed:apikeys:reader` and <br> `apikeys:create` <br> `apikeys:delete` for scope `apikeys:*` | Read, create, delete all api keys. |
|
||||
| `fixed:dashboards.permissions:reader` | `dashboards.permissions:read` | Read all dashboard permissions. |
|
||||
| `fixed:dashboards.permissions:writer` | All permissions from `fixed:dashboards.permissions:reader` and <br>`dashboards.permissions:write` | Read and update all dashboard permissions. |
|
||||
| `fixed:dashboards:creator` | `dashboards:create`<br>`folders:read` | Create dashboards. |
|
||||
| `fixed:dashboards:reader` | `dashboards:read` | Read all dashboards. |
|
||||
| `fixed:dashboards:writer` | All permissions from `fixed:dashboards:reader` and <br>`dashboards:write`<br>`dashboards:edit`<br>`dashboards:delete`<br>`dashboards:create`<br>`dashboards.permissions:read`<br>`dashboards.permissions:write` | Read, create, update, and delete all dashboards. |
|
||||
| `fixed:datasources.permissions:reader` | `datasources.permissions:read` | Read data source permissions. |
|
||||
| `fixed:datasources.permissions:writer` | All permissions from `fixed:datasources.permissions:reader` and <br>`datasources.permissions:write` | Create, read, or delete permissions of a data source. |
|
||||
| `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:id:reader` | `datasources.id:read` | Read the ID of a data source based on its name. |
|
||||
| `fixed:datasources:reader` | `datasources:read`<br>`datasources:query` | Read and query data sources. |
|
||||
| `fixed:datasources:writer` | All permissions from `fixed:datasources:reader` and <br>`datasources:create`<br>`datasources:write`<br>`datasources:delete` | Read, query, create, delete, or update a data source. |
|
||||
| `fixed:folders.permissions:reader` | `folders.permissions:read` | Read all folder permissions. |
|
||||
| `fixed:folders.permissions:writer` | All permissions from `fixed:folders.permissions:reader` and <br>`folders.permissions:write` | Read and update all folder permissions. |
|
||||
| `fixed:folders:creator` | `folders:create` | Create folders. |
|
||||
| `fixed:folders:reader` | `folders:read`<br>`dashboards:read` | Read all folders and dashboards. |
|
||||
| `fixed:folders:writer` | All permissions from `fixed:dashboards:writer` and <br>`folders:read`<br>`folders:write`<br>`folders:create`<br>`folders:delete`<br>`folders.permissions:read`<br>`folders.permissions:write` | Read, create, update, and delete all folders and dashboards. |
|
||||
| `fixed:ldap:reader` | `ldap.user:read`<br>`ldap.status:read` | Read the LDAP configuration and LDAP status information. |
|
||||
| `fixed:ldap:writer` | All permissions from `fixed:ldap:reader` and <br>`ldap.user:sync`<br>`ldap.config:reload` | Read and update the LDAP configuration, and read LDAP status information. |
|
||||
| `fixed:licensing:reader` | `licensing:read`<br>`licensing.reports:read` | Read licensing information and licensing reports. |
|
||||
| `fixed:licensing:writer` | All permissions from `fixed:licensing:viewer` and <br>`licensing:write`<br>`licensing:delete` | Read licensing information and licensing reports, update and delete the license token. |
|
||||
| `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 <br>`org.users:add`<br>`org.users:remove`<br>`org.users:write` | 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:organization:maintainer` | All permissions from `fixed:organization:reader` and <br> `orgs:write`<br>`orgs:create`<br>`orgs:delete`<br>`orgs.quotas:write` | Create, read, write, or delete an organization. Read or write its quotas. This role needs to be assigned globally. |
|
||||
| `fixed:organization:reader` | `orgs:read`<br>`orgs.quotas:read` | Read an organization and its quotas. |
|
||||
| `fixed:organization:writer` | All permissions from `fixed:organization:reader` and <br> `orgs:write`<br>`orgs.preferences:read`<br>`orgs.preferences:write` | Read an organization, its quotas, or its preferences. Update organization properties, or its preferences. |
|
||||
| `fixed:provisioning:writer` | `provisioning:reload` | Reload provisioning. |
|
||||
| `fixed:reports:reader` | `reports:read`<br>`reports:send`<br>`reports.settings:read` | Read all reports and shared report settings. |
|
||||
| `fixed:reports:writer` | All permissions from `fixed:reports:reader` and <br>`reports:create`<br>`reports:write`<br>`reports:delete`<br>`reports.settings:write` | Create, read, update, or delete all reports and shared report settings. |
|
||||
| `fixed:roles:reader` | `roles:read`<br>`teams.roles:read`<br>`users.roles:read`<br>`users.permissions:read` | Read all access control roles, roles and permissions assigned to users, teams. |
|
||||
| `fixed:roles:writer` | All permissions from `fixed:roles:reader` and <br>`roles:write`<br>`roles:delete`<br>`teams.roles:add`<br>`teams.roles:remove`<br>`users.roles:add`<br>`users.roles:remove` | Create, read, update, or delete all roles, assign or unassign roles to users, teams. |
|
||||
| `fixed:roles:resetter` | `roles:write` with scope `permissions:type:escalate` | Reset basic roles to their default. |
|
||||
| `fixed:settings:reader` | `settings:read` | Read Grafana instance settings. |
|
||||
| `fixed:settings:writer` | All permissions from `fixed:settings:reader` and<br>`settings:write` | Read and update Grafana instance settings. |
|
||||
| `fixed:stats:reader` | `server.stats:read` | Read Grafana instance statistics. |
|
||||
| `fixed:teams:creator` | `teams:create`<br>`org.users:read` | Create a team and list organization users (required to manage the created team). |
|
||||
| `fixed:teams:writer` | `teams:create`<br>`teams:delete`<br>`teams:read`<br>`teams:write`<br>`teams.permissions:read`<br>`teams.permissions:write` | Create, read, update and delete teams and manage team memberships. |
|
||||
| `fixed:users:reader` | `users:read`<br>`users.quotas:read`<br>`users.authtoken:read`<br>` | Read all users and their information, such as team memberships, authentication tokens, and quotas. |
|
||||
| `fixed:users:writer` | All permissions from `fixed:users:reader` and <br>`users:write`<br>`users:create`<br>`users:delete`<br>`users:enable`<br>`users:disable`<br>`users.password:write`<br>`users.permissions:write`<br>`users:logout`<br>`users.authtoken:write`<br>`users.quotas:write` | 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. |
|
||||
|
||||
### Alerting roles
|
||||
|
||||
|
||||
@@ -179,7 +179,7 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
usersRoute.Get("/", authorize(reqGrafanaAdmin, ac.EvalPermission(ac.ActionUsersRead)), routing.Wrap(hs.searchUsersService.SearchUsers))
|
||||
usersRoute.Get("/search", authorize(reqGrafanaAdmin, ac.EvalPermission(ac.ActionUsersRead)), routing.Wrap(hs.searchUsersService.SearchUsersWithPaging))
|
||||
usersRoute.Get("/:id", authorize(reqGrafanaAdmin, ac.EvalPermission(ac.ActionUsersRead, userIDScope)), routing.Wrap(hs.GetUserByID))
|
||||
usersRoute.Get("/:id/teams", authorize(reqGrafanaAdmin, ac.EvalPermission(ac.ActionUsersTeamRead, userIDScope)), routing.Wrap(hs.GetUserTeams))
|
||||
usersRoute.Get("/:id/teams", authorize(reqGrafanaAdmin, ac.EvalPermission(ac.ActionUsersRead, userIDScope)), routing.Wrap(hs.GetUserTeams))
|
||||
usersRoute.Get("/:id/orgs", authorize(reqGrafanaAdmin, ac.EvalPermission(ac.ActionUsersRead, userIDScope)), routing.Wrap(hs.GetUserOrgList))
|
||||
// query parameters /users/lookup?loginOrEmail=admin@example.com
|
||||
usersRoute.Get("/lookup", authorize(reqGrafanaAdmin, ac.EvalPermission(ac.ActionUsersRead, ac.ScopeGlobalUsersAll)), routing.Wrap(hs.GetUserByLoginOrEmail))
|
||||
@@ -233,7 +233,7 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
orgRoute.Get("/users", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgUsersRead)), routing.Wrap(hs.GetOrgUsersForCurrentOrg))
|
||||
orgRoute.Get("/users/search", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgUsersRead)), routing.Wrap(hs.SearchOrgUsersWithPaging))
|
||||
orgRoute.Post("/users", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgUsersAdd, ac.ScopeUsersAll)), quota("user"), routing.Wrap(hs.AddOrgUserToCurrentOrg))
|
||||
orgRoute.Patch("/users/:userId", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgUsersRoleUpdate, userIDScope)), routing.Wrap(hs.UpdateOrgUserForCurrentOrg))
|
||||
orgRoute.Patch("/users/:userId", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgUsersWrite, userIDScope)), routing.Wrap(hs.UpdateOrgUserForCurrentOrg))
|
||||
orgRoute.Delete("/users/:userId", authorize(reqOrgAdmin, ac.EvalPermission(ac.ActionOrgUsersRemove, userIDScope)), routing.Wrap(hs.RemoveOrgUserForCurrentOrg))
|
||||
|
||||
// invites
|
||||
@@ -279,7 +279,7 @@ func (hs *HTTPServer) registerRoutes() {
|
||||
orgsRoute.Delete("/", authorizeInOrg(reqGrafanaAdmin, ac.UseOrgFromContextParams, ac.EvalPermission(ActionOrgsDelete)), routing.Wrap(hs.DeleteOrgByID))
|
||||
orgsRoute.Get("/users", authorizeInOrg(reqGrafanaAdmin, ac.UseOrgFromContextParams, ac.EvalPermission(ac.ActionOrgUsersRead)), routing.Wrap(hs.GetOrgUsers))
|
||||
orgsRoute.Post("/users", authorizeInOrg(reqGrafanaAdmin, ac.UseOrgFromContextParams, ac.EvalPermission(ac.ActionOrgUsersAdd, ac.ScopeUsersAll)), routing.Wrap(hs.AddOrgUser))
|
||||
orgsRoute.Patch("/users/:userId", authorizeInOrg(reqGrafanaAdmin, ac.UseOrgFromContextParams, ac.EvalPermission(ac.ActionOrgUsersRoleUpdate, userIDScope)), routing.Wrap(hs.UpdateOrgUser))
|
||||
orgsRoute.Patch("/users/:userId", authorizeInOrg(reqGrafanaAdmin, ac.UseOrgFromContextParams, ac.EvalPermission(ac.ActionOrgUsersWrite, userIDScope)), routing.Wrap(hs.UpdateOrgUser))
|
||||
orgsRoute.Delete("/users/:userId", authorizeInOrg(reqGrafanaAdmin, ac.UseOrgFromContextParams, ac.EvalPermission(ac.ActionOrgUsersRemove, userIDScope)), routing.Wrap(hs.RemoveOrgUser))
|
||||
orgsRoute.Get("/quotas", authorizeInOrg(reqGrafanaAdmin, ac.UseOrgFromContextParams, ac.EvalPermission(ActionOrgsQuotasRead)), routing.Wrap(hs.GetOrgQuotas))
|
||||
orgsRoute.Put("/quotas/:target", authorizeInOrg(reqGrafanaAdmin, ac.UseOrgFromContextParams, ac.EvalPermission(ActionOrgsQuotasWrite)), routing.Wrap(hs.UpdateOrgQuota))
|
||||
|
||||
@@ -325,10 +325,10 @@ func TestGetOrgUsersAPIEndpoint_AccessControlMetadata(t *testing.T) {
|
||||
enableAccessControl: true,
|
||||
expectedCode: http.StatusOK,
|
||||
expectedMetadata: map[string]bool{
|
||||
"org.users.role:update": true,
|
||||
"org.users:add": true,
|
||||
"org.users:read": true,
|
||||
"org.users:remove": true},
|
||||
"org.users:write": true,
|
||||
"org.users:add": true,
|
||||
"org.users:read": true,
|
||||
"org.users:remove": true},
|
||||
user: testServerAdminViewer,
|
||||
targetOrg: testServerAdminViewer.OrgId,
|
||||
},
|
||||
|
||||
@@ -154,7 +154,7 @@ func (hs *HTTPServer) GetSignedInUserOrgList(c *models.ReqContext) response.Resp
|
||||
|
||||
// GET /api/user/teams
|
||||
func (hs *HTTPServer) GetSignedInUserTeamList(c *models.ReqContext) response.Response {
|
||||
return hs.getUserTeamList(c.Req.Context(), c.OrgId, c.UserId)
|
||||
return hs.getUserTeamList(c, c.OrgId, c.UserId)
|
||||
}
|
||||
|
||||
// GET /api/users/:id/teams
|
||||
@@ -163,13 +163,13 @@ func (hs *HTTPServer) GetUserTeams(c *models.ReqContext) response.Response {
|
||||
if err != nil {
|
||||
return response.Error(http.StatusBadRequest, "id is invalid", err)
|
||||
}
|
||||
return hs.getUserTeamList(c.Req.Context(), c.OrgId, id)
|
||||
return hs.getUserTeamList(c, c.OrgId, id)
|
||||
}
|
||||
|
||||
func (hs *HTTPServer) getUserTeamList(ctx context.Context, orgID int64, userID int64) response.Response {
|
||||
query := models.GetTeamsByUserQuery{OrgId: orgID, UserId: userID}
|
||||
func (hs *HTTPServer) getUserTeamList(c *models.ReqContext, orgID int64, userID int64) response.Response {
|
||||
query := models.GetTeamsByUserQuery{OrgId: orgID, UserId: userID, SignedInUser: c.SignedInUser}
|
||||
|
||||
if err := hs.SQLStore.GetTeamsByUser(ctx, &query); err != nil {
|
||||
if err := hs.SQLStore.GetTeamsByUser(c.Req.Context(), &query); err != nil {
|
||||
return response.Error(500, "Failed to get user teams", err)
|
||||
}
|
||||
|
||||
|
||||
@@ -62,9 +62,10 @@ type GetTeamByIdQuery struct {
|
||||
const FilterIgnoreUser int64 = 0
|
||||
|
||||
type GetTeamsByUserQuery struct {
|
||||
OrgId int64
|
||||
UserId int64 `json:"userId"`
|
||||
Result []*TeamDTO `json:"teams"`
|
||||
OrgId int64
|
||||
UserId int64 `json:"userId"`
|
||||
Result []*TeamDTO `json:"teams"`
|
||||
SignedInUser *SignedInUser
|
||||
}
|
||||
|
||||
type SearchTeamsQuery struct {
|
||||
|
||||
@@ -11,7 +11,7 @@ import (
|
||||
var sqlIDAcceptList = map[string]struct{}{
|
||||
"id": {},
|
||||
"org_user.user_id": {},
|
||||
"role.id": {},
|
||||
"role.uid": {},
|
||||
"t.id": {},
|
||||
"team.id": {},
|
||||
"u.id": {},
|
||||
|
||||
@@ -285,32 +285,31 @@ const (
|
||||
ActionAPIKeyDelete = "apikeys:delete"
|
||||
|
||||
// Users actions
|
||||
ActionUsersRead = "users:read"
|
||||
ActionUsersWrite = "users:write"
|
||||
ActionUsersTeamRead = "users.teams:read"
|
||||
ActionUsersRead = "users:read"
|
||||
ActionUsersWrite = "users:write"
|
||||
// We can ignore gosec G101 since this does not contain any credentials.
|
||||
// nolint:gosec
|
||||
ActionUsersAuthTokenList = "users.authtoken:list"
|
||||
ActionUsersAuthTokenList = "users.authtoken:read"
|
||||
// We can ignore gosec G101 since this does not contain any credentials.
|
||||
// nolint:gosec
|
||||
ActionUsersAuthTokenUpdate = "users.authtoken:update"
|
||||
ActionUsersAuthTokenUpdate = "users.authtoken:write"
|
||||
// We can ignore gosec G101 since this does not contain any credentials.
|
||||
// nolint:gosec
|
||||
ActionUsersPasswordUpdate = "users.password:update"
|
||||
ActionUsersPasswordUpdate = "users.password:write"
|
||||
ActionUsersDelete = "users:delete"
|
||||
ActionUsersCreate = "users:create"
|
||||
ActionUsersEnable = "users:enable"
|
||||
ActionUsersDisable = "users:disable"
|
||||
ActionUsersPermissionsUpdate = "users.permissions:update"
|
||||
ActionUsersPermissionsUpdate = "users.permissions:write"
|
||||
ActionUsersLogout = "users:logout"
|
||||
ActionUsersQuotasList = "users.quotas:list"
|
||||
ActionUsersQuotasUpdate = "users.quotas:update"
|
||||
ActionUsersQuotasList = "users.quotas:read"
|
||||
ActionUsersQuotasUpdate = "users.quotas:write"
|
||||
|
||||
// Org actions
|
||||
ActionOrgUsersRead = "org.users:read"
|
||||
ActionOrgUsersAdd = "org.users:add"
|
||||
ActionOrgUsersRemove = "org.users:remove"
|
||||
ActionOrgUsersRoleUpdate = "org.users.role:update"
|
||||
ActionOrgUsersRead = "org.users:read"
|
||||
ActionOrgUsersAdd = "org.users:add"
|
||||
ActionOrgUsersRemove = "org.users:remove"
|
||||
ActionOrgUsersWrite = "org.users:write"
|
||||
|
||||
// LDAP actions
|
||||
ActionLDAPUsersRead = "ldap.user:read"
|
||||
@@ -363,12 +362,12 @@ const (
|
||||
// Alerting rules actions
|
||||
ActionAlertingRuleCreate = "alert.rules:create"
|
||||
ActionAlertingRuleRead = "alert.rules:read"
|
||||
ActionAlertingRuleUpdate = "alert.rules:update"
|
||||
ActionAlertingRuleUpdate = "alert.rules:write"
|
||||
ActionAlertingRuleDelete = "alert.rules:delete"
|
||||
|
||||
// Alerting instances (+silences) actions
|
||||
ActionAlertingInstanceCreate = "alert.instances:create"
|
||||
ActionAlertingInstanceUpdate = "alert.instances:update"
|
||||
ActionAlertingInstanceUpdate = "alert.instances:write"
|
||||
ActionAlertingInstanceRead = "alert.instances:read"
|
||||
|
||||
// Alerting Notification policies actions
|
||||
|
||||
@@ -47,14 +47,14 @@ var (
|
||||
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.",
|
||||
Group: "User administration (organizational)",
|
||||
Version: 3,
|
||||
Version: 4,
|
||||
Permissions: ConcatPermissions(orgUsersReaderRole.Permissions, []Permission{
|
||||
{
|
||||
Action: ActionOrgUsersAdd,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionOrgUsersRoleUpdate,
|
||||
Action: ActionOrgUsersWrite,
|
||||
Scope: ScopeUsersAll,
|
||||
},
|
||||
{
|
||||
@@ -110,16 +110,12 @@ var (
|
||||
DisplayName: "User reader",
|
||||
Description: "Read all users and their information, such as team memberships, authentication tokens, and quotas.",
|
||||
Group: "User administration (global)",
|
||||
Version: 4,
|
||||
Version: 6,
|
||||
Permissions: []Permission{
|
||||
{
|
||||
Action: ActionUsersRead,
|
||||
Scope: ScopeGlobalUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersTeamRead,
|
||||
Scope: ScopeGlobalUsersAll,
|
||||
},
|
||||
{
|
||||
Action: ActionUsersAuthTokenList,
|
||||
Scope: ScopeGlobalUsersAll,
|
||||
@@ -136,7 +132,7 @@ var (
|
||||
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.",
|
||||
Group: "User administration (global)",
|
||||
Version: 4,
|
||||
Version: 5,
|
||||
Permissions: ConcatPermissions(usersReaderRole.Permissions, []Permission{
|
||||
{
|
||||
Action: ActionUsersPasswordUpdate,
|
||||
|
||||
@@ -273,7 +273,7 @@ func (g *dashboardGuardianImpl) getTeams() ([]*models.TeamDTO, error) {
|
||||
return g.teams, nil
|
||||
}
|
||||
|
||||
query := models.GetTeamsByUserQuery{OrgId: g.orgId, UserId: g.user.UserId}
|
||||
query := models.GetTeamsByUserQuery{OrgId: g.orgId, UserId: g.user.UserId, SignedInUser: g.user}
|
||||
err := g.store.GetTeamsByUser(g.ctx, &query)
|
||||
|
||||
g.teams = query.Result
|
||||
|
||||
@@ -4,7 +4,7 @@ import "github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
|
||||
const (
|
||||
ActionRead = "licensing:read"
|
||||
ActionUpdate = "licensing:update"
|
||||
ActionUpdate = "licensing:write"
|
||||
ActionDelete = "licensing:delete"
|
||||
ActionReportsRead = "licensing.reports:read"
|
||||
)
|
||||
|
||||
@@ -36,7 +36,7 @@ var (
|
||||
DisplayName: "Rules Editor",
|
||||
Description: "Can add, update, and delete rules in any Grafana folder and external providers",
|
||||
Group: AlertRolesGroup,
|
||||
Version: 2,
|
||||
Version: 3,
|
||||
Permissions: accesscontrol.ConcatPermissions(rulesReaderRole.Role.Permissions, []accesscontrol.Permission{
|
||||
{
|
||||
Action: accesscontrol.ActionAlertingRuleCreate,
|
||||
@@ -84,7 +84,7 @@ var (
|
||||
DisplayName: "Silences Editor",
|
||||
Description: "Can add and update silences in Grafana and external providers",
|
||||
Group: AlertRolesGroup,
|
||||
Version: 1,
|
||||
Version: 2,
|
||||
Permissions: accesscontrol.ConcatPermissions(instancesReaderRole.Role.Permissions, []accesscontrol.Permission{
|
||||
{
|
||||
Action: accesscontrol.ActionAlertingInstanceCreate,
|
||||
|
||||
@@ -209,25 +209,7 @@ func (s *ServiceAccountsStoreImpl) RetrieveServiceAccount(ctx context.Context, o
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Get Teams of service account. Can be optimized by combining with the query above
|
||||
// in refactor
|
||||
getTeamQuery := models.GetTeamsByUserQuery{UserId: serviceAccountID, OrgId: orgID}
|
||||
if err := s.sqlStore.GetTeamsByUser(ctx, &getTeamQuery); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
teams := make([]string, len(getTeamQuery.Result))
|
||||
|
||||
for i := range getTeamQuery.Result {
|
||||
teams[i] = getTeamQuery.Result[i].Name
|
||||
}
|
||||
|
||||
serviceAccount.Teams = teams
|
||||
|
||||
return serviceAccount, nil
|
||||
return serviceAccount, err
|
||||
}
|
||||
|
||||
func (s *ServiceAccountsStoreImpl) RetrieveServiceAccountIdByName(ctx context.Context, orgID int64, name string) (int64, error) {
|
||||
|
||||
@@ -4,7 +4,6 @@ import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
"github.com/grafana/grafana/pkg/services/serviceaccounts"
|
||||
"github.com/grafana/grafana/pkg/services/serviceaccounts/tests"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||
@@ -107,20 +106,3 @@ func TestStore_RetrieveServiceAccount(t *testing.T) {
|
||||
})
|
||||
}
|
||||
}
|
||||
func TestStore_RetrieveServiceAccountWithTeams(t *testing.T) {
|
||||
userToCreate := tests.TestUser{Login: "servicetestwithTeam@admin", IsServiceAccount: true}
|
||||
db, store := setupTestDatabase(t)
|
||||
user := tests.SetupUserServiceAccount(t, db, userToCreate)
|
||||
|
||||
team, err := store.sqlStore.CreateTeam("serviceTeam", "serviceTeam", user.OrgId)
|
||||
require.NoError(t, err)
|
||||
|
||||
err = store.sqlStore.AddTeamMember(user.Id, user.OrgId, team.Id, false, models.PERMISSION_VIEW)
|
||||
require.NoError(t, err)
|
||||
|
||||
dto, err := store.RetrieveServiceAccount(context.Background(), user.OrgId, user.Id)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, userToCreate.Login, dto.Login)
|
||||
require.Len(t, dto.Teams, 1)
|
||||
require.Equal(t, "serviceTeam", dto.Teams[0])
|
||||
}
|
||||
|
||||
@@ -0,0 +1,68 @@
|
||||
package accesscontrol
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/grafana/grafana/pkg/services/accesscontrol"
|
||||
"github.com/grafana/grafana/pkg/services/sqlstore/migrator"
|
||||
|
||||
"xorm.io/xorm"
|
||||
)
|
||||
|
||||
func AddActionNameMigrator(mg *migrator.Migrator) {
|
||||
mg.AddMigration("RBAC action name migrator", &actionNameMigrator{})
|
||||
}
|
||||
|
||||
type actionNameMigrator struct {
|
||||
sess *xorm.Session
|
||||
migrator *migrator.Migrator
|
||||
migrator.MigrationBase
|
||||
}
|
||||
|
||||
var _ migrator.CodeMigration = new(actionNameMigrator)
|
||||
|
||||
func (m *actionNameMigrator) SQL(migrator.Dialect) string {
|
||||
return CodeMigrationSQL
|
||||
}
|
||||
|
||||
func (m *actionNameMigrator) Exec(sess *xorm.Session, migrator *migrator.Migrator) error {
|
||||
m.sess = sess
|
||||
m.migrator = migrator
|
||||
return m.migrateActionNames()
|
||||
}
|
||||
|
||||
func (m *actionNameMigrator) migrateActionNames() error {
|
||||
actionNameMapping := map[string]string{
|
||||
"licensing:update": "licensing:write",
|
||||
"reports.admin:create": "reports:create",
|
||||
"reports.admin:write": "reports:write",
|
||||
"org.users.role:update": accesscontrol.ActionOrgUsersWrite,
|
||||
"users.authtoken:update": accesscontrol.ActionUsersAuthTokenUpdate,
|
||||
"users.password:update": accesscontrol.ActionUsersPasswordUpdate,
|
||||
"users.permissions:update": accesscontrol.ActionUsersPermissionsUpdate,
|
||||
"users.quotas:update": accesscontrol.ActionUsersQuotasUpdate,
|
||||
"teams.roles:list": "teams.roles:read",
|
||||
"users.roles:list": "users.roles:read",
|
||||
"users.authtoken:list": accesscontrol.ActionUsersAuthTokenList,
|
||||
"users.quotas:list": accesscontrol.ActionUsersQuotasList,
|
||||
"users.permissions:list": "users.permissions:read",
|
||||
"alert.instances:update": accesscontrol.ActionAlertingInstanceUpdate,
|
||||
"alert.rules:update": accesscontrol.ActionAlertingRuleUpdate,
|
||||
}
|
||||
for oldName, newName := range actionNameMapping {
|
||||
_, err := m.sess.Table(&accesscontrol.Permission{}).Where("action = ?", oldName).Update(&accesscontrol.Permission{Action: newName})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update permission table for action %s: %w", oldName, err)
|
||||
}
|
||||
}
|
||||
|
||||
actionsToDelete := []string{"users.teams:read", "roles:list"}
|
||||
for _, action := range actionsToDelete {
|
||||
_, err := m.sess.Table(&accesscontrol.Permission{}).Where("action = ?", action).Delete(accesscontrol.Permission{})
|
||||
if err != nil {
|
||||
return fmt.Errorf("failed to update permission table for action %s: %w", action, err)
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
@@ -90,6 +90,7 @@ func (*OSSMigrations) AddMigration(mg *Migrator) {
|
||||
|
||||
accesscontrol.AddManagedPermissionsMigration(mg)
|
||||
accesscontrol.AddManagedFolderAlertActionsMigration(mg)
|
||||
accesscontrol.AddActionNameMigrator(mg)
|
||||
}
|
||||
|
||||
func addMigrationLogMigrations(mg *Migrator) {
|
||||
|
||||
@@ -310,12 +310,23 @@ func (ss *SQLStore) GetTeamsByUser(ctx context.Context, query *models.GetTeamsBy
|
||||
query.Result = make([]*models.TeamDTO, 0)
|
||||
|
||||
var sql bytes.Buffer
|
||||
var params []interface{}
|
||||
params = append(params, query.OrgId, query.UserId)
|
||||
|
||||
sql.WriteString(getTeamSelectSQLBase([]string{}))
|
||||
sql.WriteString(` INNER JOIN team_member on team.id = team_member.team_id`)
|
||||
sql.WriteString(` WHERE team.org_id = ? and team_member.user_id = ?`)
|
||||
|
||||
err := sess.SQL(sql.String(), query.OrgId, query.UserId).Find(&query.Result)
|
||||
if !ac.IsDisabled(ss.Cfg) {
|
||||
acFilter, err := ac.Filter(query.SignedInUser, "team.id", "teams:id:", ac.ActionTeamsRead)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
sql.WriteString(` and` + acFilter.Where)
|
||||
params = append(params, acFilter.Args...)
|
||||
}
|
||||
|
||||
err := sess.SQL(sql.String(), params...).Find(&query.Result)
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
@@ -219,7 +219,14 @@ func TestIntegrationTeamCommandsAndQueries(t *testing.T) {
|
||||
err := sqlStore.AddTeamMember(userIds[0], testOrgID, groupId, false, 0)
|
||||
require.NoError(t, err)
|
||||
|
||||
query := &models.GetTeamsByUserQuery{OrgId: testOrgID, UserId: userIds[0]}
|
||||
query := &models.GetTeamsByUserQuery{
|
||||
OrgId: testOrgID,
|
||||
UserId: userIds[0],
|
||||
SignedInUser: &models.SignedInUser{
|
||||
OrgId: testOrgID,
|
||||
Permissions: map[int64]map[string][]string{testOrgID: {ac.ActionOrgUsersRead: {ac.ScopeUsersAll}, ac.ActionTeamsRead: {ac.ScopeTeamsAll}}},
|
||||
},
|
||||
}
|
||||
err = sqlStore.GetTeamsByUser(context.Background(), query)
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, len(query.Result), 1)
|
||||
|
||||
@@ -577,7 +577,20 @@ func (ss *SQLStore) GetSignedInUser(ctx context.Context, query *models.GetSigned
|
||||
user.ExternalAuthId = ""
|
||||
}
|
||||
|
||||
getTeamsByUserQuery := &models.GetTeamsByUserQuery{OrgId: user.OrgId, UserId: user.UserId}
|
||||
// tempUser is used to retrieve the teams for the signed in user for internal use.
|
||||
tempUser := &models.SignedInUser{
|
||||
OrgId: user.OrgId,
|
||||
Permissions: map[int64]map[string][]string{
|
||||
user.OrgId: {
|
||||
ac.ActionTeamsRead: {ac.ScopeTeamsAll},
|
||||
},
|
||||
},
|
||||
}
|
||||
getTeamsByUserQuery := &models.GetTeamsByUserQuery{
|
||||
OrgId: user.OrgId,
|
||||
UserId: user.UserId,
|
||||
SignedInUser: tempUser,
|
||||
}
|
||||
err = ss.GetTeamsByUser(ctx, getTeamsByUserQuery)
|
||||
if err != nil {
|
||||
return err
|
||||
|
||||
@@ -617,7 +617,7 @@ func TestRulerAccess(t *testing.T) {
|
||||
desc: "viewer request should fail",
|
||||
url: "http://viewer:viewer@%s/api/ruler/grafana/api/v1/rules/default",
|
||||
expStatus: http.StatusForbidden,
|
||||
expectedMessage: `You'll need additional permissions to perform this action. Permissions needed: any of alert.rules:update, alert.rules:create, alert.rules:delete`,
|
||||
expectedMessage: `You'll need additional permissions to perform this action. Permissions needed: any of alert.rules:write, alert.rules:create, alert.rules:delete`,
|
||||
},
|
||||
{
|
||||
desc: "editor request should succeed",
|
||||
|
||||
@@ -193,7 +193,7 @@ class UnThemedOrgRow extends PureComponent<OrgRowProps> {
|
||||
const { currentRole, isChangingRole } = this.state;
|
||||
const styles = getOrgRowStyles(theme);
|
||||
const labelClass = cx('width-16', styles.label);
|
||||
const canChangeRole = contextSrv.hasPermission(AccessControlAction.OrgUsersRoleUpdate);
|
||||
const canChangeRole = contextSrv.hasPermission(AccessControlAction.OrgUsersWrite);
|
||||
const canRemoveFromOrg = contextSrv.hasPermission(AccessControlAction.OrgUsersRemove);
|
||||
const rolePickerDisabled = isExternalUser || !canChangeRole;
|
||||
|
||||
@@ -328,7 +328,7 @@ export class AddToOrgModal extends PureComponent<AddToOrgModalProps, AddToOrgMod
|
||||
this.props.onOrgAdd(selectedOrg!.id, role);
|
||||
// add the stored userRoles also
|
||||
if (contextSrv.licensedAccessControlEnabled()) {
|
||||
if (contextSrv.hasPermission(AccessControlAction.OrgUsersRoleUpdate)) {
|
||||
if (contextSrv.hasPermission(AccessControlAction.OrgUsersWrite)) {
|
||||
if (this.state.pendingUserId) {
|
||||
await updateUserRoles(this.state.pendingRoles, this.state.pendingUserId!, this.state.pendingOrgId!);
|
||||
// clear pending state
|
||||
|
||||
@@ -40,7 +40,7 @@ const ServiceAccountListItem = memo(
|
||||
const displayRolePicker =
|
||||
contextSrv.hasPermission(AccessControlAction.ActionRolesList) &&
|
||||
contextSrv.hasPermission(AccessControlAction.ActionUserRolesList);
|
||||
const enableRolePicker = contextSrv.hasPermission(AccessControlAction.OrgUsersRoleUpdate) && canUpdateRole;
|
||||
const enableRolePicker = contextSrv.hasPermission(AccessControlAction.OrgUsersWrite) && canUpdateRole;
|
||||
|
||||
return (
|
||||
<tr key={serviceAccount.id} className={cx({ [styles.disabled]: serviceAccount.isDisabled })}>
|
||||
|
||||
@@ -94,13 +94,13 @@ const UsersTable: FC<Props> = (props) => {
|
||||
onBuiltinRoleChange={(newRole) => onRoleChange(newRole, user)}
|
||||
roleOptions={roleOptions}
|
||||
builtInRoles={builtinRoles}
|
||||
disabled={!contextSrv.hasPermissionInMetadata(AccessControlAction.OrgUsersRoleUpdate, user)}
|
||||
disabled={!contextSrv.hasPermissionInMetadata(AccessControlAction.OrgUsersWrite, user)}
|
||||
/>
|
||||
) : (
|
||||
<OrgRolePicker
|
||||
aria-label="Role"
|
||||
value={user.role}
|
||||
disabled={!contextSrv.hasPermissionInMetadata(AccessControlAction.OrgUsersRoleUpdate, user)}
|
||||
disabled={!contextSrv.hasPermissionInMetadata(AccessControlAction.OrgUsersWrite, user)}
|
||||
onChange={(newRole) => onRoleChange(newRole, user)}
|
||||
/>
|
||||
)}
|
||||
|
||||
@@ -10,18 +10,17 @@ export type UserPermission = Record<string, boolean>;
|
||||
export enum AccessControlAction {
|
||||
UsersRead = 'users:read',
|
||||
UsersWrite = 'users:write',
|
||||
UsersTeamRead = 'users.teams:read',
|
||||
UsersAuthTokenList = 'users.authtoken:list',
|
||||
UsersAuthTokenUpdate = 'users.authtoken:update',
|
||||
UsersPasswordUpdate = 'users.password:update',
|
||||
UsersAuthTokenList = 'users.authtoken:read',
|
||||
UsersAuthTokenUpdate = 'users.authtoken:write',
|
||||
UsersPasswordUpdate = 'users.password:write',
|
||||
UsersDelete = 'users:delete',
|
||||
UsersCreate = 'users:create',
|
||||
UsersEnable = 'users:enable',
|
||||
UsersDisable = 'users:disable',
|
||||
UsersPermissionsUpdate = 'users.permissions:update',
|
||||
UsersPermissionsUpdate = 'users.permissions:write',
|
||||
UsersLogout = 'users:logout',
|
||||
UsersQuotasList = 'users.quotas:list',
|
||||
UsersQuotasUpdate = 'users.quotas:update',
|
||||
UsersQuotasList = 'users.quotas:read',
|
||||
UsersQuotasUpdate = 'users.quotas:write',
|
||||
|
||||
ServiceAccountsRead = 'serviceaccounts:read',
|
||||
ServiceAccountsCreate = 'serviceaccounts:create',
|
||||
@@ -37,7 +36,7 @@ export enum AccessControlAction {
|
||||
OrgUsersRead = 'org.users:read',
|
||||
OrgUsersAdd = 'org.users:add',
|
||||
OrgUsersRemove = 'org.users:remove',
|
||||
OrgUsersRoleUpdate = 'org.users.role:update',
|
||||
OrgUsersWrite = 'org.users:write',
|
||||
|
||||
LDAPUsersRead = 'ldap.user:read',
|
||||
LDAPUsersSync = 'ldap.user:sync',
|
||||
@@ -59,12 +58,12 @@ export enum AccessControlAction {
|
||||
ActionTeamsPermissionsRead = 'teams.permissions:read',
|
||||
ActionTeamsPermissionsWrite = 'teams.permissions:write',
|
||||
|
||||
ActionRolesList = 'roles:list',
|
||||
ActionRolesList = 'roles:read',
|
||||
ActionBuiltinRolesList = 'roles.builtin:list',
|
||||
ActionTeamsRolesList = 'teams.roles:list',
|
||||
ActionTeamsRolesList = 'teams.roles:read',
|
||||
ActionTeamsRolesAdd = 'teams.roles:add',
|
||||
ActionTeamsRolesRemove = 'teams.roles:remove',
|
||||
ActionUserRolesList = 'users.roles:list',
|
||||
ActionUserRolesList = 'users.roles:read',
|
||||
|
||||
DashboardsRead = 'dashboards:read',
|
||||
DashboardsWrite = 'dashboards:write',
|
||||
@@ -83,12 +82,12 @@ export enum AccessControlAction {
|
||||
// Alerting rules
|
||||
AlertingRuleCreate = 'alert.rules:create',
|
||||
AlertingRuleRead = 'alert.rules:read',
|
||||
AlertingRuleUpdate = 'alert.rules:update',
|
||||
AlertingRuleUpdate = 'alert.rules:write',
|
||||
AlertingRuleDelete = 'alert.rules:delete',
|
||||
|
||||
// Alerting instances (+silences)
|
||||
AlertingInstanceCreate = 'alert.instances:create',
|
||||
AlertingInstanceUpdate = 'alert.instances:update',
|
||||
AlertingInstanceUpdate = 'alert.instances:write',
|
||||
AlertingInstanceRead = 'alert.instances:read',
|
||||
|
||||
// Alerting Notification policies
|
||||
|
||||
Reference in New Issue
Block a user