kuzzle 2.16.11 → 2.17.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.
Files changed (187) hide show
  1. package/lib/api/controllers/adminController.js +3 -3
  2. package/lib/api/controllers/authController.js +12 -12
  3. package/lib/api/controllers/baseController.js +60 -3
  4. package/lib/api/controllers/clusterController.js +1 -1
  5. package/lib/api/controllers/collectionController.js +7 -5
  6. package/lib/api/controllers/documentController.js +130 -17
  7. package/lib/api/controllers/indexController.js +1 -1
  8. package/lib/api/controllers/memoryStorageController.js +39 -38
  9. package/lib/api/controllers/realtimeController.js +1 -1
  10. package/lib/api/controllers/securityController.js +50 -50
  11. package/lib/api/controllers/serverController.js +73 -27
  12. package/lib/api/documentExtractor.js +3 -3
  13. package/lib/api/funnel.js +44 -21
  14. package/lib/api/httpRoutes.js +9 -4
  15. package/lib/api/openapi/OpenApiManager.d.ts +11 -0
  16. package/lib/api/openapi/OpenApiManager.js +96 -0
  17. package/lib/api/openapi/{document → components/document}/count.yaml +2 -2
  18. package/lib/api/openapi/{document → components/document}/create.yaml +2 -2
  19. package/lib/api/openapi/{document → components/document}/createOrReplace.yaml +2 -2
  20. package/lib/api/openapi/{document → components/document}/delete.yaml +1 -1
  21. package/lib/api/openapi/{document → components/document}/deleteByQuery.yaml +2 -2
  22. package/lib/api/openapi/{document → components/document}/exists.yaml +1 -1
  23. package/lib/api/openapi/{document → components/document}/get.yaml +1 -1
  24. package/lib/api/openapi/{document → components/document}/index.d.ts +2 -0
  25. package/lib/api/openapi/{document → components/document}/index.js +7 -2
  26. package/lib/api/openapi/{document → components/document}/replace.yaml +2 -2
  27. package/lib/api/openapi/{document → components/document}/scroll.yaml +1 -1
  28. package/lib/api/openapi/{document → components/document}/update.yaml +2 -2
  29. package/lib/api/openapi/components/document/validate.yaml +42 -0
  30. package/lib/api/openapi/components/index.d.ts +2 -0
  31. package/lib/api/openapi/components/index.js +18 -0
  32. package/lib/api/openapi/{payloads.yaml → components/payloads.yaml} +0 -0
  33. package/lib/api/openapi/index.d.ts +1 -2
  34. package/lib/api/openapi/index.js +1 -5
  35. package/lib/api/openapi/openApiGenerator.d.ts +7 -0
  36. package/lib/api/openapi/openApiGenerator.js +133 -0
  37. package/lib/api/request/kuzzleRequest.js +8 -6
  38. package/lib/cluster/node.js +9 -9
  39. package/lib/cluster/publisher.js +1 -1
  40. package/lib/cluster/state.js +20 -4
  41. package/lib/cluster/subscriber.js +1 -1
  42. package/lib/cluster/workers/IDCardRenewer.js +2 -2
  43. package/lib/config/default.config.js +1 -0
  44. package/lib/config/index.js +6 -6
  45. package/lib/core/auth/passportResponse.js +6 -6
  46. package/lib/core/auth/passportWrapper.js +5 -5
  47. package/lib/core/backend/backend.d.ts +11 -3
  48. package/lib/core/backend/backend.js +22 -17
  49. package/lib/core/backend/backendConfig.d.ts +5 -1
  50. package/lib/core/backend/backendConfig.js +25 -2
  51. package/lib/core/backend/backendController.js +21 -5
  52. package/lib/core/backend/backendErrors.d.ts +58 -0
  53. package/lib/core/backend/backendErrors.js +121 -0
  54. package/lib/core/backend/backendHook.js +21 -5
  55. package/lib/core/backend/backendImport.js +21 -5
  56. package/lib/core/backend/backendOpenApi.d.ts +9 -0
  57. package/lib/core/backend/backendOpenApi.js +69 -0
  58. package/lib/core/backend/backendPipe.js +21 -5
  59. package/lib/core/backend/backendPlugin.js +22 -3
  60. package/lib/core/backend/backendVault.js +21 -2
  61. package/lib/core/backend/index.d.ts +2 -0
  62. package/lib/core/backend/index.js +2 -0
  63. package/lib/core/network/accessLogger.js +6 -6
  64. package/lib/core/network/clientConnection.js +1 -1
  65. package/lib/core/network/entryPoint.js +5 -5
  66. package/lib/core/network/httpRouter/index.js +5 -5
  67. package/lib/core/network/httpRouter/routeHandler.js +3 -3
  68. package/lib/core/network/httpRouter/routePart.js +5 -5
  69. package/lib/core/network/protocolManifest.js +1 -1
  70. package/lib/core/network/protocols/httpMessage.js +2 -2
  71. package/lib/core/network/protocols/httpwsProtocol.js +228 -50
  72. package/lib/core/network/protocols/mqttProtocol.js +3 -3
  73. package/lib/core/network/protocols/protocol.js +3 -3
  74. package/lib/core/network/router.js +7 -6
  75. package/lib/core/plugin/plugin.js +38 -64
  76. package/lib/core/plugin/pluginContext.js +22 -3
  77. package/lib/core/plugin/pluginManifest.js +3 -3
  78. package/lib/core/plugin/pluginRepository.js +5 -5
  79. package/lib/core/plugin/pluginsManager.js +29 -28
  80. package/lib/core/realtime/channel.js +20 -4
  81. package/lib/core/realtime/hotelClerk.js +24 -5
  82. package/lib/core/realtime/notification/server.js +1 -1
  83. package/lib/core/realtime/notification/user.js +1 -1
  84. package/lib/core/realtime/notifier.js +5 -5
  85. package/lib/core/security/index.js +1 -1
  86. package/lib/core/security/profileRepository.d.ts +176 -0
  87. package/lib/core/security/profileRepository.js +445 -443
  88. package/lib/core/security/roleRepository.js +16 -16
  89. package/lib/core/security/securityLoader.js +2 -2
  90. package/lib/core/security/tokenRepository.js +11 -11
  91. package/lib/core/security/userRepository.js +8 -8
  92. package/lib/core/shared/abstractManifest.js +4 -4
  93. package/lib/core/shared/repository.js +5 -5
  94. package/lib/core/shared/sdk/embeddedSdk.js +21 -2
  95. package/lib/core/shared/sdk/funnelProtocol.js +1 -1
  96. package/lib/core/shared/sdk/impersonatedSdk.js +1 -1
  97. package/lib/core/shared/store.js +30 -23
  98. package/lib/core/statistics/statistics.js +17 -17
  99. package/lib/core/storage/clientAdapter.js +45 -10
  100. package/lib/core/storage/indexCache.js +20 -4
  101. package/lib/core/validation/baseType.js +5 -5
  102. package/lib/core/validation/types/anything.js +1 -1
  103. package/lib/core/validation/types/boolean.js +2 -2
  104. package/lib/core/validation/types/date.js +9 -9
  105. package/lib/core/validation/types/email.js +5 -5
  106. package/lib/core/validation/types/enum.js +6 -6
  107. package/lib/core/validation/types/geoPoint.js +2 -2
  108. package/lib/core/validation/types/geoShape.js +28 -25
  109. package/lib/core/validation/types/integer.js +4 -4
  110. package/lib/core/validation/types/ipAddress.js +7 -6
  111. package/lib/core/validation/types/numeric.js +4 -4
  112. package/lib/core/validation/types/object.js +5 -5
  113. package/lib/core/validation/types/string.js +5 -5
  114. package/lib/core/validation/types/url.js +7 -6
  115. package/lib/core/validation/validation.js +95 -84
  116. package/lib/kerror/codes/1-services.json +12 -0
  117. package/lib/kerror/codes/2-api.json +12 -0
  118. package/lib/kerror/codes/3-network.json +12 -0
  119. package/lib/kerror/codes/4-plugin.json +6 -0
  120. package/lib/kerror/codes/index.js +11 -11
  121. package/lib/kerror/errors/multipleErrorsError.d.ts +1 -1
  122. package/lib/kerror/errors/multipleErrorsError.js +3 -3
  123. package/lib/kerror/index.d.ts +82 -0
  124. package/lib/kerror/index.js +176 -143
  125. package/lib/kuzzle/dumpGenerator.js +3 -3
  126. package/lib/kuzzle/event/kuzzleEventEmitter.js +4 -4
  127. package/lib/kuzzle/event/pipeRunner.js +1 -1
  128. package/lib/kuzzle/event/waterfall.js +6 -6
  129. package/lib/kuzzle/kuzzle.js +59 -9
  130. package/lib/kuzzle/log.js +3 -3
  131. package/lib/kuzzle/vault.js +3 -3
  132. package/lib/model/security/profile.d.ts +54 -0
  133. package/lib/model/security/profile.js +192 -232
  134. package/lib/model/security/rights.js +1 -1
  135. package/lib/model/security/role.d.ts +40 -0
  136. package/lib/model/security/role.js +174 -190
  137. package/lib/model/security/user.d.ts +29 -0
  138. package/lib/model/security/user.js +103 -52
  139. package/lib/model/storage/apiKey.js +2 -2
  140. package/lib/model/storage/baseModel.js +3 -3
  141. package/lib/service/cache/redis.js +7 -7
  142. package/lib/service/storage/elasticsearch.js +152 -90
  143. package/lib/service/storage/esWrapper.js +2 -3
  144. package/lib/types/ControllerDefinition.d.ts +3 -3
  145. package/lib/types/ControllerRights.d.ts +22 -0
  146. package/lib/types/ControllerRights.js +23 -0
  147. package/lib/types/HttpStream.d.ts +32 -0
  148. package/lib/types/HttpStream.js +70 -0
  149. package/lib/types/OpenApiDefinition.d.ts +43 -0
  150. package/lib/types/{config/StorageService/StorageServiceElasticsearchConfiguration.js → OpenApiDefinition.js} +1 -1
  151. package/lib/types/Plugin.js +20 -4
  152. package/lib/types/Policy.d.ts +25 -0
  153. package/lib/types/{InternalLogger.js → Policy.js} +2 -2
  154. package/lib/types/PolicyRestrictions.d.ts +21 -0
  155. package/lib/types/PolicyRestrictions.js +23 -0
  156. package/lib/types/Target.d.ts +15 -0
  157. package/lib/types/Target.js +23 -0
  158. package/lib/types/config/KuzzleConfiguration.d.ts +4 -0
  159. package/lib/types/config/ServicesConfiguration.d.ts +2 -2
  160. package/lib/types/config/{StorageService/StorageServiceElasticsearchConfiguration.d.ts → storageEngine/StorageEngineElasticsearchConfiguration.d.ts} +10 -3
  161. package/lib/types/config/storageEngine/StorageEngineElasticsearchConfiguration.js +3 -0
  162. package/lib/types/errors/ErrorDefinition.d.ts +27 -0
  163. package/lib/types/errors/ErrorDefinition.js +3 -0
  164. package/lib/types/errors/ErrorDomains.d.ts +17 -0
  165. package/lib/types/errors/ErrorDomains.js +3 -0
  166. package/lib/types/index.d.ts +9 -1
  167. package/lib/types/index.js +9 -1
  168. package/lib/util/array.d.ts +11 -0
  169. package/lib/util/array.js +57 -0
  170. package/lib/util/assertType.js +6 -6
  171. package/lib/util/bufferedPassThrough.d.ts +76 -0
  172. package/lib/util/bufferedPassThrough.js +161 -0
  173. package/lib/util/deprecate.js +7 -5
  174. package/lib/util/didYouMean.js +1 -1
  175. package/lib/util/dump-collection.d.ts +3 -0
  176. package/lib/util/dump-collection.js +284 -0
  177. package/lib/util/extractFields.js +2 -2
  178. package/lib/util/inflector.d.ts +8 -0
  179. package/lib/util/inflector.js +16 -0
  180. package/lib/util/mutex.js +21 -2
  181. package/lib/util/requestAssertions.js +7 -7
  182. package/lib/util/wildcard.js +55 -0
  183. package/package-lock.json +535 -75
  184. package/package.json +5 -3
  185. package/lib/api/openApiGenerator.d.ts +0 -7
  186. package/lib/api/openApiGenerator.js +0 -197
  187. package/lib/types/InternalLogger.d.ts +0 -25
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /*
2
3
  * Kuzzle, a backend software, self-hostable and ready to use
3
4
  * to power modern apps
@@ -18,202 +19,185 @@
18
19
  * See the License for the specific language governing permissions and
19
20
  * limitations under the License.
20
21
  */
