forked from cwtch.im/cwtch
Rework group invite workflow: delete cwtchPacket references as no longer needed. Remove more events from being default handled by Peer (but allow them for some usecases still (testing, simple apps).
This commit is contained in:
parent
304a55aa5e
commit
15582c7e79
|
@ -558,11 +558,11 @@ func main() {
|
||||||
}
|
}
|
||||||
case "/import-group":
|
case "/import-group":
|
||||||
if len(commands) == 2 {
|
if len(commands) == 2 {
|
||||||
groupID, err := peer.ImportGroup(commands[1])
|
err := peer.ImportGroup(commands[1])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
fmt.Printf("Error importing group: %v\n", err)
|
fmt.Printf("Error importing group: %v\n", err)
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("Imported group: %s\n", groupID)
|
fmt.Printf("Imported group!\n")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("%v", commands)
|
fmt.Printf("%v", commands)
|
||||||
|
|
|
@ -117,6 +117,7 @@ const (
|
||||||
// Data [eg "open privacy board"]
|
// Data [eg "open privacy board"]
|
||||||
SetGroupAttribute = Type("SetGroupAttribute")
|
SetGroupAttribute = Type("SetGroupAttribute")
|
||||||
|
|
||||||
|
// PeerStateChange servers as a new incoming connection message as well, and can/is consumed by frontends to alert of new p2p connections
|
||||||
// RemotePeer
|
// RemotePeer
|
||||||
// ConnectionState
|
// ConnectionState
|
||||||
PeerStateChange = Type("PeerStateChange")
|
PeerStateChange = Type("PeerStateChange")
|
||||||
|
|
|
@ -97,10 +97,7 @@ func (g *Group) Invite(initialMessage []byte) ([]byte, error) {
|
||||||
InitialMessage: initialMessage[:],
|
InitialMessage: initialMessage[:],
|
||||||
}
|
}
|
||||||
|
|
||||||
cp := &protocol.CwtchPeerPacket{
|
invite, err := proto.Marshal(gci)
|
||||||
GroupChatInvite: gci,
|
|
||||||
}
|
|
||||||
invite, err := proto.Marshal(cp)
|
|
||||||
return invite, err
|
return invite, err
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cwtch.im/cwtch/protocol"
|
|
||||||
"github.com/golang/protobuf/proto"
|
|
||||||
"strconv"
|
"strconv"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -17,9 +15,8 @@ func TestMessagePadding(t *testing.T) {
|
||||||
alice.AddContact(sarah.Onion, &sarah.PublicProfile)
|
alice.AddContact(sarah.Onion, &sarah.PublicProfile)
|
||||||
|
|
||||||
gid, invite, _ := alice.StartGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd")
|
gid, invite, _ := alice.StartGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd")
|
||||||
gci := &protocol.CwtchPeerPacket{}
|
|
||||||
proto.Unmarshal(invite, gci)
|
sarah.ProcessInvite(string(invite), alice.Onion)
|
||||||
sarah.ProcessInvite(gci.GetGroupChatInvite(), alice.Onion)
|
|
||||||
|
|
||||||
group := alice.GetGroupByGroupID(gid)
|
group := alice.GetGroupByGroupID(gid)
|
||||||
|
|
||||||
|
@ -51,9 +48,8 @@ func TestTranscriptConsistency(t *testing.T) {
|
||||||
alice.AddContact(sarah.Onion, &sarah.PublicProfile)
|
alice.AddContact(sarah.Onion, &sarah.PublicProfile)
|
||||||
|
|
||||||
gid, invite, _ := alice.StartGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd")
|
gid, invite, _ := alice.StartGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd")
|
||||||
gci := &protocol.CwtchPeerPacket{}
|
|
||||||
proto.Unmarshal(invite, gci)
|
sarah.ProcessInvite(string(invite), alice.Onion)
|
||||||
sarah.ProcessInvite(gci.GetGroupChatInvite(), alice.Onion)
|
|
||||||
|
|
||||||
group := alice.GetGroupByGroupID(gid)
|
group := alice.GetGroupByGroupID(gid)
|
||||||
|
|
||||||
|
|
|
@ -87,20 +87,6 @@ func GenerateNewProfile(name string) *Profile {
|
||||||
return p
|
return p
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetCwtchIdentityPacket returns the wire message for conveying this profiles identity.
|
|
||||||
func (p *Profile) GetCwtchIdentityPacket() (message []byte) {
|
|
||||||
ci := &protocol.CwtchIdentity{
|
|
||||||
Name: p.Name,
|
|
||||||
Ed25519PublicKey: p.Ed25519PublicKey,
|
|
||||||
}
|
|
||||||
cpp := &protocol.CwtchPeerPacket{
|
|
||||||
CwtchIdentify: ci,
|
|
||||||
}
|
|
||||||
message, err := proto.Marshal(cpp)
|
|
||||||
utils.CheckError(err)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
// AddContact allows direct manipulation of cwtch contacts
|
// AddContact allows direct manipulation of cwtch contacts
|
||||||
func (p *Profile) AddContact(onion string, profile *PublicProfile) {
|
func (p *Profile) AddContact(onion string, profile *PublicProfile) {
|
||||||
p.lock.Lock()
|
p.lock.Lock()
|
||||||
|
@ -317,8 +303,11 @@ func (p *Profile) GetGroupByGroupID(groupID string) (g *Group) {
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProcessInvite adds a new group invite to the profile.
|
// ProcessInvite adds a new group invite to the profile. returns the new group ID
|
||||||
func (p *Profile) ProcessInvite(gci *protocol.GroupChatInvite, peerHostname string) {
|
func (p *Profile) ProcessInvite(invite string, peerHostname string) (string, error) {
|
||||||
|
var gci protocol.GroupChatInvite
|
||||||
|
err := proto.Unmarshal([]byte(invite), &gci)
|
||||||
|
if err == nil {
|
||||||
group := new(Group)
|
group := new(Group)
|
||||||
group.GroupID = gci.GetGroupName()
|
group.GroupID = gci.GetGroupName()
|
||||||
group.LocalID = generateRandomID()
|
group.LocalID = generateRandomID()
|
||||||
|
@ -330,6 +319,9 @@ func (p *Profile) ProcessInvite(gci *protocol.GroupChatInvite, peerHostname stri
|
||||||
group.Owner = peerHostname
|
group.Owner = peerHostname
|
||||||
group.Attributes = make(map[string]string)
|
group.Attributes = make(map[string]string)
|
||||||
p.AddGroup(group)
|
p.AddGroup(group)
|
||||||
|
return group.GroupID, nil
|
||||||
|
}
|
||||||
|
return "", err
|
||||||
}
|
}
|
||||||
|
|
||||||
// AddGroup is a convenience method for adding a group to a profile.
|
// AddGroup is a convenience method for adding a group to a profile.
|
||||||
|
|
|
@ -1,23 +1,14 @@
|
||||||
package model
|
package model
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cwtch.im/cwtch/protocol"
|
|
||||||
"github.com/golang/protobuf/proto"
|
|
||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
func TestProfileIdentity(t *testing.T) {
|
func TestProfileIdentity(t *testing.T) {
|
||||||
sarah := GenerateNewProfile("Sarah")
|
sarah := GenerateNewProfile("Sarah")
|
||||||
alice := GenerateNewProfile("Alice")
|
alice := GenerateNewProfile("Alice")
|
||||||
|
|
||||||
message := sarah.GetCwtchIdentityPacket()
|
|
||||||
|
|
||||||
ci := &protocol.CwtchPeerPacket{}
|
|
||||||
err := proto.Unmarshal(message, ci)
|
|
||||||
if err != nil {
|
|
||||||
t.Errorf("alice should have added sarah as a contact %v", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
alice.AddContact(sarah.Onion, &sarah.PublicProfile)
|
alice.AddContact(sarah.Onion, &sarah.PublicProfile)
|
||||||
if alice.Contacts[sarah.Onion].Name != "Sarah" {
|
if alice.Contacts[sarah.Onion].Name != "Sarah" {
|
||||||
t.Errorf("alice should have added sarah as a contact %v", alice.Contacts)
|
t.Errorf("alice should have added sarah as a contact %v", alice.Contacts)
|
||||||
|
@ -78,9 +69,7 @@ func TestRejectGroupInvite(t *testing.T) {
|
||||||
alice.AddContact(sarah.Onion, &sarah.PublicProfile)
|
alice.AddContact(sarah.Onion, &sarah.PublicProfile)
|
||||||
|
|
||||||
gid, invite, _ := alice.StartGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd")
|
gid, invite, _ := alice.StartGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd")
|
||||||
gci := &protocol.CwtchPeerPacket{}
|
sarah.ProcessInvite(string(invite), alice.Onion)
|
||||||
proto.Unmarshal(invite, gci)
|
|
||||||
sarah.ProcessInvite(gci.GetGroupChatInvite(), alice.Onion)
|
|
||||||
group := alice.GetGroupByGroupID(gid)
|
group := alice.GetGroupByGroupID(gid)
|
||||||
if len(sarah.Groups) == 1 {
|
if len(sarah.Groups) == 1 {
|
||||||
if sarah.GetGroupByGroupID(group.GroupID).Accepted {
|
if sarah.GetGroupByGroupID(group.GroupID).Accepted {
|
||||||
|
@ -102,9 +91,7 @@ func TestProfileGroup(t *testing.T) {
|
||||||
alice.AddContact(sarah.Onion, &sarah.PublicProfile)
|
alice.AddContact(sarah.Onion, &sarah.PublicProfile)
|
||||||
|
|
||||||
gid, invite, _ := alice.StartGroupWithMessage("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd", []byte("Hello World"))
|
gid, invite, _ := alice.StartGroupWithMessage("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd", []byte("Hello World"))
|
||||||
gci := &protocol.CwtchPeerPacket{}
|
sarah.ProcessInvite(string(invite), alice.Onion)
|
||||||
proto.Unmarshal(invite, gci)
|
|
||||||
sarah.ProcessInvite(gci.GetGroupChatInvite(), alice.Onion)
|
|
||||||
if len(sarah.GetGroups()) != 1 {
|
if len(sarah.GetGroups()) != 1 {
|
||||||
t.Errorf("sarah should only be in 1 group instead: %v", sarah.GetGroups())
|
t.Errorf("sarah should only be in 1 group instead: %v", sarah.GetGroups())
|
||||||
}
|
}
|
||||||
|
@ -115,9 +102,7 @@ func TestProfileGroup(t *testing.T) {
|
||||||
alice.AttemptDecryption(c, s1)
|
alice.AttemptDecryption(c, s1)
|
||||||
|
|
||||||
gid2, invite2, _ := alice.StartGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd")
|
gid2, invite2, _ := alice.StartGroup("2c3kmoobnyghj2zw6pwv7d57yzld753auo3ugauezzpvfak3ahc4bdyd")
|
||||||
gci2 := &protocol.CwtchPeerPacket{}
|
sarah.ProcessInvite(string(invite2), alice.Onion)
|
||||||
proto.Unmarshal(invite2, gci2)
|
|
||||||
sarah.ProcessInvite(gci2.GetGroupChatInvite(), alice.Onion)
|
|
||||||
group2 := alice.GetGroupByGroupID(gid2)
|
group2 := alice.GetGroupByGroupID(gid2)
|
||||||
c2, s2, _ := sarah.EncryptMessageToGroup("Hello World", group2.GroupID)
|
c2, s2, _ := sarah.EncryptMessageToGroup("Hello World", group2.GroupID)
|
||||||
alice.AttemptDecryption(c2, s2)
|
alice.AttemptDecryption(c2, s2)
|
||||||
|
@ -135,7 +120,7 @@ func TestProfileGroup(t *testing.T) {
|
||||||
|
|
||||||
bob := GenerateNewProfile("bob")
|
bob := GenerateNewProfile("bob")
|
||||||
bob.AddContact(alice.Onion, &alice.PublicProfile)
|
bob.AddContact(alice.Onion, &alice.PublicProfile)
|
||||||
bob.ProcessInvite(gci2.GetGroupChatInvite(), alice.Onion)
|
bob.ProcessInvite(string(invite2), 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)
|
||||||
|
|
|
@ -3,19 +3,19 @@ package peer
|
||||||
import (
|
import (
|
||||||
"cwtch.im/cwtch/event"
|
"cwtch.im/cwtch/event"
|
||||||
"cwtch.im/cwtch/model"
|
"cwtch.im/cwtch/model"
|
||||||
"cwtch.im/cwtch/protocol"
|
|
||||||
"cwtch.im/cwtch/protocol/connections"
|
"cwtch.im/cwtch/protocol/connections"
|
||||||
"encoding/base32"
|
"encoding/base32"
|
||||||
"encoding/base64"
|
"encoding/base64"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"errors"
|
"errors"
|
||||||
"git.openprivacy.ca/openprivacy/libricochet-go/log"
|
"git.openprivacy.ca/openprivacy/libricochet-go/log"
|
||||||
"github.com/golang/protobuf/proto"
|
|
||||||
"strings"
|
"strings"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
var autoHandleableEvents = map[event.Type]bool{event.EncryptedGroupMessage: true, event.PeerStateChange: true, event.ServerStateChange: true, event.NewGroupInvite: true}
|
||||||
|
|
||||||
// cwtchPeer manages incoming and outgoing connections and all processing for a Cwtch cwtchPeer
|
// cwtchPeer manages incoming and outgoing connections and all processing for a Cwtch cwtchPeer
|
||||||
type cwtchPeer struct {
|
type cwtchPeer struct {
|
||||||
Profile *model.Profile
|
Profile *model.Profile
|
||||||
|
@ -30,6 +30,7 @@ type cwtchPeer struct {
|
||||||
// directly implement a cwtchPeer.
|
// directly implement a cwtchPeer.
|
||||||
type CwtchPeer interface {
|
type CwtchPeer interface {
|
||||||
Init(event.Manager)
|
Init(event.Manager)
|
||||||
|
AutoHandleEvents(events []event.Type)
|
||||||
PeerWithOnion(string)
|
PeerWithOnion(string)
|
||||||
InviteOnionToGroup(string, string) error
|
InviteOnionToGroup(string, string) error
|
||||||
SendMessageToPeer(string, string) string
|
SendMessageToPeer(string, string) string
|
||||||
|
@ -51,7 +52,7 @@ type CwtchPeer interface {
|
||||||
|
|
||||||
StartGroup(string) (string, []byte, error)
|
StartGroup(string) (string, []byte, error)
|
||||||
|
|
||||||
ImportGroup(string) (string, error)
|
ImportGroup(string) error
|
||||||
ExportGroup(string) (string, error)
|
ExportGroup(string) (string, error)
|
||||||
|
|
||||||
GetGroup(string) *model.Group
|
GetGroup(string) *model.Group
|
||||||
|
@ -79,6 +80,7 @@ func NewCwtchPeer(name string) CwtchPeer {
|
||||||
func FromProfile(profile *model.Profile) CwtchPeer {
|
func FromProfile(profile *model.Profile) CwtchPeer {
|
||||||
cp := new(cwtchPeer)
|
cp := new(cwtchPeer)
|
||||||
cp.Profile = profile
|
cp.Profile = profile
|
||||||
|
cp.shutdown = false
|
||||||
return cp
|
return cp
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -88,35 +90,34 @@ func (cp *cwtchPeer) Init(eventBus event.Manager) {
|
||||||
go cp.eventHandler()
|
go cp.eventHandler()
|
||||||
|
|
||||||
cp.eventBus = eventBus
|
cp.eventBus = eventBus
|
||||||
cp.eventBus.Subscribe(event.EncryptedGroupMessage, cp.queue)
|
cp.AutoHandleEvents([]event.Type{event.EncryptedGroupMessage})
|
||||||
cp.eventBus.Subscribe(event.NewGroupInvite, cp.queue)
|
}
|
||||||
cp.eventBus.Subscribe(event.ServerStateChange, cp.queue)
|
|
||||||
cp.eventBus.Subscribe(event.PeerStateChange, cp.queue)
|
// AutoHandleEvents sets an event (if able) to be handled by this peer
|
||||||
|
func (cp *cwtchPeer) AutoHandleEvents(events []event.Type) {
|
||||||
|
for _, ev := range events {
|
||||||
|
if _, exists := autoHandleableEvents[ev]; exists {
|
||||||
|
cp.eventBus.Subscribe(ev, cp.queue)
|
||||||
|
} else {
|
||||||
|
log.Errorf("Peer asked to autohandle event it cannot: %v\n", ev)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// ImportGroup intializes a group from an imported source rather than a peer invite
|
// ImportGroup intializes a group from an imported source rather than a peer invite
|
||||||
func (cp *cwtchPeer) ImportGroup(exportedInvite string) (groupID string, err error) {
|
func (cp *cwtchPeer) ImportGroup(exportedInvite string) (err error) {
|
||||||
if strings.HasPrefix(exportedInvite, "torv3") {
|
if strings.HasPrefix(exportedInvite, "torv3") {
|
||||||
data, err := base64.StdEncoding.DecodeString(exportedInvite[5+44:])
|
data, err := base64.StdEncoding.DecodeString(exportedInvite[5:])
|
||||||
if err == nil {
|
|
||||||
cpp := &protocol.CwtchPeerPacket{}
|
|
||||||
err = proto.Unmarshal(data, cpp)
|
|
||||||
if err == nil {
|
|
||||||
jsobj, err := proto.Marshal(cpp.GetGroupChatInvite())
|
|
||||||
if err == nil {
|
if err == nil {
|
||||||
cp.eventBus.Publish(event.NewEvent(event.NewGroupInvite, map[event.Field]string{
|
cp.eventBus.Publish(event.NewEvent(event.NewGroupInvite, map[event.Field]string{
|
||||||
event.GroupInvite: string(jsobj),
|
event.GroupInvite: string(data),
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
log.Errorf("error serializing group: %v", err)
|
log.Errorf("error decoding group invite: %v", err)
|
||||||
}
|
}
|
||||||
return cpp.GroupChatInvite.GetGroupName(), nil
|
return nil
|
||||||
}
|
}
|
||||||
}
|
return errors.New("unsupported exported group type")
|
||||||
} else {
|
|
||||||
err = errors.New("unsupported exported group type")
|
|
||||||
}
|
|
||||||
return
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// ExportGroup serializes a group invite so it can be given offline
|
// ExportGroup serializes a group invite so it can be given offline
|
||||||
|
@ -125,7 +126,7 @@ func (cp *cwtchPeer) ExportGroup(groupID string) (string, error) {
|
||||||
if group != nil {
|
if group != nil {
|
||||||
invite, err := group.Invite(group.GetInitialMessage())
|
invite, err := group.Invite(group.GetInitialMessage())
|
||||||
if err == nil {
|
if err == nil {
|
||||||
exportedInvite := "torv3" + base64.StdEncoding.EncodeToString(cp.Profile.Ed25519PublicKey) + base64.StdEncoding.EncodeToString(invite)
|
exportedInvite := "torv3" + base64.StdEncoding.EncodeToString(invite)
|
||||||
return exportedInvite, err
|
return exportedInvite, err
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -342,18 +343,18 @@ func (cp *cwtchPeer) eventHandler() {
|
||||||
for {
|
for {
|
||||||
ev := cp.queue.Next()
|
ev := cp.queue.Next()
|
||||||
switch ev.EventType {
|
switch ev.EventType {
|
||||||
|
/***** Default auto handled events *****/
|
||||||
|
|
||||||
case event.EncryptedGroupMessage:
|
case event.EncryptedGroupMessage:
|
||||||
ok, groupID, message, seen := 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]))
|
||||||
if ok && !seen {
|
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.Signature: string(message.Signature), event.PreviousSignature: string(message.PreviousMessageSig), 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.PreviousSignature: string(message.PreviousMessageSig), event.RemotePeer: message.PeerID}))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/***** Non default but requestable handlable events *****/
|
||||||
|
|
||||||
case event.NewGroupInvite:
|
case event.NewGroupInvite:
|
||||||
var groupInvite protocol.GroupChatInvite
|
cp.Profile.ProcessInvite(ev.Data[event.GroupInvite], ev.Data[event.RemotePeer])
|
||||||
err := proto.Unmarshal([]byte(ev.Data[event.GroupInvite]), &groupInvite)
|
|
||||||
if err != nil {
|
|
||||||
log.Errorf("NewGroupInvite could not json decode invite: %v\n", err)
|
|
||||||
}
|
|
||||||
cp.Profile.ProcessInvite(&groupInvite, ev.Data[event.RemotePeer])
|
|
||||||
case event.PeerStateChange:
|
case event.PeerStateChange:
|
||||||
if _, exists := cp.Profile.Contacts[ev.Data[event.RemotePeer]]; exists {
|
if _, exists := cp.Profile.Contacts[ev.Data[event.RemotePeer]]; exists {
|
||||||
cp.Profile.Contacts[ev.Data[event.RemotePeer]].State = ev.Data[event.ConnectionState]
|
cp.Profile.Contacts[ev.Data[event.RemotePeer]].State = ev.Data[event.ConnectionState]
|
||||||
|
@ -364,6 +365,7 @@ func (cp *cwtchPeer) eventHandler() {
|
||||||
group.State = ev.Data[event.ConnectionState]
|
group.State = ev.Data[event.ConnectionState]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if ev.EventType != "" {
|
if ev.EventType != "" {
|
||||||
log.Errorf("peer event handler received an event it was not subscribed for: %v", ev.EventType)
|
log.Errorf("peer event handler received an event it was not subscribed for: %v", ev.EventType)
|
||||||
|
|
|
@ -11,7 +11,6 @@ import (
|
||||||
"git.openprivacy.ca/openprivacy/libricochet-go/connectivity"
|
"git.openprivacy.ca/openprivacy/libricochet-go/connectivity"
|
||||||
"git.openprivacy.ca/openprivacy/libricochet-go/log"
|
"git.openprivacy.ca/openprivacy/libricochet-go/log"
|
||||||
"git.openprivacy.ca/openprivacy/libricochet-go/utils"
|
"git.openprivacy.ca/openprivacy/libricochet-go/utils"
|
||||||
"github.com/golang/protobuf/proto"
|
|
||||||
"golang.org/x/crypto/ed25519"
|
"golang.org/x/crypto/ed25519"
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
@ -332,12 +331,7 @@ func (e *engine) sendMessageToGroup(server string, ct []byte, sig []byte) {
|
||||||
func (e *engine) handlePeerMessage(hostname string, context string, message []byte) {
|
func (e *engine) handlePeerMessage(hostname string, context string, message []byte) {
|
||||||
log.Debugf("New message from peer: %v %v", hostname, context)
|
log.Debugf("New message from peer: %v %v", hostname, context)
|
||||||
if context == event.ContextInvite {
|
if context == event.ContextInvite {
|
||||||
cpp := &protocol.CwtchPeerPacket{}
|
e.eventManager.Publish(event.NewEvent(event.NewGroupInvite, map[event.Field]string{event.TimestampReceived: time.Now().Format(time.RFC3339Nano), event.RemotePeer: hostname, event.GroupInvite: string(message)}))
|
||||||
err := proto.Unmarshal(message, cpp)
|
|
||||||
if err == nil && cpp.GetGroupChatInvite() != nil {
|
|
||||||
marshal, _ := proto.Marshal(cpp.GetGroupChatInvite())
|
|
||||||
e.eventManager.Publish(event.NewEvent(event.NewGroupInvite, map[event.Field]string{event.TimestampReceived: time.Now().Format(time.RFC3339Nano), event.RemotePeer: hostname, event.GroupInvite: string(marshal)}))
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
e.eventManager.Publish(event.NewEvent(event.NewMessageFromPeer, map[event.Field]string{event.TimestampReceived: time.Now().Format(time.RFC3339Nano), event.RemotePeer: hostname, event.Data: string(message)}))
|
e.eventManager.Publish(event.NewEvent(event.NewMessageFromPeer, map[event.Field]string{event.TimestampReceived: time.Now().Format(time.RFC3339Nano), event.RemotePeer: hostname, event.Data: string(message)}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,10 +3,8 @@ package storage
|
||||||
import (
|
import (
|
||||||
"cwtch.im/cwtch/event"
|
"cwtch.im/cwtch/event"
|
||||||
"cwtch.im/cwtch/model"
|
"cwtch.im/cwtch/model"
|
||||||
"cwtch.im/cwtch/protocol"
|
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"git.openprivacy.ca/openprivacy/libricochet-go/log"
|
"git.openprivacy.ca/openprivacy/libricochet-go/log"
|
||||||
"github.com/golang/protobuf/proto"
|
|
||||||
"os"
|
"os"
|
||||||
"time"
|
"time"
|
||||||
)
|
)
|
||||||
|
@ -212,15 +210,14 @@ func (ps *profileStore) eventHandler() {
|
||||||
log.Errorf("error accepting group invite")
|
log.Errorf("error accepting group invite")
|
||||||
}
|
}
|
||||||
case event.NewGroupInvite:
|
case event.NewGroupInvite:
|
||||||
var gci protocol.GroupChatInvite
|
gid, err := ps.profile.ProcessInvite(ev.Data[event.GroupInvite], ev.Data[event.RemotePeer])
|
||||||
err := proto.Unmarshal([]byte(ev.Data[event.GroupInvite]), &gci)
|
log.Errorf("gid: %v err:%v\n", gid, err)
|
||||||
if err == nil {
|
if err == nil {
|
||||||
ps.profile.ProcessInvite(&gci, ev.Data[event.RemotePeer])
|
|
||||||
ps.save()
|
ps.save()
|
||||||
group := ps.profile.Groups[gci.GetGroupName()]
|
group := ps.profile.Groups[gid]
|
||||||
ps.streamStores[group.GroupID] = NewStreamStore(ps.directory, group.LocalID, ps.password)
|
ps.streamStores[group.GroupID] = NewStreamStore(ps.directory, group.LocalID, ps.password)
|
||||||
} else {
|
} else {
|
||||||
log.Errorf("error storing new group invite: %v %v", ev, err)
|
log.Errorf("error storing new group invite: %v (%v)", err, ev)
|
||||||
}
|
}
|
||||||
case event.NewMessageFromGroup:
|
case event.NewMessageFromGroup:
|
||||||
groupid := ev.Data[event.GroupID]
|
groupid := ev.Data[event.GroupID]
|
||||||
|
|
|
@ -2,8 +2,6 @@ package storage
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"cwtch.im/cwtch/event"
|
"cwtch.im/cwtch/event"
|
||||||
"cwtch.im/cwtch/protocol"
|
|
||||||
"github.com/golang/protobuf/proto"
|
|
||||||
"os"
|
"os"
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
@ -32,9 +30,6 @@ func TestProfileStoreWriteRead(t *testing.T) {
|
||||||
t.Errorf("Creating group invite: %v\n", err)
|
t.Errorf("Creating group invite: %v\n", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
packet := protocol.CwtchPeerPacket{}
|
|
||||||
proto.Unmarshal(invite, &packet)
|
|
||||||
invite, _ = proto.Marshal(packet.GetGroupChatInvite())
|
|
||||||
eventBus.Publish(event.NewEvent(event.NewGroupInvite, map[event.Field]string{event.TimestampReceived: time.Now().Format(time.RFC3339Nano), event.RemotePeer: ps1.GetProfileCopy(true).Onion, event.GroupInvite: string(invite)}))
|
eventBus.Publish(event.NewEvent(event.NewGroupInvite, map[event.Field]string{event.TimestampReceived: time.Now().Format(time.RFC3339Nano), event.RemotePeer: ps1.GetProfileCopy(true).Onion, event.GroupInvite: string(invite)}))
|
||||||
time.Sleep(1 * time.Second)
|
time.Sleep(1 * time.Second)
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,7 @@ package testing
|
||||||
import (
|
import (
|
||||||
app2 "cwtch.im/cwtch/app"
|
app2 "cwtch.im/cwtch/app"
|
||||||
"cwtch.im/cwtch/app/utils"
|
"cwtch.im/cwtch/app/utils"
|
||||||
|
"cwtch.im/cwtch/event"
|
||||||
"cwtch.im/cwtch/event/bridge"
|
"cwtch.im/cwtch/event/bridge"
|
||||||
"cwtch.im/cwtch/model"
|
"cwtch.im/cwtch/model"
|
||||||
"cwtch.im/cwtch/peer"
|
"cwtch.im/cwtch/peer"
|
||||||
|
@ -163,12 +164,15 @@ func TestCwtchPeerIntegration(t *testing.T) {
|
||||||
|
|
||||||
alice := utils.WaitGetPeer(app, "alice")
|
alice := utils.WaitGetPeer(app, "alice")
|
||||||
fmt.Println("Alice created:", alice.GetProfile().Onion)
|
fmt.Println("Alice created:", alice.GetProfile().Onion)
|
||||||
|
alice.AutoHandleEvents([]event.Type{event.PeerStateChange, event.ServerStateChange, event.NewGroupInvite})
|
||||||
|
|
||||||
bob := utils.WaitGetPeer(app, "bob")
|
bob := utils.WaitGetPeer(app, "bob")
|
||||||
fmt.Println("Bob created:", bob.GetProfile().Onion)
|
fmt.Println("Bob created:", bob.GetProfile().Onion)
|
||||||
|
bob.AutoHandleEvents([]event.Type{event.PeerStateChange, event.ServerStateChange, event.NewGroupInvite})
|
||||||
|
|
||||||
carol := utils.WaitGetPeer(appClient, "carol")
|
carol := utils.WaitGetPeer(appClient, "carol")
|
||||||
fmt.Println("Carol created:", carol.GetProfile().Onion)
|
fmt.Println("Carol created:", carol.GetProfile().Onion)
|
||||||
|
carol.AutoHandleEvents([]event.Type{event.PeerStateChange, event.ServerStateChange, event.NewGroupInvite})
|
||||||
|
|
||||||
app.LaunchPeers()
|
app.LaunchPeers()
|
||||||
appClient.LaunchPeers()
|
appClient.LaunchPeers()
|
||||||
|
|
Loading…
Reference in New Issue