@holoyan/adonisjs-permissions 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. package/LICENSE.md +9 -0
  2. package/README.md +661 -0
  3. package/build/configure.d.ts +2 -0
  4. package/build/configure.js +33 -0
  5. package/build/index.d.ts +8 -0
  6. package/build/index.js +17 -0
  7. package/build/providers/role_permission_provider.d.ts +12 -0
  8. package/build/providers/role_permission_provider.js +12 -0
  9. package/build/src/acl.d.ts +11 -0
  10. package/build/src/acl.js +29 -0
  11. package/build/src/decorators.d.ts +4 -0
  12. package/build/src/decorators.js +18 -0
  13. package/build/src/mixins/has_permissions.d.ts +133 -0
  14. package/build/src/mixins/has_permissions.js +19 -0
  15. package/build/src/mixins/has_role_permissions.d.ts +128 -0
  16. package/build/src/mixins/has_role_permissions.js +10 -0
  17. package/build/src/mixins/has_roles.d.ts +1 -0
  18. package/build/src/mixins/has_roles.js +47 -0
  19. package/build/src/models/model_permission.d.ts +12 -0
  20. package/build/src/models/model_permission.js +35 -0
  21. package/build/src/models/model_role.d.ts +11 -0
  22. package/build/src/models/model_role.js +31 -0
  23. package/build/src/models/permission.d.ts +16 -0
  24. package/build/src/models/permission.js +48 -0
  25. package/build/src/models/role.d.ts +16 -0
  26. package/build/src/models/role.js +48 -0
  27. package/build/src/morph_map.d.ts +8 -0
  28. package/build/src/morph_map.js +33 -0
  29. package/build/src/services/base_service.d.ts +14 -0
  30. package/build/src/services/base_service.js +12 -0
  31. package/build/src/services/helper.d.ts +21 -0
  32. package/build/src/services/helper.js +69 -0
  33. package/build/src/services/model_has_role_permissions.d.ts +48 -0
  34. package/build/src/services/model_has_role_permissions.js +172 -0
  35. package/build/src/services/model_service.d.ts +8 -0
  36. package/build/src/services/model_service.js +31 -0
  37. package/build/src/services/permissions/permission_has_model_roles.d.ts +20 -0
  38. package/build/src/services/permissions/permission_has_model_roles.js +67 -0
  39. package/build/src/services/permissions/permissions_service.d.ts +92 -0
  40. package/build/src/services/permissions/permissions_service.js +438 -0
  41. package/build/src/services/roles/role_has_model_permissions.d.ts +66 -0
  42. package/build/src/services/roles/role_has_model_permissions.js +152 -0
  43. package/build/src/services/roles/roles_service.d.ts +16 -0
  44. package/build/src/services/roles/roles_service.js +89 -0
  45. package/build/src/types.d.ts +21 -0
  46. package/build/src/types.js +1 -0
  47. package/build/stubs/configs/permissions.stub +20 -0
  48. package/build/stubs/main.d.ts +5 -0
  49. package/build/stubs/main.js +7 -0
  50. package/build/stubs/migrations/create_db.stub +97 -0
  51. package/package.json +95 -0
