@holoyan/adonisjs-permissions 0.5.2 → 0.6.8

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 (33) hide show
  1. package/README.md +294 -97
  2. package/build/configure.js +9 -0
  3. package/build/index.d.ts +2 -1
  4. package/build/index.js +2 -1
  5. package/build/providers/role_permission_provider.js +5 -3
  6. package/build/src/acl.d.ts +14 -6
  7. package/build/src/acl.js +33 -12
  8. package/build/src/mixins/has_permissions.d.ts +1 -2
  9. package/build/src/mixins/has_permissions.js +0 -3
  10. package/build/src/model_manager.d.ts +3 -3
  11. package/build/src/scope.d.ts +7 -0
  12. package/build/src/scope.js +14 -0
  13. package/build/src/services/helper.js +3 -3
  14. package/build/src/services/model_has_role_permissions.d.ts +13 -3
  15. package/build/src/services/model_has_role_permissions.js +33 -3
  16. package/build/src/services/permissions/empty_permission.d.ts +7 -2
  17. package/build/src/services/permissions/empty_permission.js +20 -3
  18. package/build/src/services/permissions/permission_has_model_roles.d.ts +5 -2
  19. package/build/src/services/permissions/permission_has_model_roles.js +10 -1
  20. package/build/src/services/permissions/permissions_service.d.ts +11 -3
  21. package/build/src/services/permissions/permissions_service.js +48 -13
  22. package/build/src/services/query_helper.d.ts +4 -4
  23. package/build/src/services/query_helper.js +8 -8
  24. package/build/src/services/roles/empty_roles.d.ts +7 -2
  25. package/build/src/services/roles/empty_roles.js +20 -3
  26. package/build/src/services/roles/role_has_model_permissions.d.ts +7 -6
  27. package/build/src/services/roles/role_has_model_permissions.js +16 -6
  28. package/build/src/services/roles/roles_service.d.ts +10 -5
  29. package/build/src/services/roles/roles_service.js +22 -5
  30. package/build/src/types.d.ts +22 -1
  31. package/build/stubs/middlewares/acl_middleware.stub +26 -0
  32. package/build/stubs/migrations/create_db.stub +23 -24
  33. package/package.json +1 -1
