-
-
Notifications
You must be signed in to change notification settings - Fork 47
/
authorize.decorator.ts
71 lines (62 loc) · 2.17 KB
/
authorize.decorator.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
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
import { getMetadataArgsStorage } from "../../../mod.ts";
import { HookTarget } from "../../../models/hook.ts";
import { SecurityContext } from "../../context/security-context.ts";
import { BusinessType } from "../../../types/business.ts";
import {
AuthenticationScheme,
Identity,
} from "../../authentication/core/auth.interface.ts";
import { container } from "../../../injection/index.ts";
import { AuthPolicy } from "./auth-policy.model.ts";
type AuthPayload = { roles?: string[]; policy?: AuthPolicy };
type SchemePayload = { scheme: AuthenticationScheme; payload?: AuthPayload };
export function Authorize(
scheme: AuthenticationScheme,
payload?: AuthPayload,
): Function {
return function (object: any, methodName?: string) {
// add hook to global metadata
getMetadataArgsStorage().hooks.push({
type: methodName ? BusinessType.Action : BusinessType.Controller,
object,
target: object.constructor,
method: methodName ? methodName : "",
instance: container.resolve(AutorizeHook),
payload: { scheme, payload },
});
};
}
export class AutorizeHook implements
HookTarget<
unknown,
{ scheme: AuthenticationScheme; payload?: AuthPayload }
> {
async onPreAction(
context: SecurityContext<unknown>,
schemePayload: SchemePayload,
) {
let isAuthSuccess = false;
const identity = context.security.auth.identity();
if (identity != undefined && schemePayload.payload === undefined) {
isAuthSuccess = true;
}
if (schemePayload.payload && identity !== undefined) {
isAuthSuccess = isRolesContains(identity, schemePayload.payload.roles) ||
await isPolicyValidResult(context, schemePayload.payload.policy);
}
isAuthSuccess
? schemePayload.scheme.onSuccessResult(context)
: schemePayload.scheme.onFailureResult(context);
return isAuthSuccess;
}
}
function isRolesContains(identity: Identity<unknown>, roles?: string[]) {
return !!identity.roles && roles &&
!!identity.roles.find((role) => roles!.find((crole) => crole === role));
}
async function isPolicyValidResult(
context: SecurityContext,
policy?: AuthPolicy,
) {
return !!policy && await policy(context);
}