package/LICENSE.md ADDED
@@ -0,0 +1,9 @@
1
+ # The MIT License
2
+
3
+ Copyright (c) 2023
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6
+
7
+ The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8
+
9
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,661 @@
1
+ # Role permissions system for AdonisJS V6+
2
+
3
+ ## Under development!
4
+
5
+ [![test](https://github.com/holoyan/adonisjs-permissions/actions/workflows/test.yml/badge.svg)](https://github.com/holoyan/adonisjs-permissions/actions/workflows/test.yml)
6
+ [![license](https://poser.pugx.org/silber/bouncer/license.svg)](https://github.com/holoyan/adonisjs-permissions/blob/master/LICENSE.md)
7
+
8
+ ## Table of Contents
9
+
10
+ <details><summary>Click to expand</summary><p>
11
+
12
+ - [Introduction](#introduction)
13
+ - [Installation](#installation)
14
+ - [Configuration](#configuration)
15
+ - [Basic Usage](#basic-usage)
16
+ - [Creating roles and permissions](#creating-roles-and-permissions)
17
+ - [Assigning permissions to the roles (Globally)](#assigning-permissions-to-the-roles-globally)
18
+ - [Assigning permissions and roles to the users (models)](#assigning-permissions-and-roles-to-the-users-models)
19
+ - [Multi-model support](#multi-model-support)
20
+ - [Getting all roles for a user](#getting-all-roles-for-a-user)
21
+ - [Getting all permissions for a role](#getting-all-permissions-for-a-role)
22
+ - [Getting all permissions for a user (model)](#getting-all-permissions-for-a-user-model)
23
+ - [Getting users (models) for a permission](#getting-users-models-for-a-permission)
24
+ - [Getting models for a role](#getting-models-for-a-role)
25
+ - [Checking for a permission](#checking-for-a-permission)
26
+ - [Removing (revoking) roles and permissions from the model](#removing-revoking-roles-and-permissions-from-the-model)
27
+ - [Digging deeper](#digging-deeper)
28
+ - [Restricting a permission to a model (On resource)](#restricting-a-permission-to-a-model-on-resource)
29
+ - [Forbidding permissions](#forbidding-permissions)
30
+ - [Forbidding permissions on a resource](#forbidding-permissions-on-a-resource)
31
+ - [Checking for forbidden permissions](#checking-for-forbidden-permissions)
32
+ - [Unforbidding the permissions](#unforbidding-the-permissions)
33
+ - [Global v resource permissions (Important!)](#global-v-resource-permissions-important)
34
+ - [containsPermission v hasPermission](#containspermission-v-haspermission)
35
+ - [License](#license)
36
+ </p></details>
37
+
38
+ ## Introduction
39
+
40
+ AdonisJs acl is an elegant and powerful package to managing roles and permissions for any AdonisJs app. With an expressive and fluent syntax, it stays out of your way as much as possible: use it when you want, ignore it when you don't.
41
+
42
+ For a quick, glanceable list of acl's features, check out [the cheat sheet](#cheat-sheet).
43
+
44
+ Once installed, you can simply tell the Acl what you want to allow:
45
+
46
+ ```typescript
47
+ import {Acl} from '@holoyan/adonisjs-permissions'
48
+
49
+
50
+ // Give a user the permission to edit
51
+ await Acl.model(user).allow('edit');
52
+
53
+ // Alternatively, do it through a permission
54
+ await Acl.permission('edit').attachToModel(user);
55
+
56
+ // You can also grant a permission only to a specific model
57
+ const post = await Post.first()
58
+ await Acl.model(user).allow('delete', post);
59
+ ```
60
+
61
+ To be able to use full power of Acl you should have clear understanding how it is structured and works, that's why documentation will be divided into two parts - [Basic usage](#basic-usage) and [Advanced usage](#advanced-usage) .
62
+ For most of the applications [Basic usage](#basic-usage) will be enough
63
+
64
+ ## Installation
65
+ npm install ...
66
+
67
+ ## Configuration
68
+
69
+ ## Basic Usage
70
+
71
+ On this section we will explore basic role permission methods
72
+
73
+ ### Creating roles and permissions
74
+
75
+ Let's create `create,update,read,delete` permissions and `admin,manager` roles
76
+
77
+ ```typescript
78
+
79
+ // create permissions
80
+ const create = await Acl.permission().create({
81
+ slug:'create',
82
+ title:'Create some resource',
83
+ })
84
+
85
+ const update = await Acl.permission().create({
86
+ slug:'update',
87
+ title:'update some resource',
88
+ })
89
+
90
+ const read = await Acl.permission().create({
91
+ slug:'read',
92
+ title:'read some resource',
93
+ })
94
+
95
+ const delete = await Acl.permission().create({
96
+ slug:'delete',
97
+ title:'delete some resource',
98
+ })
99
+
100
+ // create roles
101
+ const admin = await Acl.role().create({
102
+ slug:'admin',
103
+ title:'Cool title for Admin',
104
+ })
105
+
106
+ const manager = await Acl.role().create({
107
+ slug:'manager',
108
+ title:'Cool title for Manager',
109
+ })
110
+
111
+ ```
112
+
113
+ next step is to [assign permissions to the roles](#assigning-permissions-to-the-roles-globally)
114
+
115
+ ### Assigning permissions to the roles (Globally)
116
+
117
+ Now once we've created roles and permissions let's assign them
118
+
119
+ ```typescript
120
+ await Acl.role(admin).assign('create')
121
+ // or you can use give() method, they are identical
122
+ await Acl.role(admin).give('update')
123
+ // or you use giveAll(), assigneAll() for bulk assign
124
+ await Acl.role(admin).giveAll(['read', 'delete'])
125
+ ```
126
+
127
+ ### Assigning permissions and roles to the users (models)
128
+
129
+ Let's see in examples how to assign [roles and permissions](#creating-roles-and-permissions) to the users
130
+
131
+ ```typescript
132
+ import {Acl} from "@holoyan/adonisjs-permissions";
133
+ import User from "#models/user";
134
+
135
+ const user1 = await User.query().where(condition1).first()
136
+ // give manager role to the user1
137
+ await Acl.model(user1).assignRole(manager)
138
+
139
+ const user2 = await User.query().where(condition2).first()
140
+ await Acl.model(user2).assignRole(admin)
141
+
142
+ ```
143
+ Or we can give permissions directly to users without having any role
144
+
145
+ ```typescript
146
+
147
+ import {Acl} from "@holoyan/adonisjs-permissions";
148
+
149
+ // create new permission
150
+ const uploadFile = await Acl.permission().create({
151
+ slug: 'upload-file-slug',
152
+ title: 'permisison to upload files',
153
+ })
154
+
155
+ Acl.model(user1).assignDirectPermission('upload-file-slug')
156
+
157
+ ```
158
+
159
+ ### Multi-model support
160
+
161
+ We are not limiting to use only User model, if you have multi auth system like User and Admin you are free to use both of them with Acl.
162
+
163
+
164
+ ```typescript
165
+ await Acl.model(user).assignRole(manager)
166
+
167
+ await Acl.model(admin).assignRole(admin)
168
+
169
+ ```
170
+
171
+ ## Getting roles and permissions
172
+
173
+ In this section we will see how to get roles and permissions for a model and vice versa
174
+
175
+ ### Getting all roles for a user
176
+
177
+ ```typescript
178
+
179
+ const roles = await Acl.model(user).roles()
180
+ ```
181
+
182
+ ### Getting all permissions for a role
183
+
184
+ ```typescript
185
+
186
+ const roles = await Acl.role(role).permissions()
187
+ ```
188
+
189
+ ### Getting all permissions for a user (model)
190
+
191
+ ```typescript
192
+
193
+ const roles = await Acl.model(user).permissions()
194
+ ```
195
+
196
+ ### Getting users (models) for a permission
197
+
198
+ ```typescript
199
+
200
+ const models = await Acl.permission(permission).models()
201
+
202
+ ```
203
+ this will return array of `ModelPermission` which will contain `modelType,modelId` attributes, where `modelType` is *alias* which you had specified in [morphMap decorator](#morph-map-decorator), `modelId` is the value of column, you've specified in [getModelId]() method.
204
+
205
+ Most of the cases you will have only one model (User), it's better to use `modelsFor()` to get concrete models
206
+
207
+ ```typescript
208
+
209
+ const models = await Acl.permission(permission).modelsFor(User)
210
+
211
+ ```
212
+ this will return [array of User models](https://lucid.adonisjs.com/docs/crud-operations#using-the-query-builder)
213
+
214
+ ### Getting models for a role
215
+
216
+ ```typescript
217
+
218
+ const models = await Acl.role(permission).models()
219
+
220
+ ```
221
+
222
+ Or if you want to get for a specific model
223
+
224
+ ```typescript
225
+
226
+ const models = await Acl.role(permission).modelsFor(Admin)
227
+
228
+ ```
229
+
230
+ ### Checking for a role
231
+
232
+ To check if user has role
233
+
234
+ ```typescript
235
+
236
+ await Acl.model(user).hasRole('admin') // :boolean
237
+
238
+ ```
239
+
240
+ you can pass array of roles
241
+
242
+ ```typescript
243
+
244
+ // returns true only if user has all roles
245
+ await Acl.model(user).hasAllRoles(['admin', 'manager'])
246
+
247
+ ```
248
+
249
+ to check if user has any of roles, will return true if user has at least one role
250
+
251
+ ```typescript
252
+
253
+ await Acl.model(user).hasAnyRole(['admin', 'manager'])
254
+
255
+ ```
256
+
257
+ ### Checking for a permission
258
+
259
+ Check if user has permission
260
+
261
+ ```typescript
262
+
263
+ await Acl.model(user).hasPermission('update')
264
+ // or
265
+ await Acl.model(user).can('update') // alias for hasPermission() method
266
+
267
+ ```
268
+
269
+ To check array of permissions
270
+
271
+ ```typescript
272
+
273
+ // returns true only if user has all permissions
274
+ await Acl.model(user).hasAllPermissions(['update', 'delete'])
275
+ // or
276
+ await Acl.model(user).canAll(['update', 'delete']) // alias for hasAllPermissions() method
277
+
278
+ ```
279
+
280
+ to check if user has any of permission, will return true if user has at least one permission
281
+
282
+ ```typescript
283
+
284
+ // returns true only if user has all permissions
285
+ await Acl.model(user).hasAnyPermission(['update', 'delete'])
286
+ // or
287
+ await Acl.model(user).canAny(['update', 'delete']) // alias for hasAnyPermission() method
288
+
289
+ ```
290
+
291
+ Same applies for role
292
+
293
+ ```typescript
294
+
295
+ await Acl.role(role).hasPermission('update')
296
+ await Acl.role(role).hasAllPermissions(['update', 'read'])
297
+ await Acl.role(role).hasAnyPermission(['update', 'read'])
298
+
299
+ ```
300
+
301
+ ### Removing (revoking) roles and permissions from the model
302
+
303
+ To remove role from the user we can use `revoke` method
304
+
305
+ ```typescript
306
+
307
+ await Acl.model(user).revokeRole('admin')
308
+ await Acl.model(user).revokeAllRoles(['admin', 'manager'])
309
+
310
+ // will remove all assigned roles
311
+ await Acl.model(user).flushRoles()
312
+
313
+ ```
314
+
315
+ Removing permissions from the user
316
+
317
+ ```typescript
318
+ await Acl.model(user).revokePermission('update')
319
+ // await Acl.model(user).hasPermission('update') will return false
320
+
321
+ await Acl.model(user).revokeAllPermissions(['update', 'delete'])
322
+
323
+ // will remove all assigned permissions
324
+ await Acl.model(user).flushPermissions()
325
+
326
+ // revokes all roles and permissions for a user
327
+ await Acl.model(user).flush()
328
+
329
+ ```
330
+
331
+ Removing permissions from the role
332
+
333
+ ```typescript
334
+ await Acl.role(role).revokePermission('update')
335
+ // or
336
+ await Acl.role(role).revoke('update') // alias for revokePermission - WORKS ONLY on roles
337
+
338
+ await Acl.role(role).revokeAllPermissions(['update', 'delete'])
339
+ // alias revokeAll(['update', 'delete']) method availalbe ONLY on roles
340
+
341
+ // remove all assigned permissions
342
+ await Acl.role(role).flushPermissions()
343
+ // alias flush() method availalbe ONLY on roles
344
+
345
+ ```
346
+
347
+
348
+ ### Deleting roles and permissions (Important!)
349
+
350
+ > Important! use Acl to delete roles and permissions, under the hood Acl does some checking
351
+
352
+ ```typescript
353
+
354
+ await Acl.role().delete('admin')
355
+
356
+ await Acl.permission().delete('edit')
357
+
358
+ ```
359
+
360
+ To see in dept usage of this methods check [next section](#digging-deeper)
361
+
362
+ ## Digging deeper
363
+
364
+ In [previous](#basic-usage) section we looked basic examples and usage, most of the time basic usage probably will be enough for your project but there are much more we can do with `Acl`
365
+
366
+ ### Restricting a permission to a model (On resource)
367
+
368
+ Sometimes you might want to restrict a permission to a specific model type. Simply pass the model name as a second argument:
369
+
370
+ ```typescript
371
+ import Product from "#models/product";
372
+
373
+ await Acl.model(user).assignDirectPermission('edit', Product)
374
+
375
+ ```
376
+ >Just don't forget to add model `MorphMap` decorator on Product class
377
+
378
+ ```typescript
379
+
380
+ @MorphMap('products')
381
+ export default class Product extends BaseModel {
382
+ // other code
383
+ }
384
+
385
+ ```
386
+
387
+ >Warning: All models which interact with Acl **MUST** use [MorphMap]() decorator
388
+
389
+ In this case we check permission again
390
+
391
+ ```typescript
392
+ import Product from "#models/product";
393
+ import Post from "#models/post";
394
+
395
+ const productModel1 = Product.first()
396
+ const productModel50 = Product.first()
397
+ const postModel = Post.first()
398
+
399
+ await Acl.model(user).hasPermission('edit', productModel1) // true
400
+ await Acl.model(user).hasPermission('edit', productModel50) // true
401
+ // ... for all Product model instances it will return true
402
+ await Acl.model(user).hasPermission('edit', Product) // true
403
+
404
+ await Acl.model(user).hasPermission('edit', postModel) // false
405
+ await Acl.model(user).hasPermission('edit', Post) // false
406
+
407
+ await Acl.model(user).hasPermission('edit') // false
408
+
409
+ // containsPermission() method will tell if user has 'edit' permission attached at all
410
+ await Acl.model(user).containsPermission('edit') // true
411
+
412
+ ```
413
+
414
+ Check [ContainsPermission vs hasPermission](#containspermission-v-haspermission) section for more details
415
+
416
+ We can restrict even more, and give permission to the specific model
417
+
418
+ ```typescript
419
+
420
+ import Product from "#models/product";
421
+
422
+ const product1 = Product.find(1)
423
+
424
+ await Acl.model(user).assignDirectPermission('edit', product1)
425
+
426
+ const product2 = Product.find(2)
427
+
428
+ await Acl.model(user).hasPermission('edit', product1) // true
429
+ await Acl.model(user).hasPermission('edit', product2) // false
430
+
431
+ await Acl.model(user).hasPermission('edit', Product) // false
432
+
433
+ await Acl.model(user).hasPermission('edit') // false
434
+ await Acl.model(user).containsPermission('edit') // true
435
+
436
+ ```
437
+
438
+ This will behave same way if assign permission through the role instead of direct
439
+
440
+ ```typescript
441
+
442
+ const product1 = Product.find(1)
443
+
444
+ await Acl.role(admin).assign('edit', product1)
445
+
446
+ const user = await User.first()
447
+
448
+ await Acl.model(user).assignRole(role)
449
+
450
+ // then if we start checking, result will be same
451
+
452
+ const product2 = Product.find(2)
453
+
454
+ await Acl.model(user).hasPermission('edit', product1) // true
455
+ await Acl.model(user).hasPermission('edit', product2) // false
456
+
457
+ await Acl.model(user).hasPermission('edit', Product) // false
458
+
459
+ await Acl.model(user).hasPermission('edit') // false
460
+ await Acl.model(user).containsPermission('edit') // true
461
+
462
+ ```
463
+
464
+ ### Forbidding permissions
465
+
466
+ Let's imagine a situation when your `manager` role has `create,update,read,delete` permissions. All your users have `manager` role but there are small amount of users you want to give `manager` role but same time do not allow `delete` action.
467
+ Good news!, we can do that
468
+
469
+ ```typescript
470
+
471
+ await Acl.role(manager).giveAll(['create','update','read','delete'])
472
+
473
+ // assigning to the users
474
+ await Acl.model(user1).assignRole(manager)
475
+
476
+ await Acl.model(user3).assignRole(manager)
477
+ await Acl.model(user3).forbid('delete')
478
+
479
+ await Acl.model(user1).hasRole(manager) // true
480
+ await Acl.model(user1).hasPermission('delete') // true
481
+
482
+ await Acl.model(user3).hasRole(manager) // true
483
+ await Acl.model(user3).hasPermission('delete') // false
484
+
485
+ await Acl.model(user3).containsPermission('delete') // true
486
+
487
+ ```
488
+
489
+ ### Forbidding permissions on a resource
490
+
491
+ You can also forbid single action on a resource
492
+
493
+ ```typescript
494
+
495
+ const post = Post.find(id1ToFind)
496
+
497
+ await Acl.model(user3).forbid('delete', post)
498
+
499
+ ```
500
+
501
+ ### Checking for forbidden permissions
502
+
503
+ In [previous](#forbidding-permissions) section we saw how to forbid certain permissions for the model, even if user has that permission through the role, now we will look how to check if permission is forbidden or not
504
+
505
+ ```typescript
506
+
507
+ await Acl.model(user3).assignRole(manager)
508
+ await Acl.model(user3).forbid('delete')
509
+
510
+ await Acl.model(user3).forbidden('delete') // true
511
+
512
+
513
+ const post1 = Post.find(id1ToFind)
514
+
515
+
516
+ await Acl.model(user).allow('edit', Post) // allow for all posts
517
+ await Acl.model(user).forbid('edit', post1) // except post1
518
+
519
+ await Acl.model(user).forbidden('edit', post1) // true
520
+
521
+ const post7 = Post.find(id7ToFind)
522
+ await Acl.model(user).forbidden('edit', post7) // false becouse 'edit' action forbidden only for post1 instance
523
+ ```
524
+
525
+ ### Unforbidding the permissions
526
+
527
+ ```typescript
528
+
529
+ await Acl.model(user3).assignRole(manager)
530
+ await Acl.model(user3).forbid('delete')
531
+
532
+ await Acl.model(user3).forbidden('delete') // true
533
+ await Acl.model(user3).hasPermission('delete') // false
534
+ await Acl.model(user3).containsPermission('delete') // true
535
+
536
+ await Acl.model(user3).unforbid('delete')
537
+ await Acl.model(user3).forbidden('delete') // false
538
+ await Acl.model(user3).hasPermission('delete') // true
539
+
540
+ ```
541
+ Same behaviour applies with roles
542
+
543
+ ```typescript
544
+ await Acl.role(role).assignRole(manager)
545
+ await Acl.role(role).forbid('delete')
546
+
547
+ await Acl.role(role).forbidden('delete') // true
548
+ await Acl.role(role).hasPermission('delete') // false
549
+ await Acl.role(role).containsPermission('delete') // true
550
+
551
+ ```
552
+
553
+ ### Global v resource permissions (Important!)
554
+
555
+ > Important! Action performed globally will affect on resource models
556
+
557
+ It is very important to understood difference between global and resource permissions and their scope.
558
+ Look at this way, if there is no `entity` model then action will be performed **globally**, otherwise **on resource**
559
+
560
+ ```typescript
561
+ // global actions
562
+ import {Acl} from "@holoyan/adonisjs-permissions";
563
+
564
+ // Give a user the permission to edit
565
+ await Acl.model(user).allow('edit');
566
+
567
+ Acl.model(user).assignDirectPermission('uploadFile')
568
+
569
+ await Acl.model(user).forbid('delete')
570
+
571
+ await Acl.model(user).hasPermission('create')
572
+ await Acl.model(user).unforbid('delete')
573
+ // ... and so on
574
+
575
+ ```
576
+
577
+ ```typescript
578
+ // On resource actions
579
+
580
+ await Acl.role(admin).assign('edit', product1)
581
+ await Acl.model(user).hasPermission('edit', product1)
582
+ await Acl.model(user).assignDirectPermission('edit', Post)
583
+
584
+ ```
585
+
586
+ As you can see if `entity` (product1, Post and so on) is specified then it's a *on resource* action
587
+
588
+ Now let's see few examples
589
+
590
+ ```typescript
591
+ import {Acl} from "@holoyan/adonisjs-permissions";
592
+
593
+ // Global action
594
+ await Acl.model(user).allow('edit');
595
+
596
+ const product1 = Product.first();
597
+
598
+ await Acl.model(user).hasPermission('edit') // true
599
+ await Acl.model(user).hasPermission('edit', product1) // true becouse 'edit' permission assigned globaly
600
+ await Acl.model(user).hasPermission('edit', ImageModel) // true becouse 'edit' permission assigned globaly
601
+
602
+ ```
603
+
604
+ Now if do same but assign on Resource, result will be different
605
+
606
+ ```typescript
607
+
608
+ const product1 = Product.first();
609
+
610
+ await Acl.model(user).allow('edit', product1);
611
+
612
+ await Acl.model(user).hasPermission('edit', product1) // true becouse 'edit' permission assigned to this specific model instance
613
+
614
+ await Acl.model(user).hasPermission('edit') // false
615
+ await Acl.model(user).hasPermission('edit', Product) // false becouse 'edit' permission assigned to the specific model instance
616
+
617
+ ```
618
+
619
+ let's see one more example
620
+
621
+ ```typescript
622
+
623
+ await Acl.model(user).allow('edit', Product); // assing to Product model, for all Product instances it will be true
624
+
625
+ const product1 = Product.first();
626
+ await Acl.model(user).hasPermission('edit', product1) // true
627
+ const product2 = Product.find(someId);
628
+ await Acl.model(user).hasPermission('edit', product2) // true
629
+ await Acl.model(user).hasPermission('edit', Product) // true
630
+
631
+ await Acl.model(user).hasPermission('edit') // false , becouse it's not global, it's only on Product resrouce
632
+
633
+ ```
634
+
635
+ Anytime you can use `containsPermission()` method to check if user has it
636
+
637
+ ### containsPermission v hasPermission
638
+
639
+ As you've already seen there are difference between `containsPermission` and `hasPermission`. `containsPermission()` method will return `true` if user has that permission, it doesn't matter if it's *global*, *on resource* or *forbidden*
640
+
641
+ Lets in example see this difference
642
+
643
+ ```typescript
644
+
645
+
646
+ await Acl.model(user).allow('edit'); // assing globally
647
+ await Acl.model(user).containsPermission('edit') // true
648
+
649
+
650
+ await Acl.model(user).allow('delete', Post); // assing on resource
651
+ await Acl.model(user).containsPermission('delete') // true
652
+
653
+
654
+ await Acl.model(user).forbid('read'); // forbid read action
655
+ await Acl.model(user).containsPermission('read') // true
656
+
657
+ ```
658
+
659
+ ## License
660
+
661
+ MIT
@@ -0,0 +1,2 @@
1
+ import ConfigureCommand from '@adonisjs/core/commands/configure';
2
+ export declare function configure(_command: ConfigureCommand): Promise<void>;
@@ -0,0 +1,33 @@
1
+ /*
2
+ |--------------------------------------------------------------------------
3
+ | Configure hook
4
+ |--------------------------------------------------------------------------
5
+ |
6
+ | The configure hook is called when someone runs "node ace configure <package>"
7
+ | command. You are free to perform any operations inside this function to
8
+ | configure the package.
9
+ |
10
+ | To make things easier, you have access to the underlying "ConfigureCommand"
11
+ | instance and you can use codemods to modify the source files.
12
+ |
13
+ */
14
+ import { stubsRoot } from './stubs/main.js';
15
+ export async function configure(_command) {
16
+ const codemods = await _command.createCodemods();
17
+ /**
18
+ * Publish config file
19
+ */
20
+ await codemods.makeUsingStub(stubsRoot, 'configs/permissions.stub', {});
21
+ /**
22
+ * Publish migration file
23
+ */
24
+ await codemods.makeUsingStub(stubsRoot, 'migrations/create_db.stub', {
25
+ prefix: new Date().getTime(),
26
+ });
27
+ /**
28
+ * Register provider
29
+ */
30
+ await codemods.updateRcFile((rcFile) => {
31
+ rcFile.addProvider('@holoyan/adonisjs-permissions/role_permission_provider');
32
+ });
33
+ }