User:Kevin Reid/Offline delegation

Mailing list post of this:


 * 1) Copyright 2008 Kevin Reid, under the terms of the MIT X license
 * 2) found at http://www.opensource.org/licenses/mit-license.html ................

pragma.syntax("0.9")


 * 1) --- Utilities ---

def makeProxy :=  def makeBrand := 

def everything { to contains(_) { return true } }


 * 1) --- Signing ---

interface ::"Signed" guards SignedStamp {}

def makeSigner(label) { def who { to __printOn(out) { out.print("<", label, ">") } }  def signer { to __printOn(out) { out.print("") }   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] }


 * 1) --- 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) }


 * 1) --- 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"))