Fixup APIs, Error handling and formatting

This commit is contained in:
Sarah Jamie Lewis 2020-07-22 10:14:32 -07:00
parent d230a1b629
commit f74e8647ef
4 changed files with 55 additions and 39 deletions

View File

@ -2,15 +2,18 @@ package model
import "errors" import "errors"
// KeyType provides a wrapper for a generic public key type identifier (could be an onion address, a zcash address etc.)
type KeyType string
const ( const (
// KeyTypeOnion - a cwtch address // KeyTypeServerOnion - a cwtch address
KeyTypeOnion = "onion" // bulletin board KeyTypeServerOnion = KeyType("bulletin_board_onion") // bulletin board
// KeyTypeTokenOnion - a cwtch peer with a PoW based token protocol // KeyTypeTokenOnion - a cwtch peer with a PoW based token protocol
KeyTypeTokenOnion = "token_onion" KeyTypeTokenOnion = KeyType("token_service_onion")
//KeyTypePrivacyPass - a privacy pass based token server //KeyTypePrivacyPass - a privacy pass based token server
KeyTypePrivacyPass = "pp_key" KeyTypePrivacyPass = KeyType("privacy_pass_public_key")
) )
// Key provides a wrapper for a generic public key identifier (could be an onion address, a zcash address etc.) // Key provides a wrapper for a generic public key identifier (could be an onion address, a zcash address etc.)
@ -18,18 +21,18 @@ type Key string
// KeyBundle manages a collection of related keys for various different services. // KeyBundle manages a collection of related keys for various different services.
type KeyBundle struct { type KeyBundle struct {
Keys map[string]Key Keys map[KeyType]Key
} }
// HasKey returns true if the bundle has a public key of a given type. // HasKeyType returns true if the bundle has a public key of a given type.
func (kb *KeyBundle) HasKey(name string) bool { func (kb *KeyBundle) HasKeyType(keytype KeyType) bool {
_, exists := kb.Keys[name] _, exists := kb.Keys[keytype]
return exists return exists
} }
// GetKey retrieves a key with a given type from the bundle // GetKey retrieves a key with a given type from the bundle
func (kb *KeyBundle) GetKey(name string) (Key, error) { func (kb *KeyBundle) GetKey(keytype KeyType) (Key, error) {
key, exists := kb.Keys[name] key, exists := kb.Keys[keytype]
if exists { if exists {
return key, nil return key, nil
} }
@ -40,7 +43,7 @@ func (kb *KeyBundle) GetKey(name string) (Key, error) {
func (kb *KeyBundle) AttributeBundle() map[string]string { func (kb *KeyBundle) AttributeBundle() map[string]string {
ab := make(map[string]string) ab := make(map[string]string)
for k, v := range kb.Keys { for k, v := range kb.Keys {
ab[k] = string(v) ab[string(k)] = string(v)
} }
return ab return ab
} }

View File

@ -78,6 +78,14 @@ func (p *PublicProfile) SetAttribute(name string, value string) {
p.Attributes[name] = value p.Attributes[name] = value
} }
// IsServer returns true if the onion address is associated with a server.
func (p *PublicProfile) IsServer(onion string) bool {
if _, isServer := p.GetAttribute(string(KeyTypeServerOnion)); isServer == true {
return true
}
return false
}
// GetAttribute returns the value of a value set with SetCustomAttribute. If no such value has been set exists is set to false. // 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) { func (p *PublicProfile) GetAttribute(name string) (value string, exists bool) {
p.lock.Lock() p.lock.Lock()

View File

@ -48,7 +48,7 @@ type CwtchPeer interface {
DeleteContact(string) DeleteContact(string)
DeleteGroup(string) DeleteGroup(string)
AddServer(string) AddServer(string) error
JoinServer(string) JoinServer(string)
SendMessageToGroup(string, string) error SendMessageToGroup(string, string) error
SendMessageToGroupTracked(string, string) (string, error) SendMessageToGroupTracked(string, string) (string, error)
@ -205,36 +205,41 @@ func (cp *cwtchPeer) AddContact(nick, onion string, authorization model.Authoriz
cp.eventBus.Publish(event.NewEventList(event.SetPeerAttribute, event.RemotePeer, onion, event.SaveHistoryKey, event.DeleteHistoryDefault)) cp.eventBus.Publish(event.NewEventList(event.SetPeerAttribute, event.RemotePeer, onion, event.SaveHistoryKey, event.DeleteHistoryDefault))
} }
func (cp *cwtchPeer) AddServer(serverSpecification string) { func (cp *cwtchPeer) AddServer(serverSpecification string) error {
keyBundle := new(model.KeyBundle) keyBundle := new(model.KeyBundle)
json.Unmarshal([]byte(serverSpecification), &keyBundle) err := json.Unmarshal([]byte(serverSpecification), &keyBundle)
log.Debugf("Got new key bundle %v", keyBundle) log.Debugf("Got new key bundle %v", keyBundle)
if keyBundle.HasKeyType(model.KeyTypeServerOnion) {
if keyBundle.HasKey(model.KeyTypeOnion) { onionKey, _ := keyBundle.GetKey(model.KeyTypeServerOnion)
onionKey, _ := keyBundle.GetKey(model.KeyTypeOnion)
onion := string(onionKey) onion := string(onionKey)
decodedPub, _ := base32.StdEncoding.DecodeString(strings.ToUpper(onion))
ab := keyBundle.AttributeBundle()
ab["nick"] = onion
pp := &model.PublicProfile{Name: onion, Ed25519PublicKey: decodedPub, Authorization: model.AuthUnknown, Onion: onion, Attributes: ab}
cp.Profile.AddContact(onion, pp) if cp.GetContact(onion) == nil {
pd, _ := json.Marshal(pp) decodedPub, _ := base32.StdEncoding.DecodeString(strings.ToUpper(onion))
cp.eventBus.Publish(event.NewEvent(event.PeerCreated, map[event.Field]string{ ab := keyBundle.AttributeBundle()
event.Data: string(pd), ab["nick"] = onion
event.RemotePeer: onion, pp := &model.PublicProfile{Name: onion, Ed25519PublicKey: decodedPub, Authorization: model.AuthUnknown, Onion: onion, Attributes: ab}
}))
// Publish every key as an attribute cp.Profile.AddContact(onion, pp)
for k, v := range ab { pd, _ := json.Marshal(pp)
log.Debugf("Server (%v) has %v key %v", onion, k, v) cp.eventBus.Publish(event.NewEvent(event.PeerCreated, map[event.Field]string{
cp.eventBus.Publish(event.NewEventList(event.SetPeerAttribute, event.RemotePeer, onion, k, v)) event.Data: string(pd),
event.RemotePeer: onion,
}))
// Publish every key as an attribute
for k, v := range ab {
log.Debugf("Server (%v) has %v key %v", onion, k, v)
cp.eventBus.Publish(event.NewEventList(event.SetPeerAttribute, event.RemotePeer, onion, k, v))
}
// Default to Deleting Peer History
cp.eventBus.Publish(event.NewEventList(event.SetPeerAttribute, event.RemotePeer, onion, event.SaveHistoryKey, event.DeleteHistoryDefault))
return nil
} }
// Server Already Exists
// Default to Deleting Peer History return errors.New("a contact already exists with the given onion address")
cp.eventBus.Publish(event.NewEventList(event.SetPeerAttribute, event.RemotePeer, onion, event.SaveHistoryKey, event.DeleteHistoryDefault))
} }
return err
} }
// GetContacts returns an unordered list of onions // GetContacts returns an unordered list of onions
@ -332,8 +337,8 @@ func (cp *cwtchPeer) InviteOnionToGroup(onion string, groupid string) error {
// JoinServer manages a new server connection with the given onion address // JoinServer manages a new server connection with the given onion address
func (cp *cwtchPeer) JoinServer(onion string) { func (cp *cwtchPeer) JoinServer(onion string) {
if cp.GetContact(onion) != nil { if cp.GetContact(onion) != nil {
tokenY, yExists := cp.GetContact(onion).GetAttribute(model.KeyTypePrivacyPass) tokenY, yExists := cp.GetContact(onion).GetAttribute(string(model.KeyTypePrivacyPass))
tokenOnion, onionExists := cp.GetContact(onion).GetAttribute(model.KeyTypeTokenOnion) tokenOnion, onionExists := cp.GetContact(onion).GetAttribute(string(model.KeyTypeTokenOnion))
if yExists && onionExists { if yExists && onionExists {
cp.eventBus.Publish(event.NewEvent(event.JoinServer, map[event.Field]string{event.GroupServer: onion, event.ServerTokenY: tokenY, event.ServerTokenOnion: tokenOnion})) cp.eventBus.Publish(event.NewEvent(event.JoinServer, map[event.Field]string{event.GroupServer: onion, event.ServerTokenY: tokenY, event.ServerTokenOnion: tokenOnion}))
} }

View File

@ -84,9 +84,9 @@ func (s *Server) Run(acn connectivity.ACN) {
// KeyBundle provides the keybundle of the server (mostly used for testing) // KeyBundle provides the keybundle of the server (mostly used for testing)
func (s *Server) KeyBundle() model.KeyBundle { func (s *Server) KeyBundle() model.KeyBundle {
kb := model.KeyBundle{Keys: make(map[string]model.Key)} kb := model.KeyBundle{Keys: make(map[model.KeyType]model.Key)}
identity := s.config.Identity() identity := s.config.Identity()
kb.Keys[model.KeyTypeOnion] = model.Key(identity.Hostname()) kb.Keys[model.KeyTypeServerOnion] = model.Key(identity.Hostname())
kb.Keys[model.KeyTypeTokenOnion] = model.Key(tor.GetTorV3Hostname(s.tokenService.PublicKey())) kb.Keys[model.KeyTypeTokenOnion] = model.Key(tor.GetTorV3Hostname(s.tokenService.PublicKey()))
kb.Keys[model.KeyTypePrivacyPass] = model.Key(s.tokenServer.Y.String()) kb.Keys[model.KeyTypePrivacyPass] = model.Key(s.tokenServer.Y.String())
return kb return kb