diff --git a/packages/backend/src/filesystem/hl_operations/hl_readdir.js b/packages/backend/src/filesystem/hl_operations/hl_readdir.js index 412a3f62..73e1d5fc 100644 --- a/packages/backend/src/filesystem/hl_operations/hl_readdir.js +++ b/packages/backend/src/filesystem/hl_operations/hl_readdir.js @@ -19,6 +19,7 @@ const APIError = require("../../api/APIError"); const { chkperm } = require("../../helpers"); const { TYPE_DIRECTORY } = require("../FSNodeContext"); +const { LLListUsers } = require("../ll_operations/ll_listusers"); const { LLReadDir } = require("../ll_operations/ll_readdir"); const { LLReadShares } = require("../ll_operations/ll_readshares"); const { HLFilesystemOperation } = require("./definitions"); @@ -48,7 +49,10 @@ class HLReadDir extends HLFilesystemOperation { namediff: await subject.get('name') !== user.username } ); - if ( + if ( subject.isRoot ) { + const ll_listusers = new LLListUsers(); + children = await ll_listusers.run(this.values); + } else if ( await subject.isUserDirectory() && await subject.get('name') !== user.username ) { diff --git a/packages/backend/src/filesystem/ll_operations/ll_listusers.js b/packages/backend/src/filesystem/ll_operations/ll_listusers.js new file mode 100644 index 00000000..410f20ed --- /dev/null +++ b/packages/backend/src/filesystem/ll_operations/ll_listusers.js @@ -0,0 +1,39 @@ +const { RootNodeSelector, NodeChildSelector } = require("../node/selectors"); +const { LLFilesystemOperation } = require("./definitions"); + +class LLListUsers extends LLFilesystemOperation { + static description = ` + List user directories which are relevant to the + current actor. + `; + + async _run () { + const { context } = this; + const svc = context.get('services'); + const svc_permission = svc.get('permission'); + const svc_fs = svc.get('filesystem'); + + const user = this.values.user; + const issuers = await svc_permission.list_user_permission_issuers(user); + + const nodes = []; + + nodes.push(await svc_fs.node(new NodeChildSelector( + new RootNodeSelector(), + user.username, + ))); + + for ( const issuer of issuers ) { + const node = await svc_fs.node(new NodeChildSelector( + new RootNodeSelector(), + issuer.username)); + nodes.push(node); + } + + return nodes; + } +} + +module.exports = { + LLListUsers, +}; diff --git a/packages/backend/src/services/auth/PermissionService.js b/packages/backend/src/services/auth/PermissionService.js index 498534d4..c4a9daee 100644 --- a/packages/backend/src/services/auth/PermissionService.js +++ b/packages/backend/src/services/auth/PermissionService.js @@ -583,6 +583,25 @@ class PermissionService extends BaseService { ] ); } + + /** + * List the users that have any permissions granted to the + * specified user. + */ + async list_user_permission_issuers (user) { + const rows = await this.db.read( + 'SELECT DISTINCT issuer_user_id FROM `user_to_user_permissions` ' + + 'WHERE `holder_user_id` = ?', + [ user.id ], + ); + + const users = []; + for ( const row of rows ) { + users.push(await get_user({ id: row.issuer_user_id })); + } + + return users; + } get_parent_permissions (permission) { const parent_perms = [];