User:Kevin Reid/Offline delegation
From Erights
< User:Kevin Reid
Revision as of 21:44, 22 November 2010 by Kevin Reid (Talk)
Mailing list post of this: [1]
# Copyright 2008 Kevin Reid, under the terms of the MIT X license # found at http://www.opensource.org/licenses/mit-license.html ................ pragma.syntax("0.9") # --- Utilities --- def makeProxy := <elib:ref.makeProxy> def makeBrand := <elib:sealing.makeBrand> def everything { to contains(_) { return true } } # --- Signing --- interface ::"Signed" guards SignedStamp {} def makeSigner(label) { def who { to __printOn(out) { out.print("<", label, ">") } } def signer { to __printOn(out) { out.print("<signing as ", label, ">") } to who() { return who } to run(what) { def ::"signed" implements SignedStamp { to _who() { return who } to _get() { return what } } return ::"signed" } } return signer } def verifyAndGet(::"signed" : ::"Signed") { return [::"signed"._get(), ::"signed"._who()] } # --- Operations --- def ::"delegate"(scap, filter, note) { def [cert, signer, host] := scap def newSigner := makeSigner(note) return [signer(["delegate", cert, newSigner.who(), filter]), newSigner, host] } /** Turn an object whose methods take an extra argument for the delegation chain into a scap. */ def exportOD(handler) { def rootSigner := makeSigner("export root") def handleMessage(delegators, verb :String, args :List, cert) { def [[=="delegate", prevCert, whoTo, filter], whoBy] := verifyAndGet(cert) if (!filter.contains(verb)) { throw(`$verb not permitted by $whoBy`) } def delegators1 := delegators.with(whoTo) return if (whoBy != rootSigner.who()) { handleMessage(delegators1, verb, args, prevCert) } else { E.call(handler, verb, [delegators1] + args) } } def host(verb, args, cert) { handleMessage([], verb, args, cert) } return [rootSigner(["delegate", Ref.broken("n/a"), rootSigner.who(), everything]), rootSigner, host] } /** Turn a scap into a normal invokable reference. */ def importOD(scap) { def [cert, signer, host] := scap return makeProxy(def handler { to handleSend(verb, args) { return host <- (verb, args, cert) } to handleSendOnly(verb, args) { return host <- (verb, args, cert) } to handleOptSealedDispatch(_) {} }, Ref.whenBroken(host, fn _ {Ref.optProblem(host)}), true) } # --- Example --- def carol(x) { def xr := importOD(x) xr <- hello("world") } def bob(x) { def xr := importOD(x) when ( carol <- (::"delegate"(x, ["hello"].asSet(), "Carol")) ) -> { xr <- goodbye() } } def alice(x) { bob <- (::"delegate"(x, ["hello", "goodbye"].asSet(), "Bob")) } def root := exportOD(def root0 { to hello(chain, greeted) { println(chain, " greeted ", greeted) } to goodbye(chain) { println(chain, " said goodbye") } }) alice(::"delegate"(root, ["hello", "goodbye"].asSet(), "Alice"))