Integrate Group Name into Invite
the build was successful Details

This commit is contained in:
Sarah Jamie Lewis 2020-12-16 17:40:03 -08:00
parent a371859b84
commit a1b2d8530f
10 changed files with 41 additions and 13 deletions

View File

@ -46,6 +46,10 @@ const (
// Imported // Imported
NewGroupInvite = Type("NewGroupInvite") NewGroupInvite = Type("NewGroupInvite")
// Inform the UI about a new group
// GroupID: groupID (allows them to fetch from the peer)
NewGroup = Type("NewGroup")
// GroupID // GroupID
AcceptGroupInvite = Type("AcceptGroupInvite") AcceptGroupInvite = Type("AcceptGroupInvite")

View File

@ -2,6 +2,7 @@ package model
import ( import (
"crypto/rand" "crypto/rand"
"cwtch.im/cwtch/model/attr"
"cwtch.im/cwtch/protocol/groups" "cwtch.im/cwtch/protocol/groups"
"encoding/json" "encoding/json"
"errors" "errors"
@ -64,6 +65,9 @@ func NewGroup(server string) (*Group, error) {
copy(group.GroupKey[:], groupKey[:]) copy(group.GroupKey[:], groupKey[:])
group.Owner = "self" group.Owner = "self"
group.Attributes = make(map[string]string) group.Attributes = make(map[string]string)
// By default we set the "name" of the group to a random string, we can override this later, but to simplify the
// codes around invite, we assume that this is always set.
group.Attributes[attr.GetLocalScope("name")] = group.GroupID
return group, nil return group, nil
} }
@ -95,7 +99,8 @@ func (g *Group) Invite(initialMessage []byte) ([]byte, error) {
g.InitialMessage = initialMessage[:] g.InitialMessage = initialMessage[:]
gci := &groups.GroupInvite{ gci := &groups.GroupInvite{
GroupName: g.GroupID, GroupID: g.GroupID,
GroupName: g.Attributes[attr.GetLocalScope("name")],
SharedKey: g.GroupKey[:], SharedKey: g.GroupKey[:],
ServerHost: g.GroupServer, ServerHost: g.GroupServer,
SignedGroupID: g.SignedGroupID[:], SignedGroupID: g.SignedGroupID[:],

View File

@ -361,13 +361,13 @@ func (p *Profile) GetGroup(groupID string) (g *Group) {
} }
// ProcessInvite adds a new group invite to the profile. returns the new group ID // ProcessInvite adds a new group invite to the profile. returns the new group ID
func (p *Profile) ProcessInvite(invite string, peerHostname string) (string, error) { func (p *Profile) ProcessInvite(invite string, peerHostname string) (string, string, error) {
var gci groups.GroupInvite var gci groups.GroupInvite
err := json.Unmarshal([]byte(invite), &gci) err := json.Unmarshal([]byte(invite), &gci)
if err == nil { if err == nil {
group := new(Group) group := new(Group)
group.Version = CurrentGroupVersion group.Version = CurrentGroupVersion
group.GroupID = gci.GroupName group.GroupID = gci.GroupID
group.LocalID = GenerateRandomID() group.LocalID = GenerateRandomID()
group.SignedGroupID = gci.SignedGroupID group.SignedGroupID = gci.SignedGroupID
copy(group.GroupKey[:], gci.SharedKey[:]) copy(group.GroupKey[:], gci.SharedKey[:])
@ -377,9 +377,9 @@ func (p *Profile) ProcessInvite(invite string, peerHostname string) (string, err
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 group.GroupID, gci.GroupName, nil
} }
return "", err 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.

View File

@ -55,7 +55,7 @@ type CwtchPeer interface {
StoreMessage(onion string, messageTxt string, sent time.Time) StoreMessage(onion string, messageTxt string, sent time.Time)
SetContactAuthorization(string, model.Authorization) error SetContactAuthorization(string, model.Authorization) error
ProcessInvite(string, string) (string, error) ProcessInvite(string, string) (string, string, error)
AcceptInvite(string) error AcceptInvite(string) error
RejectInvite(string) RejectInvite(string)
DeleteContact(string) DeleteContact(string)
@ -63,6 +63,7 @@ type CwtchPeer interface {
AddServer(string) error AddServer(string) error
JoinServer(string) error JoinServer(string) error
GetServers() []string
SendMessageToGroupTracked(string, string) (string, error) SendMessageToGroupTracked(string, string) (string, error)
GetName() string GetName() string
@ -294,6 +295,18 @@ func (cp *cwtchPeer) GetContacts() []string {
return cp.Profile.GetContacts() return cp.Profile.GetContacts()
} }
// GetServers returns an unordered list of servers
func (cp *cwtchPeer) GetServers() []string {
contacts := cp.Profile.GetContacts()
var servers []string
for _, contact := range contacts {
if cp.GetContact(contact).IsServer() {
servers = append(servers, contact)
}
}
return servers
}
// GetContact returns a given contact, nil is no such contact exists // GetContact returns a given contact, nil is no such contact exists
func (cp *cwtchPeer) GetContact(onion string) *model.PublicProfile { func (cp *cwtchPeer) GetContact(onion string) *model.PublicProfile {
cp.mutex.Lock() cp.mutex.Lock()
@ -440,7 +453,7 @@ func (cp *cwtchPeer) SetContactAuthorization(peer string, authorization model.Au
} }
// ProcessInvite adds a new group invite to the profile. returns the new group ID // ProcessInvite adds a new group invite to the profile. returns the new group ID
func (cp *cwtchPeer) ProcessInvite(invite string, remotePeer string) (string, error) { func (cp *cwtchPeer) ProcessInvite(invite string, remotePeer string) (string, string, error) {
cp.mutex.Lock() cp.mutex.Lock()
defer cp.mutex.Unlock() defer cp.mutex.Unlock()
return cp.Profile.ProcessInvite(invite, remotePeer) return cp.Profile.ProcessInvite(invite, remotePeer)
@ -656,17 +669,19 @@ func (cp *cwtchPeer) eventHandler() {
} }
case event.NewGroupInvite: case event.NewGroupInvite:
cp.mutex.Lock() cp.mutex.Lock()
group, err := cp.Profile.ProcessInvite(ev.Data[event.GroupInvite], ev.Data[event.RemotePeer]) group, groupName, err := cp.Profile.ProcessInvite(ev.Data[event.GroupInvite], ev.Data[event.RemotePeer])
if err == nil { if err == nil {
if ev.Data[event.Imported] == "true" { if ev.Data[event.Imported] == "true" {
cp.Profile.GetGroup(group).Accepted = true cp.Profile.GetGroup(group).Accepted = true
cp.mutex.Unlock() // TODO...seriously need a better way of handling these cases cp.mutex.Unlock() // TODO...seriously need a better way of handling these cases
cp.SetGroupAttribute(group, attr.GetLocalScope("name"), groupName)
err = cp.JoinServer(cp.Profile.GetGroup(group).GroupServer) err = cp.JoinServer(cp.Profile.GetGroup(group).GroupServer)
cp.mutex.Lock() cp.mutex.Lock()
if err != nil { if err != nil {
log.Errorf("Joining Server should have worked %v", err) log.Errorf("Joining Server should have worked %v", err)
} }
} }
cp.eventBus.Publish(event.NewEvent(event.NewGroup, map[event.Field]string{event.GroupID: group}))
} }
cp.mutex.Unlock() cp.mutex.Unlock()
case event.PeerStateChange: case event.PeerStateChange:

View File

@ -10,7 +10,7 @@ import (
// Fuzz various group related functions // Fuzz various group related functions
func Fuzz(data []byte) int { func Fuzz(data []byte) int {
profile := model.GenerateNewProfile("fuzz") profile := model.GenerateNewProfile("fuzz")
inviteid, err := profile.ProcessInvite(string(data), profile.Onion) inviteid, _, err := profile.ProcessInvite(string(data), profile.Onion)
if err != nil { if err != nil {
if inviteid != "" { if inviteid != "" {

View File

@ -11,6 +11,7 @@ const CwtchServerSyncedCapability = tapir.Capability("CwtchServerSyncedCapabilit
// GroupInvite provides a structured type for communicating group information to peers // GroupInvite provides a structured type for communicating group information to peers
type GroupInvite struct { type GroupInvite struct {
GroupID string
GroupName string GroupName string
SignedGroupID []byte SignedGroupID []byte
Timestamp uint64 Timestamp uint64

View File

@ -82,4 +82,7 @@ func main() {
bundle := server.KeyBundle().Serialize() bundle := server.KeyBundle().Serialize()
log.Infof("Server Config: server:%s", base64.StdEncoding.EncodeToString(bundle)) log.Infof("Server Config: server:%s", base64.StdEncoding.EncodeToString(bundle))
server.Run(acn) server.Run(acn)
for {
time.Sleep(time.Second)
}
} }

View File

@ -32,7 +32,7 @@ type Server struct {
onionServiceStopped bool onionServiceStopped bool
running bool running bool
existingMessageCount int existingMessageCount int
lock sync.RWMutex lock sync.RWMutex
} }
// Setup initialized a server from a given configuration // Setup initialized a server from a given configuration

View File

@ -52,9 +52,9 @@ func ReadProfile(directory, password string) (*model.Profile, error) {
/********************************************************************************************/ /********************************************************************************************/
// AddGroup For testing, adds a group to the profile (and startsa stream store) // AddGroup For testing, adds a group to the profile (and starts a stream store)
func (ps *ProfileStoreV0) AddGroup(invite []byte, peer string) { func (ps *ProfileStoreV0) AddGroup(invite []byte, peer string) {
gid, err := ps.profile.ProcessInvite(string(invite), peer) gid, _, err := ps.profile.ProcessInvite(string(invite), peer)
if err == nil { if err == nil {
ps.save() ps.save()
group := ps.profile.Groups[gid] group := ps.profile.Groups[gid]

View File

@ -373,7 +373,7 @@ func (ps *ProfileStoreV1) eventHandler() {
log.Errorf("error accepting group invite") log.Errorf("error accepting group invite")
} }
case event.NewGroupInvite: case event.NewGroupInvite:
gid, err := ps.profile.ProcessInvite(ev.Data[event.GroupInvite], ev.Data[event.RemotePeer]) gid, _, err := ps.profile.ProcessInvite(ev.Data[event.GroupInvite], ev.Data[event.RemotePeer])
if err == nil { if err == nil {
ps.save() ps.save()
group := ps.profile.Groups[gid] group := ps.profile.Groups[gid]