@magda/typescript-common 1.3.0-rc.0 → 2.0.0-alpha.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/BaseApiClient.d.ts +41 -0
- package/dist/BaseApiClient.js +63 -0
- package/dist/BaseApiClient.js.map +1 -0
- package/dist/IndexerApiClient.d.ts +16 -0
- package/dist/IndexerApiClient.js +39 -0
- package/dist/IndexerApiClient.js.map +1 -0
- package/dist/JsonTransformer.js +1 -2
- package/dist/JsonTransformer.js.map +1 -1
- package/dist/OpaCompileResponseParser.d.ts +260 -36
- package/dist/OpaCompileResponseParser.js +697 -297
- package/dist/OpaCompileResponseParser.js.map +1 -1
- package/dist/SQLUtils.d.ts +70 -0
- package/dist/SQLUtils.js +263 -0
- package/dist/SQLUtils.js.map +1 -0
- package/dist/ServerError.d.ts +9 -0
- package/dist/ServerError.js +17 -0
- package/dist/ServerError.js.map +1 -0
- package/dist/Try.d.ts +17 -0
- package/dist/Try.js +68 -0
- package/dist/Try.js.map +1 -0
- package/dist/authorization-api/ApiClient.d.ts +9 -13
- package/dist/authorization-api/ApiClient.js +88 -31
- package/dist/authorization-api/ApiClient.js.map +1 -1
- package/dist/authorization-api/authMiddleware.d.ts +60 -2
- package/dist/authorization-api/authMiddleware.js +154 -9
- package/dist/authorization-api/authMiddleware.js.map +1 -1
- package/dist/authorization-api/constants.d.ts +6 -0
- package/dist/authorization-api/constants.js +14 -0
- package/dist/authorization-api/constants.js.map +1 -0
- package/dist/authorization-api/model.d.ts +57 -28
- package/dist/createNoCacheFetchOptions.d.ts +15 -0
- package/dist/createNoCacheFetchOptions.js +20 -0
- package/dist/createNoCacheFetchOptions.js.map +1 -0
- package/dist/express/getNoCacheHeaders.d.ts +6 -0
- package/dist/express/getNoCacheHeaders.js +9 -0
- package/dist/express/getNoCacheHeaders.js.map +1 -0
- package/dist/express/setResponseNoCache.d.ts +3 -0
- package/dist/express/setResponseNoCache.js +9 -0
- package/dist/express/setResponseNoCache.js.map +1 -0
- package/dist/fetchRequest.d.ts +11 -0
- package/dist/fetchRequest.js +62 -0
- package/dist/fetchRequest.js.map +1 -0
- package/dist/generated/registry/api.d.ts +48 -7
- package/dist/generated/registry/api.js +197 -2
- package/dist/generated/registry/api.js.map +1 -1
- package/dist/getRequest.d.ts +1 -0
- package/dist/getRequest.js +28 -0
- package/dist/getRequest.js.map +1 -0
- package/dist/getRequestNoCache.d.ts +1 -0
- package/dist/getRequestNoCache.js +23 -0
- package/dist/getRequestNoCache.js.map +1 -0
- package/dist/getStorageUrl.d.ts +34 -0
- package/dist/getStorageUrl.js +138 -0
- package/dist/getStorageUrl.js.map +1 -0
- package/dist/handleServerError.d.ts +2 -0
- package/dist/handleServerError.js +17 -0
- package/dist/handleServerError.js.map +1 -0
- package/dist/opa/AspectQuery.d.ts +71 -0
- package/dist/opa/AspectQuery.js +219 -0
- package/dist/opa/AspectQuery.js.map +1 -0
- package/dist/opa/AuthDecision.d.ts +51 -0
- package/dist/opa/AuthDecision.js +241 -0
- package/dist/opa/AuthDecision.js.map +1 -0
- package/dist/opa/AuthDecisionQueryClient.d.ts +23 -0
- package/dist/opa/AuthDecisionQueryClient.js +113 -0
- package/dist/opa/AuthDecisionQueryClient.js.map +1 -0
- package/dist/pgTypes.d.ts +1 -0
- package/dist/pgTypes.js +18 -0
- package/dist/pgTypes.js.map +1 -0
- package/dist/registry/AuthorizedRegistryClient.d.ts +8 -11
- package/dist/registry/AuthorizedRegistryClient.js +73 -21
- package/dist/registry/AuthorizedRegistryClient.js.map +1 -1
- package/dist/registry/RegistryClient.d.ts +8 -0
- package/dist/registry/RegistryClient.js +57 -6
- package/dist/registry/RegistryClient.js.map +1 -1
- package/dist/registry/model.d.ts +5 -0
- package/dist/registry/model.js +3 -0
- package/dist/registry/model.js.map +1 -0
- package/dist/test/arbitraries.js +2 -4
- package/dist/test/arbitraries.js.map +1 -1
- package/dist/test/buildApiClient.spec.js +2 -41
- package/dist/test/buildApiClient.spec.js.map +1 -1
- package/dist/test/db/getTestDBConfig.js +1 -1
- package/dist/test/db/getTestDBConfig.js.map +1 -1
- package/dist/test/getAuthDecision.spec.js +2 -2
- package/dist/test/getAuthDecision.spec.js.map +1 -1
- package/dist/test/getStorageUrl.spec.d.ts +1 -0
- package/dist/test/getStorageUrl.spec.js +95 -0
- package/dist/test/getStorageUrl.spec.js.map +1 -0
- package/dist/test/mockAuthApiHost.js +2 -26
- package/dist/test/mockAuthApiHost.js.map +1 -1
- package/dist/test/mockAuthorization.js +2 -2
- package/dist/test/mockAuthorization.js.map +1 -1
- package/dist/test/registry/buildAuthorizedClient.spec.js +9 -7
- package/dist/test/registry/buildAuthorizedClient.spec.js.map +1 -1
- package/dist/test/sampleAuthDecisions/content.json +29 -0
- package/dist/test/sampleAuthDecisions/datasetPermissionWithOrgUnitConstraint.json +79 -0
- package/dist/test/sampleAuthDecisions/extraLargeResponse.json +2519 -0
- package/dist/test/sampleAuthDecisions/simple.json +29 -0
- package/dist/test/sampleAuthDecisions/singleTermAspectRef.json +39 -0
- package/dist/test/sampleAuthDecisions/unconditionalFalseSimple.json +6 -0
- package/dist/test/sampleAuthDecisions/unconditionalNotMacthed.json +6 -0
- package/dist/test/sampleAuthDecisions/unconditionalNotMacthedWithExtraRefs.json +6 -0
- package/dist/test/sampleAuthDecisions/unconditionalTrue.json +6 -0
- package/dist/test/sampleAuthDecisions/unconditionalTrueSimple.json +6 -0
- package/dist/test/sampleAuthDecisions/unconditionalTrueWithDefaultRule.json +6 -0
- package/dist/test/sampleAuthDecisions/withDefaultRule.json +6 -0
- package/dist/test/{sampleOpaResponse.json → sampleOpaResponses/content.json} +0 -0
- package/dist/test/sampleOpaResponses/datasetPermissionWithOrgUnitConstraint.json +341 -0
- package/dist/test/sampleOpaResponses/extraLargeResponse.json +104869 -0
- package/dist/test/{sampleOpaResponseSimple.json → sampleOpaResponses/simple.json} +0 -0
- package/dist/test/sampleOpaResponses/singleTermAspectRef.json +233 -0
- package/dist/test/sampleOpaResponses/unconditionalFalseSimple.json +3 -0
- package/dist/test/sampleOpaResponses/unconditionalNotMacthed.json +73 -0
- package/dist/test/sampleOpaResponses/unconditionalNotMacthedWithExtraRefs.json +155 -0
- package/dist/test/{sampleOpaResponseUnconditionalTrue.json → sampleOpaResponses/unconditionalTrue.json} +0 -0
- package/dist/test/sampleOpaResponses/unconditionalTrueSimple.json +48 -0
- package/dist/test/{sampleOpaResponseUnconditionalTrueWithDefaultRule.json → sampleOpaResponses/unconditionalTrueWithDefaultRule.json} +0 -0
- package/dist/test/{sampleOpaResponseWithDefaultRule.json → sampleOpaResponses/withDefaultRule.json} +0 -0
- package/dist/test/testOpaCompileResponseParser.spec.js +212 -20
- package/dist/test/testOpaCompileResponseParser.spec.js.map +1 -1
- package/package.json +9 -6
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { User, Role, Permission, OrgUnit } from "./model";
|
|
1
|
+
import { User, CreateUserData, UserRecord, Role, Permission, OrgUnit, OrgUnitRecord, CreateRolePermissionInputData, PermissionRecord, OperationRecord, ResourceRecord } from "./model";
|
|
2
2
|
import { Maybe } from "tsmonad";
|
|
3
3
|
import { RequiredKeys } from "../utilityTypes";
|
|
4
4
|
export default class ApiClient {
|
|
@@ -16,15 +16,6 @@ export default class ApiClient {
|
|
|
16
16
|
* @memberof ApiClient
|
|
17
17
|
*/
|
|
18
18
|
getUser(userId: string): Promise<Maybe<RequiredKeys<User, "id">>>;
|
|
19
|
-
/**
|
|
20
|
-
* Get the data of a user.
|
|
21
|
-
* (Deprecated) This is the public facing API and will return less fields.
|
|
22
|
-
*
|
|
23
|
-
* @param {string} userId
|
|
24
|
-
* @returns {Promise<Maybe<User>>}
|
|
25
|
-
* @memberof ApiClient
|
|
26
|
-
*/
|
|
27
|
-
getUserPublic(userId: string): Promise<Maybe<RequiredKeys<User, "id">>>;
|
|
28
19
|
/**
|
|
29
20
|
* Lookup user by source (identity provider) & sourceId (identity ID)
|
|
30
21
|
*
|
|
@@ -37,11 +28,11 @@ export default class ApiClient {
|
|
|
37
28
|
/**
|
|
38
29
|
* create a user
|
|
39
30
|
*
|
|
40
|
-
* @param {
|
|
41
|
-
* @returns {Promise<
|
|
31
|
+
* @param {CreateUserData} user
|
|
32
|
+
* @returns {Promise<UserRecord>}
|
|
42
33
|
* @memberof ApiClient
|
|
43
34
|
*/
|
|
44
|
-
createUser(user:
|
|
35
|
+
createUser(user: CreateUserData): Promise<UserRecord>;
|
|
45
36
|
/**
|
|
46
37
|
* Add Roles to a user.
|
|
47
38
|
* Returns a list of current role ids of the user.
|
|
@@ -137,5 +128,10 @@ export default class ApiClient {
|
|
|
137
128
|
* @memberof ApiClient
|
|
138
129
|
*/
|
|
139
130
|
getAllOrgUnitChildren(nodeId: string): Promise<OrgUnit[]>;
|
|
131
|
+
createOrgNode(parentNodeId: string, node: Partial<Omit<OrgUnitRecord, "id" | "createBy" | "createTime" | "editBy" | "editTime" | "left" | "right">>): Promise<OrgUnit>;
|
|
132
|
+
createRole(name: string, desc?: string): Promise<Role>;
|
|
133
|
+
createRolePermission(roleId: string, permissionData: CreateRolePermissionInputData): Promise<PermissionRecord>;
|
|
134
|
+
getOperationByUri(opUri: string): Promise<OperationRecord>;
|
|
135
|
+
getResourceByUri(resUri: string): Promise<ResourceRecord>;
|
|
140
136
|
private handleGetResult;
|
|
141
137
|
}
|
|
@@ -16,9 +16,10 @@ const isomorphic_fetch_1 = __importDefault(require("isomorphic-fetch"));
|
|
|
16
16
|
const tsmonad_1 = require("tsmonad");
|
|
17
17
|
const lodash_1 = __importDefault(require("lodash"));
|
|
18
18
|
const buildJwt_1 = __importDefault(require("../session/buildJwt"));
|
|
19
|
-
const GenericError_1 = __importDefault(require("./GenericError"));
|
|
20
19
|
const addTrailingSlash_1 = __importDefault(require("../addTrailingSlash"));
|
|
21
20
|
const urijs_1 = __importDefault(require("urijs"));
|
|
21
|
+
const ServerError_1 = __importDefault(require("../ServerError"));
|
|
22
|
+
const isUuid_1 = __importDefault(require("../util/isUuid"));
|
|
22
23
|
class ApiClient {
|
|
23
24
|
constructor(
|
|
24
25
|
// e.g. http://authorization-api/v0
|
|
@@ -30,14 +31,29 @@ class ApiClient {
|
|
|
30
31
|
if (jwtSecret && userId) {
|
|
31
32
|
this.jwt = buildJwt_1.default(jwtSecret, userId);
|
|
32
33
|
}
|
|
33
|
-
this.
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
34
|
+
if (this.jwt) {
|
|
35
|
+
this.requestInitOption = {
|
|
36
|
+
headers: {
|
|
37
|
+
"X-Magda-Session": this.jwt
|
|
38
|
+
}
|
|
39
|
+
};
|
|
40
|
+
}
|
|
38
41
|
}
|
|
39
42
|
getMergeRequestInitOption(extraOptions = null) {
|
|
40
|
-
|
|
43
|
+
let defaultContentTypeCfg = {};
|
|
44
|
+
if ((extraOptions === null || extraOptions === void 0 ? void 0 : extraOptions.body) &&
|
|
45
|
+
(!(extraOptions === null || extraOptions === void 0 ? void 0 : extraOptions.headers) ||
|
|
46
|
+
(typeof extraOptions.headers === "object" &&
|
|
47
|
+
Object.keys(extraOptions.headers)
|
|
48
|
+
.map((key) => key.toLowerCase())
|
|
49
|
+
.indexOf("content-type") == -1))) {
|
|
50
|
+
defaultContentTypeCfg = {
|
|
51
|
+
headers: {
|
|
52
|
+
"Content-Type": "application/json"
|
|
53
|
+
}
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return lodash_1.default.merge({}, this.requestInitOption, extraOptions, defaultContentTypeCfg);
|
|
41
57
|
}
|
|
42
58
|
processJsonResponse(res) {
|
|
43
59
|
return __awaiter(this, void 0, void 0, function* () {
|
|
@@ -45,8 +61,8 @@ class ApiClient {
|
|
|
45
61
|
return (yield res.json());
|
|
46
62
|
}
|
|
47
63
|
else {
|
|
48
|
-
const responseText =
|
|
49
|
-
throw new
|
|
64
|
+
const responseText = yield res.text();
|
|
65
|
+
throw new ServerError_1.default(`Error: ${res.statusText}. ${responseText.replace(/<(.|\n)*?>/g, "")}`, res.status);
|
|
50
66
|
}
|
|
51
67
|
});
|
|
52
68
|
}
|
|
@@ -58,19 +74,6 @@ class ApiClient {
|
|
|
58
74
|
* @memberof ApiClient
|
|
59
75
|
*/
|
|
60
76
|
getUser(userId) {
|
|
61
|
-
return __awaiter(this, void 0, void 0, function* () {
|
|
62
|
-
return yield this.handleGetResult(isomorphic_fetch_1.default(`${this.baseUrl}private/users/${userId}`, this.getMergeRequestInitOption()));
|
|
63
|
-
});
|
|
64
|
-
}
|
|
65
|
-
/**
|
|
66
|
-
* Get the data of a user.
|
|
67
|
-
* (Deprecated) This is the public facing API and will return less fields.
|
|
68
|
-
*
|
|
69
|
-
* @param {string} userId
|
|
70
|
-
* @returns {Promise<Maybe<User>>}
|
|
71
|
-
* @memberof ApiClient
|
|
72
|
-
*/
|
|
73
|
-
getUserPublic(userId) {
|
|
74
77
|
return __awaiter(this, void 0, void 0, function* () {
|
|
75
78
|
return yield this.handleGetResult(isomorphic_fetch_1.default(`${this.baseUrl}public/users/${userId}`, this.getMergeRequestInitOption()));
|
|
76
79
|
});
|
|
@@ -91,14 +94,14 @@ class ApiClient {
|
|
|
91
94
|
/**
|
|
92
95
|
* create a user
|
|
93
96
|
*
|
|
94
|
-
* @param {
|
|
95
|
-
* @returns {Promise<
|
|
97
|
+
* @param {CreateUserData} user
|
|
98
|
+
* @returns {Promise<UserRecord>}
|
|
96
99
|
* @memberof ApiClient
|
|
97
100
|
*/
|
|
98
101
|
createUser(user) {
|
|
99
102
|
return __awaiter(this, void 0, void 0, function* () {
|
|
100
103
|
try {
|
|
101
|
-
const res = yield isomorphic_fetch_1.default(`${this.baseUrl}
|
|
104
|
+
const res = yield isomorphic_fetch_1.default(`${this.baseUrl}public/users`, this.getMergeRequestInitOption({
|
|
102
105
|
method: "POST",
|
|
103
106
|
headers: {
|
|
104
107
|
"Content-Type": "application/json"
|
|
@@ -106,10 +109,10 @@ class ApiClient {
|
|
|
106
109
|
body: JSON.stringify(user)
|
|
107
110
|
}));
|
|
108
111
|
if (res.status >= 400) {
|
|
109
|
-
throw new Error(`Encountered error ${res.status} when
|
|
112
|
+
throw new Error(`Encountered error ${res.status}: ${yield res.text()} when creating new user to ${this.baseUrl}public/users`);
|
|
110
113
|
}
|
|
111
114
|
const resData = yield res.json();
|
|
112
|
-
return
|
|
115
|
+
return resData;
|
|
113
116
|
}
|
|
114
117
|
catch (e) {
|
|
115
118
|
console.error(e);
|
|
@@ -128,7 +131,7 @@ class ApiClient {
|
|
|
128
131
|
*/
|
|
129
132
|
addUserRoles(userId, roleIds) {
|
|
130
133
|
return __awaiter(this, void 0, void 0, function* () {
|
|
131
|
-
const res = yield isomorphic_fetch_1.default(`${this.baseUrl}public/
|
|
134
|
+
const res = yield isomorphic_fetch_1.default(`${this.baseUrl}public/users/${userId}/roles`, this.getMergeRequestInitOption({
|
|
132
135
|
method: "POST",
|
|
133
136
|
headers: {
|
|
134
137
|
"Content-Type": "application/json"
|
|
@@ -167,7 +170,7 @@ class ApiClient {
|
|
|
167
170
|
*/
|
|
168
171
|
getUserRoles(userId) {
|
|
169
172
|
return __awaiter(this, void 0, void 0, function* () {
|
|
170
|
-
const res = yield isomorphic_fetch_1.default(`${this.baseUrl}public/
|
|
173
|
+
const res = yield isomorphic_fetch_1.default(`${this.baseUrl}public/users/${userId}/roles`, this.getMergeRequestInitOption());
|
|
171
174
|
return yield this.processJsonResponse(res);
|
|
172
175
|
});
|
|
173
176
|
}
|
|
@@ -180,7 +183,7 @@ class ApiClient {
|
|
|
180
183
|
*/
|
|
181
184
|
getUserPermissions(userId) {
|
|
182
185
|
return __awaiter(this, void 0, void 0, function* () {
|
|
183
|
-
const res = yield isomorphic_fetch_1.default(`${this.baseUrl}public/
|
|
186
|
+
const res = yield isomorphic_fetch_1.default(`${this.baseUrl}public/users/${userId}/permissions`, this.getMergeRequestInitOption());
|
|
184
187
|
return yield this.processJsonResponse(res);
|
|
185
188
|
});
|
|
186
189
|
}
|
|
@@ -193,7 +196,7 @@ class ApiClient {
|
|
|
193
196
|
*/
|
|
194
197
|
getRolePermissions(roleId) {
|
|
195
198
|
return __awaiter(this, void 0, void 0, function* () {
|
|
196
|
-
const res = yield isomorphic_fetch_1.default(`${this.baseUrl}public/
|
|
199
|
+
const res = yield isomorphic_fetch_1.default(`${this.baseUrl}public/roles/${roleId}/permissions`, this.getMergeRequestInitOption());
|
|
197
200
|
return yield this.processJsonResponse(res);
|
|
198
201
|
});
|
|
199
202
|
}
|
|
@@ -303,6 +306,60 @@ class ApiClient {
|
|
|
303
306
|
return yield this.processJsonResponse(res);
|
|
304
307
|
});
|
|
305
308
|
}
|
|
309
|
+
createOrgNode(parentNodeId, node) {
|
|
310
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
311
|
+
const uri = urijs_1.default(`${this.baseUrl}public/orgunits`)
|
|
312
|
+
.segmentCoded(parentNodeId)
|
|
313
|
+
.segmentCoded("insert");
|
|
314
|
+
const res = yield isomorphic_fetch_1.default(uri.toString(), this.getMergeRequestInitOption({
|
|
315
|
+
method: "post",
|
|
316
|
+
body: JSON.stringify(node)
|
|
317
|
+
}));
|
|
318
|
+
return yield this.processJsonResponse(res);
|
|
319
|
+
});
|
|
320
|
+
}
|
|
321
|
+
createRole(name, desc) {
|
|
322
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
323
|
+
const uri = urijs_1.default(`${this.baseUrl}public/roles`);
|
|
324
|
+
const res = yield isomorphic_fetch_1.default(uri.toString(), this.getMergeRequestInitOption({
|
|
325
|
+
method: "post",
|
|
326
|
+
body: JSON.stringify({
|
|
327
|
+
name,
|
|
328
|
+
description: desc ? desc : ""
|
|
329
|
+
})
|
|
330
|
+
}));
|
|
331
|
+
return yield this.processJsonResponse(res);
|
|
332
|
+
});
|
|
333
|
+
}
|
|
334
|
+
createRolePermission(roleId, permissionData) {
|
|
335
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
336
|
+
if (!isUuid_1.default(roleId)) {
|
|
337
|
+
throw new ServerError_1.default(`roleId: ${roleId} is not a valid UUID.`);
|
|
338
|
+
}
|
|
339
|
+
const uri = urijs_1.default(`${this.baseUrl}public/roles`)
|
|
340
|
+
.segmentCoded(roleId)
|
|
341
|
+
.segmentCoded("permissions");
|
|
342
|
+
const res = yield isomorphic_fetch_1.default(uri.toString(), this.getMergeRequestInitOption({
|
|
343
|
+
method: "post",
|
|
344
|
+
body: JSON.stringify(permissionData)
|
|
345
|
+
}));
|
|
346
|
+
return yield this.processJsonResponse(res);
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
getOperationByUri(opUri) {
|
|
350
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
351
|
+
const uri = urijs_1.default(`${this.baseUrl}public/operations/byUri/${opUri}`);
|
|
352
|
+
const res = yield isomorphic_fetch_1.default(uri.toString(), this.getMergeRequestInitOption());
|
|
353
|
+
return yield this.processJsonResponse(res);
|
|
354
|
+
});
|
|
355
|
+
}
|
|
356
|
+
getResourceByUri(resUri) {
|
|
357
|
+
return __awaiter(this, void 0, void 0, function* () {
|
|
358
|
+
const uri = urijs_1.default(`${this.baseUrl}public/resources/byUri/${resUri}`);
|
|
359
|
+
const res = yield isomorphic_fetch_1.default(uri.toString(), this.getMergeRequestInitOption());
|
|
360
|
+
return yield this.processJsonResponse(res);
|
|
361
|
+
});
|
|
362
|
+
}
|
|
306
363
|
handleGetResult(promise) {
|
|
307
364
|
return __awaiter(this, void 0, void 0, function* () {
|
|
308
365
|
return promise
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ApiClient.js","sourceRoot":"","sources":["../../src/authorization-api/ApiClient.ts"],"names":[],"mappings":";;;;;;;;;;;;;;AAAA,wEAAqC;
|
|
1
|
+
{"version":3,"file":"ApiClient.js","sourceRoot":"","sources":["../../src/authorization-api/ApiClient.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,7 +1,65 @@
|
|
|
1
1
|
import { Request, Response } from "express";
|
|
2
|
-
|
|
2
|
+
import AuthDecisionQueryClient, { AuthDecisionReqConfig } from "../opa/AuthDecisionQueryClient";
|
|
3
3
|
/**
|
|
4
4
|
* Find the user making the request. Assign it to req passport style.
|
|
5
|
+
* !deprecated! should use middleware `getUserId` or `requireUserId` instead.
|
|
5
6
|
*/
|
|
6
|
-
export declare const getUser: (baseAuthUrl: string, jwtSecret: string) => (req: Request, res: Response, next: () => void) => void;
|
|
7
|
+
export declare const getUser: (baseAuthUrl: string, jwtSecret: string, actionUserId?: string) => (req: Request, res: Response, next: () => void) => void;
|
|
7
8
|
export declare const mustBeAdmin: (baseAuthUrl: string, jwtSecret: string) => (req: Request, res: Response, next: () => void) => void;
|
|
9
|
+
/**
|
|
10
|
+
* Make auth decision based on auth decision request config.
|
|
11
|
+
* Depends on the config provided, either partial eval (conditional decision on a set of records/objects)
|
|
12
|
+
* Or unconditional decision for a single record / object will be returned via `res.locals.authDecision`.
|
|
13
|
+
*
|
|
14
|
+
* @export
|
|
15
|
+
* @param {AuthDecisionQueryClient} authDecisionClient
|
|
16
|
+
* @param {AuthDecisionReqConfig} config
|
|
17
|
+
* @return {*}
|
|
18
|
+
*/
|
|
19
|
+
export declare function withAuthDecision(authDecisionClient: AuthDecisionQueryClient, config: AuthDecisionReqConfig): (req: Request, res: Response, next: () => void) => Promise<void>;
|
|
20
|
+
/**
|
|
21
|
+
* Require unconditional auth decision based on auth decision request config.
|
|
22
|
+
* When making decision on a group of records/objects, this method makes sure
|
|
23
|
+
* the user has permission to all records/objects regardless individual record / object's attributes.
|
|
24
|
+
*
|
|
25
|
+
* @export
|
|
26
|
+
* @param {AuthDecisionQueryClient} authDecisionClient
|
|
27
|
+
* @param {AuthDecisionReqConfig} config
|
|
28
|
+
* @param {boolean} [requiredDecision=true]
|
|
29
|
+
* @return {*}
|
|
30
|
+
*/
|
|
31
|
+
export declare function requireUnconditionalAuthDecision(authDecisionClient: AuthDecisionQueryClient, config: AuthDecisionReqConfig, requiredDecision?: boolean): (req: Request, res: Response, next: () => void) => void;
|
|
32
|
+
declare type InputDataOrFuncType = ((req: Request, res: Response) => Record<string, any>) | Record<string, any>;
|
|
33
|
+
/**
|
|
34
|
+
* require permission based on input data provided.
|
|
35
|
+
* Different from withAuthDecision, its method always set `unknowns` = Nil i.e. it will always attempt to make unconditional decision.
|
|
36
|
+
* It's for make decision for one single record / object. For partial eval for a set of records / objects, please use `withAuthDecision` or `requireUnconditionalAuthDecision`
|
|
37
|
+
*
|
|
38
|
+
* @export
|
|
39
|
+
* @param {AuthDecisionQueryClient} authDecisionClient
|
|
40
|
+
* @param {string} operationUri
|
|
41
|
+
* @param {InputDataOrFuncType} [inputDataFunc] either a function that produce input data (auth decision context data) from `req` & `req` or a plain object
|
|
42
|
+
* @return {*}
|
|
43
|
+
*/
|
|
44
|
+
export declare function requirePermission(authDecisionClient: AuthDecisionQueryClient, operationUri: string, inputDataOrFunc?: InputDataOrFuncType): (req: Request, res: Response, next: () => void) => void;
|
|
45
|
+
/**
|
|
46
|
+
* Try to locate userId from JwtToken.
|
|
47
|
+
* If can't find JWT token, return undefined via `res.locals.userId`
|
|
48
|
+
*
|
|
49
|
+
* @export
|
|
50
|
+
* @param {Request} req
|
|
51
|
+
* @param {Response} res
|
|
52
|
+
* @param {() => void} next
|
|
53
|
+
*/
|
|
54
|
+
export declare function getUserId(jwtSecret: string): (req: Request, res: Response, next: () => void) => void;
|
|
55
|
+
/**
|
|
56
|
+
* get current user ID from JWT token
|
|
57
|
+
* If can't locate userId, response 403 error
|
|
58
|
+
*
|
|
59
|
+
* @export
|
|
60
|
+
* @param {Request} req
|
|
61
|
+
* @param {Response} res
|
|
62
|
+
* @param {() => void} next
|
|
63
|
+
*/
|
|
64
|
+
export declare const requireUserId: (jwtSecret: string) => (req: Request, res: Response, next: () => void) => void;
|
|
65
|
+
export {};
|
|
@@ -1,24 +1,31 @@
|
|
|
1
1
|
"use strict";
|
|
2
|
+
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
|
|
3
|
+
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
|
|
4
|
+
return new (P || (P = Promise))(function (resolve, reject) {
|
|
5
|
+
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
|
|
6
|
+
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
|
|
7
|
+
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
|
|
8
|
+
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
9
|
+
});
|
|
10
|
+
};
|
|
2
11
|
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
12
|
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
13
|
};
|
|
5
14
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
-
exports.
|
|
15
|
+
exports.requireUserId = exports.getUserId = exports.requirePermission = exports.requireUnconditionalAuthDecision = exports.withAuthDecision = exports.mustBeAdmin = exports.getUser = void 0;
|
|
7
16
|
const GetUserId_1 = require("../session/GetUserId");
|
|
8
17
|
const ApiClient_1 = __importDefault(require("./ApiClient"));
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
next();
|
|
13
|
-
});
|
|
14
|
-
};
|
|
18
|
+
const AuthDecision_1 = require("../opa/AuthDecision");
|
|
19
|
+
const constants_1 = require("./constants");
|
|
20
|
+
const ServerError_1 = __importDefault(require("../ServerError"));
|
|
15
21
|
/**
|
|
16
22
|
* Find the user making the request. Assign it to req passport style.
|
|
23
|
+
* !deprecated! should use middleware `getUserId` or `requireUserId` instead.
|
|
17
24
|
*/
|
|
18
|
-
exports.getUser = (baseAuthUrl, jwtSecret) => (req, res, next) => {
|
|
25
|
+
exports.getUser = (baseAuthUrl, jwtSecret, actionUserId) => (req, res, next) => {
|
|
19
26
|
GetUserId_1.getUserId(req, jwtSecret).caseOf({
|
|
20
27
|
just: (userId) => {
|
|
21
|
-
const apiClient = new ApiClient_1.default(baseAuthUrl, jwtSecret,
|
|
28
|
+
const apiClient = new ApiClient_1.default(baseAuthUrl, jwtSecret, actionUserId ? actionUserId : constants_1.DEFAULT_ADMIN_USER_ID);
|
|
22
29
|
apiClient
|
|
23
30
|
.getUser(userId)
|
|
24
31
|
.then((maybeUser) => {
|
|
@@ -35,6 +42,7 @@ exports.getUser = (baseAuthUrl, jwtSecret) => (req, res, next) => {
|
|
|
35
42
|
nothing: next
|
|
36
43
|
});
|
|
37
44
|
};
|
|
45
|
+
// deprecated middleware. To be removed after all code is secured with new model
|
|
38
46
|
exports.mustBeAdmin = (baseAuthUrl, jwtSecret) => {
|
|
39
47
|
const getUserInstance = exports.getUser(baseAuthUrl, jwtSecret);
|
|
40
48
|
return (req, res, next) => {
|
|
@@ -49,4 +57,141 @@ exports.mustBeAdmin = (baseAuthUrl, jwtSecret) => {
|
|
|
49
57
|
});
|
|
50
58
|
};
|
|
51
59
|
};
|
|
60
|
+
/**
|
|
61
|
+
* Make auth decision based on auth decision request config.
|
|
62
|
+
* Depends on the config provided, either partial eval (conditional decision on a set of records/objects)
|
|
63
|
+
* Or unconditional decision for a single record / object will be returned via `res.locals.authDecision`.
|
|
64
|
+
*
|
|
65
|
+
* @export
|
|
66
|
+
* @param {AuthDecisionQueryClient} authDecisionClient
|
|
67
|
+
* @param {AuthDecisionReqConfig} config
|
|
68
|
+
* @return {*}
|
|
69
|
+
*/
|
|
70
|
+
function withAuthDecision(authDecisionClient, config) {
|
|
71
|
+
return (req, res, next) => __awaiter(this, void 0, void 0, function* () {
|
|
72
|
+
try {
|
|
73
|
+
const jwtToken = req.get("X-Magda-Session");
|
|
74
|
+
const authDecision = yield authDecisionClient.getAuthDecision(config, jwtToken);
|
|
75
|
+
res.locals.authDecision = authDecision;
|
|
76
|
+
next();
|
|
77
|
+
}
|
|
78
|
+
catch (e) {
|
|
79
|
+
console.error(`withAuthDecision middleware error: ${e}`);
|
|
80
|
+
if (e instanceof ServerError_1.default) {
|
|
81
|
+
res.status(e.statusCode).send(e.message);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
res.status(500).send(`An error occurred while retrieving auth decision for the request: ${e}`);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
exports.withAuthDecision = withAuthDecision;
|
|
90
|
+
/**
|
|
91
|
+
* Require unconditional auth decision based on auth decision request config.
|
|
92
|
+
* When making decision on a group of records/objects, this method makes sure
|
|
93
|
+
* the user has permission to all records/objects regardless individual record / object's attributes.
|
|
94
|
+
*
|
|
95
|
+
* @export
|
|
96
|
+
* @param {AuthDecisionQueryClient} authDecisionClient
|
|
97
|
+
* @param {AuthDecisionReqConfig} config
|
|
98
|
+
* @param {boolean} [requiredDecision=true]
|
|
99
|
+
* @return {*}
|
|
100
|
+
*/
|
|
101
|
+
function requireUnconditionalAuthDecision(authDecisionClient, config, requiredDecision = true) {
|
|
102
|
+
return (req, res, next) => {
|
|
103
|
+
withAuthDecision(authDecisionClient, config)(req, res, () => {
|
|
104
|
+
const authDecision = res.locals.authDecision;
|
|
105
|
+
if ((authDecision === null || authDecision === void 0 ? void 0 : authDecision.hasResidualRules) === false &&
|
|
106
|
+
AuthDecision_1.isTrueEquivalent(authDecision === null || authDecision === void 0 ? void 0 : authDecision.result) == requiredDecision) {
|
|
107
|
+
return next();
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
res.status(403).send(`you are not permitted to perform \`${config.operationUri}\` on required resources.`);
|
|
111
|
+
}
|
|
112
|
+
});
|
|
113
|
+
};
|
|
114
|
+
}
|
|
115
|
+
exports.requireUnconditionalAuthDecision = requireUnconditionalAuthDecision;
|
|
116
|
+
/**
|
|
117
|
+
* require permission based on input data provided.
|
|
118
|
+
* Different from withAuthDecision, its method always set `unknowns` = Nil i.e. it will always attempt to make unconditional decision.
|
|
119
|
+
* It's for make decision for one single record / object. For partial eval for a set of records / objects, please use `withAuthDecision` or `requireUnconditionalAuthDecision`
|
|
120
|
+
*
|
|
121
|
+
* @export
|
|
122
|
+
* @param {AuthDecisionQueryClient} authDecisionClient
|
|
123
|
+
* @param {string} operationUri
|
|
124
|
+
* @param {InputDataOrFuncType} [inputDataFunc] either a function that produce input data (auth decision context data) from `req` & `req` or a plain object
|
|
125
|
+
* @return {*}
|
|
126
|
+
*/
|
|
127
|
+
function requirePermission(authDecisionClient, operationUri, inputDataOrFunc) {
|
|
128
|
+
return (req, res, next) => {
|
|
129
|
+
try {
|
|
130
|
+
const config = {
|
|
131
|
+
operationUri,
|
|
132
|
+
unknowns: []
|
|
133
|
+
};
|
|
134
|
+
if (inputDataOrFunc) {
|
|
135
|
+
if (typeof inputDataOrFunc === "function") {
|
|
136
|
+
config.input = inputDataOrFunc(req, res);
|
|
137
|
+
}
|
|
138
|
+
else {
|
|
139
|
+
config.input = inputDataOrFunc;
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
requireUnconditionalAuthDecision(authDecisionClient, config, true)(req, res, next);
|
|
143
|
+
}
|
|
144
|
+
catch (e) {
|
|
145
|
+
console.error(`requirePermission middleware error: ${e}`);
|
|
146
|
+
if (e instanceof ServerError_1.default) {
|
|
147
|
+
res.status(e.statusCode).send(e.message);
|
|
148
|
+
}
|
|
149
|
+
else {
|
|
150
|
+
res.status(500).send(`requirePermission middleware error: ${e}`);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
};
|
|
154
|
+
}
|
|
155
|
+
exports.requirePermission = requirePermission;
|
|
156
|
+
/**
|
|
157
|
+
* Try to locate userId from JwtToken.
|
|
158
|
+
* If can't find JWT token, return undefined via `res.locals.userId`
|
|
159
|
+
*
|
|
160
|
+
* @export
|
|
161
|
+
* @param {Request} req
|
|
162
|
+
* @param {Response} res
|
|
163
|
+
* @param {() => void} next
|
|
164
|
+
*/
|
|
165
|
+
function getUserId(jwtSecret) {
|
|
166
|
+
return (req, res, next) => {
|
|
167
|
+
GetUserId_1.getUserId(req, jwtSecret).caseOf({
|
|
168
|
+
just: (userId) => {
|
|
169
|
+
res.locals.userId = userId;
|
|
170
|
+
next();
|
|
171
|
+
},
|
|
172
|
+
nothing: () => {
|
|
173
|
+
res.locals.userId = undefined;
|
|
174
|
+
next();
|
|
175
|
+
}
|
|
176
|
+
});
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
exports.getUserId = getUserId;
|
|
180
|
+
/**
|
|
181
|
+
* get current user ID from JWT token
|
|
182
|
+
* If can't locate userId, response 403 error
|
|
183
|
+
*
|
|
184
|
+
* @export
|
|
185
|
+
* @param {Request} req
|
|
186
|
+
* @param {Response} res
|
|
187
|
+
* @param {() => void} next
|
|
188
|
+
*/
|
|
189
|
+
exports.requireUserId = (jwtSecret) => (req, res, next) => getUserId(jwtSecret)(req, res, () => {
|
|
190
|
+
if (!res.locals.userId) {
|
|
191
|
+
res.status(403).send("Anonymous users access are not permitted: userId is required.");
|
|
192
|
+
}
|
|
193
|
+
else {
|
|
194
|
+
return next();
|
|
195
|
+
}
|
|
196
|
+
});
|
|
52
197
|
//# sourceMappingURL=authMiddleware.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"authMiddleware.js","sourceRoot":"","sources":["../../src/authorization-api/authMiddleware.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"authMiddleware.js","sourceRoot":"","sources":["../../src/authorization-api/authMiddleware.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const ANONYMOUS_USERS_ROLE_ID = "00000000-0000-0001-0000-000000000000";
|
|
2
|
+
export declare const AUTHENTICATED_USERS_ROLE_ID = "00000000-0000-0002-0000-000000000000";
|
|
3
|
+
export declare const ADMIN_USERS_ROLE_ID = "00000000-0000-0003-0000-000000000000";
|
|
4
|
+
export declare const DEFAULT_ADMIN_USER_ID = "00000000-0000-4000-8000-000000000000";
|
|
5
|
+
export declare const DATA_STEWARDS_ROLE_ID = "4154bf84-d36e-4551-9734-4666f5b1e1c0";
|
|
6
|
+
export declare const SYSTEM_ROLES: string[];
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.SYSTEM_ROLES = exports.DATA_STEWARDS_ROLE_ID = exports.DEFAULT_ADMIN_USER_ID = exports.ADMIN_USERS_ROLE_ID = exports.AUTHENTICATED_USERS_ROLE_ID = exports.ANONYMOUS_USERS_ROLE_ID = void 0;
|
|
4
|
+
exports.ANONYMOUS_USERS_ROLE_ID = "00000000-0000-0001-0000-000000000000";
|
|
5
|
+
exports.AUTHENTICATED_USERS_ROLE_ID = "00000000-0000-0002-0000-000000000000";
|
|
6
|
+
exports.ADMIN_USERS_ROLE_ID = "00000000-0000-0003-0000-000000000000";
|
|
7
|
+
exports.DEFAULT_ADMIN_USER_ID = "00000000-0000-4000-8000-000000000000";
|
|
8
|
+
exports.DATA_STEWARDS_ROLE_ID = "4154bf84-d36e-4551-9734-4666f5b1e1c0";
|
|
9
|
+
exports.SYSTEM_ROLES = [
|
|
10
|
+
exports.ANONYMOUS_USERS_ROLE_ID,
|
|
11
|
+
exports.AUTHENTICATED_USERS_ROLE_ID,
|
|
12
|
+
exports.ADMIN_USERS_ROLE_ID
|
|
13
|
+
];
|
|
14
|
+
//# sourceMappingURL=constants.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.js","sourceRoot":"","sources":["../../src/authorization-api/constants.ts"],"names":[],"mappings":";;;AAAa,QAAA,uBAAuB,GAAG,sCAAsC,CAAC;AACjE,QAAA,2BAA2B,GACpC,sCAAsC,CAAC;AAC9B,QAAA,mBAAmB,GAAG,sCAAsC,CAAC;AAC7D,QAAA,qBAAqB,GAAG,sCAAsC,CAAC;AAC/D,QAAA,qBAAqB,GAAG,sCAAsC,CAAC;AAE/D,QAAA,YAAY,GAAG;IACxB,+BAAuB;IACvB,mCAA2B;IAC3B,2BAAmB;CACtB,CAAC"}
|