@nocobase/plugin-acl 0.10.0-alpha.5 → 0.11.0-alpha.1

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.
Files changed (78) hide show
  1. package/client.d.ts +3 -0
  2. package/client.js +1 -0
  3. package/lib/client/index.d.ts +5 -0
  4. package/lib/client/index.js +22 -0
  5. package/lib/{actions → server/actions}/role-check.js +0 -3
  6. package/lib/server/index.d.ts +1 -0
  7. package/lib/server/index.js +13 -0
  8. package/lib/server/middlewares/setCurrentRole.d.ts +2 -0
  9. package/lib/{middlewares → server/middlewares}/setCurrentRole.js +16 -15
  10. package/lib/{server.js → server/server.js} +15 -16
  11. package/package.json +26 -9
  12. package/server.d.ts +3 -0
  13. package/server.js +1 -0
  14. package/src/client/index.ts +8 -0
  15. package/src/index.ts +1 -0
  16. package/src/server/__tests__/acl.test.ts +835 -0
  17. package/src/server/__tests__/actions.test.ts +141 -0
  18. package/src/server/__tests__/association-field.test.ts +413 -0
  19. package/src/server/__tests__/configuration.test.ts +70 -0
  20. package/src/server/__tests__/list-action.test.ts +446 -0
  21. package/src/server/__tests__/middleware.test.ts +210 -0
  22. package/src/server/__tests__/own.test.ts +124 -0
  23. package/src/server/__tests__/prepare.ts +20 -0
  24. package/src/server/__tests__/role-check.test.ts +46 -0
  25. package/src/server/__tests__/role-resource.test.ts +177 -0
  26. package/src/server/__tests__/role-user.test.ts +127 -0
  27. package/src/server/__tests__/role.test.ts +118 -0
  28. package/src/server/__tests__/scope.test.ts +55 -0
  29. package/src/server/__tests__/setCurrentRole.test.ts +86 -0
  30. package/src/server/__tests__/snippets.test.ts +35 -0
  31. package/src/server/__tests__/users.test.ts +136 -0
  32. package/src/server/__tests__/write-role-to-acl.test.ts +41 -0
  33. package/src/server/actions/available-actions.ts +18 -0
  34. package/src/server/actions/role-check.ts +50 -0
  35. package/src/server/actions/role-collections.ts +95 -0
  36. package/src/server/actions/user-setDefaultRole.ts +47 -0
  37. package/src/server/collections/roles-users.ts +8 -0
  38. package/src/server/collections/roles.ts +89 -0
  39. package/src/server/collections/rolesResources.ts +33 -0
  40. package/src/server/collections/rolesResourcesActions.ts +31 -0
  41. package/src/server/collections/rolesResourcesScopes.ts +25 -0
  42. package/src/server/collections/users.ts +31 -0
  43. package/src/server/index.ts +1 -0
  44. package/src/server/middlewares/setCurrentRole.ts +35 -0
  45. package/src/server/migrations/20221214072638-set-role-snippets.ts +23 -0
  46. package/src/server/model/RoleModel.ts +23 -0
  47. package/src/server/model/RoleResourceActionModel.ts +95 -0
  48. package/src/server/model/RoleResourceModel.ts +74 -0
  49. package/src/server/server.ts +854 -0
  50. package/lib/middlewares/setCurrentRole.d.ts +0 -1
  51. /package/lib/{actions → server/actions}/available-actions.d.ts +0 -0
  52. /package/lib/{actions → server/actions}/available-actions.js +0 -0
  53. /package/lib/{actions → server/actions}/role-check.d.ts +0 -0
  54. /package/lib/{actions → server/actions}/role-collections.d.ts +0 -0
  55. /package/lib/{actions → server/actions}/role-collections.js +0 -0
  56. /package/lib/{actions → server/actions}/user-setDefaultRole.d.ts +0 -0
  57. /package/lib/{actions → server/actions}/user-setDefaultRole.js +0 -0
  58. /package/lib/{collections → server/collections}/roles-users.d.ts +0 -0
  59. /package/lib/{collections → server/collections}/roles-users.js +0 -0
  60. /package/lib/{collections → server/collections}/roles.d.ts +0 -0
  61. /package/lib/{collections → server/collections}/roles.js +0 -0
  62. /package/lib/{collections → server/collections}/rolesResources.d.ts +0 -0
  63. /package/lib/{collections → server/collections}/rolesResources.js +0 -0
  64. /package/lib/{collections → server/collections}/rolesResourcesActions.d.ts +0 -0
  65. /package/lib/{collections → server/collections}/rolesResourcesActions.js +0 -0
  66. /package/lib/{collections → server/collections}/rolesResourcesScopes.d.ts +0 -0
  67. /package/lib/{collections → server/collections}/rolesResourcesScopes.js +0 -0
  68. /package/lib/{collections → server/collections}/users.d.ts +0 -0
  69. /package/lib/{collections → server/collections}/users.js +0 -0
  70. /package/lib/{migrations → server/migrations}/20221214072638-set-role-snippets.d.ts +0 -0
  71. /package/lib/{migrations → server/migrations}/20221214072638-set-role-snippets.js +0 -0
  72. /package/lib/{model → server/model}/RoleModel.d.ts +0 -0
  73. /package/lib/{model → server/model}/RoleModel.js +0 -0
  74. /package/lib/{model → server/model}/RoleResourceActionModel.d.ts +0 -0
  75. /package/lib/{model → server/model}/RoleResourceActionModel.js +0 -0
  76. /package/lib/{model → server/model}/RoleResourceModel.d.ts +0 -0
  77. /package/lib/{model → server/model}/RoleResourceModel.js +0 -0
  78. /package/lib/{server.d.ts → server/server.d.ts} +0 -0
