-
Notifications
You must be signed in to change notification settings - Fork 1
/
index.ts
76 lines (63 loc) · 2.28 KB
/
index.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
72
73
74
75
76
import { Permission, PermissionInstanceType } from "./permissions";
// Example app permissions.
/** Grants permission to "change system settings". This is all-or-nothing access, with no further granularity. A 'unit' permission */
export const PermissionToChangeSystemSettings = Permission.declare( "ChangeSystemSettings");
export type PermissionToChangeSystemSettings = PermissionInstanceType<
typeof PermissionToChangeSystemSettings
>;
/** Grants permission to view a specific document, captured by the document ID. */
export const PermissionToViewDocument = Permission.declare(
"PermissionToViewDocument",
Permission.ofType<{ documentId: DocumentId }>()
);
export type PermissionToViewDocument = PermissionInstanceType<
typeof PermissionToViewDocument
>;
/** This can be whatever basic info about your user you have on hand during requests */
type DocumentId = number;
type UserId = number;
interface UserSession {
id: UserId;
role: "admin" | "user";
}
interface DocumentMetadata {
id: DocumentId;
authorId: UserId;
}
class Authorizer {
constructor(private _user: UserSession) {}
canChangeSystemSettings = Permission.checker(
PermissionToChangeSystemSettings,
() => {
return this._user.role === "admin";
}
);
canViewDocument = Permission.asyncChecker(
PermissionToViewDocument,
async (documentId: DocumentId) => {
const document = await loadDocumentMetadata(documentId)
if (document.authorId == this._user.id) {
return { documentId: document.id };
} else {
return Permission.deny();
}
}
);
}
// Service layer / business logic layer
function updateSystemSettings(
permission: PermissionToChangeSystemSettings,
newSettings: SystemSettings
) {
//....
}
function getDocumentContent(permission: PermissionToViewDocument): Promise<string> {
return loadDocumentContentFromDb(permission.documentId);
}
// Data access functions
declare function loadDocumentMetadata(docId: DocumentId): Promise<DocumentMetadata>;
declare function loadDocumentContentFromDb(docId: DocumentId): Promise<string>;
async function documentContentResolver(_: any, args: {documentId: DocumentId}, ctx: {auth: Authorizer}) {
const hasPermission = await ctx.auth.canViewDocument.enforce(args.documentId)
return getDocumentContent(hasPermission)
}