Merge branch 'p2ptimeline' of cwtch.im/cwtch into master
This commit is contained in:
commit
7ae9954c7d
|
@ -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
|
||||
|
|
|
@ -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")
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -22,6 +22,7 @@ type PublicProfile struct {
|
|||
Blocked bool
|
||||
Onion string
|
||||
Attributes map[string]string
|
||||
Timeline Timeline
|
||||
lock sync.Mutex
|
||||
}
|
||||
|
||||
|
@ -102,6 +103,24 @@ 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()
|
||||
|
|
|
@ -4,8 +4,31 @@ 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")
|
||||
|
@ -77,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)
|
||||
|
@ -101,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)
|
||||
|
@ -114,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)
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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")
|
||||
|
|
Loading…
Reference in New Issue