-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathindex.ts
141 lines (121 loc) · 3.82 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
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
import express = require("express");
import cors = require("cors");
import { expressjwt as jwt, GetVerificationKey } from "express-jwt";
import jwksRsa = require("jwks-rsa");
import { Store } from "./store";
import { Server } from "./server";
import { UserCache, User } from "./interfaces";
import * as dotenv from "dotenv";
import * as dotenvExpand from "dotenv-expand";
import { Request as JWTRequest } from "express-jwt";
dotenvExpand.expand(dotenv.config());
import { Authorizer, Middleware, SubIdentityMapper } from "@aserto/aserto-node";
import { getConfig } from "./config";
const authzOptions = getConfig();
const authClient = new Authorizer({
authorizerServiceUrl: authzOptions.authorizerServiceUrl,
authorizerApiKey: authzOptions.authorizerApiKey,
tenantId: authzOptions.tenantId,
caFile: authzOptions.authorizerCertCAFile,
});
const checkJwt = jwt({
// Dynamically provide a signing key based on the kid in the header and the signing keys provided by the JWKS endpoint
secret: jwksRsa.expressJwtSecret({
cache: true,
rateLimit: true,
jwksRequestsPerMinute: 5,
jwksUri: process.env.JWKS_URI,
}) as GetVerificationKey,
// Validate the audience and the issuer
audience: process.env.AUDIENCE,
issuer: process.env.ISSUER,
algorithms: ["RS256"],
});
const app: express.Application = express();
app.use(express.json());
app.use(cors());
const PORT = 3001;
Store.open().then((store) => {
const server = new Server(store);
// Aserto authorizer middleware
const restMiddleware = new Middleware({
client: authClient,
policy: {
name: authzOptions.instanceName,
instanceLabel: authzOptions.instanceLabel,
root: authzOptions.policyRoot,
},
resourceMapper: async (req: express.Request) => {
if (!req.params?.id) {
return {};
}
return { object_id: req.params.id };
},
identityMapper: SubIdentityMapper(),
});
// Aserto check middleware
const checkMiddleware = new Middleware({
client: authClient,
policy: {
name: authzOptions.instanceName,
instanceLabel: authzOptions.instanceLabel,
root: "rebac",
},
identityMapper: SubIdentityMapper(),
});
// Users cache
const users: UserCache = {};
app.get(
"/users/:userID",
checkJwt,
restMiddleware.Authz(),
async (req: JWTRequest, res) => {
const { userID } = req.params;
let user: User = users[userID];
if (user) {
res.json(user);
return;
}
if (req.auth.sub === userID) {
user = await server.directory.getUserByIdentity(userID);
} else {
user = await server.directory.getUserById(userID);
}
// Fill cache
users[userID] = user;
res.json(user);
},
);
// restMiddleware.Authz() selects the policy module to evaluate based on the REST convention
// e.g. GET /todos -> todoApp.GET.todos
app.get("/todos", checkJwt, restMiddleware.Authz(), server.list.bind(server));
app.put(
"/todos/:id",
checkJwt,
restMiddleware.Authz(),
server.update.bind(server),
);
app.delete(
"/todos/:id",
checkJwt,
restMiddleware.Authz(),
server.delete.bind(server),
);
// commenting out restMiddleware.Authz() to demonstrate the use of the Check middleware below
// app.post("/todos", checkJwt, restMiddleware.Authz(), server.create.bind(server));
// checkMiddleware.Check() evaluates the "standard" rebac.check module.
// the Check below only grants access to users who are members of the resource-creators instance
app.post(
"/todos",
checkJwt,
checkMiddleware.Check({
objectType: "resource-creator",
objectId: "resource-creators",
relation: "member",
}),
server.create.bind(server),
);
app.listen(PORT, () => {
console.log(`⚡️[server]: Server is running at http://localhost:${PORT}`);
});
});