rbac 4.0.2 → 6.0.0

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 (42) hide show
  1. package/HISTORY.md +21 -3
  2. package/LICENSE +21 -0
  3. package/README.md +43 -104
  4. package/dist/Base.js +31 -65
  5. package/dist/Base.js.map +1 -0
  6. package/dist/Memory.js +139 -0
  7. package/dist/Memory.js.map +1 -0
  8. package/dist/Permission.js +99 -137
  9. package/dist/Permission.js.map +1 -0
  10. package/dist/RBAC.js +420 -798
  11. package/dist/RBAC.js.map +1 -0
  12. package/dist/Role.js +67 -142
  13. package/dist/Role.js.map +1 -0
  14. package/dist/Storage.js +160 -0
  15. package/dist/Storage.js.map +1 -0
  16. package/dist/index.js +45 -35
  17. package/dist/index.js.map +1 -0
  18. package/package.json +22 -45
  19. package/.babelrc +0 -9
  20. package/.eslintignore +0 -7
  21. package/.eslintrc +0 -5
  22. package/.npmignore +0 -4
  23. package/.travis.yml +0 -14
  24. package/__tests__/role.spec.js +0 -410
  25. package/controllers/express.js +0 -72
  26. package/coverage/clover.xml +0 -526
  27. package/coverage/coverage-final.json +0 -9
  28. package/coverage/lcov-report/base.css +0 -212
  29. package/coverage/lcov-report/index.html +0 -106
  30. package/coverage/lcov-report/prettify.css +0 -1
  31. package/coverage/lcov-report/prettify.js +0 -1
  32. package/coverage/lcov-report/sort-arrow-sprite.png +0 -0
  33. package/coverage/lcov-report/sorter.js +0 -158
  34. package/coverage/lcov-report/tests/index.html +0 -93
  35. package/coverage/lcov-report/tests/role.spec.js.html +0 -1316
  36. package/coverage/lcov.info +0 -1115
  37. package/dist/storages/Memory.js +0 -219
  38. package/dist/storages/Mongoose.js +0 -303
  39. package/dist/storages/index.js +0 -300
  40. package/example/simple.js +0 -25
  41. package/gulpfile.js +0 -16
  42. package/jsdocConfig.js +0 -20
package/dist/RBAC.js CHANGED
@@ -1,34 +1,43 @@
1
- 'use strict';
1
+ "use strict";
2
2
 
3
3
  Object.defineProperty(exports, "__esModule", {
4
4
  value: true
5
5
  });
