dev: move policy selection to call_new_

This commit is contained in:
KernelDeimos
2024-07-25 19:59:45 -04:00
committed by Eric Dubé
parent ea409d1578
commit 780a993465
2 changed files with 61 additions and 81 deletions

View File

@@ -23,7 +23,6 @@ const { TypedValue } = require("./meta/Runtime");
const BaseService = require("../BaseService");
const { Driver } = require("../../definitions/Driver");
const { PermissionUtil } = require("../auth/PermissionService");
const { PolicyEnforcer } = require("./PolicyEnforcer");
const { Invoker } = require("@heyputer/puter-js-common/src/libs/invoker");
/**
@@ -129,74 +128,12 @@ class DriverService extends BaseService {
})();
if ( driver_service_exists ) {
const service = this.services.get(driver);
const reading = await svc_permission.scan(
return await this.call_new_({
actor,
PermissionUtil.join('service', driver, 'ii', iface),
);
console.log({
perm: PermissionUtil.join('service', driver, 'ii', iface),
reading,
service,
service_name: driver,
iface, method, args: processed_args,
});
const options = PermissionUtil.reading_to_options(reading);
if ( options.length > 0 ) {
const option = await this.select_best_option_(options);
const policies = await this.get_policies_for_option_(option);
console.log('SLA', JSON.stringify(policies, undefined, ' '));
// NOT FINAL: For now we apply monthly usage logic
// to the first holder of the permission. Later this
// will be changed so monthly usage can cascade across
// multiple actors. I decided not to implement this
// immediately because it's a hefty time sink and it's
// going to be some time before we can offer this feature
// to the end-user either way.
let effective_policy = null;
for ( const policy of policies ) {
if ( policy.holder ) {
effective_policy = policy;
break;
}
}
if ( ! effective_policy ) {
throw new Error(
'policies with no effective user are not yet ' +
'supported'
);
}
// NOT FINAL: this will be handled by 'get_policies_for_option_'
// when cascading monthly usage is implemented.
const svc_systemData = this.services.get('system-data');
const svc_su = this.services.get('su');
effective_policy = await svc_su.sudo(async () => {
return await svc_systemData.interpret(effective_policy.data);
});
effective_policy = effective_policy.policy;
console.log('EFFECTIVE',
JSON.stringify(effective_policy, undefined, ' '));
const policy_enforcer = new PolicyEnforcer({
services: this.services,
actor,
policy: effective_policy,
driver, method,
});
await policy_enforcer.check();
const result = await this.call_new_({
service_name: driver,
service,
method,
args: processed_args,
iface,
});
await policy_enforcer.on_success();
return result;
}
}
const reading = await svc_permission.scan(actor, `driver:${iface}:${method}`);
@@ -279,10 +216,64 @@ class DriverService extends BaseService {
}
async call_new_ ({
actor,
service,
service_name,
service, method, args,
iface,
iface, method, args,
}) {
const svc_permission = this.services.get('permission');
const reading = await svc_permission.scan(
actor,
PermissionUtil.join('service', service_name, 'ii', iface),
);
console.log({
perm: PermissionUtil.join('service', service_name, 'ii', iface),
reading,
});
const options = PermissionUtil.reading_to_options(reading);
if ( options.length <= 0 ) {
throw APIError.create('forbidden');
}
const option = await this.select_best_option_(options);
const policies = await this.get_policies_for_option_(option);
console.log('SLA', JSON.stringify(policies, undefined, ' '));
// NOT FINAL: For now we apply monthly usage logic
// to the first holder of the permission. Later this
// will be changed so monthly usage can cascade across
// multiple actors. I decided not to implement this
// immediately because it's a hefty time sink and it's
// going to be some time before we can offer this feature
// to the end-user either way.
let effective_policy = null;
for ( const policy of policies ) {
if ( policy.holder ) {
effective_policy = policy;
break;
}
}
if ( ! effective_policy ) {
throw new Error(
'policies with no effective user are not yet ' +
'supported'
);
}
// NOT FINAL: this will be handled by 'get_policies_for_option_'
// when cascading monthly usage is implemented.
const svc_systemData = this.services.get('system-data');
const svc_su = this.services.get('su');
effective_policy = await svc_su.sudo(async () => {
return await svc_systemData.interpret(effective_policy.data);
});
effective_policy = effective_policy.policy;
console.log('EFFECTIVE',
JSON.stringify(effective_policy, undefined, ' '));
const invoker = Invoker.create({
decorators: [
{
@@ -322,7 +313,7 @@ class DriverService extends BaseService {
});
return await invoker.run(args);
}
async _driver_response_from_error (e, meta) {
let serializable = (e instanceof APIError) || (e instanceof DriverError);
if ( serializable ) {

View File

@@ -1,11 +0,0 @@
class PolicyEnforcer {
constructor (context) {
this.context = context;
}
async check () {}
async on_success () {}
async on_fail () {}
}
module.exports = { PolicyEnforcer };