Fixing up first time storage and ensuring we no longer dupe messages in timeline
This commit is contained in:
parent
b9f7ab3757
commit
2b47c50d0d
|
@ -104,7 +104,7 @@ func (g *Group) Invite(initialMessage []byte) ([]byte, error) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddMessage takes a DecryptedGroupMessage and adds it to the Groups Timeline
|
// AddMessage takes a DecryptedGroupMessage and adds it to the Groups Timeline
|
||||||
func (g *Group) AddMessage(message *protocol.DecryptedGroupMessage, sig []byte) *Message {
|
func (g *Group) AddMessage(message *protocol.DecryptedGroupMessage, sig []byte) (*Message, bool) {
|
||||||
timelineMessage := &Message{
|
timelineMessage := &Message{
|
||||||
Message: message.GetText(),
|
Message: message.GetText(),
|
||||||
Timestamp: time.Unix(int64(message.GetTimestamp()), 0),
|
Timestamp: time.Unix(int64(message.GetTimestamp()), 0),
|
||||||
|
@ -113,8 +113,8 @@ func (g *Group) AddMessage(message *protocol.DecryptedGroupMessage, sig []byte)
|
||||||
PeerID: message.GetOnion(),
|
PeerID: message.GetOnion(),
|
||||||
PreviousMessageSig: message.GetPreviousMessageSig(),
|
PreviousMessageSig: message.GetPreviousMessageSig(),
|
||||||
}
|
}
|
||||||
g.Timeline.Insert(timelineMessage)
|
seen := g.Timeline.Insert(timelineMessage)
|
||||||
return timelineMessage
|
return timelineMessage, seen
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetTimeline provides a safe copy of the timeline
|
// GetTimeline provides a safe copy of the timeline
|
||||||
|
|
|
@ -80,12 +80,12 @@ func TestTranscriptConsistency(t *testing.T) {
|
||||||
c5, s5, _ := alice.EncryptMessageToGroup("Hello World 5", group.GroupID)
|
c5, s5, _ := alice.EncryptMessageToGroup("Hello World 5", group.GroupID)
|
||||||
t.Logf("Length of Encrypted Message: %v", len(c5))
|
t.Logf("Length of Encrypted Message: %v", len(c5))
|
||||||
|
|
||||||
_, _, m1 := sarah.AttemptDecryption(c1, s1)
|
_, _, m1, _ := sarah.AttemptDecryption(c1, s1)
|
||||||
sarah.AttemptDecryption(c1, s1) // Try a duplicate
|
sarah.AttemptDecryption(c1, s1) // Try a duplicate
|
||||||
_, _, m2 := sarah.AttemptDecryption(c2, s2)
|
_, _, m2, _ := sarah.AttemptDecryption(c2, s2)
|
||||||
_, _, m3 := sarah.AttemptDecryption(c3, s3)
|
_, _, m3, _ := sarah.AttemptDecryption(c3, s3)
|
||||||
_, _, m4 := sarah.AttemptDecryption(c4, s4)
|
_, _, m4, _ := sarah.AttemptDecryption(c4, s4)
|
||||||
_, _, m5 := sarah.AttemptDecryption(c5, s5)
|
_, _, m5, _ := sarah.AttemptDecryption(c5, s5)
|
||||||
|
|
||||||
// Now we simulate a client receiving these Messages completely out of order
|
// Now we simulate a client receiving these Messages completely out of order
|
||||||
timeline.Insert(m1)
|
timeline.Insert(m1)
|
||||||
|
|
|
@ -297,7 +297,7 @@ func (p *Profile) AddGroup(group *Group) {
|
||||||
}
|
}
|
||||||
|
|
||||||
// AttemptDecryption takes a ciphertext and signature and attempts to decrypt it under known groups.
|
// AttemptDecryption takes a ciphertext and signature and attempts to decrypt it under known groups.
|
||||||
func (p *Profile) AttemptDecryption(ciphertext []byte, signature []byte) (bool, string, *Message) {
|
func (p *Profile) AttemptDecryption(ciphertext []byte, signature []byte) (bool, string, *Message, bool) {
|
||||||
for _, group := range p.Groups {
|
for _, group := range p.Groups {
|
||||||
success, dgm := group.DecryptMessage(ciphertext)
|
success, dgm := group.DecryptMessage(ciphertext)
|
||||||
if success {
|
if success {
|
||||||
|
@ -308,14 +308,15 @@ func (p *Profile) AttemptDecryption(ciphertext []byte, signature []byte) (bool,
|
||||||
// Either way, someone who has the private key is being detectably bad so we are just going to throw this message away and mark the group as Compromised.
|
// Either way, someone who has the private key is being detectably bad so we are just going to throw this message away and mark the group as Compromised.
|
||||||
if !verified {
|
if !verified {
|
||||||
group.Compromised()
|
group.Compromised()
|
||||||
return false, group.GroupID, nil
|
return false, group.GroupID, nil, false
|
||||||
}
|
}
|
||||||
return true, group.GroupID, group.AddMessage(dgm, signature)
|
message, seen := group.AddMessage(dgm, signature)
|
||||||
|
return true, group.GroupID, message, seen
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// If we couldn't find a group to decrypt the message with we just return false. This is an expected case
|
// If we couldn't find a group to decrypt the message with we just return false. This is an expected case
|
||||||
return false, "", nil
|
return false, "", nil, false
|
||||||
}
|
}
|
||||||
|
|
||||||
func getRandomness(arr *[]byte) {
|
func getRandomness(arr *[]byte) {
|
||||||
|
|
|
@ -161,13 +161,13 @@ func TestProfileGroup(t *testing.T) {
|
||||||
bob.ProcessInvite(gci2.GetGroupChatInvite(), alice.Onion)
|
bob.ProcessInvite(gci2.GetGroupChatInvite(), alice.Onion)
|
||||||
c3, s3, err := bob.EncryptMessageToGroup("Bobs Message", group2.GroupID)
|
c3, s3, err := bob.EncryptMessageToGroup("Bobs Message", group2.GroupID)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ok, _, message := alice.AttemptDecryption(c3, s3)
|
ok, _, message, _ := alice.AttemptDecryption(c3, s3)
|
||||||
if !ok {
|
if !ok {
|
||||||
t.Errorf("Bobs message to the group should be decrypted %v %v", message, ok)
|
t.Errorf("Bobs message to the group should be decrypted %v %v", message, ok)
|
||||||
}
|
}
|
||||||
|
|
||||||
eve := GenerateNewProfile("eve")
|
eve := GenerateNewProfile("eve")
|
||||||
ok, _, _ = eve.AttemptDecryption(c3, s3)
|
ok, _, _, _ = eve.AttemptDecryption(c3, s3)
|
||||||
if ok {
|
if ok {
|
||||||
t.Errorf("Eves hould not be able to decrypt Messages!")
|
t.Errorf("Eves hould not be able to decrypt Messages!")
|
||||||
}
|
}
|
||||||
|
|
|
@ -162,7 +162,7 @@ func (cp *cwtchPeer) StartGroupWithMessage(server string, initialMessage []byte)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
group := cp.GetGroup(groupID)
|
group := cp.GetGroup(groupID)
|
||||||
jsobj, err := json.Marshal(group)
|
jsobj, err := json.Marshal(group)
|
||||||
if err != nil {
|
if err == nil {
|
||||||
cp.eventBus.Publish(event.NewEvent(event.GroupCreated, map[event.Field]string{
|
cp.eventBus.Publish(event.NewEvent(event.GroupCreated, map[event.Field]string{
|
||||||
event.Data: string(jsobj),
|
event.Data: string(jsobj),
|
||||||
}))
|
}))
|
||||||
|
@ -312,10 +312,10 @@ func (cp *cwtchPeer) eventHandler() {
|
||||||
ev := cp.queue.Next()
|
ev := cp.queue.Next()
|
||||||
switch ev.EventType {
|
switch ev.EventType {
|
||||||
case event.EncryptedGroupMessage:
|
case event.EncryptedGroupMessage:
|
||||||
ok, groupID, message := cp.Profile.AttemptDecryption([]byte(ev.Data[event.Ciphertext]), []byte(ev.Data[event.Signature]))
|
ok, groupID, message, seen := cp.Profile.AttemptDecryption([]byte(ev.Data[event.Ciphertext]), []byte(ev.Data[event.Signature]))
|
||||||
log.Debugf("ok,gid,msg = %v,%v,%v", ok, groupID, message)
|
log.Debugf("ok,gid,msg = %v,%v,%v", ok, groupID, message)
|
||||||
if ok {
|
if ok && !seen {
|
||||||
cp.eventBus.Publish(event.NewEvent(event.NewMessageFromGroup, map[event.Field]string{event.TimestampReceived: message.Received.Format(time.RFC3339Nano), event.TimestampSent: message.Timestamp.Format(time.RFC3339Nano), event.Data: message.Message, event.GroupID: groupID, event.RemotePeer: message.PeerID}))
|
cp.eventBus.Publish(event.NewEvent(event.NewMessageFromGroup, map[event.Field]string{event.TimestampReceived: message.Received.Format(time.RFC3339Nano), event.TimestampSent: message.Timestamp.Format(time.RFC3339Nano), event.Data: message.Message, event.GroupID: groupID, event.Signature: string(message.Signature), event.RemotePeer: message.PeerID}))
|
||||||
}
|
}
|
||||||
case event.NewGroupInvite:
|
case event.NewGroupInvite:
|
||||||
var groupInvite protocol.GroupChatInvite
|
var groupInvite protocol.GroupChatInvite
|
||||||
|
|
|
@ -153,7 +153,7 @@ func (ps *profileStore) eventHandler() {
|
||||||
received, _ := time.Parse(time.RFC3339Nano, ev.Data[event.TimestampReceived])
|
received, _ := time.Parse(time.RFC3339Nano, ev.Data[event.TimestampReceived])
|
||||||
sent, _ := time.Parse(time.RFC3339Nano, ev.Data[event.TimestampSent])
|
sent, _ := time.Parse(time.RFC3339Nano, ev.Data[event.TimestampSent])
|
||||||
// TODO: Sig, prev message Sig
|
// TODO: Sig, prev message Sig
|
||||||
message := model.Message{Received: received, Timestamp: sent, Message: ev.Data[event.Data], PeerID: ev.Data[event.RemotePeer]}
|
message := model.Message{Received: received, Timestamp: sent, Message: ev.Data[event.Data], PeerID: ev.Data[event.RemotePeer], Signature: []byte(ev.Data[event.Signature])}
|
||||||
//ps.profile.Groups[groupid].AddMessage(message) <- wants protocol.DecryptedGroupMessage so group.Timeline will drift here from launch when it's initialized
|
//ps.profile.Groups[groupid].AddMessage(message) <- wants protocol.DecryptedGroupMessage so group.Timeline will drift here from launch when it's initialized
|
||||||
ps.streamStores[groupid].Write(message)
|
ps.streamStores[groupid].Write(message)
|
||||||
default:
|
default:
|
||||||
|
|
Loading…
Reference in New Issue