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
refactor: new schema initializer and schema settings (#2802) * fix: form * refactor: schema-initializer * fix: bug * refactor: schema initializer * refactor: rename * fix: delete SchemaInitializerProvider * refactor: props `insert` to hooks `useSchemaInitializerV2` * fix: bug * refactor: delete `SchemaInitializer.Button` * refactor: delete old SchemaInitializer * fix: bug * fix: workflow * fix: docs * fix: bug * fix: bug * feat: style * fix: remove v2 * fix: visible * fix: bug * fix: item hook * feat: item hook * fix: add search DataBlockInitializer * fix: build bug * fix: style bug * fix: style bug * fix: test bug * fix: test bug * fix: rerender bug * fix: remove menu select * fix: bug * chore: add aria-label for SchemaInitializerButton * refactor: rename name to camel case * fix: menu height bug * fix: build errors * fix: build errors * fix: bug * fix: bug * fix: performance * test: add test for header * fix: sidebar is not refresh (T-2422) * feat(e2e): support to add group page and link page * chore: make sure the page is configurable when using page.goto * test: add tests for menu initializer * fix: imporve code * chore: fix build error * chore: optimize locator of menu item * refactor: rename testid for select * test: make tests passing * fix: make tests passing * chore: upgrade vitest to v0.34.6 * chore: increase timeout of e2e * feat: core * fix: revert schema initializer demos * test: menu, page tabs, page grid, table column * fix: schema button interface * feat: refactor: page tab settings * feat: page settings * fix: dumirc * fix: export CSSVariableProvider * feat: lazy render * fix: form-item * fix: general schema desinger * feat: filter form item settings * refactor: form-v2 schema settings * refactor: form-v1 schema settings * refactor: action schema settings * fix: action bug * fix: form-item bug * fix: types error * docs: schema settings doc * docs: schema settings * feat: schema setting item add name * fix: visible lazy render bug * fix: revert form item filter * fix: test bug * fix: test JSON.parse bug * fix: test bug * fix: improve styling * fix: styling * fix: cleanup * fix: token.borderRadiusSM * fix: bug * test: add tests * fix: style bug * fix: add chart performance * feat: add SchemaDesignerContext * fix: bug * fix: test bug * style: create record action style improve * fix: make test passing * chore: mack tests passing * chore: make tests passing * test: fix tests * style: style revert * fix: bug * fix: data selector * fix: fix tests * fix: fix tests * fix: delete PluginManagerContext * refactor: improve router and add SchemaComponentProvider & CSSVariableProvider to MainComponent * fix: add dn and field builtin to SchemaSettingWrapper * feat: update docs * refactor: application providers * fix: test bug * fix: fix tests * chore: make test passing * feat: update docs * chore: rename collection name * feat: update docs * chore: skip weird test * fix: blockInitializers media to otherBlocks * fix: cancel to skip test * fix: bug * test: add test * refactor: migrate to small files * test: add tests for form block settings * chore: format * fix: add chart scroll bug * refactor: action designer improve * refactor: formitem designer schemaSetting * feat: schemaSettingsManager and schemaInitializerManager addItem and removeItem * test: add tests for color field in creating block * test: add tests for email field in creating block * test: make tests passing * perf: reduce fields number * fix: sub menu bug * test: add tests basic in editing form * test: add tests basic in details form * fix: improve code * test: make tests passing * test(plugin-mock-collections): add color for enum options * refactor: improve code * fix: bug * fix: bug * refactor: convert parameters to destructured object * test: add tests choices * test: add tests media * test: add tests for datetime in creating form * feat(plugin-mock-collection): generate faker time * test: add tests for datetime in editing form * test: add tests for datetime in details form * fix: bug * feat: improve code * test: add tests for relation fields * fix: rename SchemaSettings * fix: type bug * refactor: useDesinger() * fix: bug * fix: bug * fix: build tip * fix: designableState * fix: bug * fix: designable * fix: designable * test: add tests for relation fields * test: add tests for relation fields * test: add tests for relation fields * feat: client api doc * test: add tests for relation fields * test: avoid errors * test: make tests passing * fix: bug * test: make tests passing * test: add tests for advanced fields * test: increase e2e timeout-minutes to 60 * fix: bug * fix: improve code * feat: add schema initailizer component demos * test: make tests passing * fix: schema settings demos * feat: shallowMerge & deepMerge * test: reduce number of tests * test: make tests passing * feat: updates * fix: add Initializer Internal * demos: useSchemaSettingsRender * test: make tests passing * test: make tests passing * fix: improve docs * fix: bug * chore: upgrade dumi theme * test: make tests passing * test: add tests for linkage rules * test: add test for form data templates * test: add tests for default value * test: reduce number of tests * fix: dn.deepMerge * fix: bug * fix: bug * fix: toolbar * fix: docs ssr * test: add tests for system fields * test: add tests for actions * fix: bug * test: add tests for lazy loading of variables * test: make testing more stable * fix: update docs * fix: bug --------- Co-authored-by: Rain <958414905@qq.com> Co-authored-by: chenos <chenlinxh@gmail.com> Co-authored-by: katherinehhh <katherine_15995@163.com>
2023-12-04 14:56:46 +08:00
* actionNames - Name of the resource action
2023-02-17 19:15:30 +08:00
* 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;
});
refactor: new schema initializer and schema settings (#2802) * fix: form * refactor: schema-initializer * fix: bug * refactor: schema initializer * refactor: rename * fix: delete SchemaInitializerProvider * refactor: props `insert` to hooks `useSchemaInitializerV2` * fix: bug * refactor: delete `SchemaInitializer.Button` * refactor: delete old SchemaInitializer * fix: bug * fix: workflow * fix: docs * fix: bug * fix: bug * feat: style * fix: remove v2 * fix: visible * fix: bug * fix: item hook * feat: item hook * fix: add search DataBlockInitializer * fix: build bug * fix: style bug * fix: style bug * fix: test bug * fix: test bug * fix: rerender bug * fix: remove menu select * fix: bug * chore: add aria-label for SchemaInitializerButton * refactor: rename name to camel case * fix: menu height bug * fix: build errors * fix: build errors * fix: bug * fix: bug * fix: performance * test: add test for header * fix: sidebar is not refresh (T-2422) * feat(e2e): support to add group page and link page * chore: make sure the page is configurable when using page.goto * test: add tests for menu initializer * fix: imporve code * chore: fix build error * chore: optimize locator of menu item * refactor: rename testid for select * test: make tests passing * fix: make tests passing * chore: upgrade vitest to v0.34.6 * chore: increase timeout of e2e * feat: core * fix: revert schema initializer demos * test: menu, page tabs, page grid, table column * fix: schema button interface * feat: refactor: page tab settings * feat: page settings * fix: dumirc * fix: export CSSVariableProvider * feat: lazy render * fix: form-item * fix: general schema desinger * feat: filter form item settings * refactor: form-v2 schema settings * refactor: form-v1 schema settings * refactor: action schema settings * fix: action bug * fix: form-item bug * fix: types error * docs: schema settings doc * docs: schema settings * feat: schema setting item add name * fix: visible lazy render bug * fix: revert form item filter * fix: test bug * fix: test JSON.parse bug * fix: test bug * fix: improve styling * fix: styling * fix: cleanup * fix: token.borderRadiusSM * fix: bug * test: add tests * fix: style bug * fix: add chart performance * feat: add SchemaDesignerContext * fix: bug * fix: test bug * style: create record action style improve * fix: make test passing * chore: mack tests passing * chore: make tests passing * test: fix tests * style: style revert * fix: bug * fix: data selector * fix: fix tests * fix: fix tests * fix: delete PluginManagerContext * refactor: improve router and add SchemaComponentProvider & CSSVariableProvider to MainComponent * fix: add dn and field builtin to SchemaSettingWrapper * feat: update docs * refactor: application providers * fix: test bug * fix: fix tests * chore: make test passing * feat: update docs * chore: rename collection name * feat: update docs * chore: skip weird test * fix: blockInitializers media to otherBlocks * fix: cancel to skip test * fix: bug * test: add test * refactor: migrate to small files * test: add tests for form block settings * chore: format * fix: add chart scroll bug * refactor: action designer improve * refactor: formitem designer schemaSetting * feat: schemaSettingsManager and schemaInitializerManager addItem and removeItem * test: add tests for color field in creating block * test: add tests for email field in creating block * test: make tests passing * perf: reduce fields number * fix: sub menu bug * test: add tests basic in editing form * test: add tests basic in details form * fix: improve code * test: make tests passing * test(plugin-mock-collections): add color for enum options * refactor: improve code * fix: bug * fix: bug * refactor: convert parameters to destructured object * test: add tests choices * test: add tests media * test: add tests for datetime in creating form * feat(plugin-mock-collection): generate faker time * test: add tests for datetime in editing form * test: add tests for datetime in details form * fix: bug * feat: improve code * test: add tests for relation fields * fix: rename SchemaSettings * fix: type bug * refactor: useDesinger() * fix: bug * fix: bug * fix: build tip * fix: designableState * fix: bug * fix: designable * fix: designable * test: add tests for relation fields * test: add tests for relation fields * test: add tests for relation fields * feat: client api doc * test: add tests for relation fields * test: avoid errors * test: make tests passing * fix: bug * test: make tests passing * test: add tests for advanced fields * test: increase e2e timeout-minutes to 60 * fix: bug * fix: improve code * feat: add schema initailizer component demos * test: make tests passing * fix: schema settings demos * feat: shallowMerge & deepMerge * test: reduce number of tests * test: make tests passing * feat: updates * fix: add Initializer Internal * demos: useSchemaSettingsRender * test: make tests passing * test: make tests passing * fix: improve docs * fix: bug * chore: upgrade dumi theme * test: make tests passing * test: add tests for linkage rules * test: add test for form data templates * test: add tests for default value * test: reduce number of tests * fix: dn.deepMerge * fix: bug * fix: bug * fix: toolbar * fix: docs ssr * test: add tests for system fields * test: add tests for actions * fix: bug * test: add tests for lazy loading of variables * test: make testing more stable * fix: update docs * fix: bug --------- Co-authored-by: Rain <958414905@qq.com> Co-authored-by: chenos <chenlinxh@gmail.com> Co-authored-by: katherinehhh <katherine_15995@163.com>
2023-12-04 14:56:46 +08:00
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