Beispiel #1
0
func (self *channelAPI) Blob_Permission(perma grapher.PermaNode, permission grapher.PermissionNode) {
	mutJson := map[string]interface{}{"perma": perma.BlobRef(), "seq": permission.SequenceNumber(), "type": "permission", "user": permission.UserName(), "allow": permission.AllowBits(), "deny": permission.DenyBits(), "blobref": permission.BlobRef()}
	switch permission.Action() {
	case grapher.PermAction_Invite:
		mutJson["action"] = "invite"
	case grapher.PermAction_Expel:
		mutJson["action"] = "expel"
	case grapher.PermAction_Change:
		mutJson["action"] = "change"
	default:
		panic("Unknown action")
	}
	schema, err := json.Marshal(mutJson)
	if err != nil {
		panic(err.String())
	}
	if self.bufferOnly {
		self.messageBuffer = append(self.messageBuffer, string(schema))
	} else {
		err = self.forwardToFollowers(perma.BlobRef(), string(schema))
	}
	if err != nil {
		log.Printf("Err Forward: %v", err)
	}
}
Beispiel #2
0
func (self *channelAPI) Blob_Mutation(perma grapher.PermaNode, mutation grapher.MutationNode) {
	mutJson := map[string]interface{}{"perma": perma.BlobRef(), "seq": mutation.SequenceNumber(), "type": "mutation", "signer": mutation.Signer(), "entity": mutation.EntityBlobRef(), "field": mutation.Field(), "time": mutation.Time()}
	switch mutation.Operation().(type) {
	case []ot.StringOperation:
		op := mutation.Operation().([]ot.StringOperation) // The following two lines work around a problem in GO/JSON
		mutJson["op"] = &op
	case []byte:
		msg := json.RawMessage(mutation.Operation().([]byte))
		mutJson["op"] = &msg
	default:
		panic("Unsupported operation kind")
	}
	schema, err := json.Marshal(mutJson)
	if err != nil {
		panic(err.String())
	}
	if self.bufferOnly {
		self.messageBuffer = append(self.messageBuffer, string(schema))
	} else {
		err = self.forwardToFollowers(perma.BlobRef(), string(schema))
	}
	if err != nil {
		log.Printf("Err Forward: %v", err)
	}
}
Beispiel #3
0
func (self *dummyAPI) Signal_ReceivedInvitation(perma grapher.PermaNode, permission grapher.PermissionNode) {
	log.Printf("APP %v: Received Invitation", self.userID)
	// Automatically accept the invitation
	_, err := self.grapher.CreateKeepBlob(perma.BlobRef(), permission.BlobRef())
	if err != nil {
		self.t.Fatal(err.String())
	}
}
Beispiel #4
0
func (self *channelAPI) Signal_AcceptedInvitation(perma grapher.PermaNode, permission grapher.PermissionNode, keep grapher.KeepNode) {
	msgJson := map[string]interface{}{"perma": perma.BlobRef(), "type": "accept", "signer": permission.Signer(), "permission": permission.BlobRef()}
	schema, err := json.Marshal(msgJson)
	if err != nil {
		panic(err.String())
	}
	if self.bufferOnly {
		self.messageBuffer = append(self.messageBuffer, string(schema))
	} else {
		err = self.forwardToUser(keep.Signer(), string(schema))
	}
	if err != nil {
		log.Printf("Err Forward: %v", err)
	}
}
Beispiel #5
0
func (self *channelAPI) Blob_DeleteEntity(perma grapher.PermaNode, entity grapher.DelEntityNode) {
	entityJson := map[string]interface{}{"perma": perma.BlobRef(), "seq": entity.SequenceNumber(), "type": "delentity", "signer": entity.Signer(), "blobref": entity.BlobRef(), "entity": entity.EntityBlobRef()}
	schema, err := json.Marshal(entityJson)
	if err != nil {
		panic(err.String())
	}
	if self.bufferOnly {
		self.messageBuffer = append(self.messageBuffer, string(schema))
	} else {
		err = self.forwardToFollowers(perma.BlobRef(), string(schema))
	}
	if err != nil {
		log.Printf("Err Forward: %v", err)
	}
}
Beispiel #6
0
func (self *channelAPI) Blob_Keep(perma grapher.PermaNode, permission grapher.PermissionNode, keep grapher.KeepNode) {
	mutJson := map[string]interface{}{"perma": perma.BlobRef(), "seq": keep.SequenceNumber(), "type": "keep", "signer": keep.Signer(), "mimetype": perma.MimeType()}
	if permission != nil {
		mutJson["permission"] = permission.SequenceNumber()
	}
	schema, err := json.Marshal(mutJson)
	if err != nil {
		panic(err.String())
	}
	message := string(schema)
	if self.bufferOnly {
		self.messageBuffer = append(self.messageBuffer, string(schema))
	} else {
		self.forwardToUser(keep.Signer(), message)
		err = self.forwardToFollowers(perma.BlobRef(), message)
	}
	if err != nil {
		log.Printf("Err Forward: %v", err)
	}
}
Beispiel #7
0
func (self *channelAPI) Signal_ReceivedInvitation(perma grapher.PermaNode, permission grapher.PermissionNode) {
	// TODO: Compute digest
	var digest = "Untitled page"
	msgJson := map[string]interface{}{"perma": perma.BlobRef(), "type": "invitation", "signer": permission.Signer(), "permission": permission.BlobRef(), "digest": digest}
	fillInboxItem(self.store, perma.BlobRef(), int64(0), msgJson)
	schema, err := json.Marshal(msgJson)
	if err != nil {
		panic(err.String())
	}
	if self.bufferOnly {
		self.messageBuffer = append(self.messageBuffer, string(schema))
	} else {
		if perma.MimeType() == "application/x-lightwave-page" {
			addToInbox(self.c, permission.UserName(), perma.BlobRef(), 0)
		}
		err = self.forwardToUser(permission.UserName(), string(schema))
	}
	if err != nil {
		log.Printf("Err Forward: %v", err)
	}

	// Automatically accept the invitation
	//  self.grapher.CreateKeepBlob(perma.BlobRef(), permission.BlobRef())
}
Beispiel #8
0
func handleOpen(w http.ResponseWriter, r *http.Request) {
	c := appengine.NewContext(r)
	userid, sessionid, err := getSession(c, r)
	if err != nil {
		sendError(w, r, "No session cookie")
		return
	}
	// Read the request body
	jreq, err := ioutil.ReadAll(r.Body)
	if err != nil {
		http.Error(w, "Error reading request body", http.StatusInternalServerError)
		return
	}
	r.Body.Close()
	// Parse request
	var req openCloseRequest
	err = json.Unmarshal(jreq, &req)
	if err != nil {
		sendError(w, r, "Malformed JSON")
		return
	}
	// Load the channel infos
	var ch channelStruct
	if err = datastore.Get(c, datastore.NewKey("channel", userid+"/"+sessionid, 0, nil), &ch); err != nil {
		sendError(w, r, "Unknown channel: "+userid+"/"+sessionid)
		return
	}
	// Check
	if len(ch.OpenPermas) >= 10 {
		sendError(w, r, "Too many open channels")
		return
	}
	is_open := false
	for _, p := range ch.OpenPermas {
		if p == req.Perma {
			is_open = true
			break
		}
	}
	var perma grapher.PermaNode
	if !is_open {
		// Update channel infos
		ch.OpenPermas = append(ch.OpenPermas, req.Perma)
		_, err = datastore.Put(c, datastore.NewKey("channel", userid+"/"+sessionid, 0, nil), &ch)
		if err != nil {
			sendError(w, r, "Internal server error")
			return
		}
		// Repeat all blobs from this document.
		s := newStore(c)
		g := grapher.NewGrapher(userid, schema, s, s, nil)
		s.SetGrapher(g)
		ch := newChannelAPI(c, s, userid, sessionid, true, g)
		perma, err = g.Repeat(req.Perma, req.From)
		if err != nil {
			sendError(w, r, "Failed opening")
			return
		}
		fmt.Fprintf(w, `{"ok":true, "blobs":[%v]}`, strings.Join(ch.messageBuffer, ","))
	} else {
		fmt.Fprint(w, `{"ok":true, "blobs":[]}`)
	}

	if req.MarkAsRead {
		if perma == nil {
			s := newStore(c)
			data, err := s.GetPermaNode(req.Perma)
			if err != nil {
				log.Printf("Err: Failed reading permanode")
				return
			}
			perma = grapher.NewPermaNode(nil)
			perma.FromMap(req.Perma, data)
		}
		markAsRead(c, userid, perma.BlobRef(), perma.SequenceNumber()-1)
	}
}
Beispiel #9
0
func (self *uniAPI) blob(perma grapher.PermaNode, blob grapher.OTNode) {
	log.Printf("API blob %v", blob.SequenceNumber())
	self.mutex.Lock()
	// Is this perma blob opened?
	nextSeqNumber, ok := self.open[perma.BlobRef()]
	if !ok {
		// Is this a new keep of the local user? If yes, send it. Otherwise ignore it
		if keep, ok := blob.(grapher.KeepNode); ok && keep.Signer() == self.userID {
			self.mutex.Unlock()
			self.app.Signal_ProcessedKeep(perma, keep)
			return
		}
		self.mutex.Unlock()
		return
	}
	if nextSeqNumber > blob.SequenceNumber() {
		// Ignore this mutation. We have seen it already (should not happen anyway)
		self.mutex.Unlock()
		return
	}
	if nextSeqNumber < blob.SequenceNumber() {
		// Remember that we need to process these mutations later on, too, but not now
		q, ok := self.queues[perma.BlobRef()]
		if !ok || blob.SequenceNumber() < q {
			self.queues[perma.BlobRef()] = blob.SequenceNumber()
		}
		self.mutex.Unlock()
		return
	}
	// Store the next expected sequence number
	self.open[perma.BlobRef()] = blob.SequenceNumber() + 1
	// Is there a need to continue with queued mutations?
	cont := int64(-1)
	j, ok := self.queues[perma.BlobRef()]
	if ok {
		cont = j
		self.queues[perma.BlobRef()] = 0, false
	}
	self.mutex.Unlock()
	// Notify the application
	self.app.Blob(perma, blob)
	// Ask to repeat further blobs in case we have already seen some
	if cont != -1 {
		self.grapher.Repeat(perma.BlobRef(), cont)
	}
}