-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathpermissions.ts
More file actions
97 lines (81 loc) · 2.44 KB
/
permissions.ts
File metadata and controls
97 lines (81 loc) · 2.44 KB
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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
import { STAGE, standardAwsConfig } from "./awsIntegration";
import { S3 } from "@aws-sdk/client-s3";
interface Override {
userId: string;
active: boolean;
}
interface Permission {
permission: {
name: string;
app: string;
};
overrides: Override[];
}
const s3 = new S3(standardAwsConfig);
async function loadPermissions() {
const { Body } = await s3.getObject({
Bucket: "permissions-cache",
Key: `${STAGE}/permissions.json`,
});
if (!Body) {
throw Error("could not read permissions");
}
const transformedBody = await Body.transformToString();
const allPermissions = JSON.parse(transformedBody) as Permission[];
return { allPermissions, loadTime: new Date() };
}
let cache = loadPermissions();
async function getOrRefresh() {
const prevCache = await cache;
const now = new Date();
const sixtySecsAgo = new Date(now.getTime() - 60_000);
if (prevCache.loadTime < sixtySecsAgo) {
cache = loadPermissions().catch((e) => {
console.error(
"Refreshing permissions cache failed with error, so keeping stale cache...",
e
);
return { allPermissions: prevCache.allPermissions, loadTime: new Date() };
});
}
const { allPermissions } = await cache;
return allPermissions;
}
const getAllPermissions = () => {
return getOrRefresh();
};
const getAllPinboardOverrides = async (
permissionName: string
): Promise<Override[] | undefined> => {
const allPermissions = await getAllPermissions();
return allPermissions.find(
({ permission }) =>
permission.app === "pinboard" && permission.name === permissionName
)?.overrides;
};
export const getPinboardAccessPermissionOverrides = () =>
getAllPinboardOverrides("pinboard");
export const listUserPermissions = async (userEmail: string) => {
const allPermissions = await getAllPermissions();
const relevantPermissions = [];
for (const { permission, overrides } of allPermissions) {
if (permission.app === "pinboard") {
for (const override of overrides) {
if (override.active && override.userId === userEmail) {
relevantPermissions.push(permission.name);
break;
}
}
}
}
return relevantPermissions;
};
export const userHasPermission = async (
userEmail: string,
permission: string
): Promise<boolean> => {
const overrides = await getAllPinboardOverrides(permission);
return Boolean(
overrides?.some(({ userId, active }) => userId === userEmail && active)
);
};