Passed
Pull Request — master (#72)
by
unknown
03:09
created

RoleRbac.any   A

Complexity

Conditions 1

Size

Total Lines 11
Code Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 9
dl 0
loc 11
c 0
b 0
f 0
rs 9.95
cc 1
1
import { Injectable } from '@nestjs/common';
2
import { IRoleRbac } from './interfaces/role.rbac.interface';
3
import { IFilterPermission } from '../permissions/interfaces/filter.permission.interface';
4
import { IParamsFilter } from '../params-filter/interfaces/params.filter.interface';
5
6
@Injectable()
7
export class RoleRbac implements IRoleRbac {
8
  constructor (
9
    private readonly role: string,
10
    private readonly grant: string[],
11
    private readonly filters: object,
12
    private readonly paramsFilter?: IParamsFilter,
13
  ) {}
14
15
  async canAsync (...permissions: string[]): Promise<boolean> {
16
    return this.checkPermissions<Promise<boolean>>(permissions, 'canAsync');
17
  }
18
19
  can (...permissions: string[]): boolean {
20
    return this.checkPermissions<boolean>(permissions, 'can');
21
  }
22
23
  any (...permissions: string[][]): boolean {
24
    // loop through the list of permission list
25
    return (
26
      permissions
27
        .map(permission => {
28
          // check each of the permission list
29
          return this.can(...permission);
30
        })
31
        // any permission list is true, then return true as result
32
        .some(result => result)
33
    );
34
  }
35
36
  async anyAsync (...permissions: string[][]): Promise<boolean> {
37
    return (
38
      await Promise.all(
39
        permissions.map(async permission => {
40
          return await this.canAsync(...permission);
41
        }),
42
      )
43
    ).some(result => result);
44
  }
45
46
  private checkPermissions<T> (permissions, methodName): T {
47
    if (!permissions.length) {
48
      return false as any;
49
    }
50
    // check grant
51
    for (const permission of permissions) {
52
      if (!this.grant.includes(permission)) {
53
        return false as any;
54
      }
55
    }
56
57
    // check custom filter
58
    for (const permission of permissions) {
59
      // check particular permission [permission@action]
60
      if (this.grant.includes(permission) && permission.includes('@')) {
61
        const filter: string = permission.split('@')[1];
62
        const filterService: IFilterPermission = this.filters[filter];
63
        if (filterService) {
64
          return (
65
            filterService?.[methodName]?.(
66
              this.paramsFilter ? this.paramsFilter.getParam(filter) : null,
67
            ) ?? true
68
          );
69
        }
70
      }
71
      // check particular permission [permission]
72
      if (this.grant.includes(permission) && !permission.includes('@')) {
73
        for (const filter in this.filters) {
74
          if (
75
            this.filters.hasOwnProperty(filter) &&
76
            this.grant.includes(`${permission}@${filter}`)
77
          ) {
78
            return (
79
              this.filters[filter]?.[methodName]?.(
80
                this.paramsFilter ? this.paramsFilter.getParam(filter) : null,
81
              ) ?? true
82
            );
83
          }
84
        }
85
      }
86
    }
87
88
    return true as any;
89
  }
90
}
91