-
Notifications
You must be signed in to change notification settings - Fork 13
/
oso.guard.ts
54 lines (48 loc) · 1.91 KB
/
oso.guard.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
import {
CanActivate,
createParamDecorator,
ExecutionContext,
ForbiddenException,
Injectable, SetMetadata,
} from '@nestjs/common';
import { Reflector } from '@nestjs/core';
import { getLogger } from 'log4js';
import { Guest } from '../users/entity/guest';
import { OsoInstance } from './oso-instance';
const authorizeLogger = getLogger('@Authorize');
export const Action = (action: string) => SetMetadata('action', action);
export const Resource = (resource: any) => SetMetadata('resource', resource);
export const authorizeFactory = (data: string | undefined, ctx: ExecutionContext) => {
authorizeLogger.info('data: ', data);
const request = ctx.switchToHttp().getRequest();
const user = request.user;
const action = data || ctx.getHandler().name;
const oso = request.oso;
return async (resource: any) => {
authorizeLogger.info('isAllowed: user: ', user, '; action: ', action, '; resource: ', resource);
const isAllowed = await oso.isAllowed(user, action, resource);
authorizeLogger.info('isAllowed: ', isAllowed);
if (!isAllowed) {
authorizeLogger.info('is NOT allowed. Throwing ForbiddenException...');
throw new ForbiddenException();
}
};
};
export const Authorize = createParamDecorator(authorizeFactory);
@Injectable()
export class OsoGuard implements CanActivate {
constructor(private reflector: Reflector, private oso: OsoInstance) {
}
canActivate(context: ExecutionContext): Promise<boolean> {
const request = context.switchToHttp().getRequest();
const actor = request.user || new Guest();
const action =
this.reflector.get<string[]>('action', context.getHandler()) ||
context.getHandler().name;
const resource =
this.reflector.get<string[]>('resource', context.getHandler()) ||
this.reflector.get<string[]>('resource', context.getClass()) ||
context.getClass().name;
return this.oso.isAllowed(actor, action, resource);
}
}