mirror of
				https://github.com/strapi/strapi.git
				synced 2025-10-31 18:08:11 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			110 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
			
		
		
	
	
			110 lines
		
	
	
		
			3.1 KiB
		
	
	
	
		
			Markdown
		
	
	
	
	
	
| # Strapi Permissions
 | |
| 
 | |
| Highly customizable permission engine made for Strapi
 | |
| 
 | |
| ## Get Started
 | |
| 
 | |
| ```sh
 | |
| yarn add @strapi/permissions
 | |
| ```
 | |
| 
 | |
| ```javascript
 | |
| const permissions = require('@strapi/permissions');
 | |
| 
 | |
| const engine = permissions.engine.new({ providers });
 | |
| 
 | |
| const ability = await engine.generateAbility([
 | |
|   { action: 'read' },
 | |
|   { action: 'delete', subject: 'foo' },
 | |
|   { action: 'update', subject: 'bar', properties: { fields: ['foobar'] } },
 | |
|   {
 | |
|     action: 'create',
 | |
|     subject: 'foo',
 | |
|     properties: { fields: ['foobar'] },
 | |
|     conditions: ['isAuthor'],
 | |
|   },
 | |
| ]);
 | |
| 
 | |
| ability.can('read'); // true
 | |
| ability.can('publish'); // false
 | |
| ability.can('update', 'foo'); // false
 | |
| ability.can('update', 'bar'); // true
 | |
| ```
 | |
| 
 | |
| - You need to give both an action and a condition provider as parameters when instantiating a new permission engine instance. They must be contained in a `providers` object property.
 | |
| - You can also pass an `abilityBuilderFactory` to customize what kind of ability the `generateAbility` method will return. By default it'll use a `@casl/ability` builder.
 | |
| 
 | |
| You can also register to some hooks for each engine instance.
 | |
| See `lib/engine/hooks.js` -> `createEngineHooks` for available hooks.
 | |
| 
 | |
| ```javascript
 | |
| const permissions = require('@strapi/permissions');
 | |
| 
 | |
| const engine = permissions.engine
 | |
|   .new({ providers })
 | |
|   .on('before-format::validate.permission', ({ permission }) => {
 | |
|     if (permission.action === 'read') {
 | |
|       return false;
 | |
|     }
 | |
|   });
 | |
| 
 | |
| const ability = await engine.generateAbility([
 | |
|   { action: 'read' },
 | |
|   { action: 'delete', subject: 'foo' },
 | |
|   { action: 'update', subject: 'bar', properties: { fields: ['foobar'] } },
 | |
|   {
 | |
|     action: 'create',
 | |
|     subject: 'foo',
 | |
|     properties: { fields: ['foobar'] },
 | |
|     conditions: ['isAuthor'],
 | |
|   },
 | |
| ]);
 | |
| 
 | |
| ability.can('read'); // false since the validation hook prevents the engine from registering the permission
 | |
| ability.can('publish'); // false
 | |
| ability.can('update', 'foo'); // false
 | |
| ability.can('update', 'bar'); // true
 | |
| ```
 | |
| 
 | |
| The `format.permission` hook can be used to modify the permission.
 | |
| 
 | |
| ```javascript
 | |
| const permissions = require('@strapi/permissions');
 | |
| 
 | |
| const engine = permissions.engine
 | |
|   .new({ providers })
 | |
|   .on('before-format::validate.permission', ({ permission }) => {
 | |
|     if (permission.action === 'modify') {
 | |
|       return false;
 | |
|     }
 | |
|   })
 | |
|   .on('after-format::validate.permission', ({ permission }) => {
 | |
|     if (permission.action === 'update') {
 | |
|       return false;
 | |
|     }
 | |
|   })
 | |
|   .on('format.permission', ({ permission }) => {
 | |
|     if (permission.action === 'update') {
 | |
|       return {
 | |
|         ...permission,
 | |
|         action: 'modify',
 | |
|       };
 | |
|     }
 | |
|     if (permission.action === 'delete') {
 | |
|       return {
 | |
|         ...permission,
 | |
|         action: 'remove',
 | |
|       };
 | |
|     }
 | |
|     return permission;
 | |
|   });
 | |
| 
 | |
| const ability = await engine.generateAbility([{ action: 'update' }, { action: 'delete' }]);
 | |
| 
 | |
| ability.can('update'); // false
 | |
| ability.can('modify'); // true, because create was changed to 'modify'
 | |
| 
 | |
| ability.can('delete'); // false, doesn't exist because it was changed by format.permission
 | |
| ability.can('remove'); // true, before-format::validate.permission validates before format.permission changed it
 | |
| ```
 | 
