Integrate Group Name into Invite #336
|
@ -46,6 +46,10 @@ const (
|
|||
// Imported
|
||||
NewGroupInvite = Type("NewGroupInvite")
|
||||
|
||||
// Inform the UI about a new group
|
||||
// GroupID: groupID (allows them to fetch from the peer)
|
||||
NewGroup = Type("NewGroup")
|
||||
|
||||
// GroupID
|
||||
AcceptGroupInvite = Type("AcceptGroupInvite")
|
||||
|
||||
|
|
|
@ -2,6 +2,7 @@ package model
|
|||
|
||||
import (
|
||||
"crypto/rand"
|
||||
"cwtch.im/cwtch/model/attr"
|
||||
"cwtch.im/cwtch/protocol/groups"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
|
@ -64,6 +65,9 @@ func NewGroup(server string) (*Group, error) {
|
|||
copy(group.GroupKey[:], groupKey[:])
|
||||
group.Owner = "self"
|
||||
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
|
||||
}
|
||||
|
||||
|
@ -95,7 +99,8 @@ func (g *Group) Invite(initialMessage []byte) ([]byte, error) {
|
|||
g.InitialMessage = initialMessage[:]
|
||||
|
||||
gci := &groups.GroupInvite{
|
||||
GroupName: g.GroupID,
|
||||
GroupID: g.GroupID,
|
||||
GroupName: g.Attributes[attr.GetLocalScope("name")],
|
||||
SharedKey: g.GroupKey[:],
|
||||
ServerHost: g.GroupServer,
|
||||
SignedGroupID: g.SignedGroupID[:],
|
||||
|
|
|
@ -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
|
||||
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
|
||||
err := json.Unmarshal([]byte(invite), &gci)
|
||||
if err == nil {
|
||||
group := new(Group)
|
||||
group.Version = CurrentGroupVersion
|
||||
group.GroupID = gci.GroupName
|
||||
group.GroupID = gci.GroupID
|
||||
group.LocalID = GenerateRandomID()
|
||||
group.SignedGroupID = gci.SignedGroupID
|
||||
copy(group.GroupKey[:], gci.SharedKey[:])
|
||||
|
@ -377,9 +377,9 @@ func (p *Profile) ProcessInvite(invite string, peerHostname string) (string, err
|
|||
group.Owner = peerHostname
|
||||
group.Attributes = make(map[string]string)
|
||||
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.
|
||||
|
|
|
@ -55,7 +55,7 @@ type CwtchPeer interface {
|
|||
StoreMessage(onion string, messageTxt string, sent time.Time)
|
||||
|
||||
SetContactAuthorization(string, model.Authorization) error
|
||||
ProcessInvite(string, string) (string, error)
|
||||
ProcessInvite(string, string) (string, string, error)
|
||||
AcceptInvite(string) error
|
||||
RejectInvite(string)
|
||||
DeleteContact(string)
|
||||
|
@ -63,6 +63,7 @@ type CwtchPeer interface {
|
|||
|
||||
AddServer(string) error
|
||||
JoinServer(string) error
|
||||
GetServers() []string
|
||||
SendMessageToGroupTracked(string, string) (string, error)
|
||||
|
||||
GetName() string
|
||||
|
@ -294,6 +295,18 @@ func (cp *cwtchPeer) GetContacts() []string {
|
|||
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
|
||||
func (cp *cwtchPeer) GetContact(onion string) *model.PublicProfile {
|
||||
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
|
||||
func (cp *cwtchPeer) ProcessInvite(invite string, remotePeer string) (string, error) {
|
||||
func (cp *cwtchPeer) ProcessInvite(invite string, remotePeer string) (string, string, error) {
|
||||
cp.mutex.Lock()
|
||||
defer cp.mutex.Unlock()
|
||||
return cp.Profile.ProcessInvite(invite, remotePeer)
|
||||
|
@ -656,17 +669,19 @@ func (cp *cwtchPeer) eventHandler() {
|
|||
}
|
||||
case event.NewGroupInvite:
|
||||
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 ev.Data[event.Imported] == "true" {
|
||||
cp.Profile.GetGroup(group).Accepted = true
|
||||
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)
|
||||
cp.mutex.Lock()
|
||||
if err != nil {
|
||||
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()
|
||||
case event.PeerStateChange:
|
||||
|
|
|
@ -10,7 +10,7 @@ import (
|
|||
// Fuzz various group related functions
|
||||
func Fuzz(data []byte) int {
|
||||
profile := model.GenerateNewProfile("fuzz")
|
||||
inviteid, err := profile.ProcessInvite(string(data), profile.Onion)
|
||||
inviteid, _, err := profile.ProcessInvite(string(data), profile.Onion)
|
||||
|
||||
if err != nil {
|
||||
if inviteid != "" {
|
||||
|
|
|
@ -11,6 +11,7 @@ const CwtchServerSyncedCapability = tapir.Capability("CwtchServerSyncedCapabilit
|
|||
|
||||
// GroupInvite provides a structured type for communicating group information to peers
|
||||
type GroupInvite struct {
|
||||
GroupID string
|
||||
GroupName string
|
||||
SignedGroupID []byte
|
||||
Timestamp uint64
|
||||
|
|
|
@ -82,4 +82,7 @@ func main() {
|
|||
bundle := server.KeyBundle().Serialize()
|
||||
log.Infof("Server Config: server:%s", base64.StdEncoding.EncodeToString(bundle))
|
||||
server.Run(acn)
|
||||
for {
|
||||
time.Sleep(time.Second)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,7 +32,7 @@ type Server struct {
|
|||
onionServiceStopped bool
|
||||
running bool
|
||||
existingMessageCount int
|
||||
lock sync.RWMutex
|
||||
lock sync.RWMutex
|
||||
}
|
||||
|
||||
// Setup initialized a server from a given configuration
|
||||
|
|
|
@ -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) {
|
||||
gid, err := ps.profile.ProcessInvite(string(invite), peer)
|
||||
gid, _, err := ps.profile.ProcessInvite(string(invite), peer)
|
||||
if err == nil {
|
||||
ps.save()
|
||||
group := ps.profile.Groups[gid]
|
||||
|
|
|
@ -373,7 +373,7 @@ func (ps *ProfileStoreV1) eventHandler() {
|
|||
log.Errorf("error accepting group invite")
|
||||
}
|
||||
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 {
|
||||
ps.save()
|
||||
group := ps.profile.Groups[gid]
|
||||
|
|
Loading…
Reference in New Issue