soajs.controller 4.3.24 → 4.3.25

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/docs/mcp.md CHANGED
@@ -36,8 +36,8 @@ after 30 seconds.
36
36
 
37
37
  The ACL the gateway computes for `/soajs/acl`: the user's ACL and packages, else the tenant
38
38
  application's, else the package's. For each service, the latest allowed version; a restricted
39
- service shows only the APIs its ACL lists, per method. To give agents a different list from your
40
- apps, give the agent its own application, key and package in the tenant.
39
+ service shows only the APIs its ACL lists, per method, and none when it lists none. To give agents
40
+ a different list from your apps, give the agent its own application, key and package in the tenant.
41
41
 
42
42
  A tool call is checked again by the gateway like any API call, so a tool shown by mistake is still
43
43
  refused.
@@ -16,10 +16,12 @@ const coreLibs = require("soajs.core.libs");
16
16
  *
17
17
  * finalACL is, per service, the latest allowed version and, for a restricted service, the allowed
18
18
  * apis per method: {"urac": {"version": "3", "get": ["/user"]}}. A service that is not restricted
19
- * has only its version: all its apis are allowed.
19
+ * has only its version: all its apis are allowed. A restricted service that lists no apis also has
20
+ * only its version, so restricted says, per service, whether its latest allowed version is
21
+ * restricted.
20
22
  *
21
23
  * @param req
22
- * @returns {{acl: object|null, finalACL: object|null, packages: Array|null}}
24
+ * @returns {{acl: object|null, finalACL: object|null, restricted: object, packages: Array|null}}
23
25
  */
