Browse Source

Adding Custom Attributes to Contacts, Removing ClientIdentity Processing

pull/150/head
Sarah Jamie Lewis 4 years ago
parent
commit
1531885bcd
  1. 4
      model/message_test.go
  2. 46
      model/profile.go
  3. 5
      model/profile_test.go
  4. 23
      peer/connections/peerpeerconnection.go
  5. 28
      peer/connections/peerpeerconnection_test.go
  6. 2
      peer/connections/peerserverconnection_test.go
  7. 11
      peer/cwtch_peer.go
  8. 10
      peer/peer/peer_channel.go
  9. 25
      peer/peer/peer_channel_test.go

4
model/message_test.go

@ -23,8 +23,8 @@ func TestMessagePadding(t *testing.T) {
group := alice.GetGroupByGroupID(gid)
c1, s1, _ := sarah.EncryptMessageToGroup("Hello World 1", group.GroupID)
t.Logf("Length of Encrypted Message: %v", len(c1))
c1, s1, err := sarah.EncryptMessageToGroup("Hello World 1", group.GroupID)
t.Logf("Length of Encrypted Message: %v %v", len(c1), err)
alice.AttemptDecryption(c1, s1)
c2, s2, _ := alice.EncryptMessageToGroup("Hello World 2", group.GroupID)

46
model/profile.go

@ -21,6 +21,8 @@ type PublicProfile struct {
Trusted bool
Blocked bool
Onion string
Attributes map[string]string
lock sync.Mutex
}
// Profile encapsulates all the attributes necessary to be a Cwtch Peer.
@ -33,6 +35,25 @@ type Profile struct {
lock sync.Mutex
}
func (p *PublicProfile) init() {
p.Attributes = make(map[string]string)
}
// SetAttribute allows applications to store arbitrary configuration info at the profile level.
func (p *PublicProfile) SetAttribute(name string, value string) {
p.lock.Lock()
defer p.lock.Unlock()
p.Attributes[name] = value
}
// GetAttribute returns the value of a value set with SetCustomAttribute. If no such value has been set exists is set to false.
func (p *PublicProfile) GetAttribute(name string) (value string, exists bool) {
p.lock.Lock()
defer p.lock.Unlock()
value, exists = p.Attributes[name]
return
}
// GenerateNewProfile creates a new profile, with new encryption and signing keys, and a profile name.
func GenerateNewProfile(name string) *Profile {
p := new(Profile)
@ -63,15 +84,13 @@ func (p *Profile) GetCwtchIdentityPacket() (message []byte) {
return
}
// AddCwtchIdentity takes a wire message and if it is a CwtchIdentity message adds the identity as a contact
// otherwise returns an error
func (p *Profile) AddCwtchIdentity(onion string, ci *protocol.CwtchIdentity) {
p.AddContact(onion, &PublicProfile{Name: ci.GetName(), Ed25519PublicKey: ci.GetEd25519PublicKey(), Onion: onion})
}
// AddContact allows direct manipulation of cwtch contacts
func (p *Profile) AddContact(onion string, profile *PublicProfile) {
p.lock.Lock()
profile.init()
// TODO: More Robust V3 Onion Handling
decodedPub, _ := base32.StdEncoding.DecodeString(strings.ToUpper(onion[:56]))
profile.Ed25519PublicKey = ed25519.PublicKey(decodedPub[:32])
p.Contacts[onion] = profile
p.lock.Unlock()
}
@ -253,14 +272,13 @@ func (p *Profile) ProcessInvite(gci *protocol.GroupChatInvite, peerHostname stri
func (p *Profile) AddGroup(group *Group) {
existingGroup, exists := p.Groups[group.GroupID]
if !exists {
owner, ok := p.GetContact(group.Owner)
if ok {
valid := ed25519.Verify(owner.Ed25519PublicKey, []byte(group.GroupID+group.GroupServer), group.SignedGroupID)
if valid {
p.lock.Lock()
defer p.lock.Unlock()
p.Groups[group.GroupID] = group
}
// TODO More robust error handling (confirm this onion checksum is correct)
decodedPub, _ := base32.StdEncoding.DecodeString(strings.ToUpper(group.Owner[:56]))
valid := ed25519.Verify(ed25519.PublicKey(decodedPub[:32]), []byte(group.GroupID+group.GroupServer), group.SignedGroupID)
if valid {
p.lock.Lock()
defer p.lock.Unlock()
p.Groups[group.GroupID] = group
}
} else if exists && existingGroup.Owner == group.Owner {
p.lock.Lock()

5
model/profile_test.go

@ -17,8 +17,9 @@ func TestProfileIdentity(t *testing.T) {
if err != nil {
t.Errorf("alice should have added sarah as a contact %v", err)
}
alice.AddCwtchIdentity("sarah.onion", ci.GetCwtchIdentify())
if alice.Contacts["sarah.onion"].Name != "Sarah" {
alice.AddContact(sarah.Onion, &sarah.PublicProfile)
if alice.Contacts[sarah.Onion].Name != "Sarah" {
t.Errorf("alice should have added sarah as a contact %v", alice.Contacts)
}

23
peer/connections/peerpeerconnection.go

@ -40,21 +40,11 @@ func (ppc *PeerPeerConnection) GetState() ConnectionState {
return ppc.state
}
// ClientIdentity passes the given CwtchIdentity packet to the profile.
func (ppc *PeerPeerConnection) ClientIdentity(ci *protocol.CwtchIdentity) {
ppc.profile.AddCwtchIdentity(ppc.PeerHostname, ci)
}
// HandleGroupInvite passes the given group invite tothe profile
func (ppc *PeerPeerConnection) HandleGroupInvite(gci *protocol.GroupChatInvite) {
ppc.profile.ProcessInvite(gci, ppc.PeerHostname)
}
// GetClientIdentityPacket returns nil to avoid peers constantly sending identity packets to eachother.
func (ppc *PeerPeerConnection) GetClientIdentityPacket() []byte {
return nil
}
// HandlePacket handles data packets on the optional data channel
func (ppc *PeerPeerConnection) HandlePacket(data []byte) []byte {
return ppc.dataHandler(ppc.PeerHostname, data)
@ -145,19 +135,6 @@ func (ppc *PeerPeerConnection) Run() error {
return nil
})
}
time.Sleep(time.Second * 1)
ppc.connection.Do(func() error {
channel := ppc.connection.Channel("im.cwtch.peer", channels.Outbound)
if channel != nil {
peerchannel, ok := channel.Handler.(*peer.CwtchPeerChannel)
if ok {
peerchannel.SendMessage(ppc.profile.GetCwtchIdentityPacket())
}
}
return nil
})
}()
ppc.connection.Process(ppc)

28
peer/connections/peerpeerconnection_test.go

@ -40,21 +40,6 @@ func runtestpeer(t *testing.T, tp *TestPeer, identity identity.Identity) {
return cpc
})
go func() {
alice := model.GenerateNewProfile("alice")
time.Sleep(time.Second * 1)
rc.Do(func() error {
channel := rc.Channel("im.cwtch.peer", channels.Inbound)
if channel != nil {
peerchannel, ok := channel.Handler.(*peer.CwtchPeerChannel)
if ok {
peerchannel.SendMessage(alice.GetCwtchIdentityPacket())
}
}
return nil
})
}()
rc.Process(tp)
}
@ -64,18 +49,10 @@ type TestPeer struct {
ReceivedGroupInvite bool
}
func (tp *TestPeer) ClientIdentity(ci *protocol.CwtchIdentity) {
tp.ReceivedIdentityPacket = true
}
func (tp *TestPeer) HandleGroupInvite(gci *protocol.GroupChatInvite) {
tp.ReceivedGroupInvite = true
}
func (tp *TestPeer) GetClientIdentityPacket() []byte {
return nil
}
func TestPeerPeerConnection(t *testing.T) {
pub, priv, _ := ed25519.GenerateKey(rand.Reader)
identity := identity.InitializeV3("", &priv, &pub)
@ -97,11 +74,6 @@ func TestPeerPeerConnection(t *testing.T) {
if state != AUTHENTICATED {
t.Errorf("connection state should be authenticated(3), was instead %v", state)
}
if tp.ReceivedIdentityPacket == false {
t.Errorf("should have received an identity packet")
}
_, invite, _ := profile.StartGroup("aaa.onion")
ppc.SendGroupInvite(invite)
time.Sleep(time.Second * 3)

2
peer/connections/peerserverconnection_test.go

@ -97,7 +97,7 @@ func TestPeerServerConnection(t *testing.T) {
}
if numcalls != 2 {
t.Errorf("Should have received 2 calls from fetch request, instead received %v", numcalls)
t.Errorf("Should have received 2 calls from fetch request, instead received %v", numcalls)
}
}

11
peer/cwtch_peer.go

@ -366,23 +366,12 @@ type CwtchPeerHandler struct {
DataHandler func(string, []byte) []byte
}
// ClientIdentity handles incoming ClientIdentity packets
func (cph *CwtchPeerHandler) ClientIdentity(ci *protocol.CwtchIdentity) {
log.Printf("Received Client Identity from %v %v\n", cph.Onion, ci.String())
cph.Peer.Profile.AddCwtchIdentity(cph.Onion, ci)
}
// HandleGroupInvite handles incoming GroupInvites
func (cph *CwtchPeerHandler) HandleGroupInvite(gci *protocol.GroupChatInvite) {
log.Printf("Received GroupID from %v %v\n", cph.Onion, gci.String())
cph.Peer.Profile.ProcessInvite(gci, cph.Onion)
}
// GetClientIdentityPacket returns our ClientIdentity packet so it can be sent to the connected peer.
func (cph *CwtchPeerHandler) GetClientIdentityPacket() []byte {
return cph.Peer.Profile.GetCwtchIdentityPacket()
}
// HandlePacket handles the Cwtch cwtchPeer Data Channel
func (cph *CwtchPeerHandler) HandlePacket(data []byte) []byte {
return cph.DataHandler(cph.Onion, data)

10
peer/peer/peer_channel.go

@ -24,9 +24,7 @@ type CwtchPeerChannel struct {
// CwtchPeerChannelHandler is implemented by an application type to receive
// events from a CwtchPeerChannel.
type CwtchPeerChannelHandler interface {
ClientIdentity(*protocol.CwtchIdentity)
HandleGroupInvite(*protocol.GroupChatInvite)
GetClientIdentityPacket() []byte
}
// SendMessage sends a raw message on this channel
@ -99,13 +97,7 @@ func (cpc *CwtchPeerChannel) Packet(data []byte) {
cpp := &protocol.CwtchPeerPacket{}
err := proto.Unmarshal(data, cpp)
if err == nil {
if cpp.GetCwtchIdentify() != nil {
cpc.Handler.ClientIdentity(cpp.GetCwtchIdentify())
pkt := cpc.Handler.GetClientIdentityPacket()
if pkt != nil {
cpc.SendMessage(pkt)
}
} else if cpp.GetGroupChatInvite() != nil {
if cpp.GetGroupChatInvite() != nil {
cpc.Handler.HandleGroupInvite(cpp.GetGroupChatInvite())
}
} else {

25
peer/peer/peer_channel_test.go

@ -85,37 +85,18 @@ func TestPeerChannel(t *testing.T) {
t.Errorf("Channel should no longer be pending")
}
gm := &protocol.CwtchIdentity{
Name: "hello",
Ed25519PublicKey: []byte{},
}
cpp := &protocol.CwtchPeerPacket{
CwtchIdentify: gm,
}
packet, _ := proto.Marshal(cpp)
cpc.Packet(packet)
if th.Received == false {
t.Errorf("Should have sent packet to handler")
}
cpc2.SendMessage(packet)
if sent == false {
t.Errorf("Should have sent packet to channel")
}
gci := &protocol.GroupChatInvite{
GroupName: "hello",
GroupSharedKey: []byte{},
ServerHost: "abc.onion",
}
cpp = &protocol.CwtchPeerPacket{
cpp := &protocol.CwtchPeerPacket{
GroupChatInvite: gci,
}
packet, _ = proto.Marshal(cpp)
packet, _ := proto.Marshal(cpp)
cpc.Packet(packet)
if th.ReceviedGroupInvite == false {
if sent && th.ReceviedGroupInvite == false {
t.Errorf("Should have sent invite packet to handler")
}
}

Loading…
Cancel
Save