diff --git a/src/backend/src/filesystem/FilesystemService.js b/src/backend/src/filesystem/FilesystemService.js index bfb9d3d69..c335efe5b 100644 --- a/src/backend/src/filesystem/FilesystemService.js +++ b/src/backend/src/filesystem/FilesystemService.js @@ -132,6 +132,7 @@ class FilesystemService extends BaseService { }, })); svc_permission.register_implicator(PermissionImplicator.create({ + id: 'is-owner', matcher: permission => { return permission.startsWith('fs:'); }, @@ -164,6 +165,7 @@ class FilesystemService extends BaseService { }, })); svc_permission.register_exploder(PermissionExploder.create({ + id: 'fs-access-levels', matcher: permission => { return permission.startsWith('fs:') && PermissionUtil.split(permission).length >= 3; diff --git a/src/backend/src/services/PuterSiteService.js b/src/backend/src/services/PuterSiteService.js index 4100a68a9..97cdcda92 100644 --- a/src/backend/src/services/PuterSiteService.js +++ b/src/backend/src/services/PuterSiteService.js @@ -50,6 +50,7 @@ class PuterSiteService extends BaseService { // Imply that sites can read their own files svc_permission.register_implicator(PermissionImplicator.create({ + id: 'in-site', matcher: permission => { return permission.startsWith('fs:'); }, diff --git a/src/backend/src/services/auth/PermissionService.js b/src/backend/src/services/auth/PermissionService.js index 1b8bc6b8c..df92cde36 100644 --- a/src/backend/src/services/auth/PermissionService.js +++ b/src/backend/src/services/auth/PermissionService.js @@ -185,26 +185,17 @@ class PermissionService extends BaseService { }); } - async scan (actor, permission) { + async scan (actor, permission_options) { const reading = []; - - { - const old_perm = permission; - permission = await this._rewrite_permission(permission); - if ( permission !== old_perm ) { - reading.push({ - $: 'rewrite', - from: old_perm, - to: permission, - }); - } + + if ( ! Array.isArray(permission_options) ) { + permission_options = [permission_options]; } - - - await require('../../structured/sequence/scan-user-permission') + + await require('../../structured/sequence/scan-permission') .call(this, { actor, - permission, + permission_options, reading, }); diff --git a/src/backend/src/structured/sequence/scan-user-permission.js b/src/backend/src/structured/sequence/scan-permission.js similarity index 60% rename from src/backend/src/structured/sequence/scan-user-permission.js rename to src/backend/src/structured/sequence/scan-permission.js index 3dbffc812..19f333d56 100644 --- a/src/backend/src/structured/sequence/scan-user-permission.js +++ b/src/backend/src/structured/sequence/scan-permission.js @@ -16,6 +16,7 @@ * You should have received a copy of the GNU Affero General Public License * along with this program. If not, see . */ +const { permission } = require("process"); const { Sequence } = require("../../codex/Sequence"); const { get_user } = require("../../helpers"); const { Actor, UserActorType } = require("../../services/auth/Actor"); @@ -31,22 +32,43 @@ module.exports = new Sequence([ if ( actor.type.user.username === 'system' ) { reading.push({ $: 'option', + permission: '*', source: 'implied', + by: 'system', data: {} }) return a.stop({}); } }, async function rewrite_permission (a) { - let { permission } = a.values(); - permission = await a.icall('_rewrite_permission', permission); - a.values({ permission }); + let { reading, permission_options } = a.values(); + for ( let i=0 ; i < permission_options.length ; i++ ) { + const old_perm = permission_options[i]; + const permission = await a.icall('_rewrite_permission', old_perm); + if ( permission === old_perm ) continue; + permission_options[i] = permission; + reading.push({ + $: 'rewrite', + from: old_perm, + to: permission, + }); + } }, async function explode_permission (a) { - const { permission } = a.values(); - const permission_options = - await a.icall('get_higher_permissions', permission); - a.values({ permission_options }); + const { reading, permission_options } = a.values(); + for ( let i=0 ; i < permission_options.length ; i++ ) { + const permission = permission_options[i]; + permission_options[i] = + await a.icall('get_higher_permissions', permission); + if ( permission_options[i].length > 1 ) { + reading.push({ + $: 'explode', + from: permission, + to: permission_options[i], + }); + } + } + a.set('permission_options', permission_options.flat()); }, async function run_scanners (a) { const scanners = PERMISSION_SCANNERS; diff --git a/src/backend/src/unstructured/permission-scanners.js b/src/backend/src/unstructured/permission-scanners.js index c0d3deb06..4ed86363c 100644 --- a/src/backend/src/unstructured/permission-scanners.js +++ b/src/backend/src/unstructured/permission-scanners.js @@ -10,9 +10,11 @@ const PERMISSION_SCANNERS = [ name: 'implied', async scan (a) { const reading = a.get('reading'); - const { actor, permission } = a.values(); + const { actor, permission_options } = a.values(); const _permission_implicators = a.iget('_permission_implicators'); + + for ( const permission of permission_options ) for ( const implicator of _permission_implicators ) { if ( ! implicator.matches(permission) ) { continue; @@ -24,8 +26,9 @@ const PERMISSION_SCANNERS = [ if ( implied ) { reading.push({ $: 'option', + permission, source: 'implied', - by: `implicator:${implicator.id}`, + by: implicator.id, data: implied, }); } @@ -74,6 +77,7 @@ const PERMISSION_SCANNERS = [ reading.push({ $: 'path', via: 'user', + permission: row.permission, // issuer: issuer_actor, issuer_username: issuer_actor.type.user.username, reading: issuer_reading, @@ -119,6 +123,7 @@ const PERMISSION_SCANNERS = [ $: 'path', via: 'user-group', // issuer: issuer_actor, + permission: row.permission, issuer_username: issuer_actor.type.user.username, reading: issuer_reading, group_id: row.group_id, @@ -158,6 +163,7 @@ const PERMISSION_SCANNERS = [ if ( implicit_permissions[permission] ) { reading.push({ $: 'option', + permission, source: 'implied', by: 'user-app-hc-2', data: implicit_permissions[permission], @@ -189,6 +195,7 @@ const PERMISSION_SCANNERS = [ reading.push({ $: 'path', via: 'user-app', + permission: row.permission, issuer_username: actor.type.user.username, reading: issuer_reading, });