Passed
Push — master ( 0e7a3d...2c4b2e )
by Sergey
02:01
created

StorageRbacService.setIntoCache   A

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 3
rs 10
c 0
b 0
f 0
cc 1
1
import { Inject, Injectable, Optional } from '@nestjs/common';
2
import { IStorageRbac } from '../interfaces/storage.rbac.interface';
3
import { ModuleRef } from '@nestjs/core';
4
import { IDynamicStorageRbac } from '../interfaces/dynamic.storage.rbac.interface';
5
import { ICacheRBAC } from '../interfaces/cache.rbac.interface';
6
7
@Injectable()
8
export class StorageRbacService {
9
  constructor(
10
    private readonly moduleRef: ModuleRef,
11
    private readonly rbac: IDynamicStorageRbac,
12
    @Optional() @Inject('ICacheRBAC')
13
    private readonly cache?: ICacheRBAC,
14
  ) {
15
16
  }
17
18
  async getStorage(): Promise<IStorageRbac> {
19
    return await this.rbac.getRbac();
20
  }
21
22
  async getPermissions(): Promise<object> {
23
    return (await this.rbac.getRbac()).permissions;
24
  }
25
26
  async getGrants(): Promise<object> {
27
    return (await this.rbac.getRbac()).grants;
28
  }
29
30
  async getRoles(): Promise<string[]> {
31
    return (await this.rbac.getRbac()).roles;
32
  }
33
34
  async getGrant(role: string): Promise<string[]> {
35
    const grant: object = await this.parseGrants();
36
37
    return grant[role] || [];
38
  }
39
40
  async getFilters(): Promise<object> {
41
    const result: any = {};
42
    const filters = (await this.getStorage()).filters;
43
    /* tslint:disable */
44
    for (const key in filters) {
45
      let filter;
46
      try {
47
        filter = this.moduleRef.get(filters[key]);
48
      } catch (e) {
49
        filter = await this.moduleRef.create(filters[key]);
50
      }
51
      result[key] = filter;
52
    }
53
54
    return result;
55
  }
56
57
  private async parseGrants(): Promise<object> {
58
59
    if (this.cache) {
60
      const cache = await this.getFromCache();
61
      if (cache) {
62
63
        return cache;
64
      }
65
    }
66
67
    const { grants, permissions } = await this.rbac.getRbac();
68
    const result = {};
69
    Object.keys(grants).forEach((key) => {
70
      const grant = grants[key];
71
72
      result[key] = [
73
        // remove duplicate
74
        ...new Set(
75
          // get extended
76
          grant.filter((value: string) => !value.startsWith('&')),
77
        ),
78
      ]
79
      // remove not existed
80
        .filter((value: string) => {
81
          if (value.includes('@')) {
82
            const spilt = value.split('@');
83
            if (!permissions[spilt[0]]) {
84
              return false;
85
            }
86
87
            return permissions[spilt[0]].some((inAction) => inAction === spilt[1]);
88
          }
89
          if (permissions[value]) {
90
            return permissions[value];
91
          }
92
93
        });
94
95
    });
96
    const findExtendedGrants = {};
97
    Object.keys(grants).forEach((key) => {
98
      const grant = grants[key];
99
100
      findExtendedGrants[key] = [
101
        // remove duplicate
102
        ...new Set(
103
          // get extended
104
          grant.filter((value: string) => {
105
            if (value.startsWith('&')) {
106
              const subGrant = value.substr(1);
107
              if (grants[value.substr(1)] && subGrant !== key) {
108
                return true;
109
              }
110
            }
111
            return false;
112
          }).map(value => value.substr(1)),
113
        ),
114
      ];
115
    });
116
117
    Object.keys(findExtendedGrants).forEach((key) => {
118
      const grant = findExtendedGrants[key];
119
120
      grant.forEach((value) => {
121
        result[key] = [...new Set([...result[key], ...result[value]])];
122
      });
123
124
    });
125
126
    Object.keys(result).forEach((key) => {
127
      const grant = result[key];
128
129
      const per = [];
130
      grant.forEach((value) => {
131
        if (!value.includes('@')) {
132
          per.push(...permissions[value].map((dd) => {
133
            return `${value}@${dd}`;
134
          }));
135
        }
136
      });
137
138
      result[key] = [...new Set([...result[key], ...per])];
139
140
    });
141
142
    if (this.cache) {
143
      this.setIntoCache(result);
144
    }
145
146
    return result;
147
  }
148
149
  private async getFromCache(): Promise<object | null> {
150
    return this.cache.get();
151
  }
152
153
  private async setIntoCache(value: object): Promise<void> {
154
    await this.cache.set(value);
155
  }
156
}
157