@iobroker/db-objects-redis 7.2.2 → 7.2.3-alpha.1-20260621-61726ea22
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/build/cjs/lib/objects/objectsInRedisClient.d.ts +654 -10
- package/build/cjs/lib/objects/objectsInRedisClient.js +467 -13
- package/build/cjs/lib/objects/objectsInRedisClient.js.map +2 -2
- package/build/cjs/lib/objects/objectsUtils.d.ts +63 -0
- package/build/cjs/lib/objects/objectsUtils.js.map +2 -2
- package/build/esm/lib/objects/objectsInRedisClient.d.ts +654 -10
- package/build/esm/lib/objects/objectsInRedisClient.d.ts.map +1 -1
- package/build/esm/lib/objects/objectsInRedisClient.js +470 -13
- package/build/esm/lib/objects/objectsInRedisClient.js.map +1 -1
- package/build/esm/lib/objects/objectsUtils.d.ts +63 -0
- package/build/esm/lib/objects/objectsUtils.d.ts.map +1 -1
- package/build/esm/lib/objects/objectsUtils.js +48 -0
- package/build/esm/lib/objects/objectsUtils.js.map +1 -1
- package/build/tsconfig.build.tsbuildinfo +1 -1
- package/package.json +3 -3
|
@@ -10,24 +10,37 @@ import * as CONSTS from '../../lib/objects/constants.js';
|
|
|
10
10
|
export * as CONSTS from '../../lib/objects/constants.js';
|
|
11
11
|
export declare const ERRORS: typeof CONSTS.ERRORS;
|
|
12
12
|
export declare const REG_CHECK_ID: RegExp;
|
|
13
|
+
/** Information about a file's mime type */
|
|
13
14
|
export interface FileMimeInformation {
|
|
14
15
|
/** the mime type, of the file */
|
|
15
16
|
mimeType: string;
|
|
16
17
|
/** if content is binary or textual */
|
|
17
18
|
isBinary: boolean;
|
|
18
19
|
}
|
|
20
|
+
/** Access control list of an object, state or file */
|
|
19
21
|
export interface ACLObject {
|
|
22
|
+
/** The user that owns the object */
|
|
20
23
|
owner: string;
|
|
24
|
+
/** The group that owns the object */
|
|
21
25
|
ownerGroup: string;
|
|
26
|
+
/** Permission bitmask for object access */
|
|
22
27
|
object: number;
|
|
28
|
+
/** Permission bitmask for state access */
|
|
23
29
|
state: number;
|
|
30
|
+
/** Permission bitmask for file access */
|
|
24
31
|
file: number;
|
|
25
32
|
}
|
|
33
|
+
/** Metadata of a stored file */
|
|
26
34
|
export interface FileObject {
|
|
35
|
+
/** Whether this is a virtual file (a directory placeholder) */
|
|
27
36
|
virtualFile?: boolean;
|
|
37
|
+
/** File system stats of the file */
|
|
28
38
|
stats: any;
|
|
39
|
+
/** Timestamp (ms) when the file was last modified */
|
|
29
40
|
modifiedAt: number;
|
|
41
|
+
/** Timestamp (ms) when the file was created */
|
|
30
42
|
createdAt: number;
|
|
43
|
+
/** Evaluated access control list of the file */
|
|
31
44
|
acl: ioBroker.EvaluatedFileACL;
|
|
32
45
|
}
|
|
33
46
|
export type CheckFileRightsCallback = (err: Error | null | undefined, options: Record<string, any>, opt?: any) => void;
|
|
@@ -38,15 +51,65 @@ export type CheckFileRightsCallback = (err: Error | null | undefined, options: R
|
|
|
38
51
|
* @param isTextData if content is of type string
|
|
39
52
|
*/
|
|
40
53
|
export declare function getMimeType(ext: string, isTextData: boolean): FileMimeInformation;
|
|
54
|
+
/**
|
|
55
|
+
* Check if the given options have the required rights on a file according to its ACL
|
|
56
|
+
*
|
|
57
|
+
* @param fileOptions The stored file options including its ACL
|
|
58
|
+
* @param options The current request options including the user and group
|
|
59
|
+
* @param flag The access flag(s) to check for
|
|
60
|
+
* @param defaultNewAcl The default ACL to use if the file has none yet
|
|
61
|
+
*/
|
|
41
62
|
export declare function checkFile(fileOptions: Record<string, any>, options: Record<string, any>, flag: any, defaultNewAcl?: ACLObject | null): boolean;
|
|
63
|
+
/**
|
|
64
|
+
* Check whether the given user is allowed to access a file and call back with the effective options
|
|
65
|
+
*
|
|
66
|
+
* @param objects The objects database client
|
|
67
|
+
* @param id The id of the object owning the file
|
|
68
|
+
* @param name The file name, or null for the whole namespace
|
|
69
|
+
* @param options The current request options including the user
|
|
70
|
+
* @param flag The access flag(s) to check for
|
|
71
|
+
* @param callback Called with the effective options once the rights have been checked
|
|
72
|
+
*/
|
|
42
73
|
export declare function checkFileRights(objects: any, id: string, name: string | null, options: Record<string, any> | null | undefined, flag: CONSTS.GenericAccessFlags, callback?: CheckFileRightsCallback): any;
|
|
43
74
|
export type GetUserGroupPromiseReturn = [user: string, groups: string[], acl: ioBroker.ObjectPermissions];
|
|
44
75
|
type GetUserGroupCallback = (err: Error | null | undefined, user: string, groups: string[], acl: ioBroker.ObjectPermissions) => void;
|
|
76
|
+
/**
|
|
77
|
+
* Determine the groups and effective ACL of the given user
|
|
78
|
+
*
|
|
79
|
+
* @param objects The objects database client
|
|
80
|
+
* @param user The id of the user to look up
|
|
81
|
+
* @param callback Called with the user, its groups and the effective ACL
|
|
82
|
+
*/
|
|
45
83
|
export declare function getUserGroup(objects: any, user: ioBroker.ObjectIDs.User, callback?: GetUserGroupCallback): Promise<GetUserGroupPromiseReturn> | void;
|
|
84
|
+
/**
|
|
85
|
+
* Sanitize an object id and file name so they cannot escape the intended directory
|
|
86
|
+
*
|
|
87
|
+
* @param id The object id owning the file
|
|
88
|
+
* @param name The file name to sanitize
|
|
89
|
+
*/
|
|
46
90
|
export declare function sanitizePath(id: string, name: string): {
|
|
91
|
+
/** The sanitized object id */
|
|
47
92
|
id: string;
|
|
93
|
+
/** The sanitized file name */
|
|
48
94
|
name: string;
|
|
49
95
|
};
|
|
96
|
+
/**
|
|
97
|
+
* Check if the given options have the required rights on an object according to its ACL
|
|
98
|
+
*
|
|
99
|
+
* @param obj The object (or file object) to check, or null
|
|
100
|
+
* @param options The current request options including the user and group
|
|
101
|
+
* @param flag The access flag(s) to check for
|
|
102
|
+
*/
|
|
50
103
|
export declare function checkObject(obj: ioBroker.AnyObject | FileObject | null, options: Record<string, any>, flag: CONSTS.GenericAccessFlags): boolean;
|
|
104
|
+
/**
|
|
105
|
+
* Check whether the given user is allowed to access an object and call back with the effective options
|
|
106
|
+
*
|
|
107
|
+
* @param objects The objects database client
|
|
108
|
+
* @param id The id of the object, or null
|
|
109
|
+
* @param object The object to check, or null
|
|
110
|
+
* @param options The current request options including the user
|
|
111
|
+
* @param flag The access flag(s) to check for
|
|
112
|
+
* @param callback Called with the effective options once the rights have been checked
|
|
113
|
+
*/
|
|
51
114
|
export declare function checkObjectRights(objects: any, id: string | null, object: ioBroker.Object | null, options: Record<string, any> | null | undefined, flag: CONSTS.GenericAccessFlags, callback: (err: Error | null | undefined, options: Record<string, any>) => void): void | Promise<Record<string, any>>;
|
|
52
115
|
//# sourceMappingURL=objectsUtils.d.ts.map
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../../../src/lib/objects/objectsUtils.ts"],
|
|
4
|
-
"sourcesContent": ["/**\n * Common functions between client and server\n *\n * Copyright 2013-2024 bluefox <dogafox@gmail.com>\n *\n * MIT License\n *\n */\n\nimport path from 'node:path';\nimport deepClone from 'deep-clone';\nimport { tools } from '@iobroker/db-base';\nimport * as CONSTS from '@/lib/objects/constants.js';\nimport mime from 'mime-types';\n\nexport * as CONSTS from '@/lib/objects/constants.js';\nexport const ERRORS = CONSTS.ERRORS;\nexport const REG_CHECK_ID = CONSTS.REG_CHECK_ID;\n\nconst USER_STARTS_WITH = CONSTS.USER_STARTS_WITH;\nconst GROUP_STARTS_WITH = CONSTS.GROUP_STARTS_WITH;\n\nexport interface FileMimeInformation {\n /** the mime type, of the file */\n mimeType: string;\n /** if content is binary or textual */\n isBinary: boolean;\n}\n\nexport interface ACLObject {\n owner: string;\n ownerGroup: string;\n object: number;\n state: number;\n file: number;\n}\n\nexport interface FileObject {\n virtualFile?: boolean;\n stats: any;\n modifiedAt: number;\n createdAt: number;\n acl: ioBroker.EvaluatedFileACL;\n}\n\nexport type CheckFileRightsCallback = (err: Error | null | undefined, options: Record<string, any>, opt?: any) => void;\n\nconst textTypes = ['.js', '.json', '.svg'];\n\n/**\n * Checks if the mime type, of an extension is a known one and if it corresponds to binary content\n *\n * @param ext the file extension e.g. `.txt`\n */\nfunction getKnownMimeType(ext: string): FileMimeInformation | null {\n try {\n const mimeType = mime.lookup(ext);\n if (mimeType) {\n return { mimeType, isBinary: !mimeType.startsWith('text/') && !textTypes.includes(ext) };\n }\n } catch {\n // ignore\n }\n\n return null;\n}\n\n// For objects\nconst defaultAcl = {\n groups: [],\n acl: {\n file: {\n list: false,\n read: false,\n write: false,\n create: false,\n delete: false,\n },\n object: {\n list: false,\n read: false,\n write: false,\n create: false,\n delete: false,\n },\n state: {\n list: false,\n read: false,\n write: false,\n create: false,\n delete: false,\n },\n users: {\n list: false,\n read: false,\n write: false,\n create: false,\n delete: false,\n },\n },\n} as const;\n\n// FIXME: This should have better types. Probably Record<string, {acl: ioBroker.ObjectPermissions, [x: string | number | symbol]: any}>\nlet users: Record<ioBroker.ObjectIDs.User, any> = {};\nlet groups: ioBroker.GroupObject[] = [];\n\n/**\n * Determines the mime type, of an extension and if it is binary content\n *\n * @param ext file extension e.g. `.txt`\n * @param isTextData if content is of type string\n */\nexport function getMimeType(ext: string, isTextData: boolean): FileMimeInformation {\n if (!ext) {\n return { mimeType: isTextData ? 'text/plain' : 'application/octet-stream', isBinary: !isTextData };\n }\n\n ext = ext.toLowerCase();\n const mimeInfo = getKnownMimeType(ext);\n if (mimeInfo) {\n return mimeInfo;\n }\n return { mimeType: isTextData ? 'text/plain' : 'application/octet-stream', isBinary: !isTextData };\n}\n\nexport function checkFile(\n fileOptions: Record<string, any>,\n options: Record<string, any>,\n flag: any,\n defaultNewAcl?: ACLObject | null,\n): boolean {\n if (typeof fileOptions.acl !== 'object') {\n fileOptions = {};\n fileOptions.mimeType = deepClone(fileOptions);\n fileOptions.acl = {\n owner: (defaultNewAcl && defaultNewAcl.owner) || CONSTS.SYSTEM_ADMIN_USER,\n ownerGroup: (defaultNewAcl && defaultNewAcl.ownerGroup) || CONSTS.SYSTEM_ADMIN_GROUP,\n permissions:\n (defaultNewAcl && defaultNewAcl.file) ||\n CONSTS.ACCESS_USER_RW | CONSTS.ACCESS_GROUP_READ | CONSTS.ACCESS_EVERY_READ, // '0644'\n };\n }\n\n // Set default owner group\n fileOptions.acl.ownerGroup =\n fileOptions.acl.ownerGroup || (defaultNewAcl && defaultNewAcl.ownerGroup) || CONSTS.SYSTEM_ADMIN_GROUP;\n fileOptions.acl.owner = fileOptions.acl.owner || (defaultNewAcl && defaultNewAcl.owner) || CONSTS.SYSTEM_ADMIN_USER;\n fileOptions.acl.permissions =\n fileOptions.acl.permissions ||\n (defaultNewAcl && defaultNewAcl.file) ||\n CONSTS.ACCESS_USER_RW | CONSTS.ACCESS_GROUP_READ | CONSTS.ACCESS_EVERY_READ; // '0644'\n\n if (\n options.user !== CONSTS.SYSTEM_ADMIN_USER &&\n options.groups.indexOf(CONSTS.SYSTEM_ADMIN_GROUP) === -1 &&\n fileOptions.acl\n ) {\n if (fileOptions.acl.owner !== options.user) {\n // Check if the user is in the group\n if (options.groups.indexOf(fileOptions.acl.ownerGroup) !== -1) {\n // Check group rights\n if (!(fileOptions.acl.permissions & (flag << 4))) {\n return false;\n }\n } else {\n // everybody\n if (!(fileOptions.acl.permissions & flag)) {\n return false;\n }\n }\n } else {\n // Check user rights\n if (!(fileOptions.acl.permissions & (flag << 8))) {\n return false;\n }\n }\n }\n return true;\n}\n\nexport function checkFileRights(\n objects: any,\n id: string,\n name: string | null,\n options: Record<string, any> | null | undefined,\n flag: CONSTS.GenericAccessFlags,\n callback?: CheckFileRightsCallback,\n): any {\n const _options = options || {};\n if (!_options.user) {\n // Before files converted, lets think: if no options it is admin\n _options.user = 'system.user.admin';\n _options.params = _options;\n _options.group = 'system.group.administrator';\n }\n\n if (!_options.acl) {\n objects.getUserGroup(_options.user, (_user: any, groups: any, acl: Record<string, any>) => {\n _options.acl = acl || {};\n _options.groups = groups;\n _options.group = groups ? groups[0] : null;\n checkFileRights(objects, id, name, _options, flag, callback);\n });\n return;\n }\n // If user may write\n if (flag === CONSTS.ACCESS_WRITE && !_options.acl.file.write) {\n // write\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, _options);\n }\n // If user may read\n if (flag === CONSTS.ACCESS_READ && !_options.acl.file.read) {\n // read\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, _options);\n }\n\n _options.checked = true;\n objects.checkFile(id, name, _options, flag, (err: Error, options: Record<string, any>, opt: any) => {\n if (err) {\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, options);\n }\n return tools.maybeCallbackWithError(callback, null, options, opt);\n });\n}\n\n// For users and groups\nfunction getDefaultAdminRights(\n acl?: ioBroker.ObjectPermissions,\n _isState?: boolean,\n): Omit<ioBroker.PermissionSet, 'user' | 'groups'> {\n return {\n ...acl,\n file: {\n list: true,\n read: true,\n write: true,\n create: true,\n delete: true,\n },\n object: {\n create: true,\n list: true,\n read: true,\n write: true,\n delete: true,\n },\n users: {\n create: true,\n list: true,\n read: true,\n write: true,\n delete: true,\n },\n state: {\n read: true,\n write: true,\n delete: true,\n create: true,\n list: true,\n },\n other: {\n execute: false,\n http: false,\n sendto: false,\n },\n };\n}\n\nexport type GetUserGroupPromiseReturn = [user: string, groups: string[], acl: ioBroker.ObjectPermissions];\n\ntype GetUserGroupCallback = (\n err: Error | null | undefined,\n user: string,\n groups: string[],\n acl: ioBroker.ObjectPermissions,\n) => void;\n\nexport function getUserGroup(\n objects: any,\n user: ioBroker.ObjectIDs.User,\n callback?: GetUserGroupCallback,\n): Promise<GetUserGroupPromiseReturn> | void {\n if (!user || typeof user !== 'string' || !user.startsWith(USER_STARTS_WITH)) {\n console.log(`invalid user name: ${user}`);\n\n return tools.maybeCallbackWithError(\n callback,\n `invalid user name: ${user}`,\n deepClone(user),\n [],\n deepClone(defaultAcl.acl),\n );\n }\n if (users[user]) {\n return tools.maybeCallbackWithError(callback, null, user, users[user].groups, users[user].acl);\n }\n\n let error: Error;\n // Read all groups\n objects.getObjectList(\n { startkey: 'system.group.', endkey: 'system.group.\\u9999' },\n { checked: true },\n (\n err: Error,\n arr: {\n rows: Array<ioBroker.GetObjectViewItem<ioBroker.GroupObject>>;\n },\n ) => {\n if (err) {\n error = err;\n }\n groups = [];\n if (arr) {\n // Read all groups\n for (const g in arr.rows) {\n const val = arr.rows[g].value;\n if (!val) {\n continue;\n }\n\n groups[g] = val;\n if (groups[g]._id === CONSTS.SYSTEM_ADMIN_GROUP) {\n groups[g].common.acl = getDefaultAdminRights(groups[g].common.acl);\n }\n }\n }\n\n objects.getObjectList(\n { startkey: 'system.user.', endkey: 'system.user.\\u9999' },\n { checked: true },\n (\n err?: Error | null,\n arr?: {\n rows: ioBroker.GetObjectListItem<ioBroker.UserObject>[];\n },\n ) => {\n if (err) {\n error = err;\n }\n users = {};\n\n if (arr) {\n for (const row of arr.rows) {\n // cannot use here Object.assign, because required deep copy\n users[row.value._id] = deepClone(defaultAcl);\n }\n }\n users[CONSTS.SYSTEM_ADMIN_USER] = users[CONSTS.SYSTEM_ADMIN_USER] || deepClone(defaultAcl);\n users[CONSTS.SYSTEM_ADMIN_USER].acl = getDefaultAdminRights(users[CONSTS.SYSTEM_ADMIN_USER].acl);\n\n for (let g = 0; g < groups.length; g++) {\n if (!groups[g] || !groups[g].common || !groups[g].common.members) {\n continue;\n }\n for (let m = 0; m < groups[g].common.members.length; m++) {\n const u = groups[g].common.members[m];\n if (!users[u]) {\n error =\n error ||\n `Unknown user in group \"${groups[g]._id.replace('system.group.', '')}\": ${u}`;\n continue;\n }\n users[u].groups.push(groups[g]._id);\n\n if (groups[g].common.acl && groups[g].common.acl.file) {\n if (!users[u].acl || !users[u].acl.file) {\n users[u].acl = users[u].acl || {};\n users[u].acl.file = users[u].acl.file || {};\n\n users[u].acl.file.create = groups[g].common.acl.file.create;\n users[u].acl.file.read = groups[g].common.acl.file.read;\n users[u].acl.file.write = groups[g].common.acl.file.write;\n users[u].acl.file.delete = groups[g].common.acl.file.delete;\n users[u].acl.file.list = groups[g].common.acl.file.list;\n } else {\n users[u].acl.file.create =\n users[u].acl.file.create || groups[g].common.acl.file.create;\n users[u].acl.file.read = users[u].acl.file.read || groups[g].common.acl.file.read;\n users[u].acl.file.write =\n users[u].acl.file.write || groups[g].common.acl.file.write;\n users[u].acl.file.delete =\n users[u].acl.file.delete || groups[g].common.acl.file.delete;\n users[u].acl.file.list = users[u].acl.file.list || groups[g].common.acl.file.list;\n }\n }\n\n if (groups[g].common.acl && groups[g].common.acl.object) {\n if (!users[u].acl || !users[u].acl.object) {\n users[u].acl = users[u].acl || {};\n users[u].acl.object = users[u].acl.object || {};\n\n users[u].acl.object.create = groups[g].common.acl.object.create;\n users[u].acl.object.read = groups[g].common.acl.object.read;\n users[u].acl.object.write = groups[g].common.acl.object.write;\n users[u].acl.object.delete = groups[g].common.acl.object.delete;\n users[u].acl.object.list = groups[g].common.acl.object.list;\n } else {\n users[u].acl.object.create =\n users[u].acl.object.create || groups[g].common.acl.object.create;\n users[u].acl.object.read =\n users[u].acl.object.read || groups[g].common.acl.object.read;\n users[u].acl.object.write =\n users[u].acl.object.write || groups[g].common.acl.object.write;\n users[u].acl.object.delete =\n users[u].acl.object.delete || groups[g].common.acl.object.delete;\n users[u].acl.object.list =\n users[u].acl.object.list || groups[g].common.acl.object.list;\n }\n }\n\n if (groups[g].common.acl && groups[g].common.acl.users) {\n if (!users[u].acl || !users[u].acl.users) {\n users[u].acl = users[u].acl || {};\n users[u].acl.users = users[u].acl.users || {};\n\n users[u].acl.users.create = groups[g].common.acl.users.create;\n users[u].acl.users.read = groups[g].common.acl.users.read;\n users[u].acl.users.write = groups[g].common.acl.users.write;\n users[u].acl.users.delete = groups[g].common.acl.users.delete;\n users[u].acl.users.list = groups[g].common.acl.users.list;\n } else {\n users[u].acl.users.create =\n users[u].acl.users.create || groups[g].common.acl.users.create;\n users[u].acl.users.read =\n users[u].acl.users.read || groups[g].common.acl.users.read;\n users[u].acl.users.write =\n users[u].acl.users.write || groups[g].common.acl.users.write;\n users[u].acl.users.delete =\n users[u].acl.users.delete || groups[g].common.acl.users.delete;\n users[u].acl.users.list =\n users[u].acl.users.list || groups[g].common.acl.users.list;\n }\n }\n\n if (groups[g].common.acl && groups[g].common.acl.state) {\n if (!users[u].acl || !users[u].acl.state) {\n users[u].acl = users[u].acl || {};\n users[u].acl.state = users[u].acl.state || {};\n\n users[u].acl.state.create = groups[g].common.acl.state?.create;\n users[u].acl.state.read = groups[g].common.acl.state?.read;\n users[u].acl.state.write = groups[g].common.acl.state?.write;\n users[u].acl.state.delete = groups[g].common.acl.state?.delete;\n users[u].acl.state.list = groups[g].common.acl.state?.list;\n } else {\n users[u].acl.state.create =\n users[u].acl.state.create || groups[g].common.acl.state?.create;\n users[u].acl.state.read =\n users[u].acl.state.read || groups[g].common.acl.state?.read;\n users[u].acl.state.write =\n users[u].acl.state.write || groups[g].common.acl.state?.write;\n users[u].acl.state.delete =\n users[u].acl.state.delete || groups[g].common.acl.state?.delete;\n users[u].acl.state.list =\n users[u].acl.state.list || groups[g].common.acl.state?.list;\n }\n }\n }\n }\n\n return tools.maybeCallbackWithError(\n callback,\n error,\n user,\n users[user] ? users[user].groups : [],\n users[user] ? users[user].acl : deepClone(defaultAcl.acl),\n );\n },\n );\n },\n );\n}\n\nexport function sanitizePath(\n id: string,\n name: string,\n): {\n id: string;\n name: string;\n} {\n if (!name) {\n name = '';\n }\n if (name[0] === '/') {\n name = name.substring(1);\n }\n\n if (!id) {\n throw new Error('Empty ID');\n }\n\n id = id.replace(/[\\][*,;'\"`<>\\\\?/]/g, ''); // remove all invalid characters from states plus slashes\n id = id.replace(/\\.\\./g, ''); // do not allow to write in parent directories\n\n if (name.includes('..')) {\n name = path.normalize(`/${name}`);\n }\n if (name.includes('..')) {\n // Also after normalization we still have .. in it - should not happen if normalize worked correctly\n name = name.replace(/\\.\\./g, '');\n name = path.normalize(`/${name}`);\n }\n\n name = name.replace(/\\\\/g, '/'); // replace win path backslashes\n\n if (name[0] === '/') {\n name = name.substring(1);\n } // do not allow absolute paths\n\n return { id: id, name: name };\n}\n\nexport function checkObject(\n obj: ioBroker.AnyObject | FileObject | null,\n options: Record<string, any>,\n flag: CONSTS.GenericAccessFlags,\n): boolean {\n // read rights of object\n if (!obj || !('common' in obj) || !obj.acl || flag === CONSTS.ACCESS_LIST) {\n return true;\n }\n\n if (options.user === CONSTS.SYSTEM_ADMIN_USER) {\n return true;\n }\n\n // admins may always see everything\n if (options.group === CONSTS.SYSTEM_ADMIN_GROUP || options.groups.includes(CONSTS.SYSTEM_ADMIN_GROUP)) {\n return true;\n }\n\n // FIXME: what if flag is ACCESS_DELETE or ACCESS_CREATE? currently it will end in false\n if (flag === CONSTS.ACCESS_DELETE || flag === CONSTS.ACCESS_CREATE) {\n return false;\n }\n\n // checkObject always called after checkObjectRights and admin is checked there\n if (obj.acl.owner !== options.user) {\n // Check if the user is in the group\n if (\n (options.group && options.group === obj.acl.ownerGroup) ||\n (options.groups && options.groups.includes(obj.acl.ownerGroup))\n ) {\n // Check group rights\n if (!(obj.acl.object & (flag << 4))) {\n return false;\n }\n } else {\n // everybody\n if (!(obj.acl.object & flag)) {\n return false;\n }\n }\n } else {\n // Check group rights\n if (!(obj.acl.object & (flag << 8))) {\n return false;\n }\n }\n return true; // ALL OK\n}\n\nexport function checkObjectRights(\n objects: any,\n id: string | null,\n object: ioBroker.Object | null,\n options: Record<string, any> | null | undefined,\n flag: CONSTS.GenericAccessFlags,\n callback: (err: Error | null | undefined, options: Record<string, any>) => void,\n): void | Promise<Record<string, any>> {\n options = options || {};\n\n if (!options.user) {\n // Before files converted, lets think: if no options it is admin\n options = {\n user: CONSTS.SYSTEM_ADMIN_USER,\n params: options,\n group: CONSTS.SYSTEM_ADMIN_GROUP,\n groups: [CONSTS.SYSTEM_ADMIN_GROUP],\n acl: getDefaultAdminRights(),\n };\n }\n\n if (!options.acl) {\n return objects.getUserGroup(options.user, (_user: string, groups: any, acl: Record<string, any>) => {\n // TODO: ts needs it because we are doing async call before\n options = options || {};\n options.acl = acl || {};\n options.groups = groups;\n options.group = groups ? groups[0] : null;\n checkObjectRights(objects, id, object, options, flag, callback);\n });\n }\n\n // now options are filled and we can go\n if (\n options.user === CONSTS.SYSTEM_ADMIN_USER ||\n options.group === CONSTS.SYSTEM_ADMIN_GROUP ||\n (options.groups && options.groups.includes(CONSTS.SYSTEM_ADMIN_GROUP))\n ) {\n return tools.maybeCallbackWithError(callback, null, options);\n }\n\n // if user or group objects\n if (typeof id === 'string' && (id.startsWith(USER_STARTS_WITH) || id.startsWith(GROUP_STARTS_WITH))) {\n // If user may write\n if (flag === CONSTS.ACCESS_WRITE && !options.acl.users.write) {\n // write\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, options);\n }\n\n // If user may read\n if (flag === CONSTS.ACCESS_READ && !options.acl.users.read) {\n // read\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, options);\n }\n\n // If user may delete\n if (flag === CONSTS.ACCESS_DELETE && !options.acl.users.delete) {\n // delete\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, options);\n }\n\n // If user may list\n if (flag === CONSTS.ACCESS_LIST && !options.acl.users.list) {\n // list\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, options);\n }\n\n // If user may create\n if (flag === CONSTS.ACCESS_CREATE && !options.acl.users.create) {\n // create\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, options);\n }\n\n // If user may write\n if (flag === CONSTS.ACCESS_DELETE) {\n // he may delete\n flag = CONSTS.ACCESS_WRITE;\n }\n }\n\n // If user may write\n if (flag === CONSTS.ACCESS_WRITE && !options.acl.object.write) {\n // write\n tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, options);\n }\n\n // If user may read\n if (flag === CONSTS.ACCESS_READ && !options.acl.object.read) {\n // read\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, options);\n }\n\n // If user may delete\n if (flag === CONSTS.ACCESS_DELETE && !options.acl.object.delete) {\n // delete\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, options);\n }\n\n // If user may list\n if (flag === CONSTS.ACCESS_LIST && !options.acl.object.list) {\n // list\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, options);\n }\n\n if (flag === CONSTS.ACCESS_DELETE) {\n // write\n flag = CONSTS.ACCESS_WRITE;\n }\n\n if (id && !checkObject(object, options, flag)) {\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, options);\n }\n return tools.maybeCallbackWithError(callback, null, options);\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["/**\n * Common functions between client and server\n *\n * Copyright 2013-2024 bluefox <dogafox@gmail.com>\n *\n * MIT License\n *\n */\n\nimport path from 'node:path';\nimport deepClone from 'deep-clone';\nimport { tools } from '@iobroker/db-base';\nimport * as CONSTS from '@/lib/objects/constants.js';\nimport mime from 'mime-types';\n\nexport * as CONSTS from '@/lib/objects/constants.js';\nexport const ERRORS = CONSTS.ERRORS;\nexport const REG_CHECK_ID = CONSTS.REG_CHECK_ID;\n\nconst USER_STARTS_WITH = CONSTS.USER_STARTS_WITH;\nconst GROUP_STARTS_WITH = CONSTS.GROUP_STARTS_WITH;\n\n/** Information about a file's mime type */\nexport interface FileMimeInformation {\n /** the mime type, of the file */\n mimeType: string;\n /** if content is binary or textual */\n isBinary: boolean;\n}\n\n/** Access control list of an object, state or file */\nexport interface ACLObject {\n /** The user that owns the object */\n owner: string;\n /** The group that owns the object */\n ownerGroup: string;\n /** Permission bitmask for object access */\n object: number;\n /** Permission bitmask for state access */\n state: number;\n /** Permission bitmask for file access */\n file: number;\n}\n\n/** Metadata of a stored file */\nexport interface FileObject {\n /** Whether this is a virtual file (a directory placeholder) */\n virtualFile?: boolean;\n /** File system stats of the file */\n stats: any;\n /** Timestamp (ms) when the file was last modified */\n modifiedAt: number;\n /** Timestamp (ms) when the file was created */\n createdAt: number;\n /** Evaluated access control list of the file */\n acl: ioBroker.EvaluatedFileACL;\n}\n\nexport type CheckFileRightsCallback = (err: Error | null | undefined, options: Record<string, any>, opt?: any) => void;\n\nconst textTypes = ['.js', '.json', '.svg'];\n\n/**\n * Checks if the mime type, of an extension is a known one and if it corresponds to binary content\n *\n * @param ext the file extension e.g. `.txt`\n */\nfunction getKnownMimeType(ext: string): FileMimeInformation | null {\n try {\n const mimeType = mime.lookup(ext);\n if (mimeType) {\n return { mimeType, isBinary: !mimeType.startsWith('text/') && !textTypes.includes(ext) };\n }\n } catch {\n // ignore\n }\n\n return null;\n}\n\n// For objects\nconst defaultAcl = {\n groups: [],\n acl: {\n file: {\n list: false,\n read: false,\n write: false,\n create: false,\n delete: false,\n },\n object: {\n list: false,\n read: false,\n write: false,\n create: false,\n delete: false,\n },\n state: {\n list: false,\n read: false,\n write: false,\n create: false,\n delete: false,\n },\n users: {\n list: false,\n read: false,\n write: false,\n create: false,\n delete: false,\n },\n },\n} as const;\n\n// FIXME: This should have better types. Probably Record<string, {acl: ioBroker.ObjectPermissions, [x: string | number | symbol]: any}>\nlet users: Record<ioBroker.ObjectIDs.User, any> = {};\nlet groups: ioBroker.GroupObject[] = [];\n\n/**\n * Determines the mime type, of an extension and if it is binary content\n *\n * @param ext file extension e.g. `.txt`\n * @param isTextData if content is of type string\n */\nexport function getMimeType(ext: string, isTextData: boolean): FileMimeInformation {\n if (!ext) {\n return { mimeType: isTextData ? 'text/plain' : 'application/octet-stream', isBinary: !isTextData };\n }\n\n ext = ext.toLowerCase();\n const mimeInfo = getKnownMimeType(ext);\n if (mimeInfo) {\n return mimeInfo;\n }\n return { mimeType: isTextData ? 'text/plain' : 'application/octet-stream', isBinary: !isTextData };\n}\n\n/**\n * Check if the given options have the required rights on a file according to its ACL\n *\n * @param fileOptions The stored file options including its ACL\n * @param options The current request options including the user and group\n * @param flag The access flag(s) to check for\n * @param defaultNewAcl The default ACL to use if the file has none yet\n */\nexport function checkFile(\n fileOptions: Record<string, any>,\n options: Record<string, any>,\n flag: any,\n defaultNewAcl?: ACLObject | null,\n): boolean {\n if (typeof fileOptions.acl !== 'object') {\n fileOptions = {};\n fileOptions.mimeType = deepClone(fileOptions);\n fileOptions.acl = {\n owner: (defaultNewAcl && defaultNewAcl.owner) || CONSTS.SYSTEM_ADMIN_USER,\n ownerGroup: (defaultNewAcl && defaultNewAcl.ownerGroup) || CONSTS.SYSTEM_ADMIN_GROUP,\n permissions:\n (defaultNewAcl && defaultNewAcl.file) ||\n CONSTS.ACCESS_USER_RW | CONSTS.ACCESS_GROUP_READ | CONSTS.ACCESS_EVERY_READ, // '0644'\n };\n }\n\n // Set default owner group\n fileOptions.acl.ownerGroup =\n fileOptions.acl.ownerGroup || (defaultNewAcl && defaultNewAcl.ownerGroup) || CONSTS.SYSTEM_ADMIN_GROUP;\n fileOptions.acl.owner = fileOptions.acl.owner || (defaultNewAcl && defaultNewAcl.owner) || CONSTS.SYSTEM_ADMIN_USER;\n fileOptions.acl.permissions =\n fileOptions.acl.permissions ||\n (defaultNewAcl && defaultNewAcl.file) ||\n CONSTS.ACCESS_USER_RW | CONSTS.ACCESS_GROUP_READ | CONSTS.ACCESS_EVERY_READ; // '0644'\n\n if (\n options.user !== CONSTS.SYSTEM_ADMIN_USER &&\n options.groups.indexOf(CONSTS.SYSTEM_ADMIN_GROUP) === -1 &&\n fileOptions.acl\n ) {\n if (fileOptions.acl.owner !== options.user) {\n // Check if the user is in the group\n if (options.groups.indexOf(fileOptions.acl.ownerGroup) !== -1) {\n // Check group rights\n if (!(fileOptions.acl.permissions & (flag << 4))) {\n return false;\n }\n } else {\n // everybody\n if (!(fileOptions.acl.permissions & flag)) {\n return false;\n }\n }\n } else {\n // Check user rights\n if (!(fileOptions.acl.permissions & (flag << 8))) {\n return false;\n }\n }\n }\n return true;\n}\n\n/**\n * Check whether the given user is allowed to access a file and call back with the effective options\n *\n * @param objects The objects database client\n * @param id The id of the object owning the file\n * @param name The file name, or null for the whole namespace\n * @param options The current request options including the user\n * @param flag The access flag(s) to check for\n * @param callback Called with the effective options once the rights have been checked\n */\nexport function checkFileRights(\n objects: any,\n id: string,\n name: string | null,\n options: Record<string, any> | null | undefined,\n flag: CONSTS.GenericAccessFlags,\n callback?: CheckFileRightsCallback,\n): any {\n const _options = options || {};\n if (!_options.user) {\n // Before files converted, lets think: if no options it is admin\n _options.user = 'system.user.admin';\n _options.params = _options;\n _options.group = 'system.group.administrator';\n }\n\n if (!_options.acl) {\n objects.getUserGroup(_options.user, (_user: any, groups: any, acl: Record<string, any>) => {\n _options.acl = acl || {};\n _options.groups = groups;\n _options.group = groups ? groups[0] : null;\n checkFileRights(objects, id, name, _options, flag, callback);\n });\n return;\n }\n // If user may write\n if (flag === CONSTS.ACCESS_WRITE && !_options.acl.file.write) {\n // write\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, _options);\n }\n // If user may read\n if (flag === CONSTS.ACCESS_READ && !_options.acl.file.read) {\n // read\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, _options);\n }\n\n _options.checked = true;\n objects.checkFile(id, name, _options, flag, (err: Error, options: Record<string, any>, opt: any) => {\n if (err) {\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, options);\n }\n return tools.maybeCallbackWithError(callback, null, options, opt);\n });\n}\n\n// For users and groups\nfunction getDefaultAdminRights(\n acl?: ioBroker.ObjectPermissions,\n _isState?: boolean,\n): Omit<ioBroker.PermissionSet, 'user' | 'groups'> {\n return {\n ...acl,\n file: {\n list: true,\n read: true,\n write: true,\n create: true,\n delete: true,\n },\n object: {\n create: true,\n list: true,\n read: true,\n write: true,\n delete: true,\n },\n users: {\n create: true,\n list: true,\n read: true,\n write: true,\n delete: true,\n },\n state: {\n read: true,\n write: true,\n delete: true,\n create: true,\n list: true,\n },\n other: {\n execute: false,\n http: false,\n sendto: false,\n },\n };\n}\n\nexport type GetUserGroupPromiseReturn = [user: string, groups: string[], acl: ioBroker.ObjectPermissions];\n\ntype GetUserGroupCallback = (\n err: Error | null | undefined,\n user: string,\n groups: string[],\n acl: ioBroker.ObjectPermissions,\n) => void;\n\n/**\n * Determine the groups and effective ACL of the given user\n *\n * @param objects The objects database client\n * @param user The id of the user to look up\n * @param callback Called with the user, its groups and the effective ACL\n */\nexport function getUserGroup(\n objects: any,\n user: ioBroker.ObjectIDs.User,\n callback?: GetUserGroupCallback,\n): Promise<GetUserGroupPromiseReturn> | void {\n if (!user || typeof user !== 'string' || !user.startsWith(USER_STARTS_WITH)) {\n console.log(`invalid user name: ${user}`);\n\n return tools.maybeCallbackWithError(\n callback,\n `invalid user name: ${user}`,\n deepClone(user),\n [],\n deepClone(defaultAcl.acl),\n );\n }\n if (users[user]) {\n return tools.maybeCallbackWithError(callback, null, user, users[user].groups, users[user].acl);\n }\n\n let error: Error;\n // Read all groups\n objects.getObjectList(\n { startkey: 'system.group.', endkey: 'system.group.\\u9999' },\n { checked: true },\n (\n err: Error,\n arr: {\n /** The matching group objects */\n rows: Array<ioBroker.GetObjectViewItem<ioBroker.GroupObject>>;\n },\n ) => {\n if (err) {\n error = err;\n }\n groups = [];\n if (arr) {\n // Read all groups\n for (const g in arr.rows) {\n const val = arr.rows[g].value;\n if (!val) {\n continue;\n }\n\n groups[g] = val;\n if (groups[g]._id === CONSTS.SYSTEM_ADMIN_GROUP) {\n groups[g].common.acl = getDefaultAdminRights(groups[g].common.acl);\n }\n }\n }\n\n objects.getObjectList(\n { startkey: 'system.user.', endkey: 'system.user.\\u9999' },\n { checked: true },\n (\n err?: Error | null,\n arr?: {\n /** The matching user objects */\n rows: ioBroker.GetObjectListItem<ioBroker.UserObject>[];\n },\n ) => {\n if (err) {\n error = err;\n }\n users = {};\n\n if (arr) {\n for (const row of arr.rows) {\n // cannot use here Object.assign, because required deep copy\n users[row.value._id] = deepClone(defaultAcl);\n }\n }\n users[CONSTS.SYSTEM_ADMIN_USER] = users[CONSTS.SYSTEM_ADMIN_USER] || deepClone(defaultAcl);\n users[CONSTS.SYSTEM_ADMIN_USER].acl = getDefaultAdminRights(users[CONSTS.SYSTEM_ADMIN_USER].acl);\n\n for (let g = 0; g < groups.length; g++) {\n if (!groups[g] || !groups[g].common || !groups[g].common.members) {\n continue;\n }\n for (let m = 0; m < groups[g].common.members.length; m++) {\n const u = groups[g].common.members[m];\n if (!users[u]) {\n error =\n error ||\n `Unknown user in group \"${groups[g]._id.replace('system.group.', '')}\": ${u}`;\n continue;\n }\n users[u].groups.push(groups[g]._id);\n\n if (groups[g].common.acl && groups[g].common.acl.file) {\n if (!users[u].acl || !users[u].acl.file) {\n users[u].acl = users[u].acl || {};\n users[u].acl.file = users[u].acl.file || {};\n\n users[u].acl.file.create = groups[g].common.acl.file.create;\n users[u].acl.file.read = groups[g].common.acl.file.read;\n users[u].acl.file.write = groups[g].common.acl.file.write;\n users[u].acl.file.delete = groups[g].common.acl.file.delete;\n users[u].acl.file.list = groups[g].common.acl.file.list;\n } else {\n users[u].acl.file.create =\n users[u].acl.file.create || groups[g].common.acl.file.create;\n users[u].acl.file.read = users[u].acl.file.read || groups[g].common.acl.file.read;\n users[u].acl.file.write =\n users[u].acl.file.write || groups[g].common.acl.file.write;\n users[u].acl.file.delete =\n users[u].acl.file.delete || groups[g].common.acl.file.delete;\n users[u].acl.file.list = users[u].acl.file.list || groups[g].common.acl.file.list;\n }\n }\n\n if (groups[g].common.acl && groups[g].common.acl.object) {\n if (!users[u].acl || !users[u].acl.object) {\n users[u].acl = users[u].acl || {};\n users[u].acl.object = users[u].acl.object || {};\n\n users[u].acl.object.create = groups[g].common.acl.object.create;\n users[u].acl.object.read = groups[g].common.acl.object.read;\n users[u].acl.object.write = groups[g].common.acl.object.write;\n users[u].acl.object.delete = groups[g].common.acl.object.delete;\n users[u].acl.object.list = groups[g].common.acl.object.list;\n } else {\n users[u].acl.object.create =\n users[u].acl.object.create || groups[g].common.acl.object.create;\n users[u].acl.object.read =\n users[u].acl.object.read || groups[g].common.acl.object.read;\n users[u].acl.object.write =\n users[u].acl.object.write || groups[g].common.acl.object.write;\n users[u].acl.object.delete =\n users[u].acl.object.delete || groups[g].common.acl.object.delete;\n users[u].acl.object.list =\n users[u].acl.object.list || groups[g].common.acl.object.list;\n }\n }\n\n if (groups[g].common.acl && groups[g].common.acl.users) {\n if (!users[u].acl || !users[u].acl.users) {\n users[u].acl = users[u].acl || {};\n users[u].acl.users = users[u].acl.users || {};\n\n users[u].acl.users.create = groups[g].common.acl.users.create;\n users[u].acl.users.read = groups[g].common.acl.users.read;\n users[u].acl.users.write = groups[g].common.acl.users.write;\n users[u].acl.users.delete = groups[g].common.acl.users.delete;\n users[u].acl.users.list = groups[g].common.acl.users.list;\n } else {\n users[u].acl.users.create =\n users[u].acl.users.create || groups[g].common.acl.users.create;\n users[u].acl.users.read =\n users[u].acl.users.read || groups[g].common.acl.users.read;\n users[u].acl.users.write =\n users[u].acl.users.write || groups[g].common.acl.users.write;\n users[u].acl.users.delete =\n users[u].acl.users.delete || groups[g].common.acl.users.delete;\n users[u].acl.users.list =\n users[u].acl.users.list || groups[g].common.acl.users.list;\n }\n }\n\n if (groups[g].common.acl && groups[g].common.acl.state) {\n if (!users[u].acl || !users[u].acl.state) {\n users[u].acl = users[u].acl || {};\n users[u].acl.state = users[u].acl.state || {};\n\n users[u].acl.state.create = groups[g].common.acl.state?.create;\n users[u].acl.state.read = groups[g].common.acl.state?.read;\n users[u].acl.state.write = groups[g].common.acl.state?.write;\n users[u].acl.state.delete = groups[g].common.acl.state?.delete;\n users[u].acl.state.list = groups[g].common.acl.state?.list;\n } else {\n users[u].acl.state.create =\n users[u].acl.state.create || groups[g].common.acl.state?.create;\n users[u].acl.state.read =\n users[u].acl.state.read || groups[g].common.acl.state?.read;\n users[u].acl.state.write =\n users[u].acl.state.write || groups[g].common.acl.state?.write;\n users[u].acl.state.delete =\n users[u].acl.state.delete || groups[g].common.acl.state?.delete;\n users[u].acl.state.list =\n users[u].acl.state.list || groups[g].common.acl.state?.list;\n }\n }\n }\n }\n\n return tools.maybeCallbackWithError(\n callback,\n error,\n user,\n users[user] ? users[user].groups : [],\n users[user] ? users[user].acl : deepClone(defaultAcl.acl),\n );\n },\n );\n },\n );\n}\n\n/**\n * Sanitize an object id and file name so they cannot escape the intended directory\n *\n * @param id The object id owning the file\n * @param name The file name to sanitize\n */\nexport function sanitizePath(\n id: string,\n name: string,\n): {\n /** The sanitized object id */\n id: string;\n /** The sanitized file name */\n name: string;\n} {\n if (!name) {\n name = '';\n }\n if (name[0] === '/') {\n name = name.substring(1);\n }\n\n if (!id) {\n throw new Error('Empty ID');\n }\n\n id = id.replace(/[\\][*,;'\"`<>\\\\?/]/g, ''); // remove all invalid characters from states plus slashes\n id = id.replace(/\\.\\./g, ''); // do not allow to write in parent directories\n\n if (name.includes('..')) {\n name = path.normalize(`/${name}`);\n }\n if (name.includes('..')) {\n // Also after normalization we still have .. in it - should not happen if normalize worked correctly\n name = name.replace(/\\.\\./g, '');\n name = path.normalize(`/${name}`);\n }\n\n name = name.replace(/\\\\/g, '/'); // replace win path backslashes\n\n if (name[0] === '/') {\n name = name.substring(1);\n } // do not allow absolute paths\n\n return { id: id, name: name };\n}\n\n/**\n * Check if the given options have the required rights on an object according to its ACL\n *\n * @param obj The object (or file object) to check, or null\n * @param options The current request options including the user and group\n * @param flag The access flag(s) to check for\n */\nexport function checkObject(\n obj: ioBroker.AnyObject | FileObject | null,\n options: Record<string, any>,\n flag: CONSTS.GenericAccessFlags,\n): boolean {\n // read rights of object\n if (!obj || !('common' in obj) || !obj.acl || flag === CONSTS.ACCESS_LIST) {\n return true;\n }\n\n if (options.user === CONSTS.SYSTEM_ADMIN_USER) {\n return true;\n }\n\n // admins may always see everything\n if (options.group === CONSTS.SYSTEM_ADMIN_GROUP || options.groups.includes(CONSTS.SYSTEM_ADMIN_GROUP)) {\n return true;\n }\n\n // FIXME: what if flag is ACCESS_DELETE or ACCESS_CREATE? currently it will end in false\n if (flag === CONSTS.ACCESS_DELETE || flag === CONSTS.ACCESS_CREATE) {\n return false;\n }\n\n // checkObject always called after checkObjectRights and admin is checked there\n if (obj.acl.owner !== options.user) {\n // Check if the user is in the group\n if (\n (options.group && options.group === obj.acl.ownerGroup) ||\n (options.groups && options.groups.includes(obj.acl.ownerGroup))\n ) {\n // Check group rights\n if (!(obj.acl.object & (flag << 4))) {\n return false;\n }\n } else {\n // everybody\n if (!(obj.acl.object & flag)) {\n return false;\n }\n }\n } else {\n // Check group rights\n if (!(obj.acl.object & (flag << 8))) {\n return false;\n }\n }\n return true; // ALL OK\n}\n\n/**\n * Check whether the given user is allowed to access an object and call back with the effective options\n *\n * @param objects The objects database client\n * @param id The id of the object, or null\n * @param object The object to check, or null\n * @param options The current request options including the user\n * @param flag The access flag(s) to check for\n * @param callback Called with the effective options once the rights have been checked\n */\nexport function checkObjectRights(\n objects: any,\n id: string | null,\n object: ioBroker.Object | null,\n options: Record<string, any> | null | undefined,\n flag: CONSTS.GenericAccessFlags,\n callback: (err: Error | null | undefined, options: Record<string, any>) => void,\n): void | Promise<Record<string, any>> {\n options = options || {};\n\n if (!options.user) {\n // Before files converted, lets think: if no options it is admin\n options = {\n user: CONSTS.SYSTEM_ADMIN_USER,\n params: options,\n group: CONSTS.SYSTEM_ADMIN_GROUP,\n groups: [CONSTS.SYSTEM_ADMIN_GROUP],\n acl: getDefaultAdminRights(),\n };\n }\n\n if (!options.acl) {\n return objects.getUserGroup(options.user, (_user: string, groups: any, acl: Record<string, any>) => {\n // TODO: ts needs it because we are doing async call before\n options = options || {};\n options.acl = acl || {};\n options.groups = groups;\n options.group = groups ? groups[0] : null;\n checkObjectRights(objects, id, object, options, flag, callback);\n });\n }\n\n // now options are filled and we can go\n if (\n options.user === CONSTS.SYSTEM_ADMIN_USER ||\n options.group === CONSTS.SYSTEM_ADMIN_GROUP ||\n (options.groups && options.groups.includes(CONSTS.SYSTEM_ADMIN_GROUP))\n ) {\n return tools.maybeCallbackWithError(callback, null, options);\n }\n\n // if user or group objects\n if (typeof id === 'string' && (id.startsWith(USER_STARTS_WITH) || id.startsWith(GROUP_STARTS_WITH))) {\n // If user may write\n if (flag === CONSTS.ACCESS_WRITE && !options.acl.users.write) {\n // write\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, options);\n }\n\n // If user may read\n if (flag === CONSTS.ACCESS_READ && !options.acl.users.read) {\n // read\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, options);\n }\n\n // If user may delete\n if (flag === CONSTS.ACCESS_DELETE && !options.acl.users.delete) {\n // delete\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, options);\n }\n\n // If user may list\n if (flag === CONSTS.ACCESS_LIST && !options.acl.users.list) {\n // list\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, options);\n }\n\n // If user may create\n if (flag === CONSTS.ACCESS_CREATE && !options.acl.users.create) {\n // create\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, options);\n }\n\n // If user may write\n if (flag === CONSTS.ACCESS_DELETE) {\n // he may delete\n flag = CONSTS.ACCESS_WRITE;\n }\n }\n\n // If user may write\n if (flag === CONSTS.ACCESS_WRITE && !options.acl.object.write) {\n // write\n tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, options);\n }\n\n // If user may read\n if (flag === CONSTS.ACCESS_READ && !options.acl.object.read) {\n // read\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, options);\n }\n\n // If user may delete\n if (flag === CONSTS.ACCESS_DELETE && !options.acl.object.delete) {\n // delete\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, options);\n }\n\n // If user may list\n if (flag === CONSTS.ACCESS_LIST && !options.acl.object.list) {\n // list\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, options);\n }\n\n if (flag === CONSTS.ACCESS_DELETE) {\n // write\n flag = CONSTS.ACCESS_WRITE;\n }\n\n if (id && !checkObject(object, options, flag)) {\n return tools.maybeCallbackWithError(callback, ERRORS.ERROR_PERMISSION, options);\n }\n return tools.maybeCallbackWithError(callback, null, options);\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["CONSTS", "CONSTS", "mime", "deepClone", "groups", "options", "err", "arr", "path"]
|
|
7
7
|
}
|