@@ -6,7 +6,8 @@ export default class PermissionsService extends BaseService {
6
6
  modelPermissionClassName;
7
7
  modelRoleClassName;
8
8
  map;
9
- permissionQuery;
9
+ scope;
10
+ // private permissionQuery
10
11
  permissionTable;
11
12
  // private roleQuery
12
13
  // private readonly roleTable
@@ -14,14 +15,15 @@ export default class PermissionsService extends BaseService {
14
15
  modelPermissionTable;
15
16
  // private modelRoleQuery
16
17
  modelRoleTable;
17
- constructor(permissionClassName, roleClassName, modelPermissionClassName, modelRoleClassName, map) {
18
+ constructor(permissionClassName, roleClassName, modelPermissionClassName, modelRoleClassName, map, scope) {
18
19
  super();
19
20
  this.permissionClassName = permissionClassName;
20
21
  this.roleClassName = roleClassName;
21
22
  this.modelPermissionClassName = modelPermissionClassName;
22
23
  this.modelRoleClassName = modelRoleClassName;
23
24
  this.map = map;
24
- this.permissionQuery = getPermissionModelQuery(this.permissionClassName);
25
+ this.scope = scope;
26
+ // this.permissionQuery = getPermissionModelQuery(this.permissionClassName)
25
27
  this.permissionTable = this.permissionClassName.table;
26
28
  // this.roleQuery = getRoleModelQuery(this.roleClassName)
27
29
  // this.roleTable = this.roleClassName.table
@@ -30,6 +32,11 @@ export default class PermissionsService extends BaseService {
30
32
  // this.modelRoleQuery = getModelRoleModelQuery(this.modelRoleClassName)
31
33
  this.modelRoleTable = this.modelRoleClassName.table;
32
34
  }
35
+ get permissionQuery() {
36
+ const q = getPermissionModelQuery(this.permissionClassName);
37
+ this.applyScopes(q);
38
+ return q;
39
+ }
33
40
  /**
34
41
  * return all permissions, including forbidden
35
42
  */
@@ -85,6 +92,16 @@ export default class PermissionsService extends BaseService {
85
92
  .distinct(this.permissionTable + '.id')
86
93
  .select(this.permissionTable + '.*');
87
94
  }
95
+ async throughRoles(modelType, modelId, includeForbiddings = false) {
96
+ return this.modelPermissionQueryBuilder({
97
+ modelType,
98
+ modelId,
99
+ includeForbiddings,
100
+ throughRoles: true,
101
+ })
102
+ .distinct(this.permissionTable + '.id')
103
+ .select(this.permissionTable + '.*');
104
+ }
88
105
  directGlobal(modelType, modelId, includeForbiddings = false) {
89
106
  return this.modelPermissionQueryBuilder({
90
107
  modelType,
@@ -106,7 +123,7 @@ export default class PermissionsService extends BaseService {
106
123
  directPermissions: true,
107
124
  includeForbiddings,
108
125
  })
109
- .whereNotNull(this.permissionTable + '.entity_id')
126
+ .where(this.permissionTable + '.entity_type', '!=', '*')
110
127
  .distinct(this.permissionTable + '.id')
111
128
  .select(this.permissionTable + '.*');
112
129
  }
@@ -312,6 +329,7 @@ export default class PermissionsService extends BaseService {
312
329
  .where('p.allowed', true)
313
330
  .where(this.modelPermissionTable + '.model_type', modelType)
314
331
  .where(this.modelPermissionTable + '.model_id', modelId);
332
+ this.applyModelPermissionScopes(q, 'p');
315
333
  if (entityType) {
316
334
  q.where('p.entity_type', entityType);
317
335
  if (entityId) {
@@ -352,13 +370,13 @@ export default class PermissionsService extends BaseService {
352
370
  * to remove forbidden permission on model
353
371
  */
354
372
  async unforbidAll(modelType, modelId, permissionsSlug, entityType, entityId) {
355
- // todo replace using reverseModelPermissionQuery() method
356
373
  const q = this.modelPermissionQuery
357
374
  .leftJoin(this.permissionTable + ' as p', 'p.id', '=', this.modelPermissionTable + '.permission_id')
358
375
  .where('model_type', modelType)
359
376
  .where('model_id', modelId)
360
377
  .whereIn('p.slug', permissionsSlug)
361
378
  .where('p.allowed', false);
379
+ this.applyModelPermissionScopes(q, 'p');
362
380
  if (entityType) {
363
381
  q.where('p.entity_type', entityType);
364
382
  if (entityId) {
@@ -384,15 +402,21 @@ export default class PermissionsService extends BaseService {
384
402
  else {
385
403
  q.leftJoin(this.modelRoleTable + ' as mr', (joinQuery) => {
386
404
  joinQuery.onVal('mr.model_type', modelType).onVal('mr.model_id', modelId);
387
- }).where((subQuery) => {
388
- subQuery
389
- .where((query) => {
390
- query.where('mp.model_type', modelType).where('mp.model_id', modelId);
391
- })
392
- .orWhere((query) => {
393
- query.whereRaw('mr.role_id=mp.model_id').where('mp.model_type', 'roles');
394
- });
395
405
  });
406
+ if (conditions.throughRoles) {
407
+ q.whereRaw('mr.role_id=mp.model_id').where('mp.model_type', 'roles');
408
+ }
409
+ else {
410
+ q.where((subQuery) => {
411
+ subQuery
412
+ .where((query) => {
413
+ query.where('mp.model_type', modelType).where('mp.model_id', modelId);
414
+ })
415
+ .orWhere((query) => {
416
+ query.whereRaw('mr.role_id=mp.model_id').where('mp.model_type', 'roles');
417
+ });
418
+ });
419
+ }
396
420
  }
397
421
  }
398
422
  if (!includeForbiddings) {
@@ -402,6 +426,7 @@ export default class PermissionsService extends BaseService {
402
426
  .leftJoin(this.modelPermissionTable + ' as mp2', 'mp2.permission_id', '=', 'p2.id')
403
427
  .where('p2.allowed', false)
404
428
  .whereRaw('p2.slug=' + this.permissionTable + '.slug')
429
+ .whereRaw('p2.scope=' + this.permissionTable + '.scope')
405
430
  .select('p2.slug')
406
431
  .groupBy('p2.slug');
407
432
  if (conditions.entity) {
@@ -414,6 +439,10 @@ export default class PermissionsService extends BaseService {
414
439
  }
415
440
  return q;
416
441
  }
442
+ /**
443
+ * @deprecated
444
+ * @param conditions
445
+ */
417
446
  reverseModelPermissionQuery(conditions) {
418
447
  const { modelId, modelType, permissionSlugs, directPermissions } = conditions;
419
448
  const q = this.modelPermissionQuery.leftJoin(this.permissionTable + ' as p', 'p.id', '=', this.modelPermissionTable + '.permission_id');
@@ -478,4 +507,10 @@ export default class PermissionsService extends BaseService {
478
507
  q.where(table + '.entity_type', '*').whereNull(table + '.entity_id');
479
508
  }
480
509
  }
510
+ applyScopes(q) {
511
+ q.where(this.permissionTable + '.scope', this.scope.get());
512
+ }
513
+ applyModelPermissionScopes(q, table) {
514
+ q.where(table + '.scope', this.scope.get());
515
+ }
481
516
  }
@@ -1,7 +1,7 @@
1
1
  import { LucidModel, ModelQueryBuilderContract } from '@adonisjs/lucid/types/model';
2
2
  import { BaseModel } from '@adonisjs/lucid/orm';
3
3
  import { ModelPermissionModel, ModelRoleModel, PermissionModel, RoleModel } from '../types.js';
4
- export declare function getPermissionModelQuery<T extends LucidModel>(permissionClassName: typeof BaseModel): ModelQueryBuilderContract<T, PermissionModel<T>>;
5
- export declare function getRoleModelQuery<T extends LucidModel>(permissionClassName: typeof BaseModel): ModelQueryBuilderContract<T, RoleModel<T>>;
6
- export declare function getModelPermissionModelQuery<T extends LucidModel>(permissionClassName: typeof BaseModel): ModelQueryBuilderContract<T, ModelPermissionModel<T>>;
7
- export declare function getModelRoleModelQuery<T extends LucidModel>(permissionClassName: typeof BaseModel): ModelQueryBuilderContract<T, ModelRoleModel<T>>;
4
+ export declare function getPermissionModelQuery<T extends LucidModel>(className: typeof BaseModel): ModelQueryBuilderContract<T, PermissionModel<T>>;
5
+ export declare function getRoleModelQuery<T extends LucidModel>(className: typeof BaseModel): ModelQueryBuilderContract<T, RoleModel<T>>;
6
+ export declare function getModelPermissionModelQuery<T extends LucidModel>(className: typeof BaseModel): ModelQueryBuilderContract<T, ModelPermissionModel<T>>;
7
+ export declare function getModelRoleModelQuery<T extends LucidModel>(className: typeof BaseModel): ModelQueryBuilderContract<T, ModelRoleModel<T>>;
@@ -1,12 +1,12 @@
1
- export function getPermissionModelQuery(permissionClassName) {
2
- return permissionClassName.query();
1
+ export function getPermissionModelQuery(className) {
2
+ return className.query();
3
3
  }
4
- export function getRoleModelQuery(permissionClassName) {
5
- return permissionClassName.query();
4
+ export function getRoleModelQuery(className) {
5
+ return className.query();
6
6
  }
7
- export function getModelPermissionModelQuery(permissionClassName) {
8
- return permissionClassName.query();
7
+ export function getModelPermissionModelQuery(className) {
8
+ return className.query();
9
9
  }
10
- export function getModelRoleModelQuery(permissionClassName) {
11
- return permissionClassName.query();
10
+ export function getModelRoleModelQuery(className) {
11
+ return className.query();
12
12
  }
@@ -1,8 +1,13 @@
1
1
  import { BaseModel } from '@adonisjs/lucid/orm';
2
+ import { RoleInterface, RoleModel, ScopeInterface } from '../../types.js';
2
3
  export default class EmptyRoles {
3
4
  private roleClassName;
5
+ private scope;
4
6
  private roleQuery;
5
- constructor(roleClassName: typeof BaseModel);
7
+ constructor(roleClassName: typeof BaseModel, scope: ScopeInterface);
8
+ on(scope: number): this;
9
+ getScope(): number;
6
10
  delete(role: string): import("@adonisjs/lucid/types/model").ModelQueryBuilderContract<import("@adonisjs/lucid/types/model").LucidModel, any>;
7
- query(): import("@adonisjs/lucid/types/model").ModelQueryBuilderContract<import("@adonisjs/lucid/types/model").LucidModel, import("../../types.js").RoleModel<import("@adonisjs/lucid/types/model").LucidModel>>;
11
+ create(values: Partial<RoleInterface>): Promise<RoleModel<import("@adonisjs/lucid/types/model").LucidModel>>;
12
+ query(): import("@adonisjs/lucid/types/model").ModelQueryBuilderContract<import("@adonisjs/lucid/types/model").LucidModel, RoleModel<import("@adonisjs/lucid/types/model").LucidModel>>;
8
13
  }
@@ -1,16 +1,33 @@
1
1
  import { getRoleModelQuery } from '../query_helper.js';
2
2
  export default class EmptyRoles {
3
3
  roleClassName;
4
+ scope;
4
5
  roleQuery;
5
- constructor(roleClassName) {
6
+ constructor(roleClassName, scope) {
6
7
  this.roleClassName = roleClassName;
8
+ this.scope = scope;
7
9
  this.roleQuery = getRoleModelQuery(this.roleClassName);
8
10
  }
11
+ on(scope) {
12
+ this.scope.set(scope);
13
+ return this;
14
+ }
15
+ getScope() {
16
+ return this.scope.get();
17
+ }
9
18
  delete(role) {
10
- // get all permissions by slug
11
- // if there is permission with allowed false then check if it has `links`
12
19
  return this.roleQuery.where('slug', role).delete();
13
20
  }
21
+ async create(values) {
22
+ if (!values.slug) {
23
+ throw new Error('The attribute slug is required');
24
+ }
25
+ const search = {
26
+ slug: values.slug,
27
+ scope: values.scope || this.getScope(),
28
+ };
29
+ return (await this.roleClassName.updateOrCreate(search, values));
30
+ }
14
31
  query() {
15
32
  return this.roleQuery;
16
33
  }
@@ -1,18 +1,17 @@
1
1
  import ModelService from '../model_service.js';
2
2
  import PermissionsService from '../permissions/permissions_service.js';
3
- import { AclModel, MorphInterface, PermissionInterface, RoleInterface } from '../../types.js';
3
+ import { AclModel, MorphInterface, PermissionInterface, RoleInterface, ScopeInterface } from '../../types.js';
4
4
  export declare class RoleHasModelPermissions {
5
5
  private role;
6
6
  private permissionService;
7
7
  private modelService;
8
8
  private map;
9
- constructor(role: RoleInterface, permissionService: PermissionsService, modelService: ModelService, map: MorphInterface);
9
+ private scope;
10
+ constructor(role: RoleInterface, permissionService: PermissionsService, modelService: ModelService, map: MorphInterface, scope: ScopeInterface);
11
+ on(scope: number): this;
12
+ getScope(): number;
10
13
  models(): import("@adonisjs/lucid/types/model").ModelQueryBuilderContract<import("@adonisjs/lucid/types/model").LucidModel, import("../../types.js").ModelRoleModel<import("@adonisjs/lucid/types/model").LucidModel>>;
11
14
  modelsFor(modelType: string): Promise<any>;
12
- /**
13
- * todo
14
- * @param model
15
- */
16
15
  permissions(): Promise<import("../../types.js").PermissionModel<import("@adonisjs/lucid/types/model").LucidModel>[]>;
17
16
  globalPermissions(): Promise<import("../../types.js").PermissionModel<import("@adonisjs/lucid/types/model").LucidModel>[]>;
18
17
  onResourcePermissions(): Promise<import("../../types.js").PermissionModel<import("@adonisjs/lucid/types/model").LucidModel>[]>;
@@ -52,9 +51,11 @@ export declare class RoleHasModelPermissions {
52
51
  canAny(permissions: (string | PermissionInterface)[]): Promise<boolean>;
53
52
  forbidden(permission: string | PermissionInterface, target?: AclModel | Function): Promise<boolean>;
54
53
  assign(permission: string, target?: AclModel | Function): Promise<import("@adonisjs/lucid/types/model").LucidRow[]>;
54
+ allow(permission: string, target?: AclModel | Function): Promise<import("@adonisjs/lucid/types/model").LucidRow[]>;
55
55
  give(permission: string, target?: AclModel | Function): Promise<import("@adonisjs/lucid/types/model").LucidRow[]>;
56
56
  giveAll(permissions: string[], target?: AclModel | Function): Promise<import("@adonisjs/lucid/types/model").LucidRow[]>;
57
57
  assingAll(permissions: string[], target?: AclModel | Function): Promise<import("@adonisjs/lucid/types/model").LucidRow[]>;
58
+ allowAll(permissions: string[], target?: AclModel | Function): Promise<import("@adonisjs/lucid/types/model").LucidRow[]>;
58
59
  revokePermission(permission: string): Promise<any[]>;
59
60
  revoke(permission: string): Promise<any[]>;
60
61
  revokeAll(permissions: string[], target?: AclModel | Function): Promise<any[]>;
@@ -4,11 +4,20 @@ export class RoleHasModelPermissions {
4
4
  permissionService;
5
5
  modelService;
6
6
  map;
7
- constructor(role, permissionService, modelService, map) {
7
+ scope;
8
+ constructor(role, permissionService, modelService, map, scope) {
8
9
  this.role = role;
9
10
  this.permissionService = permissionService;
10
11
  this.modelService = modelService;
11
12
  this.map = map;
13
+ this.scope = scope;
14
+ }
15
+ on(scope) {
16
+ this.scope.set(scope);
17
+ return this;
18
+ }
19
+ getScope() {
20
+ return this.scope.get();
12
21
  }
13
22
  models() {
14
23
  return this.modelService.all(this.role.getModelId());
@@ -16,11 +25,6 @@ export class RoleHasModelPermissions {
16
25
  modelsFor(modelType) {
17
26
  return this.modelService.allFor(modelType, this.role.getModelId());
18
27
  }
19
- /**
20
- * todo
21
- * @param model
22
- */
23
- // attachTo(model: LucidModel) {}
24
28
  // permissions related BEGIN
25
29
  async permissions() {
26
30
  // for roles direct and all permissions are same
@@ -100,6 +104,9 @@ export class RoleHasModelPermissions {
100
104
  assign(permission, target) {
101
105
  return this.give(permission, target);
102
106
  }
107
+ allow(permission, target) {
108
+ return this.give(permission, target);
109
+ }
103
110
  async give(permission, target) {
104
111
  const entity = await destructTarget(this.map, target);
105
112
  return this.permissionService.giveAll(this.map.getAlias(this.role), this.role.getModelId(), [permission], entity.targetClass, entity.targetId, true);
@@ -111,6 +118,9 @@ export class RoleHasModelPermissions {
111
118
  assingAll(permissions, target) {
112
119
  return this.giveAll(permissions, target);
113
120
  }
121
+ allowAll(permissions, target) {
122
+ return this.giveAll(permissions, target);
123
+ }
114
124
  async revokePermission(permission) {
115
125
  return this.revoke(permission);
116
126
  }
@@ -1,19 +1,22 @@
1
- import { AclModel, MorphInterface, RoleInterface } from '../../types.js';
1
+ import { AclModel, MorphInterface, RoleInterface, ScopeInterface } from '../../types.js';
2
2
  import BaseService from '../base_service.js';
3
3
  import { BaseModel } from '@adonisjs/lucid/orm';
4
+ import { ModelQueryBuilderContract } from '@adonisjs/lucid/types/model';
4
5
  export default class RolesService extends BaseService {
5
6
  private roleClassName;
6
7
  private modelPermissionClassName;
7
8
  private modelRoleClassName;
8
9
  private map;
10
+ private scope;
9
11
  private roleQuery;
10
12
  private readonly roleTable;
11
13
  private readonly modelPermissionTable;
12
14
  private modelRoleQuery;
13
15
  private readonly modelRoleTable;
14
- constructor(roleClassName: typeof BaseModel, modelPermissionClassName: typeof BaseModel, modelRoleClassName: typeof BaseModel, map: MorphInterface);
16
+ private currentScope;
17
+ constructor(roleClassName: typeof BaseModel, modelPermissionClassName: typeof BaseModel, modelRoleClassName: typeof BaseModel, map: MorphInterface, scope: ScopeInterface);
15
18
  private modelRolesQuery;
16
- all(modelType: string, modelId: number): import("@adonisjs/lucid/types/model").ModelQueryBuilderContract<import("@adonisjs/lucid/types/model").LucidModel, import("../../types.js").RoleModel<import("@adonisjs/lucid/types/model").LucidModel>>;
19
+ all(modelType: string, modelId: number): ModelQueryBuilderContract<import("@adonisjs/lucid/types/model").LucidModel, import("../../types.js").RoleModel<import("@adonisjs/lucid/types/model").LucidModel>>;
17
20
  has(modelType: string, modelId: number, role: string | RoleInterface): Promise<boolean>;
18
21
  hasAll(modelType: string, modelId: number, roles: (string | RoleInterface)[]): Promise<boolean>;
19
22
  hasAny(modelType: string, modelId: number, roles: (string | RoleInterface)[]): Promise<boolean>;
@@ -22,6 +25,8 @@ export default class RolesService extends BaseService {
22
25
  revoke(role: string | number, model: AclModel): Promise<boolean>;
23
26
  revokeAll(roles: (string | number)[], model: AclModel): Promise<boolean>;
24
27
  private extractRoleModel;
25
- roleModelPermissionQuery(modelType: string): import("@adonisjs/lucid/types/model").ModelQueryBuilderContract<import("@adonisjs/lucid/types/model").LucidModel, import("../../types.js").RoleModel<import("@adonisjs/lucid/types/model").LucidModel>>;
26
- flush(modelType: string, modelId: number): import("@adonisjs/lucid/types/model").ModelQueryBuilderContract<import("@adonisjs/lucid/types/model").LucidModel, any>;
28
+ roleModelPermissionQuery(modelType: string): ModelQueryBuilderContract<import("@adonisjs/lucid/types/model").LucidModel, import("../../types.js").RoleModel<import("@adonisjs/lucid/types/model").LucidModel>>;
29
+ flush(modelType: string, modelId: number): ModelQueryBuilderContract<import("@adonisjs/lucid/types/model").LucidModel, any>;
30
+ private applyScopes;
31
+ private applyModelRoleScopes;
27
32
  }
@@ -9,6 +9,7 @@ export default class RolesService extends BaseService {
9
9
  modelPermissionClassName;
10
10
  modelRoleClassName;
11
11
  map;
12
+ scope;
12
13
  // private permissionQuery
13
14
  // private readonly permissionTable
14
15
  roleQuery;
@@ -17,18 +18,22 @@ export default class RolesService extends BaseService {
17
18
  modelPermissionTable;
18
19
  modelRoleQuery;
19
20
  modelRoleTable;
21
+ currentScope;
20
22
  constructor(roleClassName,
21
23
  // private permissionClassName: typeof BaseModel,
22
- modelPermissionClassName, modelRoleClassName, map) {
24
+ modelPermissionClassName, modelRoleClassName, map, scope) {
23
25
  super();
24
26
  this.roleClassName = roleClassName;
25
27
  this.modelPermissionClassName = modelPermissionClassName;
26
28
  this.modelRoleClassName = modelRoleClassName;
27
29
  this.map = map;
30
+ this.scope = scope;
28
31
  // this.permissionQuery = getPermissionModelQuery(this.permissionClassName)
29
32
  // this.permissionTable = this.permissionClassName.table
33
+ this.currentScope = this.scope.get();
30
34
  this.roleQuery = getRoleModelQuery(this.roleClassName);
31
35
  this.roleTable = this.roleClassName.table;
36
+ this.applyScopes(this.roleQuery, this.currentScope);
32
37
  // this.modelPermissionQuery = getModelPermissionModelQuery(this.modelPermissionClassName)
33
38
  this.modelPermissionTable = this.modelPermissionClassName.table;
34
39
  this.modelRoleQuery = getModelRoleModelQuery(this.modelRoleClassName);
@@ -110,14 +115,20 @@ export default class RolesService extends BaseService {
110
115
  }
111
116
  async revokeAll(roles, model) {
112
117
  const { slugs, ids } = this.formatListStringNumbers(roles);
113
- await this.modelRoleQuery
118
+ const q = this.modelRoleQuery
114
119
  .leftJoin(this.roleTable + ' as r', 'r.id', '=', this.modelRoleTable + '.role_id')
115
120
  .where('model_type', this.map.getAlias(model))
116
121
  .where('model_id', model.getModelId())
117
122
  .where((query) => {
118
- query.whereIn('r.id', ids).orWhereIn('r.slug', slugs);
119
- })
120
- .delete();
123
+ if (slugs.length) {
124
+ query.orWhereIn('r.slug', slugs);
125
+ }
126
+ if (ids.length) {
127
+ query.orWhereIn('r.id', ids);
128
+ }
129
+ });
130
+ this.applyModelRoleScopes(q, 'r', this.currentScope);
131
+ await q.delete();
121
132
  return true;
122
133
  }
123
134
  async extractRoleModel(roles) {
@@ -142,4 +153,10 @@ export default class RolesService extends BaseService {
142
153
  flush(modelType, modelId) {
143
154
  return this.modelRoleQuery.where('model_type', modelType).where('model_id', modelId).delete();
144
155
  }
156
+ applyScopes(q, scope) {
157
+ q.where(this.roleTable + '.scope', scope);
158
+ }
159
+ applyModelRoleScopes(q, table, scope) {
160
+ q.where(table + '.scope', scope);
161
+ }
145
162
  }
@@ -1,5 +1,7 @@
1
1
  import { LucidModel } from '@adonisjs/lucid/types/model';
2
2
  import { DateTime } from 'luxon';
3
+ import { BaseModel } from '@adonisjs/lucid/orm';
4
+ import { Scope } from './scope.js';
3
5
  export interface AclModelInterface {
4
6
  getModelId(): number;
5
7
  }
@@ -60,6 +62,7 @@ export interface ModelPermissionsQuery extends AclModelQuery {
60
62
  directPermissions: boolean;
61
63
  includeForbiddings: boolean;
62
64
  entity: Entity;
65
+ throughRoles: boolean;
63
66
  }
64
67
  export interface MorphMapInterface {
65
68
  [key: string]: any;
@@ -72,10 +75,28 @@ export interface MorphInterface {
72
75
  getAlias(target: any): string;
73
76
  }
74
77
  export interface ModelManagerInterface {
75
- [key: string]: LucidModel;
78
+ [key: string]: any;
76
79
  }
77
80
  export interface Permissions {
78
81
  tables: Object;
79
82
  morphMaps: Object;
80
83
  }
84
+ export interface ScopeInterface {
85
+ set(scope: number): ScopeInterface;
86
+ get(): number;
87
+ default(): number;
88
+ }
89
+ export interface ModelManagerBindings {
90
+ scope: typeof Scope;
91
+ role: typeof BaseModel;
92
+ permission: typeof BaseModel;
93
+ modelRole: typeof BaseModel;
94
+ modelPermission: typeof BaseModel;
95
+ }
96
+ export interface AclMiddlewareOptions {
97
+ role: string;
98
+ permission: string;
99
+ scope: number;
100
+ method: string;
101
+ }
81
102
  export {};
@@ -0,0 +1,26 @@
1
+ {{{
2
+ exports({ to: app.middlewarePath('', 'acl_middleware.ts') })
3
+ }}}
4
+ import type { HttpContext } from '@adonisjs/core/http'
5
+ import type { NextFn } from '@adonisjs/core/types/http'
6
+ import { AclManager, Scope } from '@holoyan/adonisjs-permissions'
7
+
8
+ declare module '@adonisjs/core/http' {
9
+ export interface HttpContext {
10
+ acl: AclManager
11
+ }
12
+ }
13
+
14
+ export default class UserScopeMiddleware {
15
+ //@ts-ignore
16
+ async handle(ctx: HttpContext, next: NextFn) {
17
+ const scope = new Scope()
18
+ ctx.acl = new AclManager().scope(scope)
19
+ /**
20
+ * Call next method in the pipeline and return its output
21
+ */
22
+ const output = await next()
23
+ return output
24
+ }
25
+ }
26
+
@@ -3,17 +3,16 @@
3
3
  to: app.makePath('database', 'migrations', prefix + '_create_role_permissions_table.ts')
4
4
  })
5
5
  }}}
6
-
7
6
  import { BaseSchema } from '@adonisjs/lucid/schema'
8
7
  import config from "@adonisjs/core/services/config";
9
8
 
10
9
  export default class extends BaseSchema {
11
10
 
12
11
  async up() {
13
- this.schema.createTable(config.get('permissions.permissionsConfig.tables.roles'), (table) => {
14
- table.increments('id')
12
+ this.schema.createTable(config.get('permissions.permissionsConfig.tables.permissions'), (table) => {
13
+ table.bigIncrements('id')
15
14
 
16
- table.string('slug').index()
15
+ table.string('slug')
17
16
  table.string('title').nullable()
18
17
  table.string('entity_type').defaultTo('*')
19
18
  table.bigint('entity_id').unsigned().nullable()
@@ -26,16 +25,19 @@ export default class extends BaseSchema {
26
25
  table.timestamp('created_at', { useTz: true })
27
26
  table.timestamp('updated_at', { useTz: true })
28
27
 
29
- table.unique(['slug', 'scope'])
28
+ table.index(['slug', 'scope'])
30
29
  table.index(['entity_type', 'entity_id'])
31
30
  })
32
31
 
33
- this.schema.createTable(config.get('permissions.permissionsConfig.tables.modelRoles'), (table) => {
34
- table.increments('id')
32
+ this.schema.createTable(config.get('permissions.permissionsConfig.tables.roles'), (table) => {
33
+ table.bigIncrements('id')
35
34
 
36
- table.string('model_type')
37
- table.bigint('model_id').unsigned()
38
- table.bigInteger('role_id').unsigned()
35
+ table.string('slug')
36
+ table.string('title').nullable()
37
+ table.string('entity_type').defaultTo('*')
38
+ table.bigint('entity_id').unsigned().nullable()
39
+ table.integer('scope').unsigned().defaultTo(0)
40
+ table.boolean('allowed').defaultTo(true)
39
41
 
40
42
  /**
41
43
  * Uses timestamptz for PostgreSQL and DATETIME2 for MSSQL
@@ -43,20 +45,16 @@ export default class extends BaseSchema {
43
45
  table.timestamp('created_at', { useTz: true })
44
46
  table.timestamp('updated_at', { useTz: true })
45
47
 
46
- table.index(['model_type', 'model_id'])
47
-
48
- table.foreign('role_id').references('roles.id').onDelete('CASCADE')
48
+ table.index(['slug', 'scope'])
49
+ table.index(['entity_type', 'entity_id'])
49
50
  })
50
51
 
51
- this.schema.createTable(config.get('permissions.permissionsConfig.tables.permissions'), (table) => {
52
- table.increments('id')
52
+ this.schema.createTable(config.get('permissions.permissionsConfig.tables.modelRoles'), (table) => {
53
+ table.bigIncrements('id')
53
54
 
54
- table.string('slug').index()
55
- table.string('title').nullable()
56
- table.string('entity_type').defaultTo('*')
57
- table.bigint('entity_id').unsigned().nullable()
58
- table.integer('scope').unsigned().defaultTo('*')
59
- table.boolean('allowed').defaultTo(true)
55
+ table.string('model_type')
56
+ table.bigint('model_id').unsigned()
57
+ table.bigInteger('role_id').unsigned()
60
58
 
61
59
  /**
62
60
  * Uses timestamptz for PostgreSQL and DATETIME2 for MSSQL
@@ -64,12 +62,13 @@ export default class extends BaseSchema {
64
62
  table.timestamp('created_at', { useTz: true })
65
63
  table.timestamp('updated_at', { useTz: true })
66
64
 
67
- table.unique(['slug', 'scope'])
68
- table.index(['entity_type', 'entity_id'])
65
+ table.index(['model_type', 'model_id'])
66
+
67
+ table.foreign('role_id').references('roles.id').onDelete('CASCADE')
69
68
  })
70
69
 
71
70
  this.schema.createTable(config.get('permissions.permissionsConfig.tables.modelPermissions'), (table) => {
72
- table.increments('id')
71
+ table.bigIncrements('id')
73
72
 
74
73
  table.string('model_type')
75
74
  table.bigint('model_id').unsigned()
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@holoyan/adonisjs-permissions",
3
3
  "description": "Adonisjs roles and permissions system",
4
- "version": "0.5.2",
4
+ "version": "0.6.8",
5
5
  "engines": {
6
6
  "node": ">=18.16.0"
7
7
  },