@iobroker/db-objects-redis 4.0.21 → 4.1.0-alpha.0-20220819-74ceeddc

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 (38) hide show
  1. package/build/index.d.ts +5 -0
  2. package/build/index.js +35 -0
  3. package/build/lib/objects/constants.d.ts +32 -0
  4. package/build/lib/objects/constants.d.ts.map +1 -0
  5. package/build/lib/objects/constants.js +35 -0
  6. package/build/lib/objects/constants.js.map +1 -0
  7. package/{lib → build/lib}/objects/lua-v3/custom.lua +0 -0
  8. package/{lib → build/lib}/objects/lua-v3/filter.lua +0 -0
  9. package/{lib → build/lib}/objects/lua-v3/programs.lua +0 -0
  10. package/{lib → build/lib}/objects/lua-v3/script.lua +0 -0
  11. package/{lib → build/lib}/objects/lua-v3/variables.lua +0 -0
  12. package/{lib → build/lib}/objects/lua-v4/custom.lua +0 -0
  13. package/{lib → build/lib}/objects/lua-v4/filter.lua +0 -0
  14. package/{lib → build/lib}/objects/lua-v4/programs.lua +0 -0
  15. package/{lib → build/lib}/objects/lua-v4/redlock_acquire.lua +0 -0
  16. package/{lib → build/lib}/objects/lua-v4/redlock_extend.lua +0 -0
  17. package/{lib → build/lib}/objects/lua-v4/redlock_release.lua +0 -0
  18. package/{lib → build/lib}/objects/lua-v4/script.lua +0 -0
  19. package/{lib → build/lib}/objects/lua-v4/variables.lua +0 -0
  20. package/{lib → build/lib}/objects/lua-v4-no-sets/custom.lua +0 -0
  21. package/{lib → build/lib}/objects/lua-v4-no-sets/filter.lua +0 -0
  22. package/{lib → build/lib}/objects/lua-v4-no-sets/programs.lua +0 -0
  23. package/{lib → build/lib}/objects/lua-v4-no-sets/redlock_acquire.lua +0 -0
  24. package/{lib → build/lib}/objects/lua-v4-no-sets/redlock_extend.lua +0 -0
  25. package/{lib → build/lib}/objects/lua-v4-no-sets/redlock_release.lua +0 -0
  26. package/{lib → build/lib}/objects/lua-v4-no-sets/script.lua +0 -0
  27. package/{lib → build/lib}/objects/lua-v4-no-sets/variables.lua +0 -0
  28. package/build/lib/objects/objectsInRedisClient.d.ts +340 -0
  29. package/build/lib/objects/objectsInRedisClient.d.ts.map +1 -0
  30. package/{lib → build/lib}/objects/objectsInRedisClient.js +1730 -2130
  31. package/build/lib/objects/objectsInRedisClient.js.map +1 -0
  32. package/build/lib/objects/objectsUtils.d.ts +57 -0
  33. package/build/lib/objects/objectsUtils.d.ts.map +1 -0
  34. package/build/lib/objects/objectsUtils.js +637 -0
  35. package/build/lib/objects/objectsUtils.js.map +1 -0
  36. package/package.json +13 -8
  37. package/index.js +0 -8
  38. package/lib/objects/objectsUtils.js +0 -777