21
-
22
- 'use strict';
23
-
24
- const kerror = require('../../kerror');
25
- const { has, isPlainObject } = require('../../util/safeObject');
26
-
22
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
25
+ }) : (function(o, m, k, k2) {
26
+ if (k2 === undefined) k2 = k;
27
+ o[k2] = m[k];
28
+ }));
29
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
30
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
31
+ }) : function(o, v) {
32
+ o["default"] = v;
33
+ });
34
+ var __importStar = (this && this.__importStar) || function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ Object.defineProperty(exports, "__esModule", { value: true });
42
+ exports.Role = void 0;
43
+ const kerror = __importStar(require("../../kerror"));
44
+ const safeObject_1 = require("../../util/safeObject");
45
+ const array_1 = require("../../util/array");
27
46
  const assertionError = kerror.wrap('api', 'assert');
28
-
29
47
  /**
30
48
  * @class Role
31
49
  */
32
50
  class Role {
33
- constructor () {
34
- this.controllers = {};
35
- }
36
-
37
- /**
38
- * @param {Request} request
39
- * @param {Array} restrictedTo
40
- * @returns {boolean}
41
- */
42
- isActionAllowed (request, restrictedTo = []) {
43
- if (!global.kuzzle) {
44
- throw kerror.get('security', 'role', 'uninitialized', this._id);
45
- }
46
-
47
- if (this.controllers === undefined || this.controllers === null) {
48
- return false;
49
- }
50
-
51
- let controllerRights;
52
-
53
- // @deprecated - the "memoryStorage" alias should be removed in the next
54
- // major version
55
- // Handles the memory storage controller aliases: ms, memoryStorage
56
- if ((request.input.controller === 'ms' || request.input.controller === 'memoryStorage')
57
- && (this.controllers.ms || this.controllers.memoryStorage)
58
- ) {
59
- controllerRights = this.controllers.ms || this.controllers.memoryStorage;
60
- }
61
- else if (has(this.controllers, request.input.controller)) {
62
- controllerRights = this.controllers[request.input.controller];
63
- }
64
- else if (this.controllers['*'] !== undefined) {
65
- controllerRights = this.controllers['*'];
66
- }
67
- else {
68
- return false;
69
- }
70
-
71
- if (controllerRights.actions === undefined) {
72
- return false;
73
- }
74
-
75
- let actionRights;
76
-
77
- if (has(controllerRights.actions, request.input.action)) {
78
- actionRights = controllerRights.actions[request.input.action];
79
- }
80
- else if (controllerRights.actions['*'] !== undefined) {
81
- actionRights = controllerRights.actions['*'];
82
- }
83
- else {
84
- return false;
85
- }
86
-
87
- if (typeof actionRights !== 'boolean' || !actionRights) {
88
- return false;
89
- }
90
-
91
- return checkRestrictions(request, restrictedTo);
92
- }
93
-
94
- /**
95
- * @returns {Promise}
96
- */
97
- async validateDefinition () {
98
- if (this.controllers === undefined || this.controllers === null) {
99
- throw assertionError.get('missing_argument', `${this._id}.controllers`);
100
- }
101
-
102
- if (!isPlainObject(this.controllers)) {
103
- throw assertionError.get('invalid_type', `${this._id}.controllers`, 'object');
104
- }
105
-
106
- if (Object.keys(this.controllers).length === 0) {
107
- throw assertionError.get('empty_argument', `${this._id}.controllers`);
108
- }
109
-
110
- Object
111
- .entries(this.controllers)
112
- .forEach(entry => this.validateControllerRights(...entry));
113
- }
114
-
115
- /**
116
- * Verifies that a controller rights definition is correct
117
- *
118
- * @param {Array.<string, Object>}
119
- * @throws If the controller definition is invalid
120
- */
121
- validateControllerRights (name, controller) {
122
- if (!isPlainObject(controller)) {
123
- throw assertionError.get('invalid_type', name, 'object');
124
- }
125
-
126
- if (Object.keys(controller).length === 0) {
127
- throw assertionError.get('empty_argument', name);
128
- }
129
-
130
- if (!has(controller, 'actions')) {
131
- throw assertionError.get('missing_argument', name);
132
- }
133
-
134
- if (!isPlainObject(controller.actions)) {
135
- throw assertionError.get('invalid_type', `${name}.actions`, 'object');
136
- }
137
-
138
- if (Object.keys(controller.actions).length === 0) {
139
- throw assertionError.get('empty_argument', `${name}.actions`);
140
- }
141
-
142
- for (const [actionName, action] of Object.entries(controller.actions)) {
143
- if (typeof action !== 'boolean') {
144
- throw assertionError.get('invalid_type', `${name}.actions.${actionName}`, 'boolean');
145
- }
146
- }
147
- }
148
-
149
- /**
150
- * Checks if current role allows to log in
151
- *
152
- * @returns {boolean}
153
- */
154
- canLogIn () {
155
- for (const controllerKey of ['auth', '*']) {
156
- if (this.controllers[controllerKey]) {
157
- const controller = this.controllers[controllerKey];
158
-
159
- for (const actionKey of ['login', '*']) {
160
- const action = controller.actions[actionKey];
161
-
162
- if (typeof action === 'boolean' && action) {
51
+ constructor() {
52
+ this.controllers = {};
53
+ }
54
+ /**
55
+ * @param {Request} request
56
+ * @returns {boolean}
57
+ */
58
+ isActionAllowed(request) {
59
+ if (!global.kuzzle) {
60
+ throw kerror.get('security', 'role', 'uninitialized', this._id);
61
+ }
62
+ if (this.controllers === undefined || this.controllers === null) {
63
+ return false;
64
+ }
65
+ let controllerRights;
66
+ // @deprecated - the "memoryStorage" alias should be removed in the next
67
+ // major version
68
+ // Handles the memory storage controller aliases: ms, memoryStorage
69
+ if ((request.input.controller === 'ms' || request.input.controller === 'memoryStorage')
70
+ && (this.controllers.ms || this.controllers.memoryStorage)) {
71
+ controllerRights = this.controllers.ms || this.controllers.memoryStorage;
72
+ }
73
+ else if ((0, safeObject_1.has)(this.controllers, request.input.controller)) {
74
+ controllerRights = this.controllers[request.input.controller];
75
+ }
76
+ else if (this.controllers['*'] !== undefined) {
77
+ controllerRights = this.controllers['*'];
78
+ }
79
+ else {
80
+ return false;
81
+ }
82
+ if (controllerRights.actions === undefined) {
83
+ return false;
84
+ }
85
+ let actionRights;
86
+ if ((0, safeObject_1.has)(controllerRights.actions, request.input.action)) {
87
+ actionRights = controllerRights.actions[request.input.action];
88
+ }
89
+ else if (controllerRights.actions['*'] !== undefined) {
90
+ actionRights = controllerRights.actions['*'];
91
+ }
92
+ else {
93
+ return false;
94
+ }
95
+ if (typeof actionRights !== 'boolean' || !actionRights) {
96
+ return false;
97
+ }
98
+ return true;
99
+ }
100
+ /**
101
+ * @returns {Promise}
102
+ */
103
+ async validateDefinition() {
104
+ if (this.controllers === undefined || this.controllers === null) {
105
+ throw assertionError.get('missing_argument', `${this._id}.controllers`);
106
+ }
107
+ if (!(0, safeObject_1.isPlainObject)(this.controllers)) {
108
+ throw assertionError.get('invalid_type', `${this._id}.controllers`, 'object');
109
+ }
110
+ if (Object.keys(this.controllers).length === 0) {
111
+ throw assertionError.get('empty_argument', `${this._id}.controllers`);
112
+ }
113
+ Object
114
+ .entries(this.controllers)
115
+ .forEach(entry => this.validateControllerRights(...entry));
116
+ }
117
+ /**
118
+ * @param {String} index
119
+ * @param {String} collection
120
+ * @param {Map<string, string[]>} restrictedTo Restricted indexes
121
+ * @returns {Boolean} resolves to a Boolean value
122
+ */
123
+ checkRestrictions(index, collection, restrictedTo) {
124
+ // If no restrictions, we allow the action:
125
+ if (!restrictedTo || restrictedTo.size === 0) {
163
126
  return true;
164
- }
165
127
  }
166
- }
128
+ // If the request's action does not refer to an index, restrictions are
129
+ // useless for this action (=> ignore them)
130
+ if (!index) {
131
+ return true;
132
+ }
133
+ // If the index is not in the restrictions, the action is not allowed
134
+ if (!restrictedTo.has(index)) {
135
+ return false;
136
+ }
137
+ const collections = restrictedTo.get(index);
138
+ // if no collections given on the restriction, the action is allowed for all
139
+ // collections:
140
+ if (!collections || collections.length === 0) {
141
+ return true;
142
+ }
143
+ // Find collection index in array
144
+ // If the collection is not in the array, the action is not allowed
145
+ // The array must be sorted for binary search to work
146
+ const indexOfCollection = (0, array_1.binarySearch)(collections, (collectionName) => {
147
+ if (collection > collectionName) {
148
+ return 1;
149
+ }
150
+ return collection < collectionName ? -1 : 0;
151
+ });
152
+ return indexOfCollection > -1; // Collection found
153
+ }
154
+ /**
155
+ * Verifies that a controller rights definition is correct
156
+ *
157
+ * @param {Array.<string, Object>}
158
+ * @throws If the controller definition is invalid
159
+ */
160
+ validateControllerRights(name, controller) {
161
+ if (!(0, safeObject_1.isPlainObject)(controller)) {
162
+ throw assertionError.get('invalid_type', name, 'object');
163
+ }
164
+ if (Object.keys(controller).length === 0) {
165
+ throw assertionError.get('empty_argument', name);
166
+ }
167
+ if (!(0, safeObject_1.has)(controller, 'actions')) {
168
+ throw assertionError.get('missing_argument', name);
169
+ }
170
+ if (!(0, safeObject_1.isPlainObject)(controller.actions)) {
171
+ throw assertionError.get('invalid_type', `${name}.actions`, 'object');
172
+ }
173
+ if (Object.keys(controller.actions).length === 0) {
174
+ throw assertionError.get('empty_argument', `${name}.actions`);
175
+ }
176
+ for (const [actionName, action] of Object.entries(controller.actions)) {
177
+ if (typeof action !== 'boolean') {
178
+ throw assertionError.get('invalid_type', `${name}.actions.${actionName}`, 'boolean');
179
+ }
180
+ }
181
+ }
182
+ /**
183
+ * Checks if current role allows to log in
184
+ *
185
+ * @returns {boolean}
186
+ */
187
+ canLogIn() {
188
+ for (const controllerKey of ['auth', '*']) {
189
+ if (this.controllers[controllerKey]) {
190
+ const controller = this.controllers[controllerKey];
191
+ for (const actionKey of ['login', '*']) {
192
+ const action = controller.actions[actionKey];
193
+ if (typeof action === 'boolean' && action) {
194
+ return true;
195
+ }
196
+ }
197
+ }
198
+ }
199
+ return false;
167
200
  }
168
-
169
- return false;
170
- }
171
- }
172
-
173
- /**
174
- * @param {Request} request
175
- * @param {object} restriction a restriction object on an index
176
- * @returns {Boolean}
177
- */
178
- function checkIndexRestriction(request, restriction) {
179
- if (restriction.index !== request.input.args.index) {
180
- return false;
181
- }
182
-
183
- // if no collections given on the restriction, the action is allowed for all
184
- // collections:
185
- if (!restriction.collections || restriction.collections.length === 0) {
186
- return true;
187
- }
188
-
189
- // If the request's action does not refer to a collection, the restriction
190
- // is useless for this action (=> ignored):
191
- if (!request.input.args.collection) {
192
- return true;
193
- }
194
-
195
- return restriction.collections.includes(request.input.args.collection);
196
- }
197
-
198
- /**
199
- * @param {Request} request
200
- * @param {Array} restrictedTo
201
- * @returns {Boolean} resolves to a Boolean value
202
- */
203
- function checkRestrictions(request, restrictedTo) {
204
- // If no restrictions, we allow the action:
205
- if (restrictedTo.length === 0) {
206
- return true;
207
- }
208
-
209
- // If the request's action does not refer to an index, restrictions are
210
- // useless for this action (=> ignore them)
211
- if (!request.input.args.index) {
212
- return true;
213
- }
214
-
215
- return restrictedTo
216
- .some(restriction => checkIndexRestriction(request, restriction));
217
201
  }
218
-
219
- module.exports = Role;
202
+ exports.Role = Role;
203
+ //# sourceMappingURL=role.js.map
@@ -0,0 +1,29 @@
1
+ import { Profile } from './profile';
2
+ import { KuzzleRequest } from '../../../index';
3
+ /**
4
+ * @class User
5
+ */
6
+ export declare class User {
7
+ _id: string;
8
+ profileIds: string[];
9
+ constructor();
10
+ /**
11
+ * @returns {Promise<Profile[]>}
12
+ */
13
+ getProfiles(): Promise<Profile[]>;
14
+ /**
15
+ * @returns {Promise}
16
+ */
17
+ getRights(): Promise<{}>;
18
+ /**
19
+ * @param {Request} request
20
+ * @returns {Promise.<boolean>}
21
+ */
22
+ isActionAllowed(request: KuzzleRequest): Promise<boolean>;
23
+ /**
24
+ * Verifies that every targets are allowed by at least one profile,
25
+ * while skipping the ones that includes a wildcard since they will be expanded
26
+ * later on, based on index and collections authorized for the given user.
27
+ */
28
+ private areTargetsAllowed;
29
+ }
@@ -1,3 +1,4 @@
1
+ "use strict";
1
2
  /*
2
3
  * Kuzzle, a backend software, self-hostable and ready to use
3
4
  * to power modern apps
@@ -18,62 +19,112 @@
18
19
  * See the License for the specific language governing permissions and
19
20
  * limitations under the License.
20
21
  */
21
-
22
- 'use strict';
23
-
24
- const Rights = require('./rights');
25
- const Bluebird = require('bluebird');
26
- const _ = require('lodash');
27
- const kerror = require('../../kerror');
28
-
22
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
23
+ if (k2 === undefined) k2 = k;
24
+ Object.defineProperty(o, k2, { enumerable: true, get: function() { return m[k]; } });
25
+ }) : (function(o, m, k, k2) {
26
+ if (k2 === undefined) k2 = k;
27
+ o[k2] = m[k];
28
+ }));
29
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
30
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
31
+ }) : function(o, v) {
32
+ o["default"] = v;
33
+ });
34
+ var __importStar = (this && this.__importStar) || function (mod) {
35
+ if (mod && mod.__esModule) return mod;
36
+ var result = {};
37
+ if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
38
+ __setModuleDefault(result, mod);
39
+ return result;
40
+ };
41
+ var __importDefault = (this && this.__importDefault) || function (mod) {
42
+ return (mod && mod.__esModule) ? mod : { "default": mod };
43
+ };
44
+ Object.defineProperty(exports, "__esModule", { value: true });
45
+ exports.User = void 0;
46
+ const rights_1 = __importDefault(require("./rights"));
47
+ const bluebird_1 = __importDefault(require("bluebird"));
48
+ const lodash_1 = __importDefault(require("lodash"));
49
+ const kerror = __importStar(require("../../kerror"));
29
50
  /**
30
51
  * @class User
31
52
  */
