tachybase_todo/docs/en-US/api/acl/acl.md

260 lines
6.3 KiB
Markdown
Raw Normal View History

# ACL
2023-02-17 19:15:30 +08:00
## Overview
2022-11-13 23:00:59 +08:00
2023-02-17 19:15:30 +08:00
ACL is the permission control module in NocoBase. After registering roles and resources in ACL and configuring corresponding permissions, you can authenticate permissions for roles.
2023-02-17 19:15:30 +08:00
### Basic Usage
2022-11-13 23:00:59 +08:00
```javascript
const { ACL } = require('@nocobase/acl');
const acl = new ACL();
2023-02-17 19:15:30 +08:00
// Define a role named member
2022-11-13 23:00:59 +08:00
const memberRole = acl.define({
role: 'member',
});
2023-02-17 19:15:30 +08:00
// Grant the role of member list permission of the posts resource
2022-11-13 23:00:59 +08:00
memberRole.grantAction('posts:list');
acl.can('member', 'posts:list'); // true
acl.can('member', 'posts:edit'); // null
```
2023-02-17 19:15:30 +08:00
### Concepts
2023-02-17 19:15:30 +08:00
* Role (`ACLRole`): Object that needs permission authentication.
* Resource (`ACLResource`)In NocoBase ACL, a resource usually corresponds to a database table; it is conceptually analogous to the Resource in Restful API.
* Action: Actions to be taken on resources, such as `create`, `read`, `update`, `delete`, etc.
* Strategy (`ACLAvailableStrategy`): Normally each role has its own permission strategy, which defines the default permissions of the role.
* Grant Action: Call the `grantAction` function in `ACLRole` instance to grant access to `Action` for the role.
* Authentication: Call the `can` function in `ACL` instance, and return the authentication result of the user.
2023-02-17 19:15:30 +08:00
## Class Methods
### `constructor()`
2023-02-17 19:15:30 +08:00
To create a `ACL` instance.
```typescript
import { ACL } from '@nocobase/database';
const acl = new ACL();
```
### `define()`
2023-02-17 19:15:30 +08:00
Define a ACL role.
**Signature**
* `define(options: DefineOptions): ACLRole`
2023-02-17 19:15:30 +08:00
**Type**
```typescript
interface DefineOptions {
role: string;
allowConfigure?: boolean;
strategy?: string | AvailableStrategyOptions;
actions?: ResourceActionsOptions;
routes?: any;
}
```
2023-02-17 19:15:30 +08:00
**Detailed Information**
2023-02-17 19:15:30 +08:00
* `role` - Name of the role
```typescript
2023-02-17 19:15:30 +08:00
// Define a role named admin
acl.define({
role: 'admin',
});
```
2023-02-17 19:15:30 +08:00
* `allowConfigure` - Whether to allow permission configuration
* `strategy` - Permission strategy of the role
* It can be a name of strategy in `string`, means to use a strategy that is already defined.
* Or `AvailableStrategyOptions` means to define a new strategy for this role, refer to [`setAvailableActions()`](#setavailableactions).
* `actions` - Pass in the `actions` objects accessible to the role when defining the role, then call `aclRole.grantAction` in turn to grant resource permissions. Refer to [`aclRole.grantAction`](./acl-role.md#grantaction) for details
```typescript
acl.define({
role: 'admin',
actions: {
'posts:edit': {}
},
});
2023-02-17 19:15:30 +08:00
// Equivalent to
const role = acl.define({
role: 'admin',
});
role.grantAction('posts:edit', {});
```
### `getRole()`
2023-02-17 19:15:30 +08:00
Get registered role objects by role name.
**Signature**
* `getRole(name: string): ACLRole`
### `removeRole()`
2023-02-17 19:15:30 +08:00
Remove role by role name.
**Signature**
* `removeRole(name: string)`
### `can()`
2023-02-17 19:15:30 +08:00
Authentication function.
**Signature**
* `can(options: CanArgs): CanResult | null`
2023-02-17 19:15:30 +08:00
**Type**
```typescript
interface CanArgs {
2023-02-17 19:15:30 +08:00
role: string; // Name of the role
resource: string; // Name of the resource
action: string; // Name of the action
}
interface CanResult {
2023-02-17 19:15:30 +08:00
role: string; // Name of the role
resource: string; // Name of the resource
action: string; // Name of the action
params?: any; // Parameters passed in when registering the permission
}
```
2023-02-17 19:15:30 +08:00
**Detailed Information**
2023-02-17 19:15:30 +08:00
The `can` method first checks if the role has the corresponding `Action` permission registered; if not, it checks if the `strategy` and the role matches. It means that the role has no permissions if it returns `null`; else it returns the `CanResult` object, which means that the role has permissions.
**Example**
```typescript
2023-02-17 19:15:30 +08:00
// Define role and register permissions
acl.define({
role: 'admin',
actions: {
'posts:edit': {
fields: ['title', 'content'],
},
},
});
const canResult = acl.can({
role: 'admin',
resource: 'posts',
action: 'edit',
});
/**
* canResult = {
* role: 'admin',
* resource: 'posts',
* action: 'edit',
* params: {
* fields: ['title', 'content'],
* }
* }
*/
acl.can({
role: 'admin',
resource: 'posts',
action: 'destroy',
}); // null
```
2023-02-17 19:15:30 +08:00
### `use()`
2023-02-17 19:15:30 +08:00
**Signature**
* `use(fn: any)`
2023-02-17 19:15:30 +08:00
Add middleware function into middlewares.
### `middleware()`
2023-02-17 19:15:30 +08:00
Return a middleware function to be used in `@nocobase/server`. After using this `middleware`, `@nocobase/server` will perform permission authentication before each request is processed.
### `allow()`
2023-02-17 19:15:30 +08:00
Set the resource as publicly accessible.
**Signature**
* `allow(resourceName: string, actionNames: string[] | string, condition?: string | ConditionFunc)`
2023-02-17 19:15:30 +08:00
**Type**
```typescript
type ConditionFunc = (ctx: any) => Promise<boolean> | boolean;
```
2023-02-17 19:15:30 +08:00
**Detailed Information**
2023-02-17 19:15:30 +08:00
* resourceName - Name of the resource
* actionNames - Name of the resource action
* condition? - Configuration of the validity condition
* Pass in a `string` to use a condition that is already defined; Use the `acl.allowManager.registerCondition` method to register a condition.
```typescript
acl.allowManager.registerAllowCondition('superUser', async () => {
return ctx.state.user?.id === 1;
});
2023-02-17 19:15:30 +08:00
// Open permissions of the users:list with validity condition superUser
acl.allow('users', 'list', 'superUser');
```
2023-02-17 19:15:30 +08:00
* Pass in ConditionFunc, which can take the `ctx` parameter; return `boolean` that indicate whether it is in effect.
```typescript
2023-02-17 19:15:30 +08:00
// user:list accessible to user with ID of 1
acl.allow('users', 'list', (ctx) => {
return ctx.state.user?.id === 1;
});
```
2023-02-17 19:15:30 +08:00
**Example**
```typescript
2023-02-17 19:15:30 +08:00
// Register users:login to be publicly accssible
acl.allow('users', 'login');
```
### `setAvailableActions()`
2023-02-17 19:15:30 +08:00
**Signature**
* `setAvailableStrategy(name: string, options: AvailableStrategyOptions)`
2023-02-17 19:15:30 +08:00
Register an available permission strategy.
2023-02-17 19:15:30 +08:00
**Type**
```typescript
interface AvailableStrategyOptions {
displayName?: string;
actions?: false | string | string[];
allowConfigure?: boolean;
resource?: '*';
}
```
2023-02-17 19:15:57 +08:00
**Detailed Information**
2023-02-17 19:15:30 +08:00
* displayName - Name of the strategy
* allowConfigure - Whether this strategy has permission of **resource configuration**; if set to `true`, the permission that requests to register as `configResources` resource in `ACL` will return pass
* actions - List of actions in the strategy, wildcard `*` is supported
* resource - Definition of resource in the strategy, wildcard `*` is supported