@@ -1,777 +0,0 @@
1
- /**
2
- * Common functions between client and server
3
- *
4
- * Copyright 2013-2022 bluefox <dogafox@gmail.com>
5
- *
6
- * MIT License
7
- *
8
- */
9
-
10
- 'use strict';
11
- const stream = require('stream');
12
- const Writable = stream.Writable;
13
- const memStore = {};
14
- const util = require('util');
15
- const path = require('path');
16
- const deepClone = require('deep-clone');
17
- const tools = require('@iobroker/db-base').tools;
18
-
19
- const userStartsWith = 'system.user.';
20
- const groupStartsWith = 'system.group.';
21
- const regCheckId = /[*?[\]]|\$%\$/;
22
-
23
- const SYSTEM_ADMIN_USER = 'system.user.admin';
24
- const SYSTEM_ADMIN_GROUP = 'system.group.administrator';
25
-
26
- const ERROR_PERMISSION = 'permissionError';
27
- const ERROR_NOT_FOUND = 'Not exists';
28
- const ERROR_DB_CLOSED = 'DB closed';
29
-
30
- const ACCESS_EVERY_EXEC = 0x1;
31
- const ACCESS_EVERY_WRITE = 0x2;
32
- const ACCESS_EVERY_READ = 0x4;
33
- const ACCESS_EVERY_RW = ACCESS_EVERY_WRITE | ACCESS_EVERY_READ;
34
- const ACCESS_EVERY_ALL = ACCESS_EVERY_WRITE | ACCESS_EVERY_READ | ACCESS_EVERY_EXEC;
35
-
36
- const ACCESS_GROUP_EXEC = 0x10;
37
- const ACCESS_GROUP_WRITE = 0x20;
38
- const ACCESS_GROUP_READ = 0x40;
39
- const ACCESS_GROUP_RW = ACCESS_GROUP_WRITE | ACCESS_GROUP_READ;
40
- const ACCESS_GROUP_ALL = ACCESS_GROUP_WRITE | ACCESS_GROUP_READ | ACCESS_GROUP_EXEC;
41
-
42
- const ACCESS_USER_EXEC = 0x100;
43
- const ACCESS_USER_WRITE = 0x200;
44
- const ACCESS_USER_READ = 0x400;
45
- const ACCESS_USER_RW = ACCESS_USER_WRITE | ACCESS_USER_READ;
46
- const ACCESS_USER_ALL = ACCESS_USER_WRITE | ACCESS_USER_READ | ACCESS_USER_EXEC;
47
-
48
- const ACCESS_WRITE = 0x2;
49
- const ACCESS_READ = 0x4;
50
- const ACCESS_LIST = 'list';
51
- const ACCESS_DELETE = 'delete';
52
- const ACCESS_CREATE = 'create';
53
-
54
- const mimeTypes = {
55
- '.css': { type: 'text/css', binary: false },
56
- '.bmp': { type: 'image/bmp', binary: true },
57
- '.png': { type: 'image/png', binary: true },
58
- '.jpg': { type: 'image/jpeg', binary: true },
59
- '.jpeg': { type: 'image/jpeg', binary: true },
60
- '.gif': { type: 'image/gif', binary: true },
61
- '.ico': { type: 'image/x-icon', binary: true },
62
- '.webp': { type: 'image/webp', binary: true },
63
- '.wbmp': { type: 'image/vnd.wap.wbmp', binary: true },
64
- '.tif': { type: 'image/tiff', binary: true },
65
- '.js': { type: 'application/javascript', binary: false },
66
- '.html': { type: 'text/html', binary: false },
67
- '.htm': { type: 'text/html', binary: false },
68
- '.json': { type: 'application/json', binary: false },
69
- '.md': { type: 'text/markdown', binary: false },
70
- '.xml': { type: 'text/xml', binary: false },
71
- '.svg': { type: 'image/svg+xml', binary: false },
72
- '.eot': { type: 'application/vnd.ms-fontobject', binary: true },
73
- '.ttf': { type: 'application/font-sfnt', binary: true },
74
- '.cur': { type: 'application/x-win-bitmap', binary: true },
75
- '.woff': { type: 'application/font-woff', binary: true },
76
- '.wav': { type: 'audio/wav', binary: true },
77
- '.mp3': { type: 'audio/mpeg3', binary: true },
78
- '.avi': { type: 'video/avi', binary: true },
79
- '.qt': { type: 'video/quicktime', binary: true },
80
- '.ppt': { type: 'application/vnd.ms-powerpoint', binary: true },
81
- '.pptx': { type: 'application/vnd.ms-powerpoint', binary: true },
82
- '.doc': { type: 'application/msword', binary: true },
83
- '.docx': { type: 'application/msword', binary: true },
84
- '.xls': { type: 'application/vnd.ms-excel', binary: true },
85
- '.xlsx': { type: 'application/vnd.ms-excel', binary: true },
86
- '.mp4': { type: 'video/mp4', binary: true },
87
- '.mkv': { type: 'video/mkv', binary: true },
88
- '.zip': { type: 'application/zip', binary: true },
89
- '.ogg': { type: 'audio/ogg', binary: true },
90
- '.manifest': { type: 'text/cache-manifest', binary: false },
91
- '.pdf': { type: 'application/pdf', binary: true },
92
- '.gz': { type: 'application/gzip', binary: true },
93
- '.gzip': { type: 'application/gzip', binary: true }
94
- };
95
-
96
- let users = {};
97
- let groups = {};
98
-
99
- function getMimeType(ext) {
100
- if (!ext) {
101
- return { mimeType: 'text/html', isBinary: false };
102
- }
103
- if (ext instanceof Array) {
104
- ext = ext[0];
105
- }
106
- ext = ext.toLowerCase();
107
- let mimeType = 'text/javascript';
108
- let isBinary = false;
109
-
110
- if (mimeTypes[ext]) {
111
- mimeType = mimeTypes[ext].type;
112
- isBinary = mimeTypes[ext].binary;
113
- }
114
-
115
- return { mimeType, isBinary };
116
- }
117
-
118
- /**
119
- * @class
120
- * Writable memory stream
121
- */
122
- function WMStrm(key, options) {
123
- // allow use without new operator
124
- if (!(this instanceof WMStrm)) {
125
- return new WMStrm(key, options);
126
- }
127
-
128
- Writable.call(this, options); // init super
129
- this.key = key; // save key
130
- memStore[key] = Buffer.alloc(0); // empty
131
- }
132
- util.inherits(WMStrm, Writable);
133
-
134
- WMStrm.prototype._write = function (chunk, enc, cb) {
135
- if (chunk) {
136
- // our memory store stores things in buffers
137
- const buffer = Buffer.isBuffer(chunk)
138
- ? chunk // already is Buffer use it
139
- : Buffer.from(chunk, enc); // string, convert
140
-
141
- // concatenate to the buffer already there
142
- if (!memStore[this.key]) {
143
- memStore[this.key] = Buffer.alloc(0);
144
- console.log(`memstore for ${this.key} is null`);
145
- }
146
- memStore[this.key] = Buffer.concat([memStore[this.key], buffer]);
147
- }
148
- if (!cb) {
149
- throw new Error('Callback is empty');
150
- }
151
- cb();
152
- };
153
-
154
- function insert(objects, id, attName, _ignore, options, _obj, callback) {
155
- if (typeof options === 'string') {
156
- options = { mimeType: options };
157
- }
158
-
159
- // return pipe for write into redis
160
- const strm = new WMStrm(`${id}/${attName}`);
161
- // @ts-ignore
162
- strm.on('finish', () => {
163
- let error = null;
164
- if (!memStore[id + '/' + attName]) {
165
- error = `File ${id} / ${attName} is empty`;
166
- }
167
- objects.writeFile(id, attName, memStore[id + '/' + attName] || '', options, () => {
168
- if (memStore[id + '/' + attName] !== undefined) {
169
- delete memStore[id + '/' + attName];
170
- }
171
- return tools.maybeCallbackWithError(callback, error, null);
172
- });
173
- });
174
- return strm;
175
- }
176
-
177
- function checkFile(fileOptions, options, flag, defaultNewAcl) {
178
- if (typeof fileOptions.acl !== 'object') {
179
- fileOptions = {};
180
- fileOptions.mimeType = deepClone(fileOptions);
181
- fileOptions.acl = {
182
- owner: (defaultNewAcl && defaultNewAcl.owner) || SYSTEM_ADMIN_USER,
183
- ownerGroup: (defaultNewAcl && defaultNewAcl.ownerGroup) || SYSTEM_ADMIN_GROUP,
184
- permissions: (defaultNewAcl && defaultNewAcl.file) || ACCESS_USER_RW | ACCESS_GROUP_READ | ACCESS_EVERY_READ // '0644'
185
- };
186
- }
187
-
188
- // Set default owner group
189
- fileOptions.acl.ownerGroup =
190
- fileOptions.acl.ownerGroup || (defaultNewAcl && defaultNewAcl.ownerGroup) || SYSTEM_ADMIN_GROUP;
191
- fileOptions.acl.owner = fileOptions.acl.owner || (defaultNewAcl && defaultNewAcl.owner) || SYSTEM_ADMIN_USER;
192
- fileOptions.acl.permissions =
193
- fileOptions.acl.permissions ||
194
- (defaultNewAcl && defaultNewAcl.file) ||
195
- ACCESS_USER_RW | ACCESS_GROUP_READ | ACCESS_EVERY_READ; // '0644'
196
-
197
- if (options.user !== SYSTEM_ADMIN_USER && options.groups.indexOf(SYSTEM_ADMIN_GROUP) === -1 && fileOptions.acl) {
198
- if (fileOptions.acl.owner !== options.user) {
199
- // Check if the user is in the group
200
- if (options.groups.indexOf(fileOptions.acl.ownerGroup) !== -1) {
201
- // Check group rights
202
- if (!(fileOptions.acl.permissions & (flag << 4))) {
203
- return false;
204
- }
205
- } else {
206
- // everybody
207
- if (!(fileOptions.acl.permissions & flag)) {
208
- return false;
209
- }
210
- }
211
- } else {
212
- // Check user rights
213
- if (!(fileOptions.acl.permissions & (flag << 8))) {
214
- return false;
215
- }
216
- }
217
- }
218
- return true;
219
- }
220
-
221
- function checkFileRights(objects, id, name, options, flag, callback) {
222
- options = options || {};
223
- if (!options.user) {
224
- // Before files converted, lets think: if no options it is admin
225
- options = {
226
- user: 'system.user.admin',
227
- params: options,
228
- group: 'system.group.administrator'
229
- };
230
- }
231
-
232
- /*if (options.checked) {
233
- return callback(null, options);
234
- }*/
235
-
236
- if (!options.acl) {
237
- objects.getUserGroup(options.user, (_user, groups, acl) => {
238
- options.acl = acl || {};
239
- options.groups = groups;
240
- options.group = groups ? groups[0] : null;
241
- checkFileRights(objects, id, name, options, flag, callback);
242
- });
243
- return;
244
- }
245
- // If user may write
246
- if (flag === 2 && !options.acl.file.write) {
247
- // write
248
- return tools.maybeCallbackWithError(callback, ERROR_PERMISSION, options);
249
- }
250
- // If user may read
251
- if (flag === 4 && !options.acl.file.read) {
252
- // read
253
- return tools.maybeCallbackWithError(callback, ERROR_PERMISSION, options);
254
- }
255
-
256
- options.checked = true;
257
- objects.checkFile(id, name, options, flag, (err, options, opt) => {
258
- if (err) {
259
- return tools.maybeCallbackWithError(callback, ERROR_PERMISSION, options);
260
- } else {
261
- return tools.maybeCallbackWithError(callback, null, options, opt);
262
- }
263
- });
264
-
265
- /*if (typeof fileOptions[id][name].acl != 'object') {
266
- fileOptions[id][name] = {
267
- mimeType: fileOptions[id][name],
268
- acl: {
269
- owner: 'system.user.admin',
270
- permissions: 0x644,
271
- ownerGroup: 'system.group.administrator'
272
- }
273
- };
274
- }
275
- // Set default onwer group
276
- fileOptions[id][name].acl.ownerGroup = fileOptions[id][name].acl.ownerGroup || 'system.group.administrator';
277
-
278
- if (options.user != 'system.user.admin' &&
279
- options.groups.indexOf('system.group.administrator') == -1 &&
280
- fileOptions[id][name].acl) {
281
- if (fileOptions[id][name].acl.owner != options.user) {
282
- // Check if the user is in the group
283
- if (options.groups.indexOf(fileOptions[id][name].acl.ownerGroup) != -1) {
284
- // Check group rights
285
- if (!(fileOptions[id][name].acl.permissions & (flag << 4))) {
286
- return callback(ERROR_PERMISSION, options);
287
- }
288
- } else {
289
- // everybody
290
- if (!(fileOptions[id][name].acl.permissions & flag)) {
291
- return callback(ERROR_PERMISSION, options);
292
- }
293
- }
294
- } else {
295
- // Check user rights
296
- if (!(fileOptions[id][name].acl.permissions & (flag << 8))) {
297
- return callback(ERROR_PERMISSION, options);
298
- }
299
- }
300
- }
301
- return callback(null, options);*/
302
- }
303
- // For users and groups
304
- function getDefaultAdminRights(acl, _isState) {
305
- acl = acl || {};
306
- acl.file = {
307
- list: true,
308
- read: true,
309
- write: true,
310
- create: true,
311
- delete: true
312
- };
313
- acl.object = {
314
- create: true,
315
- list: true,
316
- read: true,
317
- write: true,
318
- delete: true
319
- };
320
- acl.users = {
321
- create: true,
322
- list: true,
323
- read: true,
324
- write: true,
325
- delete: true
326
- };
327
- acl.state = {
328
- read: true,
329
- write: true,
330
- delete: true,
331
- create: true,
332
- list: true
333
- };
334
-
335
- return acl;
336
- }
337
-
338
- function getUserGroup(objects, user, callback) {
339
- if (!user || typeof user !== 'string' || !user.startsWith(userStartsWith)) {
340
- console.log(`invalid user name: ${user}`);
341
- user = JSON.stringify(user);
342
- // deep copy
343
- return tools.maybeCallbackWithError(
344
- callback,
345
- `invalid user name: ${user}`,
346
- user,
347
- [],
348
- deepClone(defaultAcl.acl)
349
- );
350
- }
351
- if (users[user]) {
352
- return tools.maybeCallbackWithError(callback, null, user, users[user].groups, users[user].acl);
353
- }
354
-
355
- let error;
356
- // Read all groups
357
- objects.getObjectList(
358
- { startkey: 'system.group.', endkey: 'system.group.\u9999' },
359
- { checked: true },
360
- (err, arr) => {
361
- if (err) {
362
- error = err;
363
- }
364
- groups = [];
365
- if (arr) {
366
- // Read all groups
367
- for (let g = 0; g < arr.rows.length; g++) {
368
- groups[g] = arr.rows[g].value;
369
- if (groups[g]._id === SYSTEM_ADMIN_GROUP) {
370
- groups[g].common.acl = getDefaultAdminRights(groups[g].common.acl);
371
- }
372
- }
373
- }
374
-
375
- objects.getObjectList(
376
- { startkey: 'system.user.', endkey: 'system.user.\u9999' },
377
- { checked: true },
378
- (err, arr) => {
379
- if (err) {
380
- error = err;
381
- }
382
- users = {};
383
-
384
- if (arr) {
385
- for (let i = 0; i < arr.rows.length; i++) {
386
- // cannot use here Object.assign, because required deep copy
387
- users[arr.rows[i].value._id] = deepClone(defaultAcl);
388
- }
389
- }
390
- users[SYSTEM_ADMIN_USER] = users[SYSTEM_ADMIN_USER] || deepClone(defaultAcl);
391
- users[SYSTEM_ADMIN_USER].acl = getDefaultAdminRights(users[SYSTEM_ADMIN_USER].acl);
392
-
393
- for (let g = 0; g < groups.length; g++) {
394
- if (!groups[g] || !groups[g].common || !groups[g].common.members) {
395
- continue;
396
- }
397
- for (let m = 0; m < groups[g].common.members.length; m++) {
398
- const u = groups[g].common.members[m];
399
- if (!users[u]) {
400
- error =
401
- error ||
402
- `Unknown user in group "${groups[g]._id.replace('system.group.', '')}": ${u}`;
403
- continue;
404
- }
405
- users[u].groups.push(groups[g]._id);
406
-
407
- if (groups[g].common.acl && groups[g].common.acl.file) {
408
- if (!users[u].acl || !users[u].acl.file) {
409
- users[u].acl = users[u].acl || {};
410
- users[u].acl.file = users[u].acl.file || {};
411
-
412
- users[u].acl.file.create = groups[g].common.acl.file.create;
413
- users[u].acl.file.read = groups[g].common.acl.file.read;
414
- users[u].acl.file.write = groups[g].common.acl.file.write;
415
- users[u].acl.file['delete'] = groups[g].common.acl.file['delete'];
416
- users[u].acl.file.list = groups[g].common.acl.file.list;
417
- } else {
418
- users[u].acl.file.create =
419
- users[u].acl.file.create || groups[g].common.acl.file.create;
420
- users[u].acl.file.read = users[u].acl.file.read || groups[g].common.acl.file.read;
421
- users[u].acl.file.write =
422
- users[u].acl.file.write || groups[g].common.acl.file.write;
423
- users[u].acl.file['delete'] =
424
- users[u].acl.file['delete'] || groups[g].common.acl.file['delete'];
425
- users[u].acl.file.list = users[u].acl.file.list || groups[g].common.acl.file.list;
426
- }
427
- }
428
-
429
- if (groups[g].common.acl && groups[g].common.acl.object) {
430
- if (!users[u].acl || !users[u].acl.object) {
431
- users[u].acl = users[u].acl || {};
432
- users[u].acl.object = users[u].acl.object || {};
433
-
434
- users[u].acl.object.create = groups[g].common.acl.object.create;
435
- users[u].acl.object.read = groups[g].common.acl.object.read;
436
- users[u].acl.object.write = groups[g].common.acl.object.write;
437
- users[u].acl.object['delete'] = groups[g].common.acl.object['delete'];
438
- users[u].acl.object.list = groups[g].common.acl.object.list;
439
- } else {
440
- users[u].acl.object.create =
441
- users[u].acl.object.create || groups[g].common.acl.object.create;
442
- users[u].acl.object.read =
443
- users[u].acl.object.read || groups[g].common.acl.object.read;
444
- users[u].acl.object.write =
445
- users[u].acl.object.write || groups[g].common.acl.object.write;
446
- users[u].acl.object['delete'] =
447
- users[u].acl.object['delete'] || groups[g].common.acl.object['delete'];
448
- users[u].acl.object.list =
449
- users[u].acl.object.list || groups[g].common.acl.object.list;
450
- }
451
- }
452
-
453
- if (groups[g].common.acl && groups[g].common.acl.users) {
454
- if (!users[u].acl || !users[u].acl.users) {
455
- users[u].acl = users[u].acl || {};
456
- users[u].acl.users = users[u].acl.users || {};
457
-
458
- users[u].acl.users.create = groups[g].common.acl.users.create;
459
- users[u].acl.users.read = groups[g].common.acl.users.read;
460
- users[u].acl.users.write = groups[g].common.acl.users.write;
461
- users[u].acl.users['delete'] = groups[g].common.acl.users['delete'];
462
- users[u].acl.users.list = groups[g].common.acl.users.list;
463
- } else {
464
- users[u].acl.users.create =
465
- users[u].acl.users.create || groups[g].common.acl.users.create;
466
- users[u].acl.users.read =
467
- users[u].acl.users.read || groups[g].common.acl.users.read;
468
- users[u].acl.users.write =
469
- users[u].acl.users.write || groups[g].common.acl.users.write;
470
- users[u].acl.users['delete'] =
471
- users[u].acl.users['delete'] || groups[g].common.acl.users['delete'];
472
- users[u].acl.users.list =
473
- users[u].acl.users.list || groups[g].common.acl.users.list;
474
- }
475
- }
476
-
477
- if (groups[g].common.acl && groups[g].common.acl.state) {
478
- if (!users[u].acl || !users[u].acl.state) {
479
- users[u].acl = users[u].acl || {};
480
- users[u].acl.state = users[u].acl.state || {};
481
-
482
- users[u].acl.state.create = groups[g].common.acl.state.create;
483
- users[u].acl.state.read = groups[g].common.acl.state.read;
484
- users[u].acl.state.write = groups[g].common.acl.state.write;
485
- users[u].acl.state['delete'] = groups[g].common.acl.state['delete'];
486
- users[u].acl.state.list = groups[g].common.acl.state.list;
487
- } else {
488
- users[u].acl.state.create =
489
- users[u].acl.state.create || groups[g].common.acl.state.create;
490
- users[u].acl.state.read =
491
- users[u].acl.state.read || groups[g].common.acl.state.read;
492
- users[u].acl.state.write =
493
- users[u].acl.state.write || groups[g].common.acl.state.write;
494
- users[u].acl.state['delete'] =
495
- users[u].acl.state['delete'] || groups[g].common.acl.state['delete'];
496
- users[u].acl.state.list =
497
- users[u].acl.state.list || groups[g].common.acl.state.list;
498
- }
499
- }
500
- }
501
- }
502
-
503
- return tools.maybeCallbackWithError(
504
- callback,
505
- error,
506
- user,
507
- users[user] ? users[user].groups : [],
508
- users[user] ? users[user].acl : JSON.parse(JSON.stringify(defaultAcl.acl))
509
- );
510
- }
511
- );
512
- }
513
- );
514
- }
515
-
516
- function sanitizePath(id, name) {
517
- if (!name) {
518
- name = '';
519
- }
520
- if (name[0] === '/') {
521
- name = name.substring(1);
522
- }
523
-
524
- if (!id) {
525
- throw new Error('Empty ID');
526
- }
527
-
528
- id = id.replace(/[\][*,;'"`<>\\?/]/g, ''); // remove all invalid characters from states plus slashes
529
- id = id.replace(/\.\./g, ''); // do not allow to write in parent directories
530
-
531
- if (name.includes('..')) {
532
- name = path.normalize('/' + name);
533
- }
534
- if (name.includes('..')) {
535
- // Also after normalization we still have .. in it - should not happen if normalize worked correctly
536
- name = name.replace(/\.\./g, '');
537
- name = path.normalize('/' + name);
538
- }
539
-
540
- name = name.replace(/\\/g, '/'); // replace win path backslashes
541
-
542
- if (name[0] === '/') {
543
- name = name.substring(1);
544
- } // do not allow absolute paths
545
-
546
- return { id: id, name: name };
547
- }
548
-
549
- function checkObject(obj, options, flag) {
550
- // read rights of object
551
- if (!obj || !obj.common || !obj.acl || flag === ACCESS_LIST) {
552
- return true;
553
- }
554
-
555
- if (options.user === SYSTEM_ADMIN_USER) {
556
- return true;
557
- }
558
-
559
- // admins may always see everything
560
- if (options.group === SYSTEM_ADMIN_GROUP || options.groups.includes(SYSTEM_ADMIN_GROUP)) {
561
- return true;
562
- }
563
-
564
- // checkObject always called after checkObjectRights and admin is checked there
565
- if (obj.acl.owner !== options.user) {
566
- // Check if the user is in the group
567
- if (
568
- (options.group && options.group === obj.acl.ownerGroup) ||
569
- (options.groups && options.groups.includes(obj.acl.ownerGroup))
570
- ) {
571
- // Check group rights
572
- if (!(obj.acl.object & (flag << 4))) {
573
- return false;
574
- }
575
- } else {
576
- // everybody
577
- if (!(obj.acl.object & flag)) {
578
- return false;
579
- }
580
- }
581
- } else {
582
- // Check group rights
583
- if (!(obj.acl.object & (flag << 8))) {
584
- return false;
585
- }
586
- }
587
- return true; // ALL OK
588
- }
589
-
590
- function checkObjectRights(objects, id, object, options, flag, callback) {
591
- options = options || {};
592
-
593
- if (!options.user) {
594
- // Before files converted, lets think: if no options it is admin
595
- options = {
596
- user: SYSTEM_ADMIN_USER,
597
- params: options,
598
- group: SYSTEM_ADMIN_GROUP,
599
- groups: [SYSTEM_ADMIN_GROUP],
600
- acl: getDefaultAdminRights()
601
- };
602
- }
603
-
604
- if (!options.acl) {
605
- return objects.getUserGroup(options.user, (_user, groups, acl) => {
606
- options.acl = acl || {};
607
- options.groups = groups;
608
- options.group = groups ? groups[0] : null;
609
- checkObjectRights(objects, id, object, options, flag, callback);
610
- });
611
- }
612
-
613
- // now options are filled and we can go
614
- if (
615
- options.user === SYSTEM_ADMIN_USER ||
616
- options.group === SYSTEM_ADMIN_GROUP ||
617
- (options.groups && options.groups.includes(SYSTEM_ADMIN_GROUP))
618
- ) {
619
- return tools.maybeCallbackWithError(callback, null, options);
620
- }
621
-
622
- // if user or group objects
623
- if (typeof id === 'string' && (id.startsWith(userStartsWith) || id.startsWith(groupStartsWith))) {
624
- // If user may write
625
- if (flag === ACCESS_WRITE && !options.acl.users.write) {
626
- // write
627
- return tools.maybeCallbackWithError(callback, ERROR_PERMISSION, options);
628
- }
629
-
630
- // If user may read
631
- if (flag === ACCESS_READ && !options.acl.users.read) {
632
- // read
633
- return tools.maybeCallbackWithError(callback, ERROR_PERMISSION, options);
634
- }
635
-
636
- // If user may delete
637
- if (flag === ACCESS_DELETE && !options.acl.users.delete) {
638
- // delete
639
- return tools.maybeCallbackWithError(callback, ERROR_PERMISSION, options);
640
- }
641
-
642
- // If user may list
643
- if (flag === ACCESS_LIST && !options.acl.users.list) {
644
- // list
645
- return tools.maybeCallbackWithError(callback, ERROR_PERMISSION, options);
646
- }
647
-
648
- // If user may create
649
- if (flag === ACCESS_CREATE && !options.acl.users.create) {
650
- // create
651
- return tools.maybeCallbackWithError(callback, ERROR_PERMISSION, options);
652
- }
653
-
654
- // If user may write
655
- if (flag === ACCESS_DELETE) {
656
- // he may delete
657
- flag = ACCESS_WRITE;
658
- }
659
- }
660
-
661
- // If user may write
662
- if (flag === ACCESS_WRITE && !options.acl.object.write) {
663
- // write
664
- return tools.maybeCallbackWithError(callback, ERROR_PERMISSION, options);
665
- }
666
-
667
- // If user may read
668
- if (flag === ACCESS_READ && !options.acl.object.read) {
669
- // read
670
- return tools.maybeCallbackWithError(callback, ERROR_PERMISSION, options);
671
- }
672
-
673
- // If user may delete
674
- if (flag === ACCESS_DELETE && !options.acl.object.delete) {
675
- // delete
676
- return tools.maybeCallbackWithError(callback, ERROR_PERMISSION, options);
677
- }
678
-
679
- // If user may list
680
- if (flag === ACCESS_LIST && !options.acl.object.list) {
681
- // list
682
- return tools.maybeCallbackWithError(callback, ERROR_PERMISSION, options);
683
- }
684
-
685
- if (flag === ACCESS_DELETE) {
686
- // write
687
- flag = ACCESS_WRITE;
688
- }
689
-
690
- if (id && !checkObject(object, options, flag)) {
691
- return tools.maybeCallbackWithError(callback, ERROR_PERMISSION, options);
692
- } else {
693
- return tools.maybeCallbackWithError(callback, null, options);
694
- }
695
- }
696
-
697
- // For objects
698
- const defaultAcl = {
699
- groups: [],
700
- acl: {
701
- file: {
702
- list: false,
703
- read: false,
704
- write: false,
705
- create: false,
706
- delete: false
707
- },
708
- object: {
709
- list: false,
710
- read: false,
711
- write: false,
712
- create: false,
713
- delete: false
714
- },
715
- state: {
716
- list: false,
717
- read: false,
718
- write: false,
719
- create: false,
720
- delete: false
721
- },
722
- users: {
723
- list: false,
724
- read: false,
725
- write: false,
726
- create: false,
727
- delete: false
728
- }
729
- }
730
- };
731
-
732
- module.exports = {
733
- getMimeType,
734
- insert,
735
- checkFileRights,
736
- checkFile,
737
- getUserGroup,
738
- sanitizePath,
739
- checkObject,
740
- checkObjectRights,
741
-
742
- regCheckId,
743
-
744
- ERRORS: {
745
- ERROR_PERMISSION,
746
- ERROR_NOT_FOUND,
747
- ERROR_DB_CLOSED
748
- },
749
- CONSTS: {
750
- SYSTEM_ADMIN_USER,
751
- SYSTEM_ADMIN_GROUP,
752
-
753
- ACCESS_EVERY_EXEC,
754
- ACCESS_EVERY_WRITE,
755
- ACCESS_EVERY_READ,
756
- ACCESS_EVERY_RW,
757
- ACCESS_EVERY_ALL,
758
-
759
- ACCESS_GROUP_EXEC,
760
- ACCESS_GROUP_WRITE,
761
- ACCESS_GROUP_READ,
762
- ACCESS_GROUP_RW,
763
- ACCESS_GROUP_ALL,
764
-
765
- ACCESS_USER_EXEC,
766
- ACCESS_USER_WRITE,
767
- ACCESS_USER_READ,
768
- ACCESS_USER_RW,
769
- ACCESS_USER_ALL,
770
-
771
- ACCESS_WRITE,
772
- ACCESS_READ,
773
- ACCESS_LIST,
774
- ACCESS_DELETE,
775
- ACCESS_CREATE
776
- }
777
- };