6
+ exports.default = void 0;
7
+ var _Base = _interopRequireDefault(require("./Base"));
8
+ var _Role = _interopRequireDefault(require("./Role"));
9
+ var _Permission = _interopRequireDefault(require("./Permission"));
10
+ var _Storage = _interopRequireDefault(require("./Storage"));
11
+ var _Memory = _interopRequireDefault(require("./Memory"));
12
+ function _interopRequireDefault(e) { return e && e.__esModule ? e : { default: e }; }
13
+ function isPlainObject(value) {
14
+ if (typeof value !== 'object' || value === null) return false;
15
+ const proto = Object.getPrototypeOf(value);
16
+ return proto === Object.prototype || proto === null;
17
+ }
18
+ const DEFAULT_OPTIONS = {
19
+ permissions: {},
20
+ roles: [],
21
+ grant: {},
22
+ delimiter: '_'
23
+ };
24
+ class RBAC {
25
+ /**
26
+ * Convert Array of permissions to permission name
27
+ * @function getPermissionNames
28
+ * @memberof RBAC
29
+ * @param {Array} permissions List of array items of permission names. It contan action and resource
30
+ * @param {string} delimiter
31
+ * @return {string[]}
32
+ * @static
33
+ */
34
+ static getPermissionNames(permissions, delimiter) {
35
+ if (!delimiter) {
36
+ throw new Error('Delimiter is not defined');
37
+ }
38
+ return permissions.map(permission => _Permission.default.createName(permission[0], permission[1], delimiter));
39
+ }
6
40
 
7
- var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
8
-
9
- var _isPlainObject = require('lodash/isPlainObject');
10
-
11
- var _isPlainObject2 = _interopRequireDefault(_isPlainObject);
12
-
13
- var _async = require('async');
14
-
15
- var _Role = require('./Role');
16
-
17
- var _Role2 = _interopRequireDefault(_Role);
18
-
19
- var _Permission = require('./Permission');
20
-
21
- var _Permission2 = _interopRequireDefault(_Permission);
22
-
23
- var _Memory = require('./storages/Memory');
24
-
25
- var _Memory2 = _interopRequireDefault(_Memory);
26
-
27
- function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
28
-
29
- function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
30
-
31
- var RBAC = function () {
32
41
  /**
33
42
  * RBAC constructor
34
43
  * @constructor RBAC
@@ -37,828 +46,441 @@ var RBAC = function () {
37
46
  * @param {Array} [options.roles] List of role names (String)
38
47
  * @param {Object} [options.permissions] List of permissions
39
48
  * @param {Object} [options.grants] List of grants
40
- * @param {Function} [callback] Callback function
41
49
  */
42
- function RBAC() {
43
- var _this = this;
44
-
45
- var options = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
46
- var callback = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : function () {};
47
-
48
- _classCallCheck(this, RBAC);
49
-
50
- options.storage = options.storage || new _Memory2.default();
51
-
52
- this._options = options;
53
-
54
- this.storage.rbac = this;
55
-
56
- var permissions = options.permissions || {};
57
- var roles = options.roles || [];
58
- var grants = options.grants || {};
59
-
60
- this.create(roles, permissions, grants, function (err) {
61
- if (err) {
62
- return callback(err);
63
- }
64
-
65
- return callback(null, _this);
66
- });
50
+ constructor(options) {
51
+ this.options = {
52
+ ...DEFAULT_OPTIONS,
53
+ ...options
54
+ };
55
+ this.storage = this.options.storage || new _Memory.default();
56
+ this.storage.useRBAC(this);
57
+ }
58
+ async init() {
59
+ const {
60
+ roles,
61
+ permissions,
62
+ grants
63
+ } = this.options;
64
+ return this.create(roles, permissions, grants);
67
65
  }
68
66
 
69
67
  /**
70
- * The RBAC's options.
71
- * @member RBAC#options {Object}
68
+ * Get instance of Role or Permission by his name
69
+ * @method RBAC#get
70
+ * @param {String} name Name of item
72
71
  */
72
+ async get(name) {
73
+ return this.storage.get(name);
74
+ }
73
75
 
74
-
75
- _createClass(RBAC, [{
76
- key: 'add',
77
-
78
-
79
- /**
80
- * Register role or permission to actual RBAC instance
81
- * @method RBAC#add
82
- * @param {Role|Permission} item Instance of Base
83
- * @param {Function} cb Callback function
84
- * @return {RBAC} Return actual instance
85
- */
86
- value: function add(item, cb) {
87
- if (!item) {
88
- return cb(new Error('Item is undefined'));
89
- }
90
-
91
- if (item.rbac !== this) {
92
- return cb(new Error('Item is associated to another RBAC instance'));
93
- }
94
-
95
- this.storage.add(item, cb);
96
- return this;
76
+ /**
77
+ * Register role or permission to actual RBAC instance
78
+ * @method RBAC#add
79
+ * @param {Base} item Instance of Base
80
+ */
81
+ async add(item) {
82
+ if (!item) {
83
+ throw new Error('Item is undefined');
97
84
  }
98
-
99
- /**
100
- * Get instance of Role or Permission by his name
101
- * @method RBAC#get
102
- * @param {String} name Name of item
103
- * @param {Function} cb Callback function
104
- * @return {RBAC} Return instance of actual RBAC
105
- */
106
-
107
- }, {
108
- key: 'get',
109
- value: function get(name, cb) {
110
- this.storage.get(name, cb);
111
- return this;
85
+ if (item.rbac !== this) {
86
+ throw new Error('Item is associated to another RBAC instance');
112
87
  }
88
+ return this.storage.add(item);
89
+ }
113
90
 
114
- /**
115
- * Remove role or permission from RBAC
116
- * @method RBAC#remove
117
- * @param {Role|Permission} item Instance of role or permission
118
- * @param {Function} cb Callback function
119
- * @return {RBAC} Current instance
120
- */
121
-
122
- }, {
123
- key: 'remove',
124
- value: function remove(item, cb) {
125
- if (!item) {
126
- return cb(new Error('Item is undefined'));
127
- }
128
-
129
- if (item.rbac !== this) {
130
- return cb(new Error('Item is associated to another RBAC instance'));
131
- }
132
-
133
- this.storage.remove(item, cb);
134
- return this;
91
+ /**
92
+ * Remove role or permission from RBAC
93
+ * @method RBAC#remove
94
+ * @param {Base} item Instance of role or permission
95
+ */
96
+ async remove(item) {
97
+ if (!item) {
98
+ throw new Error('Item is undefined');
135
99
  }
136
-
137
- /**
138
- * Remove role or permission from RBAC
139
- * @method RBAC#removeByName
140
- * @param {String} name Name of role or permission
141
- * @param {Function} cb Callback function
142
- * @return {RBAC} Current instance
143
- */
144
-
145
- }, {
146
- key: 'removeByName',
147
- value: function removeByName(name, cb) {
148
- this.get(name, function (err, item) {
149
- if (err) {
150
- return cb(err);
151
- }
152
-
153
- if (!item) {
154
- return cb(null, false);
155
- }
156
-
157
- item.remove(cb);
158
- });
159
-
160
- return this;
100
+ if (item.rbac !== this) {
101
+ throw new Error('Item is associated to another RBAC instance');
161
102
  }
103
+ return this.storage.remove(item);
104
+ }
162
105
 
163
- /**
164
- * Grant permission or role to the role
165
- * @method RBAC#grant
166
- * @param {Role} role Instance of the role
167
- * @param {Role|Permission} child Instance of the role or permission
168
- * @param {Function} cb Callback function
169
- * @return {RBAC} Current instance
170
- */
171
-
172
- }, {
173
- key: 'grant',
174
- value: function grant(role, child, cb) {
175
- if (!role || !child) {
176
- return cb(new Error('One of item is undefined'));
177
- }
178
-
179
- if (role.rbac !== this || child.rbac !== this) {
180
- return cb(new Error('Item is associated to another RBAC instance'));
181
- }
182
-
183
- if (!RBAC.isRole(role)) {
184
- return cb(new Error('Role is not instance of Role'));
185
- }
186
-
187
- this.storage.grant(role, child, cb);
188
- return this;
106
+ /**
107
+ * Remove role or permission from RBAC
108
+ * @method RBAC#removeByName
109
+ * @param {String} name Name of role or permission
110
+ */
111
+ async removeByName(name) {
112
+ const item = await this.get(name);
113
+ if (!item) {
114
+ return true;
189
115
  }
116
+ return item.remove();
117
+ }
190
118
 
191
- /**
192
- * Revoke permission or role from the role
193
- * @method RBAC#revoke
194
- * @param {Role} role Instance of the role
195
- * @param {Role|Permission} child Instance of the role or permission
196
- * @param {Function} cb Callback function
197
- * @return {RBAC} Current instance
198
- */
199
-
200
- }, {
201
- key: 'revoke',
202
- value: function revoke(role, child, cb) {
203
- if (!role || !child) {
204
- return cb(new Error('One of item is undefined'));
205
- }
206
-
207
- if (role.rbac !== this || child.rbac !== this) {
208
- return cb(new Error('Item is associated to another RBAC instance'));
209
- }
210
-
211
- this.storage.revoke(role, child, cb);
212
- return this;
119
+ /**
120
+ * Grant permission or role to the role
121
+ * @method RBAC#grant
122
+ * @param {Role} role Instance of the role
123
+ * @param {Base} child Instance of the role or permission
124
+ */
125
+ async grant(role, child) {
126
+ if (!role || !child) {
127
+ throw new Error('One of item is undefined');
213
128
  }
214
-
215
- /**
216
- * Revoke permission or role from the role by names
217
- * @method RBAC#revokeByName
218
- * @param {String} roleName Instance of the role
219
- * @param {String} childName Instance of the role or permission
220
- * @param {Function} cb Callback function
221
- * @return {RBAC} Current instance
222
- */
223
-
224
- }, {
225
- key: 'revokeByName',
226
- value: function revokeByName(roleName, childName, cb) {
227
- var _this2 = this;
228
-
229
- (0, _async.parallel)({
230
- role: function role(callback) {
231
- return _this2.get(roleName, callback);
232
- },
233
- child: function child(callback) {
234
- return _this2.get(childName, callback);
235
- }
236
- }, function (err, results) {
237
- if (err) {
238
- return cb(err);
239
- }
240
-
241
- _this2.revoke(results.role, results.child, cb);
242
- });
243
-
244
- return this;
129
+ if (role.rbac !== this || child.rbac !== this) {
130
+ throw new Error('Item is associated to another RBAC instance');
245
131
  }
246
-
247
- /**
248
- * Grant permission or role from the role by names
249
- * @method RBAC#grantByName
250
- * @param {String} roleName Instance of the role
251
- * @param {String} childName Instance of the role or permission
252
- * @param {Function} cb Callback function
253
- * @return {RBAC} Current instance
254
- */
255
-
256
- }, {
257
- key: 'grantByName',
258
- value: function grantByName(roleName, childName, cb) {
259
- var _this3 = this;
260
-
261
- (0, _async.parallel)({
262
- role: function role(callback) {
263
- return _this3.get(roleName, callback);
264
- },
265
- child: function child(callback) {
266
- return _this3.get(childName, callback);
267
- }
268
- }, function (err, results) {
269
- if (err) {
270
- return cb(err);
271
- }
272
-
273
- _this3.grant(results.role, results.child, cb);
274
- });
275
-
276
- return this;
132
+ if (!(role instanceof _Role.default)) {
133
+ throw new Error('Role is not instance of Role');
277
134
  }
135
+ return this.storage.grant(role, child);
136
+ }
278
137
 
279
- /**
280
- * Create a new role assigned to actual instance of RBAC
281
- * @method RBAC#createRole
282
- * @param {String} roleName Name of new Role
283
- * @param {Boolean} [add=true] True if you need to add it to the storage
284
- * @return {Role} Instance of the Role
285
- */
286
-
287
- }, {
288
- key: 'createRole',
289
- value: function createRole(roleName, add, cb) {
290
- return new _Role2.default(this, roleName, add, cb);
138
+ /**
139
+ * Revoke permission or role from the role
140
+ * @method RBAC#revoke
141
+ * @param {Role} role Instance of the role
142
+ * @param {Base} child Instance of the role or permission
143
+ */
144
+ async revoke(role, child) {
145
+ if (!role || !child) {
146
+ throw new Error('One of item is undefined');
291
147
  }
292
-
293
- /**
294
- * Create a new permission assigned to actual instance of RBAC
295
- * @method RBAC#createPermission
296
- * @param {String} action Name of action
297
- * @param {String} resource Name of resource
298
- * @param {Boolean} [add=true] True if you need to add it to the storage
299
- * @param {Function} cb Callback function
300
- * @return {Permission} Instance of the Permission
301
- */
302
-
303
- }, {
304
- key: 'createPermission',
305
- value: function createPermission(action, resource, add, cb) {
306
- return new _Permission2.default(this, action, resource, add, cb);
148
+ if (role.rbac !== this || child.rbac !== this) {
149
+ throw new Error('Item is associated to another RBAC instance');
307
150
  }
151
+ return this.storage.revoke(role, child);
152
+ }
308
153
 
309
- /**
310
- * Callback returns true if role or permission exists
311
- * @method RBAC#exists
312
- * @param {String} name Name of item
313
- * @param {Function} cb Callback function
314
- * @return {RBAC} Return instance of actual RBAC
315
- */
316
-
317
- }, {
318
- key: 'exists',
319
- value: function exists(name, cb) {
320
- this.storage.exists(name, cb);
321
- return this;
322
- }
154
+ /**
155
+ * Revoke permission or role from the role by names
156
+ * @method RBAC#revokeByName
157
+ * @param {String} roleName Instance of the role
158
+ * @param {String} childName Instance of the role or permission
159
+ */
160
+ async revokeByName(roleName, childName) {
161
+ const [role, child] = await Promise.all([this.get(roleName), this.get(childName)]);
162
+ return this.revoke(role, child);
163
+ }
323
164
 
324
- /**
325
- * Callback returns true if role exists
326
- * @method RBAC#existsRole
327
- * @param {String} name Name of item
328
- * @param {Function} cb Callback function
329
- * @return {RBAC} Return instance of actual RBAC
330
- */
331
-
332
- }, {
333
- key: 'existsRole',
334
- value: function existsRole(name, cb) {
335
- this.storage.existsRole(name, cb);
336
- return this;
337
- }
165
+ /**
166
+ * Grant permission or role from the role by names
167
+ * @method RBAC#grantByName
168
+ * @param {String} roleName Instance of the role
169
+ * @param {String} childName Instance of the role or permission
170
+ */
171
+ async grantByName(roleName, childName) {
172
+ const [role, child] = await Promise.all([this.get(roleName), this.get(childName)]);
173
+ return this.grant(role, child);
174
+ }
338
175
 
339
- /**
340
- * Callback returns true if permission exists
341
- * @method RBAC#existsPermission
342
- * @param {String} action Name of action
343
- * @param {String} resource Name of resource
344
- * @param {Function} cb Callback function
345
- * @return {RBAC} Return instance of actual RBAC
346
- */
347
-
348
- }, {
349
- key: 'existsPermission',
350
- value: function existsPermission(action, resource, cb) {
351
- this.storage.existsPermission(action, resource, cb);
352
- return this;
176
+ /**
177
+ * Create a new role assigned to actual instance of RBAC
178
+ * @method RBAC#createRole
179
+ * @param {String} roleName Name of new Role
180
+ * @param {Boolean} [add] True if you need to add it to the storage
181
+ * @return {Role} Instance of the Role
182
+ */
183
+ async createRole(roleName, add) {
184
+ const role = new _Role.default(this, roleName);
185
+ if (add) {
186
+ await role.add();
353
187
  }
188
+ return role;
189
+ }
354
190
 
355
- /**
356
- * Return instance of Role by his name
357
- * @method RBAC#getRole
358
- * @param {String} name Name of role
359
- * @param {Function} cb Callback function
360
- * @return {RBAC} Return instance of actual RBAC
361
- */
362
-
363
- }, {
364
- key: 'getRole',
365
- value: function getRole(name, cb) {
366
- this.storage.getRole(name, cb);
367
- return this;
191
+ /**
192
+ * Create a new permission assigned to actual instance of RBAC
193
+ * @method RBAC#createPermission
194
+ * @param {String} action Name of action
195
+ * @param {String} resource Name of resource
196
+ * @param {Boolean} [add] True if you need to add it to the storage
197
+ * @return {Permission} Instance of the Permission
198
+ */
199
+ async createPermission(action, resource, add) {
200
+ const permission = new _Permission.default(this, action, resource);
201
+ if (add) {
202
+ await permission.add();
368
203
  }
204
+ return permission;
205
+ }
369
206
 
370
- /**
371
- * Return all instances of Role
372
- * @method RBAC#getRoles
373
- * @param {Function} cb Callback function
374
- * @return {RBAC} Return instance of actual RBAC
375
- */
376
-
377
- }, {
378
- key: 'getRoles',
379
- value: function getRoles(cb) {
380
- this.storage.getRoles(cb);
381
- return this;
382
- }
207
+ /**
208
+ * Callback returns true if role or permission exists
209
+ * @method RBAC#exists
210
+ * @param {String} name Name of item
211
+ */
212
+ async exists(name) {
213
+ return this.storage.exists(name);
214
+ }
383
215
 
384
- /**
385
- * Return instance of Permission by his action and resource
386
- * @method RBAC#getPermission
387
- * @param {String} action Name of action
388
- * @param {String} resource Name of resource
389
- * @param {Function} cb Callback function
390
- * @return {RBAC} Return instance of actual RBAC
391
- */
392
-
393
- }, {
394
- key: 'getPermission',
395
- value: function getPermission(action, resource, cb) {
396
- this.storage.getPermission(action, resource, cb);
397
- return this;
398
- }
216
+ /**
217
+ * Callback returns true if role exists
218
+ * @method RBAC#existsRole
219
+ * @param {String} name Name of item
220
+ */
221
+ async existsRole(name) {
222
+ return this.storage.existsRole(name);
223
+ }
399
224
 
400
- /**
401
- * Return instance of Permission by his name
402
- * @method RBAC#getPermission
403
- * @param {String} name Name of permission
404
- * @param {Function} cb Callback function
405
- * @return {RBAC} Return instance of actual RBAC
406
- */
407
-
408
- }, {
409
- key: 'getPermissionByName',
410
- value: function getPermissionByName(name, cb) {
411
- var data = _Permission2.default.decodeName(name);
412
- this.storage.getPermission(data.action, data.resource, cb);
413
- return this;
414
- }
225
+ /**
226
+ * Callback returns true if permission exists
227
+ * @method RBAC#existsPermission
228
+ * @param {String} action Name of action
229
+ * @param {String} resource Name of resource
230
+ */
231
+ async existsPermission(action, resource) {
232
+ return this.storage.existsPermission(action, resource);
233
+ }
415
234
 
416
- /**
417
- * Return all instances of Permission
418
- * @method RBAC#getPermissions
419
- * @param {Function} cb Callback function
420
- * @return {RBAC} Return instance of actual RBAC
421
- */
422
-
423
- }, {
424
- key: 'getPermissions',
425
- value: function getPermissions(cb) {
426
- this.storage.getPermissions(cb);
427
- return this;
428
- }
235
+ /**
236
+ * Return instance of Role by his name
237
+ * @method RBAC#getRole
238
+ * @param {String} name Name of role
239
+ */
240
+ async getRole(name) {
241
+ return this.storage.getRole(name);
242
+ }
429
243
 
430
- /**
431
- * Create multiple permissions in one step
432
- * @method RBAC#createPermissions
433
- * @param {Object} permissions Object of permissions
434
- * @param {Boolean} [add=true] True if you need to add it to the storage
435
- * @param {Function} cb Callbck function
436
- * @return {RBAC} Instance of actual RBAC
437
- */
438
-
439
- }, {
440
- key: 'createPermissions',
441
- value: function createPermissions(resources, add, cb) {
442
- var _this4 = this;
443
-
444
- if (typeof add === 'function') {
445
- return this.createPermissions(resources, true, add);
446
- }
244
+ /**
245
+ * Return all instances of Role
246
+ * @method RBAC#getRoles
247
+ */
248
+ async getRoles() {
249
+ return this.storage.getRoles();
250
+ }
447
251
 
448
- var tasks = {};
252
+ /**
253
+ * Return instance of Permission by his action and resource
254
+ * @method RBAC#getPermission
255
+ * @param {String} action Name of action
256
+ * @param {String} resource Name of resource
257
+ */
258
+ async getPermission(action, resource) {
259
+ return this.storage.getPermission(action, resource);
260
+ }
449
261
 
450
- if (!(0, _isPlainObject2.default)(resources)) {
451
- return cb(new Error('Resources is not a plain object'));
452
- }
262
+ /**
263
+ * Return instance of Permission by his name
264
+ * @method RBAC#getPermission
265
+ * @param {String} name Name of permission
266
+ */
267
+ async getPermissionByName(name) {
268
+ const data = _Permission.default.decodeName(name, this.options.delimiter);
269
+ return this.storage.getPermission(data.action, data.resource);
270
+ }
453
271
 
454
- Object.keys(resources).forEach(function (resource) {
455
- resources[resource].forEach(function (action) {
456
- var name = _Permission2.default.createName(action, resource);
457
- tasks[name] = function (callback) {
458
- return _this4.createPermission(action, resource, add, callback);
459
- };
460
- }, _this4);
461
- }, this);
462
-
463
- (0, _async.parallel)(tasks, cb);
464
- return this;
465
- }
272
+ /**
273
+ * Return all instances of Permission
274
+ * @method RBAC#getPermissions
275
+ */
276
+ async getPermissions() {
277
+ return this.storage.getPermissions();
278
+ }
466
279
 
467
- /**
468
- * Create multiple roles in one step assigned to actual instance of RBAC
469
- * @method RBAC#createRoles
470
- * @param {Array} roleNames Array of role names
471
- * @param {Boolean} [add=true] True if you need to add it to the storage
472
- * @param {Function} cb Callback function
473
- * @return {RBAC} Current instance
474
- */
475
-
476
- }, {
477
- key: 'createRoles',
478
- value: function createRoles(roleNames, add, cb) {
479
- var _this5 = this;
480
-
481
- if (typeof add === 'function') {
482
- return this.createRoles(roleNames, true, add);
483
- }
280
+ /**
281
+ * Create multiple permissions in one step
282
+ * @method RBAC#createPermissions
283
+ * @param {Object} permissions Object of permissions
284
+ * @param {Boolean} [add=true] True if you need to add it to the storage
285
+ */
286
+ async createPermissions(resources, add = true) {
287
+ if (!isPlainObject(resources)) {
288
+ throw new Error('Resources is not a plain object');
289
+ }
290
+ const permissions = {};
291
+ await Promise.all(Object.keys(resources).map(async resource => {
292
+ const actions = resources[resource];
293
+ await Promise.all(actions.map(async action => {
294
+ const permission = await this.createPermission(action, resource, add);
295
+ permissions[permission.name] = permission;
296
+ }));
297
+ }));
298
+ return permissions;
299
+ }
484
300
 
485
- var tasks = {};
301
+ /**
302
+ * Create multiple roles in one step assigned to actual instance of RBAC
303
+ * @method RBAC#createRoles
304
+ * @param {Array} roleNames Array of role names
305
+ * @param {Boolean} [add=true] True if you need to add it to the storage
306
+ */
307
+ async createRoles(roleNames, add = true) {
308
+ const roles = {};
309
+ await Promise.all(roleNames.map(async roleName => {
310
+ const role = await this.createRole(roleName, add);
311
+ roles[role.name] = role;
312
+ }));
313
+ return roles;
314
+ }
486
315
 
487
- roleNames.forEach(function (roleName) {
488
- tasks[roleName] = function (callback) {
489
- return _this5.createRole(roleName, add, callback);
490
- };
491
- }, this);
316
+ /**
317
+ * Grant multiple items in one function
318
+ * @method RBAC#grants
319
+ * @param {Object} List of roles
320
+ */
321
+ async grants(roles) {
322
+ if (!isPlainObject(roles)) {
323
+ throw new Error('Grants is not a plain object');
324
+ }
325
+ await Promise.all(Object.keys(roles).map(async roleName => {
326
+ const grants = roles[roleName];
327
+ await Promise.all(grants.map(async grant => {
328
+ await this.grantByName(roleName, grant);
329
+ }));
330
+ }));
331
+ }
492
332
 
493
- (0, _async.parallel)(tasks, cb);
494
- return this;
495
- }
333
+ /**
334
+ * Create multiple permissions and roles in one step
335
+ * @method RBAC#create
336
+ * @param {Object[]} roleNames List of role names
337
+ * @param {Object[]} permissionNames List of permission names
338
+ * @param {Object} [grants] List of grants
339
+ */
340
+ async create(roleNames, permissionNames, grantsData) {
341
+ const [permissions, roles] = await Promise.all([this.createPermissions(permissionNames), this.createRoles(roleNames)]);
342
+ if (grantsData) {
343
+ await this.grants(grantsData);
344
+ }
345
+ return {
346
+ permissions,
347
+ roles
348
+ };
349
+ }
496
350
 
497
- /**
498
- * Grant multiple items in one function
499
- * @method RBAC#grants
500
- * @param {Object} List of roles
501
- * @param {Function} cb Callback function
502
- * @return {RBAC} Current instance
503
- */
504
-
505
- }, {
506
- key: 'grants',
507
- value: function grants(roles, cb) {
508
- var _this6 = this;
509
-
510
- if (!(0, _isPlainObject2.default)(roles)) {
511
- return cb(new Error('Grants is not a plain object'));
351
+ /**
352
+ * Traverse hierarchy of roles.
353
+ * Callback function returns as second parameter item from hierarchy or null if we are on the end of hierarchy.
354
+ * @method RBAC#_traverseGrants
355
+ * @param {string} roleName Name of role
356
+ * @param {Function} cb Callback function
357
+ * @private
358
+ */
359
+ async traverseGrants(roleName, cb, next = [roleName], used = {}) {
360
+ const actualRole = next.shift();
361
+ used[actualRole] = true;
362
+ const grants = await this.storage.getGrants(actualRole);
363
+ for (let i = 0; i < grants.length; i += 1) {
364
+ const item = grants[i];
365
+ const {
366
+ name
367
+ } = item;
368
+ if (item instanceof _Role.default && !used[name]) {
369
+ used[name] = true;
370
+ next.push(name);
512
371
  }
513
-
514
- var tasks = [];
515
-
516
- Object.keys(roles).forEach(function (role) {
517
- roles[role].forEach(function (grant) {
518
- tasks.push(function (callback) {
519
- return _this6.grantByName(role, grant, callback);
520
- });
521
- }, _this6);
522
- }, this);
523
-
524
- (0, _async.parallel)(tasks, cb);
525
- return this;
526
- }
527
-
528
- /**
529
- * Create multiple permissions and roles in one step
530
- * @method RBAC#create
531
- * @param {Array} roleNames List of role names
532
- * @param {Object} permissionNames List of permission names
533
- * @param {Object} [grants] List of grants
534
- * @param {Array} cb Callback function
535
- * @return {RBAC} Instance of actual RBAC
536
- */
537
-
538
- }, {
539
- key: 'create',
540
- value: function create(roleNames, permissionNames, grants, cb) {
541
- var _this7 = this;
542
-
543
- if (typeof grants === 'function') {
544
- return this.create(roleNames, permissionNames, null, grants);
372
+ const result = await cb(item);
373
+ if (result !== undefined) {
374
+ return result;
545
375
  }
546
-
547
- var tasks = {
548
- permissions: function permissions(callback) {
549
- return _this7.createPermissions(permissionNames, callback);
550
- },
551
- roles: function roles(callback) {
552
- return _this7.createRoles(roleNames, callback);
553
- }
554
- };
555
-
556
- (0, _async.parallel)(tasks, function (err, result) {
557
- if (err || !grants) {
558
- return cb(err, result);
559
- }
560
-
561
- // add grants to roles
562
- _this7.grants(grants, function (err2) {
563
- if (err2) {
564
- return cb(err2);
565
- }
566
-
567
- cb(null, result);
568
- });
569
- });
570
-
571
- return this;
572
- }
573
-
574
- /**
575
- * Traverse hierarchy of roles.
576
- * Callback function returns as second parameter item from hierarchy or null if we are on the end of hierarchy.
577
- * @method RBAC#_traverseGrants
578
- * @param {String} roleName Name of role
579
- * @param {Function} cb Callback function
580
- * @return {RBAC} Return instance of actual RBAC
581
- * @private
582
- */
583
-
584
- }, {
585
- key: '_traverseGrants',
586
- value: function _traverseGrants(roleName, cb) {
587
- var _this8 = this;
588
-
589
- var next = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [roleName];
590
- var used = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : {};
591
-
592
- var actualRole = next.shift();
593
- used[actualRole] = true;
594
-
595
- this.storage.getGrants(actualRole, function (err) {
596
- var items = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : [];
597
-
598
- if (err) {
599
- return cb(err);
600
- }
601
-
602
- for (var i = 0; i < items.length; i++) {
603
- var item = items[i];
604
- var name = item.name;
605
-
606
- if (RBAC.isRole(item) && !used[name]) {
607
- used[name] = true;
608
- next.push(name);
609
- }
610
-
611
- if (cb(null, item) === false) {
612
- return void 0;
613
- }
614
- }
615
-
616
- if (next.length === 0) {
617
- return cb(null, null);
618
- }
619
-
620
- _this8._traverseGrants(null, cb, next, used);
621
- });
622
-
623
- return this;
624
376
  }
625
-
626
- /**
627
- * Return true if role has allowed permission
628
- * @method RBAC#can
629
- * @param {String} roleName Name of role
630
- * @param {String} action Name of action
631
- * @param {String} resource Name of resource
632
- * @param {Function} cb Callback function
633
- * @return {RBAC} Current instance
634
- */
635
-
636
- }, {
637
- key: 'can',
638
- value: function can(roleName, action, resource, cb) {
639
- this._traverseGrants(roleName, function (err, item) {
640
- // if there is a error
641
- if (err) {
642
- return cb(err);
643
- }
644
-
645
- // this is last item
646
- if (!item) {
647
- return cb(null, false);
648
- }
649
-
650
- if (RBAC.isPermission(item) && item.can(action, resource) === true) {
651
- cb(null, true);
652
- // end up actual traversing
653
- return false;
654
- }
655
- });
656
-
657
- return this;
658
- }
659
-
660
- /**
661
- * Check if the role has any of the given permissions.
662
- * @method RBAC#canAny
663
- * @param {String} roleName Name of role
664
- * @param {Array} permissions Array (String action, String resource)
665
- * @param {Function} cb Callback function
666
- * @return {RBAC} Current instance
667
- */
668
-
669
- }, {
670
- key: 'canAny',
671
- value: function canAny(roleName, permissions, cb) {
672
- // prepare the names of permissions
673
- var permissionNames = RBAC.getPermissionNames(permissions);
674
-
675
- // traverse hierarchy
676
- this._traverseGrants(roleName, function (err, item) {
677
- // if there is a error
678
- if (err) {
679
- return cb(err);
680
- }
681
-
682
- // this is last item
683
- if (!item) {
684
- return cb(null, false);
685
- }
686
-
687
- if (RBAC.isPermission(item) && permissionNames.indexOf(item.name) !== -1) {
688
- cb(null, true);
689
- // end up actual traversing
690
- return false;
691
- }
692
- });
693
-
694
- return this;
695
- }
696
-
697
- /**
698
- * Check if the model has all of the given permissions.
699
- * @method RBAC#canAll
700
- * @param {String} roleName Name of role
701
- * @param {Array} permissions Array (String action, String resource)
702
- * @param {Function} cb Callback function
703
- * @return {RBAC} Current instance
704
- */
705
-
706
- }, {
707
- key: 'canAll',
708
- value: function canAll(roleName, permissions, cb) {
709
- // prepare the names of permissions
710
- var permissionNames = RBAC.getPermissionNames(permissions);
711
- var founded = {};
712
- var foundedCount = 0;
713
-
714
- // traverse hierarchy
715
- this._traverseGrants(roleName, function (err, item) {
716
- // if there is a error
717
- if (err) {
718
- return cb(err);
719
- }
720
-
721
- // this is last item
722
- if (!item) {
723
- return cb(null, false);
724
- }
725
-
726
- if (RBAC.isPermission(item) && permissionNames.indexOf(item.name) !== -1 && !founded[item.name]) {
727
- founded[item.name] = true;
728
- foundedCount++;
729
-
730
- if (foundedCount === permissionNames.length) {
731
- cb(null, true);
732
- // end up actual traversing
733
- return false;
734
- }
735
- }
736
- });
737
-
738
- return this;
377
+ if (next.length) {
378
+ return this.traverseGrants(null, cb, next, used);
739
379
  }
380
+ }
740
381
 
741
- /**
742
- * Return true if role has allowed permission
743
- * @method RBAC#hasRole
744
- * @param {String} roleName Name of role
745
- * @param {String} roleChildName Name of child role
746
- * @param {Function} cb Callback function
747
- * @return {RBAC} Current instance
748
- */
749
-
750
- }, {
751
- key: 'hasRole',
752
- value: function hasRole(roleName, roleChildName, cb) {
753
- if (roleName === roleChildName) {
754
- cb(null, true);
755
- return this;
382
+ /**
383
+ * Return true if role has allowed permission
384
+ * @method RBAC#can
385
+ * @param {string} roleName Name of role
386
+ * @param {string} action Name of action
387
+ * @param {string} resource Name of resource
388
+ * @return {boolean}
389
+ */
390
+ async can(roleName, action, resource) {
391
+ const can = await this.traverseGrants(roleName, item => {
392
+ if (item instanceof _Permission.default && item.can(action, resource)) {
393
+ return true;
756
394
  }
395
+ });
396
+ return can || false;
397
+ }
757
398
 
758
- this._traverseGrants(roleName, function (err, item) {
759
- // if there is a error
760
- if (err) {
761
- return cb(err);
762
- }
763
-
764
- // this is last item
765
- if (!item) {
766
- return cb(null, false);
767
- }
768
-
769
- if (RBAC.isRole(item) && item.name === roleChildName) {
770
- cb(null, true);
771
- // end up actual traversing
772
- return false;
773
- }
774
- });
775
-
776
- return this;
777
- }
778
-
779
- /**
780
- * Return array of all permission assigned to role of RBAC
781
- * @method RBAC#getScope
782
- * @param {String} roleName Name of role
783
- * @param {Function} cb Callback function
784
- * @return {RBAC} Current instance
785
- */
786
-
787
- }, {
788
- key: 'getScope',
789
- value: function getScope(roleName, cb) {
790
- var scope = [];
791
-
792
- // traverse hierarchy
793
- this._traverseGrants(roleName, function (err, item) {
794
- // if there is a error
795
- if (err) {
796
- return cb(err);
797
- }
798
-
799
- // this is last item
800
- if (!item) {
801
- return cb(null, scope);
802
- }
399
+ /**
400
+ * Check if the role has any of the given permissions.
401
+ * @method RBAC#canAny
402
+ * @param {string} roleName Name of role
403
+ * @param {Object[]} permissions Array (String action, String resource)
404
+ * @return {boolean}
405
+ */
406
+ async canAny(roleName, permissions) {
407
+ // prepare the names of permissions
408
+ const permissionNames = RBAC.getPermissionNames(permissions, this.options.delimiter);
409
+
410
+ // traverse hierarchy
411
+ const can = await this.traverseGrants(roleName, item => {
412
+ if (item instanceof _Permission.default && permissionNames.includes(item.name)) {
413
+ return true;
414
+ }
415
+ return undefined;
416
+ });
417
+ return can || false;
418
+ }
803
419
 
804
- if (RBAC.isPermission(item) && scope.indexOf(item.name) === -1) {
805
- scope.push(item.name);
420
+ /**
421
+ * Check if the model has all of the given permissions.
422
+ * @method RBAC#canAll
423
+ * @param {string} roleName Name of role
424
+ * @param {Object[]} permissions Array (String action, String resource)
425
+ * @return {boolean} Current instance
426
+ */
427
+ async canAll(roleName, permissions) {
428
+ // prepare the names of permissions
429
+ const permissionNames = RBAC.getPermissionNames(permissions, this.options.delimiter);
430
+ const founded = {};
431
+ let foundedCount = 0;
432
+
433
+ // traverse hierarchy
434
+ await this.traverseGrants(roleName, item => {
435
+ if (item instanceof _Permission.default && permissionNames.includes(item.name) && !founded[item.name]) {
436
+ founded[item.name] = true;
437
+ foundedCount += 1;
438
+ if (foundedCount === permissionNames.length) {
439
+ return true;
806
440
  }
807
- });
808
-
809
- return this;
810
- }
811
-
812
- /**
813
- * Convert Array of permissions to permission name
814
- * @function getPermissionNames
815
- * @memberof RBAC
816
- * @param {Array} permissions List of array items of permission names. It contan action and resource
817
- * @return {Array} List of permission names
818
- * @static
819
- */
820
-
821
- }, {
822
- key: 'options',
823
- get: function get() {
824
- return this._options;
825
- }
826
-
827
- /**
828
- * The RBAC's storage.
829
- * @member RBAC#storage {Storage}
830
- */
831
-
832
- }, {
833
- key: 'storage',
834
- get: function get() {
835
- return this.options.storage;
836
- }
837
- }], [{
838
- key: 'getPermissionNames',
839
- value: function getPermissionNames(permissions) {
840
- var permissionNames = [];
841
-
842
- for (var i = 0; i < permissions.length; i++) {
843
- var permission = permissions[i];
844
- permissionNames.push(_Permission2.default.createName(permission[0], permission[1]));
845
441
  }
442
+ return undefined;
443
+ });
444
+ return foundedCount === permissionNames.length;
445
+ }
846
446
 
847
- return permissionNames;
848
- }
849
- }, {
850
- key: 'isPermission',
851
- value: function isPermission(item) {
852
- return item instanceof _Permission2.default;
853
- }
854
- }, {
855
- key: 'isRole',
856
- value: function isRole(item) {
857
- return item instanceof _Role2.default;
447
+ /**
448
+ * Return true if role has allowed permission
449
+ * @method RBAC#hasRole
450
+ * @param {String} roleName Name of role
451
+ * @param {String} roleChildName Name of child role
452
+ * @return {boolean}
453
+ */
454
+ async hasRole(roleName, roleChildName) {
455
+ if (roleName === roleChildName) {
456
+ return true;
858
457
  }
859
- }]);
458
+ const has = await this.traverseGrants(roleName, item => {
459
+ if (item instanceof _Role.default && item.name === roleChildName) {
460
+ return true;
461
+ }
462
+ return undefined;
463
+ });
464
+ return has || false;
465
+ }
860
466
 
861
- return RBAC;
862
- }();
467
+ /**
468
+ * Return array of all permission assigned to role of RBAC
469
+ * @method RBAC#getScope
470
+ * @param {string} roleName Name of role
471
+ * @return {string[]}
472
+ */
473
+ async getScope(roleName) {
474
+ const scope = [];
863
475
 
864
- exports.default = RBAC;
476
+ // traverse hierarchy
477
+ await this.traverseGrants(roleName, item => {
478
+ if (item instanceof _Permission.default && !scope.includes(item.name)) {
479
+ scope.push(item.name);
480
+ }
481
+ });
482
+ return scope;
483
+ }
484
+ }
485
+ exports.default = RBAC;
486
+ //# sourceMappingURL=RBAC.js.map