24
26
  function computeACL(req) {
25
27
  let ACL = null;
@@ -42,6 +44,7 @@ function computeACL(req) {
42
44
  ACL = coreLibs.utils.cloneObj(req.soajs.controller.serviceParams.packObj.acl);
43
45
  }
44
46
  let finalACL = null;
47
+ let restricted = {};
45
48
  if (ACL) {
46
49
  finalACL = {};
47
50
  for (let s in ACL) {
@@ -58,7 +61,8 @@ function computeACL(req) {
58
61
  finalACL[s] = {
59
62
  "version": v
60
63
  };
61
- if (sv.apisPermission && sv.apisPermission === "restricted") {
64
+ restricted[s] = !!(sv.apisPermission && sv.apisPermission === "restricted");
65
+ if (restricted[s]) {
62
66
  for (let m in sv) {
63
67
  if (sv.hasOwnProperty(m)) {
64
68
  if (m !== "access" && m !== "apisPermission") {
@@ -91,6 +95,7 @@ function computeACL(req) {
91
95
  return {
92
96
  "acl": ACL,
93
97
  "finalACL": finalACL,
98
+ "restricted": restricted,
94
99
  "packages": ALLOWED_PACKAGES
95
100
  };
96
101
  }
@@ -224,11 +224,10 @@ function toolName(serviceName, tool, taken) {
224
224
  }
225
225
 
226
226
  /**
227
- * Whether the caller's ACL allows the api: a restricted service lists its apis per method.
227
+ * Whether the caller's ACL allows the api: a restricted service allows only the apis it lists per
228
+ * method, none when it lists none.
228
229
  */
229
- function allowed(serviceACL, tool) {
230
- let methods = ["get", "post", "put", "delete", "del"];
231
- let restricted = methods.some((m) => Array.isArray(serviceACL[m]));
230
+ function allowed(serviceACL, tool, restricted) {
232
231
  if (!restricted) {
233
232
  return true;
234
233
  }
@@ -253,7 +252,7 @@ function listTools(req, configuration, config) {
253
252
  let taken = {};
254
253
  services.forEach((serviceName, i) => {
255
254
  lists[i].forEach((tool) => {
256
- if (tools.length >= config.maxTools || !allowed(finalACL[serviceName], tool)) {
255
+ if (tools.length >= config.maxTools || !allowed(finalACL[serviceName], tool, computed.restricted[serviceName])) {
257
256
  return;
258
257
  }
259
258
  let name = toolName(serviceName, tool, taken);
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "soajs.controller",
3
3
  "description": "soajs multi tenant API gateway",
4
- "version": "4.3.24",
4
+ "version": "4.3.25",
5
5
  "author": {
6
6
  "name": "soajs team",
7
7
  "email": "team@soajs.org"
@@ -216,14 +216,17 @@ describe("Unit test for: mw - soajsRoutes mcp", () => {
216
216
 
217
217
  describe("allowed", () => {
218
218
  it("a service that is not restricted allows all its apis", () => {
219
- assert.ok(tools.allowed({version: "1"}, {m: "delete", v: "/x"}));
219
+ assert.ok(tools.allowed({version: "1"}, {m: "delete", v: "/x"}, false));
220
220
  });
221
221
  it("a restricted service allows the apis it lists", () => {
222
222
  let acl = {version: "1", get: ["/users"], del: ["/user/:id"]};
223
- assert.ok(tools.allowed(acl, {m: "get", v: "/users"}));
224
- assert.ok(!tools.allowed(acl, {m: "get", v: "/user/:id"}));
225
- assert.ok(tools.allowed(acl, {m: "delete", v: "/user/:id"}));
226
- assert.ok(!tools.allowed(acl, {m: "post", v: "/users"}));
223
+ assert.ok(tools.allowed(acl, {m: "get", v: "/users"}, true));
224
+ assert.ok(!tools.allowed(acl, {m: "get", v: "/user/:id"}, true));
225
+ assert.ok(tools.allowed(acl, {m: "delete", v: "/user/:id"}, true));
226
+ assert.ok(!tools.allowed(acl, {m: "post", v: "/users"}, true));
227
+ });
228
+ it("a restricted service that lists no apis allows none", () => {
229
+ assert.ok(!tools.allowed({version: "1"}, {m: "get", v: "/users"}, true));
227
230
  });
228
231
  });
229
232
 
@@ -342,6 +345,14 @@ describe("Unit test for: mw - soajsRoutes mcp", () => {
342
345
  }).catch(done);
343
346
  });
344
347
 
348
+ it("listTools: a restricted service that lists no apis has no tools", (done) => {
349
+ let acl = {urac: {"1": {access: true, apisPermission: "restricted", post: {apis: {}}}}};
350
+ tools.listTools(makeReq({services: services(), acl: acl}), configuration, config).then((list) => {
351
+ assert.deepStrictEqual(list.tools, []);
352
+ done();
353
+ }).catch(done);
354
+ });
355
+
345
356
  describe("callTool", () => {
346
357
  let gateway = null;
347
358
  let gatewayPort = null;
@@ -568,5 +579,16 @@ describe("Unit test for: mw - soajsRoutes mcp", () => {
568
579
  req = makeReq({acl: {urac: {"1": {access: true, apisPermission: "restricted", get: [{group: "a", apis: {"/x": {}}}, {group: "b", apis: {"/y": {}, "/x": {}}}]}}}});
569
580
  assert.deepStrictEqual(aclLib.computeACL(req).finalACL, {"urac": {"version": "1", "get": ["/x", "/y"]}});
570
581
  });
582
+ it("restricted follows the latest allowed version", () => {
583
+ let req = makeReq({
584
+ acl: {
585
+ urac: {"1": {access: true, apisPermission: "restricted", get: {apis: {"/x": {}}}}, "2": {access: true}},
586
+ oauth: {"1": {access: true, apisPermission: "restricted", post: {apis: {}}}}
587
+ }
588
+ });
589
+ let computed = aclLib.computeACL(req);
590
+ assert.deepStrictEqual(computed.finalACL, {"urac": {"version": "2"}, "oauth": {"version": "1"}});
591
+ assert.deepStrictEqual(computed.restricted, {"urac": false, "oauth": true});
592
+ });
571
593
  });
572
594
  });