Passed
Push — master ( 198edd...da006d )
by Sergey
04:08 queued 01:46
created

RBAcGuard.canActivate   B

Complexity

Conditions 6

Size

Total Lines 48
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 34
dl 0
loc 48
rs 8.1306
c 0
b 0
f 0
cc 6
1
import { CanActivate, ExecutionContext, ForbiddenException, Injectable } from '@nestjs/common';
2
import { Reflector } from '@nestjs/core';
3
import { RbacService } from '../services/rbac.service';
4
import { IRole } from '../role/interfaces/role.interface';
5
import { ParamsFilter } from '../params-filter/params.filter';
6
import { ASYNC_RBAC_REQUEST_FILTER, RBAC_REQUEST_FILTER } from '../constans';
7
import {
8
    RBAcAnyAsyncPermissions,
9
    RBAcAnyPermissions,
10
    RBAcAsyncPermissions,
11
    RBAcPermissions
12
} from '../decorators/rbac.permissions.decorator';
13
14
@Injectable()
15
export class RBAcGuard implements CanActivate {
16
    constructor(
17
        private readonly reflector: Reflector,
18
        private readonly rbacService: RbacService,
19
    ) {
20
21
    }
22
23
    async canActivate(
24
        context: ExecutionContext,
25
    ): Promise<boolean> {
26
        const request = context.switchToHttp().getRequest();
27
        const user: IRole = request.user;
28
29
        if (!user) {
30
            throw new ForbiddenException('Getting user was failed.');
31
        }
32
33
        {
34
            const permAsync = this.rbacAsync(context);
35
            if (permAsync.length > 0) {
36
                const filter = new ParamsFilter();
37
                filter.setParam(ASYNC_RBAC_REQUEST_FILTER, {...request});
38
                return (await this.rbacService.getRole(user.role, filter)).canAsync(...permAsync);
39
            }
40
        }
41
42
        {
43
            const perm = this.rbac(context);
44
            if (perm.length > 0) {
45
                const filter = new ParamsFilter();
46
                filter.setParam(RBAC_REQUEST_FILTER, {...request});
47
                return (await this.rbacService.getRole(user.role, filter)).can(...perm);
48
            }
49
        }
50
51
        {
52
            const permAny = this.rbacAny(context);
53
            if (permAny.length > 0) {
54
                const filter = new ParamsFilter();
55
                filter.setParam(RBAC_REQUEST_FILTER, {...request});
56
                return (await this.rbacService.getRole(user.role, filter)).any(...permAny);
57
            }
58
        }
59
60
        {
61
            const permAnyAsync = this.rbacAnyAsync(context);
62
            if (permAnyAsync.length > 0) {
63
                const filter = new ParamsFilter();
64
                filter.setParam(ASYNC_RBAC_REQUEST_FILTER, {...request});
65
                return await (await this.rbacService.getRole(user.role, filter)).anyAsync(...permAnyAsync);
66
            }
67
        }
68
69
        throw new ForbiddenException();
70
    }
71
72
    private rbacAsync(context: ExecutionContext): string[] {
73
        const permissions = this.reflector.get<string[]>(RBAcAsyncPermissions.name, context.getHandler())
74
            || this.reflector.get<string[]>(RBAcAsyncPermissions.name, context.getClass());
75
76
        if (permissions !== undefined) {
77
            return permissions;
78
        }
79
80
        return [];
81
    }
82
83
    private rbac(context: ExecutionContext): string[] {
84
        const permissions = this.reflector.get<string[]>(RBAcPermissions.name, context.getHandler())
85
            || this.reflector.get<string[]>(RBAcPermissions.name, context.getClass());
86
87
        if (permissions !== undefined) {
88
            return permissions;
89
        }
90
91
        return [];
92
    }
93
94
    private rbacAny(context: ExecutionContext): string[][] {
95
        const permissions = this.reflector.get<string[][]>(RBAcAnyPermissions.name, context.getHandler())
96
            || this.reflector.get<string[][]>(RBAcAnyPermissions.name, context.getClass());
97
98
        if (permissions !== undefined) {
99
            return permissions;
100
        }
101
102
        return [];
103
    }
104
105
    private rbacAnyAsync(context: ExecutionContext): string[][] {
106
        const permissions = this.reflector.get<string[][]>(RBAcAnyAsyncPermissions.name, context.getHandler())
107
            || this.reflector.get<string[][]>(RBAcAnyAsyncPermissions.name, context.getClass());
108
109
        if (permissions !== undefined) {
110
            return permissions;
111
        }
112
113
        return [];
114
    }
115
}
116