|
|
@ -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() |
|
|
|