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.
- package/lib/api/controllers/adminController.js +3 -3
- package/lib/api/controllers/authController.js +12 -12
- package/lib/api/controllers/baseController.js +60 -3
- package/lib/api/controllers/clusterController.js +1 -1
- package/lib/api/controllers/collectionController.js +7 -5
- package/lib/api/controllers/documentController.js +130 -17
- package/lib/api/controllers/indexController.js +1 -1
- package/lib/api/controllers/memoryStorageController.js +39 -38
- package/lib/api/controllers/realtimeController.js +1 -1
- package/lib/api/controllers/securityController.js +50 -50
- package/lib/api/controllers/serverController.js +73 -27
- package/lib/api/documentExtractor.js +3 -3
- package/lib/api/funnel.js +44 -21
- package/lib/api/httpRoutes.js +9 -4
- package/lib/api/openapi/OpenApiManager.d.ts +11 -0
- package/lib/api/openapi/OpenApiManager.js +96 -0
- package/lib/api/openapi/{document → components/document}/count.yaml +2 -2
- package/lib/api/openapi/{document → components/document}/create.yaml +2 -2
- package/lib/api/openapi/{document → components/document}/createOrReplace.yaml +2 -2
- package/lib/api/openapi/{document → components/document}/delete.yaml +1 -1
- package/lib/api/openapi/{document → components/document}/deleteByQuery.yaml +2 -2
- package/lib/api/openapi/{document → components/document}/exists.yaml +1 -1
- package/lib/api/openapi/{document → components/document}/get.yaml +1 -1
- package/lib/api/openapi/{document → components/document}/index.d.ts +2 -0
- package/lib/api/openapi/{document → components/document}/index.js +7 -2
- package/lib/api/openapi/{document → components/document}/replace.yaml +2 -2
- package/lib/api/openapi/{document → components/document}/scroll.yaml +1 -1
- package/lib/api/openapi/{document → components/document}/update.yaml +2 -2
- package/lib/api/openapi/components/document/validate.yaml +42 -0
- package/lib/api/openapi/components/index.d.ts +2 -0
- package/lib/api/openapi/components/index.js +18 -0
- package/lib/api/openapi/{payloads.yaml → components/payloads.yaml} +0 -0
- package/lib/api/openapi/index.d.ts +1 -2
- package/lib/api/openapi/index.js +1 -5
- package/lib/api/openapi/openApiGenerator.d.ts +7 -0
- package/lib/api/openapi/openApiGenerator.js +133 -0
- package/lib/api/request/kuzzleRequest.js +8 -6
- package/lib/cluster/node.js +9 -9
- package/lib/cluster/publisher.js +1 -1
- package/lib/cluster/state.js +20 -4
- package/lib/cluster/subscriber.js +1 -1
- package/lib/cluster/workers/IDCardRenewer.js +2 -2
- package/lib/config/default.config.js +1 -0
- package/lib/config/index.js +6 -6
- package/lib/core/auth/passportResponse.js +6 -6
- package/lib/core/auth/passportWrapper.js +5 -5
- package/lib/core/backend/backend.d.ts +11 -3
- package/lib/core/backend/backend.js +22 -17
- package/lib/core/backend/backendConfig.d.ts +5 -1
- package/lib/core/backend/backendConfig.js +25 -2
- package/lib/core/backend/backendController.js +21 -5
- package/lib/core/backend/backendErrors.d.ts +58 -0
- package/lib/core/backend/backendErrors.js +121 -0
- package/lib/core/backend/backendHook.js +21 -5
- package/lib/core/backend/backendImport.js +21 -5
- package/lib/core/backend/backendOpenApi.d.ts +9 -0
- package/lib/core/backend/backendOpenApi.js +69 -0
- package/lib/core/backend/backendPipe.js +21 -5
- package/lib/core/backend/backendPlugin.js +22 -3
- package/lib/core/backend/backendVault.js +21 -2
- package/lib/core/backend/index.d.ts +2 -0
- package/lib/core/backend/index.js +2 -0
- package/lib/core/network/accessLogger.js +6 -6
- package/lib/core/network/clientConnection.js +1 -1
- package/lib/core/network/entryPoint.js +5 -5
- package/lib/core/network/httpRouter/index.js +5 -5
- package/lib/core/network/httpRouter/routeHandler.js +3 -3
- package/lib/core/network/httpRouter/routePart.js +5 -5
- package/lib/core/network/protocolManifest.js +1 -1
- package/lib/core/network/protocols/httpMessage.js +2 -2
- package/lib/core/network/protocols/httpwsProtocol.js +228 -50
- package/lib/core/network/protocols/mqttProtocol.js +3 -3
- package/lib/core/network/protocols/protocol.js +3 -3
- package/lib/core/network/router.js +7 -6
- package/lib/core/plugin/plugin.js +38 -64
- package/lib/core/plugin/pluginContext.js +22 -3
- package/lib/core/plugin/pluginManifest.js +3 -3
- package/lib/core/plugin/pluginRepository.js +5 -5
- package/lib/core/plugin/pluginsManager.js +29 -28
- package/lib/core/realtime/channel.js +20 -4
- package/lib/core/realtime/hotelClerk.js +24 -5
- package/lib/core/realtime/notification/server.js +1 -1
- package/lib/core/realtime/notification/user.js +1 -1
- package/lib/core/realtime/notifier.js +5 -5
- package/lib/core/security/index.js +1 -1
- package/lib/core/security/profileRepository.d.ts +176 -0
- package/lib/core/security/profileRepository.js +445 -443
- package/lib/core/security/roleRepository.js +16 -16
- package/lib/core/security/securityLoader.js +2 -2
- package/lib/core/security/tokenRepository.js +11 -11
- package/lib/core/security/userRepository.js +8 -8
- package/lib/core/shared/abstractManifest.js +4 -4
- package/lib/core/shared/repository.js +5 -5
- package/lib/core/shared/sdk/embeddedSdk.js +21 -2
- package/lib/core/shared/sdk/funnelProtocol.js +1 -1
- package/lib/core/shared/sdk/impersonatedSdk.js +1 -1
- package/lib/core/shared/store.js +30 -23
- package/lib/core/statistics/statistics.js +17 -17
- package/lib/core/storage/clientAdapter.js +45 -10
- package/lib/core/storage/indexCache.js +20 -4
- package/lib/core/validation/baseType.js +5 -5
- package/lib/core/validation/types/anything.js +1 -1
- package/lib/core/validation/types/boolean.js +2 -2
- package/lib/core/validation/types/date.js +9 -9
- package/lib/core/validation/types/email.js +5 -5
- package/lib/core/validation/types/enum.js +6 -6
- package/lib/core/validation/types/geoPoint.js +2 -2
- package/lib/core/validation/types/geoShape.js +28 -25
- package/lib/core/validation/types/integer.js +4 -4
- package/lib/core/validation/types/ipAddress.js +7 -6
- package/lib/core/validation/types/numeric.js +4 -4
- package/lib/core/validation/types/object.js +5 -5
- package/lib/core/validation/types/string.js +5 -5
- package/lib/core/validation/types/url.js +7 -6
- package/lib/core/validation/validation.js +95 -84
- package/lib/kerror/codes/1-services.json +12 -0
- package/lib/kerror/codes/2-api.json +12 -0
- package/lib/kerror/codes/3-network.json +12 -0
- package/lib/kerror/codes/4-plugin.json +6 -0
- package/lib/kerror/codes/index.js +11 -11
- package/lib/kerror/errors/multipleErrorsError.d.ts +1 -1
- package/lib/kerror/errors/multipleErrorsError.js +3 -3
- package/lib/kerror/index.d.ts +82 -0
- package/lib/kerror/index.js +176 -143
- package/lib/kuzzle/dumpGenerator.js +3 -3
- package/lib/kuzzle/event/kuzzleEventEmitter.js +4 -4
- package/lib/kuzzle/event/pipeRunner.js +1 -1
- package/lib/kuzzle/event/waterfall.js +6 -6
- package/lib/kuzzle/kuzzle.js +59 -9
- package/lib/kuzzle/log.js +3 -3
- package/lib/kuzzle/vault.js +3 -3
- package/lib/model/security/profile.d.ts +54 -0
- package/lib/model/security/profile.js +192 -232
- package/lib/model/security/rights.js +1 -1
- package/lib/model/security/role.d.ts +40 -0
- package/lib/model/security/role.js +174 -190
- package/lib/model/security/user.d.ts +29 -0
- package/lib/model/security/user.js +103 -52
- package/lib/model/storage/apiKey.js +2 -2
- package/lib/model/storage/baseModel.js +3 -3
- package/lib/service/cache/redis.js +7 -7
- package/lib/service/storage/elasticsearch.js +152 -90
- package/lib/service/storage/esWrapper.js +2 -3
- package/lib/types/ControllerDefinition.d.ts +3 -3
- package/lib/types/ControllerRights.d.ts +22 -0
- package/lib/types/ControllerRights.js +23 -0
- package/lib/types/HttpStream.d.ts +32 -0
- package/lib/types/HttpStream.js +70 -0
- package/lib/types/OpenApiDefinition.d.ts +43 -0
- package/lib/types/{config/StorageService/StorageServiceElasticsearchConfiguration.js → OpenApiDefinition.js} +1 -1
- package/lib/types/Plugin.js +20 -4
- package/lib/types/Policy.d.ts +25 -0
- package/lib/types/{InternalLogger.js → Policy.js} +2 -2
- package/lib/types/PolicyRestrictions.d.ts +21 -0
- package/lib/types/PolicyRestrictions.js +23 -0
- package/lib/types/Target.d.ts +15 -0
- package/lib/types/Target.js +23 -0
- package/lib/types/config/KuzzleConfiguration.d.ts +4 -0
- package/lib/types/config/ServicesConfiguration.d.ts +2 -2
- package/lib/types/config/{StorageService/StorageServiceElasticsearchConfiguration.d.ts → storageEngine/StorageEngineElasticsearchConfiguration.d.ts} +10 -3
- package/lib/types/config/storageEngine/StorageEngineElasticsearchConfiguration.js +3 -0
- package/lib/types/errors/ErrorDefinition.d.ts +27 -0
- package/lib/types/errors/ErrorDefinition.js +3 -0
- package/lib/types/errors/ErrorDomains.d.ts +17 -0
- package/lib/types/errors/ErrorDomains.js +3 -0
- package/lib/types/index.d.ts +9 -1
- package/lib/types/index.js +9 -1
- package/lib/util/array.d.ts +11 -0
- package/lib/util/array.js +57 -0
- package/lib/util/assertType.js +6 -6
- package/lib/util/bufferedPassThrough.d.ts +76 -0
- package/lib/util/bufferedPassThrough.js +161 -0
- package/lib/util/deprecate.js +7 -5
- package/lib/util/didYouMean.js +1 -1
- package/lib/util/dump-collection.d.ts +3 -0
- package/lib/util/dump-collection.js +284 -0
- package/lib/util/extractFields.js +2 -2
- package/lib/util/inflector.d.ts +8 -0
- package/lib/util/inflector.js +16 -0
- package/lib/util/mutex.js +21 -2
- package/lib/util/requestAssertions.js +7 -7
- package/lib/util/wildcard.js +55 -0
- package/package-lock.json +535 -75
- package/package.json +5 -3
- package/lib/api/openApiGenerator.d.ts +0 -7
- package/lib/api/openApiGenerator.js +0 -197
- 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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
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
|
-
|
|
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
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
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
|
-
|
|
34
|
-
|
|
35
|
-
|
|
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
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
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
|
-
|
|
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
|
|
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);
|