User:Kevin Reid/Offline delegation
From Erights
(Difference between revisions)
(link to mailing list message) |
Kevin Reid (Talk | contribs) (publishing offline delegation attempt #2) |
||
| Line 1: | Line 1: | ||
| - | |||
| - | |||
<pre> | <pre> | ||
# Copyright 2008 Kevin Reid, under the terms of the MIT X license | # Copyright 2008 Kevin Reid, under the terms of the MIT X license | ||
| Line 54: | Line 52: | ||
} | } | ||
| - | /** Turn an object whose methods take an extra argument for the delegation chain into a | + | /** Turn an object whose methods take an extra argument for the delegation chain into a certificate. */ |
def exportOD(handler) { | def exportOD(handler) { | ||
def rootSigner := makeSigner("export root") | def rootSigner := makeSigner("export root") | ||
Revision as of 16:59, 30 May 2008
# 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 certificate. */
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"))