32
53
  class User {
33
- constructor() {
34
- this._id = null;
35
- this.profileIds = [];
36
- }
37
-
38
- /**
39
- * @returns {Promise<Profile[]>}
40
- */
41
- getProfiles() {
42
- if (!global.kuzzle) {
43
- return kerror.reject('security', 'user', 'uninitialized', this._id);
54
+ constructor() {
55
+ this._id = null;
56
+ this.profileIds = [];
44
57
  }
45
-
46
- return global.kuzzle.ask('core:security:profile:mGet', this.profileIds);
47
- }
48
-
49
- /**
50
- * @returns {Promise}
51
- */
52
- async getRights() {
53
- const profiles = await this.getProfiles();
54
- const results = await Bluebird.map(profiles, p => p.getRights());
55
-
56
- const rights = {};
57
-
58
- results.forEach(right => _.assignWith(rights, right, Rights.merge));
59
-
60
- return rights;
61
- }
62
-
63
- /**
64
- * @param {Request} request
65
- * @returns {Promise.<boolean>}
66
- */
67
- async isActionAllowed(request) {
68
- if (this.profileIds === undefined || this.profileIds.length === 0) {
69
- return false;
58
+ /**
59
+ * @returns {Promise<Profile[]>}
60
+ */
61
+ getProfiles() {
62
+ if (!global.kuzzle) {
63
+ return kerror.reject('security', 'user', 'uninitialized', this._id);
64
+ }
65
+ return global.kuzzle.ask('core:security:profile:mGet', this.profileIds);
66
+ }
67
+ /**
68
+ * @returns {Promise}
69
+ */
70
+ async getRights() {
71
+ const profiles = await this.getProfiles();
72
+ const results = await bluebird_1.default.map(profiles, p => p.getRights());
73
+ const rights = {};
74
+ results.forEach(right => lodash_1.default.assignWith(rights, right, rights_1.default.merge));
75
+ return rights;
76
+ }
77
+ /**
78
+ * @param {Request} request
79
+ * @returns {Promise.<boolean>}
80
+ */
81
+ async isActionAllowed(request) {
82
+ if (this.profileIds === undefined || this.profileIds.length === 0) {
83
+ return false;
84
+ }
85
+ const targets = request.getArray('targets', []);
86
+ const profiles = await this.getProfiles();
87
+ if (targets.length === 0) {
88
+ for (const profile of profiles) {
89
+ if (await profile.isActionAllowed(request)) {
90
+ return true;
91
+ }
92
+ }
93
+ return false;
94
+ }
95
+ // Every target must be allowed by at least one profile
96
+ return this.areTargetsAllowed(profiles, targets);
97
+ }
98
+ /**
99
+ * Verifies that every targets are allowed by at least one profile,
100
+ * while skipping the ones that includes a wildcard since they will be expanded
101
+ * later on, based on index and collections authorized for the given user.
102
+ */
103
+ async areTargetsAllowed(profiles, targets) {
104
+ const profilesPolicies = await bluebird_1.default.map(profiles, profile => profile.getAllowedPolicies());
105
+ // Every target must be allowed by at least one profile
106
+ for (const target of targets) {
107
+ // Skip targets with no Index or Collection
108
+ if (!target.index || !target.collections) {
109
+ continue;
110
+ }
111
+ // TODO: Support Wildcard
112
+ if (target.index.includes('*')) {
113
+ return false;
114
+ }
115
+ for (const collection of target.collections) {
116
+ // TODO: Support Wildcard
117
+ if (collection.includes('*')) {
118
+ return false;
119
+ }
120
+ const isTargetAllowed = profilesPolicies.some(policies => policies.some(policy => policy.role.checkRestrictions(target.index, collection, policy.restrictedTo)));
121
+ if (!isTargetAllowed) {
122
+ return false;
123
+ }
124
+ }
125
+ }
126
+ return true;
70
127
  }
71
-
72
- const profiles = await this.getProfiles();
73
- const result = await Bluebird.map(profiles, p => p.isActionAllowed(request));
74
-
75
- return result.includes(true);
76
- }
77
128
  }
78
-
79
- module.exports = User;
129
+ exports.User = User;
130
+ //# sourceMappingURL=user.js.map
@@ -50,7 +50,7 @@ class ApiKey extends BaseModel {
50
50
  }
51
51
  }
52
52
 
53
- serialize ({ includeToken=false } = {}) {
53
+ serialize ({ includeToken = false } = {}) {
54
54
  const serialized = super.serialize();
55
55
 
56
56
  if (! includeToken) {
@@ -90,7 +90,7 @@ class ApiKey extends BaseModel {
90
90
  user,
91
91
  expiresIn,
92
92
  description,
93
- { creatorId=null, apiKeyId=null, refresh, bypassMaxTTL=false } = {}
93
+ { creatorId = null, apiKeyId = null, refresh, bypassMaxTTL = false } = {}
94
94
  ) {
95
95
  const token = await global.kuzzle.ask('core:security:token:create', user, {
96
96
  bypassMaxTTL,
@@ -73,7 +73,7 @@ class BaseModel {
73
73
  *
74
74
  * @returns {Promise}
75
75
  */
76
- async save ({ userId=null, refresh } = {}) {
76
+ async save ({ userId = null, refresh } = {}) {
77
77
  if (! this.__persisted) {
78
78
  const { _id, _source } = await global.kuzzle.internalIndex.create(
79
79
  this.constructor.collection,
@@ -123,7 +123,7 @@ class BaseModel {
123
123
  */
124
124
  serialize () {
125
125
  return {
126
- _id : this._id,
126
+ _id: this._id,
127
127
  _source: this._source
128
128
  };
129
129
  }
@@ -195,7 +195,7 @@ class BaseModel {
195
195
  await Bluebird.map(
196
196
  documents,
197
197
  document => this._instantiateFromDb(document)._afterDelete(),
198
- {concurrency: 10}); // limits the load on storage services
198
+ { concurrency: 10 }); // limits the load on storage services
199
199
 
200
200
  if (refresh) {
201
201
  await global.kuzzle.internalIndex.refreshCollection(this.collection);