func (this *ApiMgr) addWriter(w http.ResponseWriter, req *http.Request) { vars := mux.Vars(req) cid := vars["cid"] var keystr string if !this.decodeJsonBody(w, req, &keystr) { return } var pubkey *crypto.PublicIdentity err := transfer.DecodeString(keystr, &pubkey) if err != nil { this.sendError(w, http.StatusBadRequest, "Invalid public key") return } owner := this.GetOwner(cid) if owner == nil { this.sendError(w, http.StatusNotFound, "Collection invalid") return } if owner.Fingerprint().String() != this.Ident.Public().Fingerprint().String() { this.sendError(w, http.StatusUnauthorized, "You are not the owner of the collection") return } this.AddWriter(cid, this.Ident, pubkey) this.sendJson(w, "/collections/"+cid+"/writers/"+pubkey.Fingerprint().String()) }
// Adds/Removes a writer. If a writer is removed, records from that writer may be out of sync func (this *MetaMgr) AddWriter(cid string, owner *crypto.SecretIdentity, writer *crypto.PublicIdentity) { // Setup some variables key := writer.Fingerprint().String() priority := 0 // Default priority is 0, otherwise, current + 1 newValue := transfer.AsBytes(writer) // Check current writer state rec := this.SyncMgr.Get(sync.RTWriter, cid, key) if rec != nil { // If no change, leave alone if bytes.Equal(rec.Value, newValue) { return } // Otherwise, override old priority priority = rec.Priority + 1 } // Add the record wrr := &sync.Record{ RecordType: sync.RTWriter, Topic: cid, Key: key, Priority: priority, Value: newValue, } signRecord(wrr, owner) this.SyncMgr.Put(wrr) }
func verifyRecord(rec *sync.Record, writer *crypto.PublicIdentity) bool { hash := crypto.HashOf(rec.RecordType, rec.Topic, rec.Key, rec.Value, rec.Priority) var sig *crypto.Signature err := transfer.DecodeBytes(rec.Signature, &sig) if err != nil { panic(err) } return writer.Verify(hash, sig) }
func (this *MetaMgr) onWriter(who int, remote *crypto.Digest, rec *sync.Record) { this.Log.Printf("Processing Writer") // Verify the basis basisRec := this.SyncMgr.Get(sync.RTBasis, rec.Topic, "$") owner := this.decodeBasis(basisRec, false) if owner == nil { this.Log.Printf("Getting record before basis, ignoring") return } // Validate the incoming writer record is valid var checkit *crypto.PublicIdentity err := transfer.DecodeBytes(rec.Value, &checkit) if err != nil { this.Log.Printf("Writer record is misformed: %s", err) return } if checkit.Fingerprint().String() != rec.Key { this.Log.Printf("Writer record is misformed, key != hash") return } this.verifyUpdate(rec, owner) }