SturdyRef gatekeeper

This commit is contained in:
Tony Garnock-Jones 2021-03-04 22:08:49 +01:00
parent 1c7e68f461
commit 26582f2799
4 changed files with 70 additions and 11 deletions

View File

@ -340,7 +340,10 @@ export interface RelayActorOptions extends RelayOptions {
nextLocalOid?: Oid;
}
export function spawnRelay(t: Turn, options: RelayActorOptions): Promise<Ref | null> {
export function spawnRelay(t: Turn, options: RelayActorOptions & {initialOid: Oid}): Promise<Ref>;
export function spawnRelay(t: Turn, options: Omit<RelayActorOptions, 'initialOid'>): Promise<null>;
export function spawnRelay(t: Turn, options: RelayActorOptions): Promise<Ref | null>
{
return new Promise(resolve => {
t.spawn(t => {
const relay = new Relay(t, options);

View File

@ -1,9 +1,13 @@
import { Actor, Ref, Turn } from "./actor.js";
import { Actor, Assertion, Ref, Turn } from "./actor.js";
import { Relay, spawnRelay } from "./relay.js";
import { sturdyDecode } from "./sturdy.js";
import { Observe } from "./dataspace.js";
import * as net from 'net';
import { Bytes } from "preserves";
const [ moduleName ] = process.argv.slice(2);
const [ moduleName, hexCap ] = process.argv.slice(2);
const cap = sturdyDecode(Bytes.fromHex(hexCap ?? ''));
const socket = net.createConnection({ port: 5999, host: 'localhost' }, () => {
Turn.for(new Actor(), t => {
@ -23,9 +27,13 @@ const socket = net.createConnection({ port: 5999, host: 'localhost' }, () => {
},
initialOid: 0,
// debug: true,
}).then(ds => import(moduleName).then(m => t.freshen(t => {
}).then(gatekeeper => import(moduleName).then(m => t.freshen(t => {
t.assert(shutdownRef, true);
m.default(t, ds);
t.assert(gatekeeper, Observe(cap as Assertion, t.ref({
assert(t, ds) {
m.default(t, ds);
}
})));
})));
});
});

View File

@ -1,8 +1,28 @@
import { Actor, Turn } from './actor.js';
import { Dataspace } from './dataspace.js';
import { Actor, Handle, Turn } from './actor.js';
import { Dataspace, Observe } from './dataspace.js';
import { Relay, spawnRelay } from './relay.js';
import * as net from 'net';
import { Caveat, mint, Or, Rewrite, sturdyEncode, SturdyRef, validate, _Or, _Rewrite } from './sturdy.js';
import { KEY_LENGTH } from './cryptography.js';
import { attenuate, Attenuation } from './rewrite.js';
import { Bytes, IdentityMap } from 'preserves';
const secretKey = new Bytes(KEY_LENGTH);
mint('syndicate', secretKey).then(v => {
console.log(v.asPreservesText());
console.log(sturdyEncode(v).toHex());
});
function internalize(caveatChain: Caveat[][]): Attenuation {
const a: Attenuation = [];
caveatChain.slice().reverse().forEach(cs => a.push(... cs.map(c => {
const alts = c.label === _Rewrite ? [c] : Or<Rewrite>()._.alternatives(c);
return alts.map(r => ({ pattern: Rewrite._.pattern(r), template: Rewrite._.template(r) }));
})));
return a;
}
Turn.for(new Actor(), t => {
const ds = t.ref(new Dataspace());
@ -18,7 +38,28 @@ Turn.for(new Actor(), t => {
socket.on('data', data => r.accept(data));
t.actor.atExit(() => socket.destroy());
},
initialRef: ds,
initialRef: t.ref({
handleMap: new IdentityMap<Handle, Handle>(),
async assert(t, a, h) {
if (!Observe.isClassOf(a)) return;
const r = Observe._.label(a);
if (!SturdyRef.isClassOf(r)) return;
if (!await validate(r, secretKey)) {
console.warn(`Invalid SturdyRef: ${r.asPreservesText()}`);
return;
}
const attenuated_ds = attenuate(
ds,
... internalize(SturdyRef._.caveatChain(r)));
t.freshen(t => this.handleMap.set(
h,
t.assert(Observe._.observer(a), attenuated_ds)));
},
retract(t, h) {
t.retract(this.handleMap.get(h));
this.handleMap.delete(h);
}
}),
// debug: true,
});
}

View File

@ -7,10 +7,10 @@
// California: Internet Society, 2014.
import { mac } from './cryptography.js';
import { Bytes, encode, is, Record, Value } from 'preserves';
import { Bytes, decode, encode, is, Record, Value } from 'preserves';
import type { Pattern, Template } from './rewrite.js';
export type EmbeddedRef = { ref: SturdyRef };
export type EmbeddedRef = never;
export type SturdyValue = Value<EmbeddedRef>;
export const _SturdyRef = Symbol.for('sturdyref');
@ -44,7 +44,14 @@ export function sturdyEncode(v: SturdyValue): Bytes {
return encode<EmbeddedRef>(v, {
canonical: true,
includeAnnotations: false,
encodePointer(v) { return v },
encodePointer() { throw new Error("EmbeddedRef not permitted in SturdyRef"); },
});
}
export function sturdyDecode(bs: Bytes): SturdyValue {
return decode<EmbeddedRef>(bs, {
includeAnnotations: false,
decodePointer() { throw new Error("EmbeddedRef not permitted in SturdyRef"); },
});
}