dev: remove svc_permission.check

This commit is contained in:
KernelDeimos 2024-07-23 19:34:12 -04:00 committed by Eric Dubé
parent 191be84e32
commit cca19ad495
2 changed files with 0 additions and 320 deletions

View File

@ -188,15 +188,6 @@ class PermissionService extends BaseService {
return permission;
}
async check () {
const ld = (Context.get('logdent') ?? 0) + 1;
return await Context.get().sub({ logdent: ld }).arun(async () => {
const res = await this.check__(...arguments);
// this.log.noticeme('RETURN ' + res);
return res;
});
}
async scan (actor, permission_options) {
const reading = [];
@ -214,171 +205,6 @@ class PermissionService extends BaseService {
return reading;
}
async check__ (actor, permission) {
permission = await this._rewrite_permission(permission);
this.log.info(`checking permission ${permission} for actor ${actor.uid}`, {
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);
}
if ( actor.type instanceof AccessTokenActorType ) {
// Authorizer must have permission
const authorizer_permission = await this.check(actor.type.authorizer, permission);
if ( ! authorizer_permission ) return false;
return await this.check_access_token_permission(
actor.type.authorizer, actor.type.token, permission
);
}
// Prevent undefined behaviour
if ( actor.type instanceof AppUnderUserActorType ) {
// 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_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);
}
if ( actor.type instanceof SiteActorType ) {
return await this.check_site_permission(actor, permission);
}
console.log ('WHAT ACTOR TYPE THEN???', actor.type);
throw new Error('unrecognized actor type');
}
// TODO: context meta for cycle detection
async check_user_permission (actor, permission) {
return await require('../../structured/sequence/check-user-permission')
.call(this, {
// passed
actor,
permission,
// constants
implicit_user_permissions,
});
}
async check_access_token_permission (authorizer, token, permission) {
const rows = await this.db.read(
'SELECT * FROM `access_token_permissions` ' +
'WHERE `token_uid` = ? AND `permission` = ?',
[
token,
permission,
]
);
// Token must have permission
if ( ! rows[0] ) return undefined;
return rows[0].extra;
}
async check_user_app_permission (actor, app_uid, permission) {
permission = await this._rewrite_permission(permission);
let app = await get_app({ uid: app_uid });
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 = await this.get_higher_permissions(permission);
for ( const permission of parent_perms ) {
// Check hardcoded permissions
if ( default_implicit_user_app_permissions[permission] ) {
return default_implicit_user_app_permissions[permission];
}
// Check implicit permissions
const implicit_permissions = {};
for ( const implicit_permission of implicit_user_app_permissions ) {
if ( implicit_permission.apps.includes(app_uid) ) {
implicit_permissions[permission] = implicit_permission.permissions[permission];
}
}
if ( implicit_permissions[permission] ) {
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.
let sql_perm = parent_perms.map((perm) =>
`\`permission\` = ?`).join(' OR ');
if ( parent_perms.length > 1 ) sql_perm = '(' + sql_perm + ')';
// SELECT permission
const rows = await this.db.read(
'SELECT * FROM `user_to_app_permissions` ' +
'WHERE `user_id` = ? AND `app_id` = ? AND ' +
sql_perm,
[
actor.type.user.id,
app_id,
...parent_perms,
]
);
if ( ! rows[0] ) return undefined;
return rows[0].extra;
}
async check_site_permission (actor, permission) {
permission = await this._rewrite_permission(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 ) {
if ( implicit_user_permissions[parent_perm] ) {
return implicit_user_permissions[parent_perm];
}
}
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;
}
}
async grant_user_app_permission (actor, app_uid, permission, extra = {}, meta) {
permission = await this._rewrite_permission(permission);

View File

@ -1,146 +0,0 @@
/*
* Copyright (C) 2024 Puter Technologies Inc.
*
* This file is part of Puter.
*
* Puter is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as published
* by the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <https://www.gnu.org/licenses/>.
*/
const { Sequence } = require("../../codex/Sequence");
const { get_user } = require("../../helpers");
const { Actor, UserActorType } = require("../../services/auth/Actor");
module.exports = new Sequence([
async function grant_if_system (a) {
const { actor } = a.values();
if ( actor.type.user.username === 'system' ) {
return a.stop({});
}
},
async function rewrite_permission (a) {
let { permission } = a.values();
permission = await a.icall('_rewrite_permission', permission);
a.values({ permission });
},
async function explode_permission (a) {
const { permission } = a.values();
const permission_options =
await a.icall('get_higher_permissions', permission);
a.values({ permission_options });
},
async function try_hardcoded_permission (a) {
const {
permission_options,
implicit_user_permissions
} = a.values();
for ( const perm of permission_options ) {
if ( implicit_user_permissions[perm] ) {
return a.stop(implicit_user_permissions[perm]);
}
}
},
async function try_permission_implicators (a) {
// NOTE: it's really weird that we check `permission` only and not
// the `permission_options` list here. I haven't changed this
// to avoid regressions but it's something to consider.
const { actor, permission } = a.values();
const _permission_implicators = a.iget('_permission_implicators');
for ( const implicator of _permission_implicators ) {
if ( ! implicator.matches(permission) ) continue;
const implied = await implicator.check({
actor,
permission,
recurse: this.check.bind(this),
});
if ( implied ) {
return a.stop(implied);
}
}
},
async function try_user_to_user_permissions (a) {
const { actor, permission_options } = a.values();
const db = a.iget('db');
let sql_perm = permission_options.map((perm) =>
`\`permission\` = ?`).join(' OR ');
if ( permission_options.length > 1 ) {
sql_perm = '(' + sql_perm + ')';
}
// SELECT permission
const rows = await db.read(
'SELECT * FROM `user_to_user_permissions` ' +
'WHERE `holder_user_id` = ? AND ' +
sql_perm,
[
actor.type.user.id,
...permission_options,
]
);
// Return the first matching permission where the
// issuer also has the permission granted
for ( const row of rows ) {
const issuer_actor = new Actor({
type: new UserActorType({
user: await get_user({ id: row.issuer_user_id }),
}),
});
// const issuer_perm = await this.check(issuer_actor, row.permission);
const issuer_perm = await a.icall('check', issuer_actor, row.permission);
if ( ! issuer_perm ) continue;
return a.stop(row.extra);
}
},
async function try_user_to_group_permissions (a) {
const { actor, permission_options } = a.values();
const db = a.iget('db');
let sql_perm = permission_options.map((perm) =>
`p.permission = ?`).join(' OR ');
if ( permission_options.length > 1 ) {
sql_perm = '(' + sql_perm + ')';
}
const rows = await db.read(
'SELECT p.permission, p.user_id, p.extra FROM `user_to_group_permissions` p ' +
'JOIN `jct_user_group` ug ON p.group_id = ug.group_id ' +
'WHERE ug.user_id = ? AND ' + sql_perm,
[
actor.type.user.id,
...permission_options,
]
);
for ( const row of rows ) {
const issuer_actor = new Actor({
type: new UserActorType({
user: await get_user({ id: row.user_id }),
}),
});
const issuer_perm = await a.icall('check', issuer_actor, row.permission);
if ( ! issuer_perm ) continue;
return a.stop(row.extra);
}
}
]);