From 8083e6fa5c1a0a5693bd5ce191e797272ea0d36b Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Wed, 21 Nov 2018 13:23:59 -0800 Subject: [PATCH 1/2] Adding Method to Save Messages in p2p Transcript --- model/message.go | 6 +++--- model/profile.go | 20 ++++++++++++++++++++ model/profile_test.go | 27 +++++++++++++++++++++++++++ 3 files changed, 50 insertions(+), 3 deletions(-) diff --git a/model/message.go b/model/message.go index 4ce71f0..ded861d 100644 --- a/model/message.go +++ b/model/message.go @@ -55,11 +55,11 @@ func (t *Timeline) Swap(i, j int) { t.Messages[i], t.Messages[j] = t.Messages[j], t.Messages[i] } -// Less checks 2 messages (i and j) in the timeline and returns true if i occcured before j, else false +// Less checks 2 messages (i and j) in the timeline and returns true if i occurred before j, else false func (t *Timeline) Less(i, j int) bool { - if t.Messages[i].Timestamp.Before(t.Messages[j].Timestamp) { - return true + if t.Messages[j].Timestamp.Before(t.Messages[i].Timestamp) { + return false } if compareSignatures(t.Messages[i].PreviousMessageSig, t.SignedGroupID) { diff --git a/model/profile.go b/model/profile.go index 8bb48fe..5fceef9 100644 --- a/model/profile.go +++ b/model/profile.go @@ -22,6 +22,7 @@ type PublicProfile struct { Blocked bool Onion string Attributes map[string]string + Timeline Timeline lock sync.Mutex } @@ -102,6 +103,25 @@ func (p *Profile) RejectInvite(groupID string) { p.lock.Unlock() } +// AddMessageToContactTimeline allows the saving of a message sent via a direct connection chat to the profile. +func (p *Profile) AddMessageToContactTimeline(onion string, fromMe bool, message string, sent time.Time) { + p.lock.Lock() + defer p.lock.Unlock() + contact, ok := p.Contacts[onion] + + // We don't really need a Signature here, but we use it to maintain order + now := time.Now() + sig := p.SignMessage(onion + message + sent.String() + now.String()) + if ok { + if fromMe { + contact.Timeline.Insert(&Message{PeerID: p.Onion, Message: message, Timestamp: sent, Received: now, Signature: sig}) + } else { + contact.Timeline.Insert(&Message{PeerID: onion, Message: message, Timestamp: sent, Received: now, Signature: sig}) + } + } +} + + // AcceptInvite accepts a group invite func (p *Profile) AcceptInvite(groupID string) (err error) { p.lock.Lock() diff --git a/model/profile_test.go b/model/profile_test.go index e8493bc..53e845c 100644 --- a/model/profile_test.go +++ b/model/profile_test.go @@ -4,8 +4,33 @@ import ( "cwtch.im/cwtch/protocol" "github.com/golang/protobuf/proto" "testing" + "time" ) + +func TestP2P(t *testing.T) { + sarah := GenerateNewProfile("Sarah") + alice := GenerateNewProfile("Alice") + + sarah.AddContact(alice.Onion, &alice.PublicProfile) + + sarah.AddMessageToContactTimeline(alice.Onion, false, "hello",time.Now()) + sarah.AddMessageToContactTimeline(alice.Onion, true, "world",time.Now()) + + contact,_ := sarah.GetContact(alice.Onion) + for i,m := range contact.Timeline.GetMessages() { + if i == 0 && (m.Message != "hello" || m.PeerID != alice.Onion) { + t.Fatalf("Timeline is invalid: %v", m) + } + + if i == 1 && (m.Message != "world" || m.PeerID != sarah.Onion) { + t.Fatalf("Timeline is invalid: %v", m) + } + t.Logf("Message: %v", m) + } +} + + func TestProfileIdentity(t *testing.T) { sarah := GenerateNewProfile("Sarah") alice := GenerateNewProfile("Alice") @@ -66,6 +91,8 @@ func TestBlockPeer(t *testing.T) { } } + + func TestAcceptNonExistentGroup(t *testing.T) { sarah := GenerateNewProfile("Sarah") sarah.AcceptInvite("doesnotexist") From dc489398eaf22df3546ebb588dc80e4ae18b10f8 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Wed, 21 Nov 2018 14:15:43 -0800 Subject: [PATCH 2/2] Checking if a group is setup on a v3 onion server --- model/group.go | 5 +++++ model/group_test.go | 9 ++++++++- model/message_test.go | 4 ++-- model/profile.go | 1 - model/profile_test.go | 22 +++++++++------------ peer/connections/peerpeerconnection_test.go | 2 +- peer/cwtch_peer_test.go | 2 +- 7 files changed, 26 insertions(+), 19 deletions(-) diff --git a/model/group.go b/model/group.go index d28db70..9adf2e8 100644 --- a/model/group.go +++ b/model/group.go @@ -34,6 +34,11 @@ type Group struct { // NewGroup initializes a new group associated with a given CwtchServer func NewGroup(server string) (*Group, error) { group := new(Group) + + if utils.IsValidHostname(server) == false { + return nil, errors.New("Server is not a valid v3 onion") + } + group.GroupServer = server var groupID [16]byte diff --git a/model/group_test.go b/model/group_test.go index 233eaac..00b52ae 100644 --- a/model/group_test.go +++ b/model/group_test.go @@ -8,7 +8,7 @@ import ( ) func TestGroup(t *testing.T) { - g, _ := NewGroup("server.onion") + g, _ := NewGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd") dgm := &protocol.DecryptedGroupMessage{ Onion: proto.String("onion"), Text: proto.String("Hello World!"), @@ -30,3 +30,10 @@ func TestGroup(t *testing.T) { } t.Logf("Got message %v", message) } + +func TestGroupErr(t *testing.T) { + _, err := NewGroup("not a real group name") + if err == nil { + t.Errorf("Group Setup Should Have Failed") + } +} diff --git a/model/message_test.go b/model/message_test.go index a639d59..c66d0d6 100644 --- a/model/message_test.go +++ b/model/message_test.go @@ -16,7 +16,7 @@ func TestMessagePadding(t *testing.T) { sarah.AddContact(alice.Onion, &alice.PublicProfile) alice.AddContact(sarah.Onion, &sarah.PublicProfile) - gid, invite, _ := alice.StartGroup("aaa.onion") + gid, invite, _ := alice.StartGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd") gci := &protocol.CwtchPeerPacket{} proto.Unmarshal(invite, gci) sarah.ProcessInvite(gci.GetGroupChatInvite(), alice.Onion) @@ -50,7 +50,7 @@ func TestTranscriptConsistency(t *testing.T) { sarah.AddContact(alice.Onion, &alice.PublicProfile) alice.AddContact(sarah.Onion, &sarah.PublicProfile) - gid, invite, _ := alice.StartGroup("aaa.onion") + gid, invite, _ := alice.StartGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd") gci := &protocol.CwtchPeerPacket{} proto.Unmarshal(invite, gci) sarah.ProcessInvite(gci.GetGroupChatInvite(), alice.Onion) diff --git a/model/profile.go b/model/profile.go index 5fceef9..9096a42 100644 --- a/model/profile.go +++ b/model/profile.go @@ -121,7 +121,6 @@ func (p *Profile) AddMessageToContactTimeline(onion string, fromMe bool, message } } - // AcceptInvite accepts a group invite func (p *Profile) AcceptInvite(groupID string) (err error) { p.lock.Lock() diff --git a/model/profile_test.go b/model/profile_test.go index 53e845c..ba02b23 100644 --- a/model/profile_test.go +++ b/model/profile_test.go @@ -7,30 +7,28 @@ import ( "time" ) - func TestP2P(t *testing.T) { sarah := GenerateNewProfile("Sarah") alice := GenerateNewProfile("Alice") sarah.AddContact(alice.Onion, &alice.PublicProfile) - sarah.AddMessageToContactTimeline(alice.Onion, false, "hello",time.Now()) - sarah.AddMessageToContactTimeline(alice.Onion, true, "world",time.Now()) + sarah.AddMessageToContactTimeline(alice.Onion, false, "hello", time.Now()) + sarah.AddMessageToContactTimeline(alice.Onion, true, "world", time.Now()) - contact,_ := sarah.GetContact(alice.Onion) - for i,m := range contact.Timeline.GetMessages() { - if i == 0 && (m.Message != "hello" || m.PeerID != alice.Onion) { + contact, _ := sarah.GetContact(alice.Onion) + for i, m := range contact.Timeline.GetMessages() { + if i == 0 && (m.Message != "hello" || m.PeerID != alice.Onion) { t.Fatalf("Timeline is invalid: %v", m) } - if i == 1 && (m.Message != "world" || m.PeerID != sarah.Onion) { + if i == 1 && (m.Message != "world" || m.PeerID != sarah.Onion) { t.Fatalf("Timeline is invalid: %v", m) } t.Logf("Message: %v", m) } } - func TestProfileIdentity(t *testing.T) { sarah := GenerateNewProfile("Sarah") alice := GenerateNewProfile("Alice") @@ -91,8 +89,6 @@ func TestBlockPeer(t *testing.T) { } } - - func TestAcceptNonExistentGroup(t *testing.T) { sarah := GenerateNewProfile("Sarah") sarah.AcceptInvite("doesnotexist") @@ -104,7 +100,7 @@ func TestRejectGroupInvite(t *testing.T) { sarah.AddContact(alice.Onion, &alice.PublicProfile) alice.AddContact(sarah.Onion, &sarah.PublicProfile) - gid, invite, _ := alice.StartGroup("aaa.onion") + gid, invite, _ := alice.StartGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd") gci := &protocol.CwtchPeerPacket{} proto.Unmarshal(invite, gci) sarah.ProcessInvite(gci.GetGroupChatInvite(), alice.Onion) @@ -128,7 +124,7 @@ func TestProfileGroup(t *testing.T) { sarah.AddContact(alice.Onion, &alice.PublicProfile) alice.AddContact(sarah.Onion, &sarah.PublicProfile) - gid, invite, _ := alice.StartGroupWithMessage("aaa.onion", []byte("Hello World")) + gid, invite, _ := alice.StartGroupWithMessage("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd", []byte("Hello World")) gci := &protocol.CwtchPeerPacket{} proto.Unmarshal(invite, gci) sarah.ProcessInvite(gci.GetGroupChatInvite(), alice.Onion) @@ -141,7 +137,7 @@ func TestProfileGroup(t *testing.T) { c, s1, _ := sarah.EncryptMessageToGroup("Hello World", group.GroupID) alice.AttemptDecryption(c, s1) - gid2, invite2, _ := alice.StartGroup("bbb.onion") + gid2, invite2, _ := alice.StartGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd") gci2 := &protocol.CwtchPeerPacket{} proto.Unmarshal(invite2, gci2) sarah.ProcessInvite(gci2.GetGroupChatInvite(), alice.Onion) diff --git a/peer/connections/peerpeerconnection_test.go b/peer/connections/peerpeerconnection_test.go index a9d5827..4901a5e 100644 --- a/peer/connections/peerpeerconnection_test.go +++ b/peer/connections/peerpeerconnection_test.go @@ -77,7 +77,7 @@ func TestPeerPeerConnection(t *testing.T) { if state != AUTHENTICATED { t.Errorf("connection state should be authenticated(3), was instead %v", state) } - _, invite, _ := profile.StartGroup("aaa.onion") + _, invite, _ := profile.StartGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd") ppc.SendGroupInvite(invite) time.Sleep(time.Second * 3) if tp.ReceivedGroupInvite == false { diff --git a/peer/cwtch_peer_test.go b/peer/cwtch_peer_test.go index 84325fb..b71a9bd 100644 --- a/peer/cwtch_peer_test.go +++ b/peer/cwtch_peer_test.go @@ -20,7 +20,7 @@ func TestCwtchPeerGenerate(t *testing.T) { } func TestTrustPeer(t *testing.T) { - groupName := "test.server" + groupName := "2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd" alice := NewCwtchPeer("alice") alice.Init(connectivity.LocalProvider()) bob := NewCwtchPeer("bob")