mirror of
https://github.com/HeyPuter/puter.git
synced 2025-02-02 23:28:39 +08:00
fix: fix permission cascade properly this time
This commit is contained in:
parent
10cbf08233
commit
de5886698e
@ -34,7 +34,7 @@ const APIError = require('../api/APIError.js');
|
||||
const { LLMkdir } = require('./ll_operations/ll_mkdir.js');
|
||||
const { LLCWrite, LLOWrite } = require('./ll_operations/ll_write.js');
|
||||
const { LLCopy } = require('./ll_operations/ll_copy.js');
|
||||
const { PermissionUtil, PermissionRewriter, PermissionImplicator } = require('../services/auth/PermissionService.js');
|
||||
const { PermissionUtil, PermissionRewriter, PermissionImplicator, PermissionExploder } = require('../services/auth/PermissionService.js');
|
||||
const { DB_WRITE } = require("../services/database/consts");
|
||||
const { UserActorType } = require('../services/auth/Actor');
|
||||
const { get_user } = require('../helpers');
|
||||
@ -165,38 +165,34 @@ class FilesystemService extends AdvancedBase {
|
||||
return undefined;
|
||||
},
|
||||
}));
|
||||
svc_permission.register_implicator(PermissionImplicator.create({
|
||||
svc_permission.register_exploder(PermissionExploder.create({
|
||||
matcher: permission => {
|
||||
return permission.startsWith('fs:');
|
||||
return permission.startsWith('fs:') &&
|
||||
PermissionUtil.split(permission).length >= 3;
|
||||
},
|
||||
checker: async ({ actor, permission, recurse }) => {
|
||||
exploder: async ({ permission }) => {
|
||||
const permissions = [permission];
|
||||
const parts = PermissionUtil.split(permission);
|
||||
if ( parts.length < 3 ) return undefined;
|
||||
|
||||
const specified_mode = parts[2];
|
||||
|
||||
const mode = {
|
||||
write: 'read',
|
||||
read: 'list',
|
||||
list: 'see',
|
||||
}[specified_mode];
|
||||
const rules = {
|
||||
see: ['list', 'read', 'write'],
|
||||
list: ['read', 'write'],
|
||||
read: ['write'],
|
||||
};
|
||||
|
||||
if ( ! mode ) return undefined;
|
||||
|
||||
const perm = await recurse(actor,
|
||||
PermissionUtil.join(
|
||||
parts[0],
|
||||
parts[1],
|
||||
mode,
|
||||
...parts.slice(3),
|
||||
)
|
||||
)
|
||||
if ( perm ) {
|
||||
console.log('RETURNING IT!', perm);
|
||||
return perm;
|
||||
if ( rules.hasOwnProperty(specified_mode) ) {
|
||||
permissions.push(...rules[specified_mode].map(
|
||||
mode => PermissionUtil.join(
|
||||
parts[0], parts[1],
|
||||
mode,
|
||||
...parts.slice(3),
|
||||
)
|
||||
));
|
||||
}
|
||||
|
||||
return undefined;
|
||||
return permissions;
|
||||
},
|
||||
}));
|
||||
}
|
||||
|
@ -108,7 +108,8 @@ class ACLService extends BaseService {
|
||||
|
||||
const svc_permission = await context.get('services').get('permission');
|
||||
|
||||
const modes = this._higher_modes(mode);
|
||||
// const modes = this._higher_modes(mode);
|
||||
const modes = [mode];
|
||||
let perm_fsNode = fsNode;
|
||||
while ( ! await perm_fsNode.get('is-root') ) {
|
||||
for ( const mode of modes ) {
|
||||
|
@ -135,6 +135,32 @@ class PermissionImplicator {
|
||||
}
|
||||
}
|
||||
|
||||
class PermissionExploder {
|
||||
static create ({ id, matcher, exploder }) {
|
||||
return new PermissionExploder({ id, matcher, exploder });
|
||||
}
|
||||
|
||||
constructor ({ id, matcher, exploder }) {
|
||||
this.id = id;
|
||||
this.matcher = matcher;
|
||||
this.exploder = exploder;
|
||||
}
|
||||
|
||||
matches (permission) {
|
||||
return this.matcher(permission);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the permission is implied by this implicator
|
||||
* @param {Actor} actor
|
||||
* @param {string} permission
|
||||
* @returns
|
||||
*/
|
||||
async explode ({ actor, permission }) {
|
||||
return await this.exploder({ actor, permission });
|
||||
}
|
||||
}
|
||||
|
||||
class PermissionUtil {
|
||||
static unescape_permission_component (component) {
|
||||
let unescaped_str = '';
|
||||
@ -194,6 +220,7 @@ class PermissionService extends BaseService {
|
||||
|
||||
this._permission_rewriters = [];
|
||||
this._permission_implicators = [];
|
||||
this._permission_exploders = [];
|
||||
}
|
||||
|
||||
async _rewrite_permission (permission) {
|
||||
@ -220,6 +247,17 @@ class PermissionService extends BaseService {
|
||||
actor: actor.uid,
|
||||
permission,
|
||||
});
|
||||
|
||||
// for ( const implicator of this._permission_implicators ) {
|
||||
// if ( ! implicator.matches(permission) ) continue;
|
||||
// const implied = await implicator.check({
|
||||
// actor,
|
||||
// permission,
|
||||
// recurse: this.check.bind(this),
|
||||
// });
|
||||
// if ( implied ) return implied;
|
||||
// }
|
||||
|
||||
// For now we're only checking driver permissions, and users have all of them
|
||||
if ( actor.type instanceof UserActorType ) {
|
||||
return await this.check_user_permission(actor, permission);
|
||||
@ -240,8 +278,17 @@ class PermissionService extends BaseService {
|
||||
// NEXT:
|
||||
const app_uid = actor.type.app.uid;
|
||||
const user_actor = actor.get_related_actor(UserActorType);
|
||||
const user_has_permission = await this.check_user_permission(user_actor, permission);
|
||||
// const user_has_permission = await this.check_user_permission(user_actor, permission);
|
||||
const user_has_permission = await this.check__(
|
||||
user_actor, permission,
|
||||
);
|
||||
if ( ! user_has_permission ) return undefined;
|
||||
|
||||
// This was a useful log so I'm keeping it here
|
||||
// console.log('\x1B[36;1m>=== THIS IS HERE ===<\x1B[0m',
|
||||
// app_uid,
|
||||
// permission,
|
||||
// )
|
||||
|
||||
return await this.check_user_app_permission(actor, app_uid, permission);
|
||||
}
|
||||
@ -252,7 +299,8 @@ class PermissionService extends BaseService {
|
||||
// TODO: context meta for cycle detection
|
||||
async check_user_permission (actor, permission) {
|
||||
permission = await this._rewrite_permission(permission);
|
||||
const parent_perms = this.get_parent_permissions(permission);
|
||||
// const parent_perms = this.get_parent_permissions(permission);
|
||||
const parent_perms = await this.get_higher_permissions(permission);
|
||||
|
||||
// Check implicit permissions
|
||||
for ( const parent_perm of parent_perms ) {
|
||||
@ -329,7 +377,8 @@ class PermissionService extends BaseService {
|
||||
if ( ! app ) app = await get_app({ name: app_uid });
|
||||
const app_id = app.id;
|
||||
|
||||
const parent_perms = this.get_parent_permissions(permission);
|
||||
// const parent_perms = this.get_parent_permissions(permission);
|
||||
const parent_perms = await this.get_higher_permissions(permission);
|
||||
|
||||
for ( const permission of parent_perms ) {
|
||||
// Check hardcoded permissions
|
||||
@ -348,7 +397,7 @@ class PermissionService extends BaseService {
|
||||
return implicit_permissions[permission];
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// My biggest gripe with SQL is doing string manipulation for queries.
|
||||
// If the grammar for SQL was simpler we could model it, write this as
|
||||
// data, and even implement macros for common patterns.
|
||||
@ -665,6 +714,21 @@ class PermissionService extends BaseService {
|
||||
|
||||
return retval;
|
||||
}
|
||||
|
||||
async get_higher_permissions (permission) {
|
||||
const higher_perms = [];
|
||||
const parent_perms = this.get_parent_permissions(permission);
|
||||
for ( const parent_perm of parent_perms ) {
|
||||
for ( const exploder of this._permission_exploders ) {
|
||||
if ( ! exploder.matches(parent_perm) ) continue;
|
||||
const perms = await exploder.explode({
|
||||
permission: parent_perm,
|
||||
});
|
||||
higher_perms.push(...perms);
|
||||
}
|
||||
}
|
||||
return higher_perms;
|
||||
}
|
||||
|
||||
get_parent_permissions (permission) {
|
||||
const parent_perms = [];
|
||||
@ -699,6 +763,14 @@ class PermissionService extends BaseService {
|
||||
this._permission_implicators.push(implicator);
|
||||
}
|
||||
|
||||
register_exploder (exploder) {
|
||||
if ( ! (exploder instanceof PermissionExploder) ) {
|
||||
throw new Error('exploder must be a PermissionExploder');
|
||||
}
|
||||
|
||||
this._permission_exploders.push(exploder);
|
||||
}
|
||||
|
||||
_register_commands (commands) {
|
||||
commands.registerCommands('perms', [
|
||||
{
|
||||
@ -723,6 +795,7 @@ class PermissionService extends BaseService {
|
||||
module.exports = {
|
||||
PermissionRewriter,
|
||||
PermissionImplicator,
|
||||
PermissionExploder,
|
||||
PermissionUtil,
|
||||
PermissionService,
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user