mirror of https://github.com/perkeep/perkeep.git
publish work: optionally create publish root permanodes+claims on start
Change-Id: I8659e977cea8872443ff2b311a7d0d8a2804c269
This commit is contained in:
parent
494d57cb4a
commit
23ff0a071f
|
@ -1 +1 @@
|
|||
6g version weekly.2011-06-16 8838+
|
||||
6g version weekly.2011-06-16 8858+
|
||||
|
|
|
@ -14,9 +14,9 @@
|
|||
"handlerArgs": {
|
||||
"rootName": "dev-blog-root",
|
||||
"blobRoot": "/bs/",
|
||||
"createPermanodeIfNeeded": true,
|
||||
"searchRoot": "/my-search/",
|
||||
"cache": "/cache/"
|
||||
"cache": "/cache/",
|
||||
"devBootstrapPermanodeUsing": "/sighelper/"
|
||||
}
|
||||
},
|
||||
|
||||
|
@ -25,9 +25,9 @@
|
|||
"handlerArgs": {
|
||||
"rootName": "dev-pics-root",
|
||||
"blobRoot": "/bs/",
|
||||
"createPermanodeIfNeeded": true,
|
||||
"searchRoot": "/my-search/",
|
||||
"cache": "/cache/"
|
||||
"cache": "/cache/",
|
||||
"devBootstrapPermanodeUsing": "/sighelper/"
|
||||
}
|
||||
},
|
||||
|
||||
|
|
|
@ -216,13 +216,14 @@ func (mi *Indexer) populateClaim(client *mysql.Client, blobRef *blobref.BlobRef,
|
|||
}
|
||||
|
||||
if verifiedKeyId != "" {
|
||||
// TODO: limit this to only certain attributes (for now, just "camliRoot") once search handler
|
||||
// is working and the UI permits setting camliRoot.
|
||||
if err = execSQL(client, "INSERT IGNORE INTO signerattrvalue (keyid, attr, value, claimdate, blobref, permanode) "+
|
||||
"VALUES (?, ?, ?, ?, ?, ?)",
|
||||
verifiedKeyId, camli.Attribute, camli.Value,
|
||||
camli.ClaimDate, blobRef.String(), camli.Permanode); err != nil {
|
||||
return
|
||||
switch camli.Attribute {
|
||||
case "camliRoot":
|
||||
if err = execSQL(client, "INSERT IGNORE INTO signerattrvalue (keyid, attr, value, claimdate, blobref, permanode) "+
|
||||
"VALUES (?, ?, ?, ?, ?, ?)",
|
||||
verifiedKeyId, camli.Attribute, camli.Value,
|
||||
camli.ClaimDate, blobRef.String(), camli.Permanode); err != nil {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -67,6 +67,15 @@ func newHandlerFromConfig(ld blobserver.Loader, conf jsonconfig.Obj) (http.Handl
|
|||
}, nil
|
||||
}
|
||||
|
||||
// TODO: figure out a plan for an owner having multiple active public keys, or public
|
||||
// key rotation
|
||||
func (h *Handler) Owner() *blobref.BlobRef {
|
||||
return h.owner
|
||||
}
|
||||
|
||||
func (h *Handler) Index() Index {
|
||||
return h.index
|
||||
}
|
||||
|
||||
func jsonMap() map[string]interface{} {
|
||||
return make(map[string]interface{})
|
||||
|
|
|
@ -20,10 +20,13 @@ import (
|
|||
"fmt"
|
||||
"html"
|
||||
"http"
|
||||
"log"
|
||||
"os"
|
||||
|
||||
"camli/blobserver"
|
||||
"camli/client" // just for NewUploadHandleFromString. move elsewhere?
|
||||
"camli/jsonconfig"
|
||||
"camli/schema"
|
||||
"camli/search"
|
||||
)
|
||||
|
||||
|
@ -46,7 +49,7 @@ func newPublishFromConfig(ld blobserver.Loader, conf jsonconfig.Obj) (h http.Han
|
|||
blobRoot := conf.RequiredString("blobRoot")
|
||||
searchRoot := conf.RequiredString("searchRoot")
|
||||
cachePrefix := conf.OptionalString("cache", "")
|
||||
createPermanode := conf.OptionalBool("createPermanodeIfNeeded", false)
|
||||
bootstrapSignRoot := conf.OptionalString("devBootstrapPermanodeUsing", "")
|
||||
if err = conf.Validate(); err != nil {
|
||||
return
|
||||
}
|
||||
|
@ -65,10 +68,22 @@ func newPublishFromConfig(ld blobserver.Loader, conf jsonconfig.Obj) (h http.Han
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("publish handler's searchRoot of %q error: %v", searchRoot, err)
|
||||
}
|
||||
pub.Search = si.(*search.Handler) // TODO: don't crash here if wrong type; return error
|
||||
var ok bool
|
||||
pub.Search, ok = si.(*search.Handler)
|
||||
if !ok {
|
||||
return nil, fmt.Errorf("publish handler's searchRoot of %q is of type %T, expecting a search handler",
|
||||
searchRoot, si)
|
||||
}
|
||||
|
||||
if createPermanode {
|
||||
// ... TODO
|
||||
if bootstrapSignRoot != "" {
|
||||
if t := ld.GetHandlerType(bootstrapSignRoot); t != "jsonsign" {
|
||||
return nil, fmt.Errorf("publish handler's devBootstrapPermanodeUsing must be of type jsonsign")
|
||||
}
|
||||
h, _ := ld.GetHandler(bootstrapSignRoot)
|
||||
jsonSign := h.(*JSONSignHandler)
|
||||
if err := pub.bootstrapPermanode(jsonSign); err != nil {
|
||||
return nil, fmt.Errorf("error bootstrapping permanode: %v", err)
|
||||
}
|
||||
}
|
||||
|
||||
if cachePrefix != "" {
|
||||
|
@ -86,6 +101,45 @@ func (pub *PublishHandler) ServeHTTP(rw http.ResponseWriter, req *http.Request)
|
|||
base := req.Header.Get("X-PrefixHandler-PathBase")
|
||||
suffix := req.Header.Get("X-PrefixHandler-PathSuffix")
|
||||
|
||||
fmt.Fprintf(rw, "I am publish handler at base %q, serving root %q, suffix %q",
|
||||
base, pub.RootName, html.EscapeString(suffix))
|
||||
pn, err := pub.Search.Index().PermanodeOfSignerAttrValue(pub.Search.Owner(), "camliRoot", pub.RootName)
|
||||
if err != nil {
|
||||
rw.WriteHeader(404)
|
||||
fmt.Fprintf(rw, "Error: publish handler at base %q, serving root name %q has no configured permanode",
|
||||
base, pub.RootName)
|
||||
return
|
||||
}
|
||||
|
||||
fmt.Fprintf(rw, "I am publish handler at base %q, serving root %q (permanode=%s), suffix %q",
|
||||
base, pub.RootName, pn, html.EscapeString(suffix))
|
||||
}
|
||||
|
||||
func (pub *PublishHandler) bootstrapPermanode(jsonSign *JSONSignHandler) os.Error {
|
||||
if pn, err := pub.Search.Index().PermanodeOfSignerAttrValue(pub.Search.Owner(), "camliRoot", pub.RootName); err == nil {
|
||||
log.Printf("Publish root %q using existing permanode %s", pub.RootName, pn)
|
||||
return nil
|
||||
}
|
||||
log.Printf("Publish root %q needs a permanode + claim", pub.RootName)
|
||||
|
||||
// Step 1: create a permanode
|
||||
pn, err := jsonSign.SignMap(schema.NewUnsignedPermanode())
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating new permanode: %v", err)
|
||||
}
|
||||
ph := client.NewUploadHandleFromString(pn)
|
||||
_, err = pub.Storage.ReceiveBlob(ph.BlobRef, ph.Contents)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error uploading permanode: %v", err)
|
||||
}
|
||||
|
||||
// Step 2: addd a claim that the new permanode is the desired root.
|
||||
claim, err := jsonSign.SignMap(schema.NewSetAttributeClaim(ph.BlobRef, "camliRoot", pub.RootName))
|
||||
if err != nil {
|
||||
return fmt.Errorf("error creating claim: %v", err)
|
||||
}
|
||||
ch := client.NewUploadHandleFromString(claim)
|
||||
_, err = pub.Storage.ReceiveBlob(ch.BlobRef, ch.Contents)
|
||||
if err != nil {
|
||||
return fmt.Errorf("error uploading claim: %v", err)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import (
|
|||
"camli/httputil"
|
||||
"camli/jsonconfig"
|
||||
"camli/jsonsign"
|
||||
"camli/schema"
|
||||
)
|
||||
|
||||
var _ = log.Printf
|
||||
|
@ -229,3 +230,18 @@ func (h *JSONSignHandler) handleSign(rw http.ResponseWriter, req *http.Request)
|
|||
}
|
||||
rw.Write([]byte(signedJson))
|
||||
}
|
||||
|
||||
func (h *JSONSignHandler) SignMap(m map[string]interface{}) (string, os.Error) {
|
||||
m["camliSigner"] = h.pubKeyBlobRef.String()
|
||||
unsigned, err := schema.MapToCamliJson(m)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
sreq := &jsonsign.SignRequest{
|
||||
UnsignedJson: unsigned,
|
||||
Fetcher: h.pubKeyFetcher,
|
||||
ServerMode: true,
|
||||
SecretKeyringPath: h.secretRing,
|
||||
}
|
||||
return sreq.Sign()
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue