Passed
Push — master ( 7db79b...f0c033 )
by Sergey
02:16 queued 10s
created

RoleRbac.checkPermissions   F

Complexity

Conditions 20

Size

Total Lines 45
Code Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 36
dl 0
loc 45
rs 0
c 0
b 0
f 0
cc 20

How to fix   Complexity   

Complexity

Complex classes like RoleRbac.checkPermissions often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

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
9
  constructor(
10
    private readonly role: string,
11
    private readonly grant: string[],
12
    private readonly filters: object,
13
    private readonly paramsFilter?: IParamsFilter,
14
  ) {
15
  }
16
17
  async canAsync(...permissions: string[]): Promise<boolean> {
18
    return this.checkPermissions<Promise<boolean>>(permissions, 'canAsync');
19
  }
20
21
  can(...permissions: string[]): boolean {
22
    return this.checkPermissions<boolean>(permissions, 'can');
23
  }
24
25
  private checkPermissions<T>(permissions, methodName): T {
26
    if (!permissions.length) {
27
      return (<any>false);
28
    }
29
    // check grant
30
    for (const permission of permissions) {
31
      if (!this.grant.includes(permission)) {
32
        return (<any>false);
33
      }
34
    }
35
36
    // check custom filter
37
    for (const permission of permissions) {
38
      // check particular permission [permission@action]
39
      if (
40
        this.grant.includes(permission)
41
        && permission.includes('@')
42
      ) {
43
        const filter: string = permission.split('@')[1];
44
        const filterService: IFilterPermission = this.filters[filter];
45
        if (filterService) {
46
          return filterService?.[methodName]?.(
47
            this.paramsFilter ? this.paramsFilter.getParam(filter) : null,
48
          ) ?? true
49
        }
50
      }
51
      // check particular permission [permission]
52
      if (this.grant.includes(permission)
53
        && !permission.includes('@')) {
54
55
        for (const filter in this.filters) {
56
          if (
57
            this.filters.hasOwnProperty(filter) &&
58
            this.grant.includes(`${permission}@${filter}`)
59
          ) {
60
            return this.filters[filter]?.[methodName]?.(
61
              this.paramsFilter ? this.paramsFilter.getParam(filter) : null,
62
            ) ?? true
63
          }
64
        }
65
      }
66
    }
67
68
    return (<any>true);
69
  }
70
}
71