|
2 | 2 | title: "canAccessWithPermissions" |
3 | 3 | --- |
4 | 4 |
|
5 | | -**Tip**: `ra-core-ee` is part of the [React-Admin Enterprise Edition](https://marmelab.com/ra-enterprise/), and hosted in a private npm registry. You need to subscribe to one of the Enterprise Edition plans to access this package. |
| 5 | +`canAccessWithPermissions` is a helper function that facilitates the implementation of [Access Control](./Permissions.md#access-control) policies based on an underlying list of user roles and permissions. |
6 | 6 |
|
7 | | -`canAccessWithPermissions` is a helper function that facilitates the `authProvider.canAccess()` method implementation: |
| 7 | +It is a builder block to implement the `authProvider.canAccess()` method, which is called by ra-core to check whether the current user has the right to perform a given action on a given resource or record. |
| 8 | + |
| 9 | +This feature requires a valid [Enterprise Edition](https://marmelab.com/ra-enterprise/) subscription. |
| 10 | + |
| 11 | +## Installation |
| 12 | + |
| 13 | +```bash |
| 14 | +npm install --save @react-admin/ra-core-ee |
| 15 | +# or |
| 16 | +yarn add @react-admin/ra-core-ee |
| 17 | +``` |
8 | 18 |
|
9 | 19 | ## Usage |
10 | 20 |
|
11 | | -The user roles and permissions should be returned upon login. The `authProvider` should store the permissions in memory, or in localStorage. This allows `authProvider.canAccess()` to read the permissions from localStorage. |
| 21 | +`canAccessWithPermissions` is a pure function that you can call from your `authProvider.canAccess()` implementation. |
| 22 | + |
| 23 | +```tsx |
| 24 | +import { canAccessWithPermissions } from '@react-admin/ra-core-ee'; |
| 25 | + |
| 26 | +const authProvider = { |
| 27 | + // ... |
| 28 | + canAccess: async ({ action, resource, record }) => { |
| 29 | + const permissions = myGetPermissionsFunction(); |
| 30 | + return canAccessWithPermissions({ |
| 31 | + permissions, |
| 32 | + action, |
| 33 | + resource, |
| 34 | + record, |
| 35 | + }); |
| 36 | + } |
| 37 | + // ... |
| 38 | +}; |
| 39 | +``` |
| 40 | + |
| 41 | +The `permissions` parameter must be an array of permissions. A *permission* is an object that represents access to a subset of the application. It is defined by a `resource` (usually a noun) and an `action` (usually a verb), with sometimes an additional `record`. |
| 42 | + |
| 43 | +Here are a few examples of permissions: |
| 44 | + |
| 45 | +- `{ action: "*", resource: "*" }`: allow everything |
| 46 | +- `{ action: "read", resource: "*" }`: allow read actions on all resources |
| 47 | +- `{ action: "read", resource: ["companies", "people"] }`: allow read actions on a subset of resources |
| 48 | +- `{ action: ["read", "create", "edit", "export"], resource: "companies" }`: allow all actions except delete on companies |
| 49 | +- `{ action: ["write"], resource: "game.score", record: { "id": "123" } }`: allow write action on the score of the game with id 123 |
| 50 | + |
| 51 | +:::tip |
| 52 | +When the `record` field is omitted, the permission is valid for all records. |
| 53 | +::: |
| 54 | + |
| 55 | +In most cases, the permissions are derived from user roles, which are fetched at login and stored in memory or in localStorage. Check the [`getPermissionsFromRoles`](./getPermissionsFromRoles.md) function to merge the permissions from multiple roles into a single flat array of permissions. |
| 56 | + |
| 57 | +## Parameters |
| 58 | + |
| 59 | +This function takes an object as argument with the following fields: |
| 60 | + |
| 61 | +| Name | Optional | Type | Description |
| 62 | +| - | - | - | - | |
| 63 | +| `permissions` | Required | `Array<Permission>` | An array of permissions for the current user |
| 64 | +| `action` | Required | `string` | The action for which to check users has the execution right |
| 65 | +| `resource` | Required | `string` | The resource for which to check users has the execution right |
| 66 | +| `record` | Required | `string` | The record for which to check users has the execution right |
| 67 | + |
| 68 | +`canAccessWithPermissions` expects the `permissions` to be a flat array of permissions. It is your responsibility to fetch these permissions (usually during login). If the permissions are spread into several role definitions, you can merge them into a single array using the [`getPermissionsFromRoles`](#getpermissionsfromroles) function. |
| 69 | + |
| 70 | +## Building RBAC |
| 71 | + |
| 72 | +The following example shows how to implement Role-based Access Control (RBAC) in `authProvider.canAccess()` using `canAccessWithPermissions` and `getPermissionsFromRoles`. The role permissions are defined in the code, and the user roles are returned by the authentication endpoint. Additional user permissions can also be returned by the authentication endpoint. |
| 73 | + |
| 74 | +The `authProvider` stores the permissions in `localStorage`, so that returning users can access their permissions without having to log in again. |
12 | 75 |
|
13 | 76 | ```tsx |
14 | 77 | // in roleDefinitions.ts |
@@ -62,16 +125,3 @@ const authProvider = { |
62 | 125 | // ... |
63 | 126 | }; |
64 | 127 | ``` |
65 | | - |
66 | | -## Parameters |
67 | | - |
68 | | -This function takes an object as argument with the following fields: |
69 | | - |
70 | | -| Name | Optional | Type | Description |
71 | | -| - | - | - | - | |
72 | | -| `permissions` | Required | `Array<Permission>` | An array of permissions for the current user |
73 | | -| `action` | Required | `string` | The action for which to check users has the execution right |
74 | | -| `resource` | Required | `string` | The resource for which to check users has the execution right |
75 | | -| `record` | Required | `string` | The record for which to check users has the execution right |
76 | | - |
77 | | -`canAccessWithPermissions` expects the `permissions` to be a flat array of permissions. It is your responsibility to fetch these permissions (usually during login). If the permissions are spread into several role definitions, you can merge them into a single array using the [`getPermissionsFromRoles`](#getpermissionsfromroles) function. |
|
0 commit comments