package/client.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from './src/client';
2
+ export { default } from './src/client';
3
+
package/client.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('./lib/client/index.js');
@@ -0,0 +1,5 @@
1
+ import { Plugin } from '@nocobase/client';
2
+ declare class AclPlugin extends Plugin {
3
+ load(): Promise<void>;
4
+ }
5
+ export default AclPlugin;
@@ -0,0 +1,22 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ exports.default = void 0;
7
+ function _client() {
8
+ const data = require("@nocobase/client");
9
+ _client = function _client() {
10
+ return data;
11
+ };
12
+ return data;
13
+ }
14
+ function asyncGeneratorStep(gen, resolve, reject, _next, _throw, key, arg) { try { var info = gen[key](arg); var value = info.value; } catch (error) { reject(error); return; } if (info.done) { resolve(value); } else { Promise.resolve(value).then(_next, _throw); } }
15
+ function _asyncToGenerator(fn) { return function () { var self = this, args = arguments; return new Promise(function (resolve, reject) { var gen = fn.apply(self, args); function _next(value) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "next", value); } function _throw(err) { asyncGeneratorStep(gen, resolve, reject, _next, _throw, "throw", err); } _next(undefined); }); }; }
16
+ class AclPlugin extends _client().Plugin {
17
+ load() {
18
+ return _asyncToGenerator(function* () {})();
19
+ }
20
+ }
21
+ var _default = AclPlugin;
22
+ exports.default = _default;
@@ -42,9 +42,6 @@ function checkAction(_x2, _x3) {
42
42
  function _checkAction() {
43
43
  _checkAction = _asyncToGenerator(function* (ctx, next) {
44
44
  const currentRole = ctx.state.currentRole;
45
- if (!currentRole) {
46
- throw new Error('User role not found');
47
- }
48
45
  const roleInstance = yield ctx.db.getRepository('roles').findOne({
49
46
  filter: {
50
47
  name: currentRole
@@ -0,0 +1 @@
1
+ export { default } from './server';
@@ -0,0 +1,13 @@
1
+ "use strict";
2
+
3
+ Object.defineProperty(exports, "__esModule", {
4
+ value: true
5
+ });
6
+ Object.defineProperty(exports, "default", {
7
+ enumerable: true,
8
+ get: function get() {
9
+ return _server.default;
10
+ }
11
+ });
12
+ var _server = _interopRequireDefault(require("./server"));
13
+ function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
@@ -0,0 +1,2 @@
1
+ import { Context } from '@nocobase/actions';
2
+ export declare function setCurrentRole(ctx: Context, next: any): Promise<any>;
@@ -11,7 +11,7 @@ function setCurrentRole(_x, _x2) {
11
11
  }
12
12
  function _setCurrentRole() {
13
13
  _setCurrentRole = _asyncToGenerator(function* (ctx, next) {
14
- let currentRole = ctx.get('X-Role');
14
+ const currentRole = ctx.get('X-Role');
15
15
  if (currentRole === 'anonymous') {
16
16
  ctx.state.currentRole = currentRole;
17
17
  return next();
@@ -22,21 +22,22 @@ function _setCurrentRole() {
22
22
  const repository = ctx.db.getRepository('users.roles', ctx.state.currentUser.id);
23
23
  const roles = yield repository.find();
24
24
  ctx.state.currentUser.setDataValue('roles', roles);
25
- if (roles.length == 1) {
26
- currentRole = roles[0].name;
27
- } else if (roles.length > 1) {
28
- const role = roles.find(item => item.name === currentRole);
29
- if (!role) {
30
- var _ref;
31
- const defaultRole = roles.find(item => {
32
- var _item$rolesUsers;
33
- return item === null || item === void 0 ? void 0 : (_item$rolesUsers = item.rolesUsers) === null || _item$rolesUsers === void 0 ? void 0 : _item$rolesUsers.default;
34
- });
35
- currentRole = (_ref = defaultRole || roles[0]) === null || _ref === void 0 ? void 0 : _ref.name;
36
- }
37
- }
25
+ // 1. If the X-Role is set, use the specified role
38
26
  if (currentRole) {
39
- ctx.state.currentRole = currentRole;
27
+ var _roles$find;
28
+ ctx.state.currentRole = (_roles$find = roles.find(role => role.name === currentRole)) === null || _roles$find === void 0 ? void 0 : _roles$find.name;
29
+ }
30
+ // 2. If the X-Role is not set, use the default role
31
+ else {
32
+ var _ref;
33
+ const defaultRole = roles.find(item => {
34
+ var _item$rolesUsers;
35
+ return item === null || item === void 0 ? void 0 : (_item$rolesUsers = item.rolesUsers) === null || _item$rolesUsers === void 0 ? void 0 : _item$rolesUsers.default;
36
+ });
37
+ ctx.state.currentRole = (_ref = defaultRole || roles[0]) === null || _ref === void 0 ? void 0 : _ref.name;
38
+ }
39
+ if (!ctx.state.currentRole) {
40
+ return ctx.throw(401, 'User role not found');
40
41
  }
41
42
  yield next();
42
43
  });
@@ -32,9 +32,9 @@ function _server() {
32
32
  };
33
33
  return data;
34
34
  }
35
- function _lodash() {
36
- const data = _interopRequireDefault(require("lodash"));
37
- _lodash = function _lodash() {
35
+ function _utils() {
36
+ const data = require("@nocobase/utils");
37
+ _utils = function _utils() {
38
38
  return data;
39
39
  };
40
40
  return data;
@@ -54,7 +54,6 @@ var _setCurrentRole = require("./middlewares/setCurrentRole");
54
54
  var _RoleModel = require("./model/RoleModel");
55
55
  var _RoleResourceActionModel = require("./model/RoleResourceActionModel");
56
56
  var _RoleResourceModel = require("./model/RoleResourceModel");
57
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
58
57
  function _slicedToArray(arr, i) { return _arrayWithHoles(arr) || _iterableToArrayLimit(arr, i) || _unsupportedIterableToArray(arr, i) || _nonIterableRest(); }
59
58
  function _nonIterableRest() { throw new TypeError("Invalid attempt to destructure non-iterable instance.\nIn order to be iterable, non-array objects must have a [Symbol.iterator]() method."); }
60
59
  function _iterableToArrayLimit(arr, i) { var _i = null == arr ? null : "undefined" != typeof Symbol && arr[Symbol.iterator] || arr["@@iterator"]; if (null != _i) { var _s, _e, _x, _r, _arr = [], _n = !0, _d = !1; try { if (_x = (_i = _i.call(arr)).next, 0 === i) { if (Object(_i) !== _i) return; _n = !1; } else for (; !(_n = (_s = _x.call(_i)).done) && (_arr.push(_s.value), _arr.length !== i); _n = !0); } catch (err) { _d = !0, _e = err; } finally { try { if (!_n && null != _i.return && (_r = _i.return(), Object(_r) !== _r)) return; } finally { if (_d) throw _e; } } return _arr; } }
@@ -244,7 +243,7 @@ class PluginACL extends _server().Plugin {
244
243
  return field instanceof _database().RelationField;
245
244
  });
246
245
  ctx.params = _objectSpread(_objectSpread({}, ctx.params), {}, {
247
- fields: _lodash().default.difference(fieldsParams, associationsFields),
246
+ fields: _utils().lodash.difference(fieldsParams, associationsFields),
248
247
  appends: associationsFields
249
248
  });
250
249
  }
@@ -660,7 +659,7 @@ class PluginACL extends _server().Plugin {
660
659
  // is association request
661
660
  if (resourceName.includes('.') && resourceOf) {
662
661
  var _ctx$permission2, _ctx$permission2$can, _availableAction$opti;
663
- if (!(ctx === null || ctx === void 0 ? void 0 : (_ctx$permission2 = ctx.permission) === null || _ctx$permission2 === void 0 ? void 0 : (_ctx$permission2$can = _ctx$permission2.can) === null || _ctx$permission2$can === void 0 ? void 0 : _ctx$permission2$can.params)) {
662
+ if (!(ctx !== null && ctx !== void 0 && (_ctx$permission2 = ctx.permission) !== null && _ctx$permission2 !== void 0 && (_ctx$permission2$can = _ctx$permission2.can) !== null && _ctx$permission2$can !== void 0 && _ctx$permission2$can.params)) {
664
663
  return next();
665
664
  }
666
665
  // 关联数据去掉 filter
@@ -674,7 +673,7 @@ class PluginACL extends _server().Plugin {
674
673
  action: actionName
675
674
  });
676
675
  const availableAction = _this5.app.acl.getAvailableAction(actionName);
677
- if (availableAction === null || availableAction === void 0 ? void 0 : (_availableAction$opti = availableAction.options) === null || _availableAction$opti === void 0 ? void 0 : _availableAction$opti.onNewRecord) {
676
+ if (availableAction !== null && availableAction !== void 0 && (_availableAction$opti = availableAction.options) !== null && _availableAction$opti !== void 0 && _availableAction$opti.onNewRecord) {
678
677
  if (action) {
679
678
  ctx.permission.skip = true;
680
679
  } else {
@@ -744,10 +743,10 @@ class PluginACL extends _server().Plugin {
744
743
  }
745
744
  const Model = collection.model;
746
745
  const primaryKeyField = Model.primaryKeyField || Model.primaryKeyAttribute;
747
- const dataPath = ((_ctx$body = ctx.body) === null || _ctx$body === void 0 ? void 0 : _ctx$body.rows) ? 'body.rows' : 'body';
748
- let listData = _lodash().default.get(ctx, dataPath);
746
+ const dataPath = (_ctx$body = ctx.body) !== null && _ctx$body !== void 0 && _ctx$body.rows ? 'body.rows' : 'body';
747
+ let listData = _utils().lodash.get(ctx, dataPath);
749
748
  if (actionName == 'get') {
750
- listData = _lodash().default.castArray(listData);
749
+ listData = _utils().lodash.castArray(listData);
751
750
  }
752
751
  const inspectActions = ['view', 'update', 'destroy'];
753
752
  const actionsParams = [];
@@ -810,7 +809,7 @@ class PluginACL extends _server().Plugin {
810
809
  if (!params) {
811
810
  continue;
812
811
  }
813
- if (_lodash().default.isEmpty(params) || _lodash().default.isEmpty(params.filter)) {
812
+ if (_utils().lodash.isEmpty(params) || _utils().lodash.isEmpty(params.filter)) {
814
813
  allAllowed.push(action);
815
814
  continue;
816
815
  }
@@ -828,7 +827,7 @@ class PluginACL extends _server().Plugin {
828
827
  };
829
828
  // change camelCase to snake_case
830
829
  const iterate = (rootObj, path = []) => {
831
- const obj = path.length == 0 ? rootObj : _lodash().default.get(rootObj, path);
830
+ const obj = path.length == 0 ? rootObj : _utils().lodash.get(rootObj, path);
832
831
  if (Array.isArray(obj)) {
833
832
  for (let i = 0; i < obj.length; i++) {
834
833
  if (obj[i] === null) {
@@ -850,13 +849,13 @@ class PluginACL extends _server().Plugin {
850
849
  if (typeof key === 'string' && key !== (0, _database().snakeCase)(key)) {
851
850
  const setKey = isAssociationKey(key) ? (() => {
852
851
  const parts = key.split('.');
853
- parts[parts.length - 1] = _lodash().default.snakeCase(parts[parts.length - 1]);
852
+ parts[parts.length - 1] = _utils().lodash.snakeCase(parts[parts.length - 1]);
854
853
  const result = parts.join('.');
855
854
  return result.endsWith('$') ? result : `${result}$`;
856
855
  })() : (0, _database().snakeCase)(key);
857
- const setValue = _lodash().default.cloneDeep(obj[key]);
858
- _lodash().default.unset(rootObj, [...path, key]);
859
- _lodash().default.set(rootObj, [...path, setKey], setValue);
856
+ const setValue = _utils().lodash.cloneDeep(obj[key]);
857
+ _utils().lodash.unset(rootObj, [...path, key]);
858
+ _utils().lodash.set(rootObj, [...path, setKey], setValue);
860
859
  }
861
860
  });
862
861
  };
package/package.json CHANGED
@@ -4,20 +4,37 @@
4
4
  "displayName.zh-CN": "权限控制",
5
5
  "description": "A simple access control based on roles, resources and actions",
6
6
  "description.zh-CN": "基于角色、资源和操作的权限控制。",
7
- "version": "0.10.0-alpha.5",
7
+ "version": "0.11.0-alpha.1",
8
8
  "license": "AGPL-3.0",
9
- "main": "./lib/index.js",
10
- "types": "./lib/index.d.ts",
11
- "dependencies": {
12
- "@nocobase/acl": "0.10.0-alpha.5",
13
- "@nocobase/database": "0.10.0-alpha.5",
14
- "@nocobase/plugin-users": "0.10.0-alpha.5",
15
- "@nocobase/server": "0.10.0-alpha.5"
9
+ "main": "./lib/server/index.js",
10
+ "files": [
11
+ "lib",
12
+ "src",
13
+ "README.md",
14
+ "README.zh-CN.md",
15
+ "CHANGELOG.md",
16
+ "server.js",
17
+ "server.d.ts",
18
+ "client.js",
19
+ "client.d.ts"
20
+ ],
21
+ "devDependencies": {
22
+ "@nocobase/acl": "0.11.0-alpha.1",
23
+ "@nocobase/actions": "0.11.0-alpha.1",
24
+ "@nocobase/client": "0.11.0-alpha.1",
25
+ "@nocobase/database": "0.11.0-alpha.1",
26
+ "@nocobase/server": "0.11.0-alpha.1",
27
+ "@nocobase/test": "0.11.0-alpha.1",
28
+ "@nocobase/utils": "0.11.0-alpha.1",
29
+ "@types/jsonwebtoken": "^8.5.8",
30
+ "jsonwebtoken": "^8.5.1",
31
+ "react": "^18.2.0",
32
+ "react-dom": "^18.2.0"
16
33
  },
17
34
  "repository": {
18
35
  "type": "git",
19
36
  "url": "git+https://github.com/nocobase/nocobase.git",
20
37
  "directory": "packages/plugins/acl"
21
38
  },
22
- "gitHead": "1be8fcdad42688064460761cea22830cf392c7c0"
39
+ "gitHead": "7581b6d3a3a54f09f06a9effb7e3e65328281b2b"
23
40
  }
package/server.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export * from './src/server';
2
+ export { default } from './src/server';
3
+
package/server.js ADDED
@@ -0,0 +1 @@
1
+ module.exports = require('./lib/server/index.js');
@@ -0,0 +1,8 @@
1
+ import { Plugin } from '@nocobase/client';
2
+
3
+ class AclPlugin extends Plugin {
4
+ async load() {
5
+ }
6
+ }
7
+
8
+ export default AclPlugin;
package/src/index.ts ADDED
@@ -0,0 +1 @@
1
+ export { default } from './server';