forked from cwtch.im/cwtch
1
0
Fork 0

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"
// KeyType provides a wrapper for a generic public key type identifier (could be an onion address, a zcash address etc.)
type KeyType string
const (
// KeyTypeOnion - a cwtch address
KeyTypeOnion = "onion" // bulletin board
// KeyTypeServerOnion - a cwtch address
KeyTypeServerOnion = KeyType("bulletin_board_onion") // bulletin board
// 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 = "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.)
@ -18,18 +21,18 @@ type Key string
// KeyBundle manages a collection of related keys for various different services.
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.
func (kb *KeyBundle) HasKey(name string) bool {
_, exists := kb.Keys[name]
// HasKeyType returns true if the bundle has a public key of a given type.
func (kb *KeyBundle) HasKeyType(keytype KeyType) bool {
_, exists := kb.Keys[keytype]
return exists
}
// GetKey retrieves a key with a given type from the bundle
func (kb *KeyBundle) GetKey(name string) (Key, error) {
key, exists := kb.Keys[name]
func (kb *KeyBundle) GetKey(keytype KeyType) (Key, error) {
key, exists := kb.Keys[keytype]
if exists {
return key, nil
}
@ -40,7 +43,7 @@ func (kb *KeyBundle) GetKey(name string) (Key, error) {
func (kb *KeyBundle) AttributeBundle() map[string]string {
ab := make(map[string]string)
for k, v := range kb.Keys {
ab[k] = string(v)
ab[string(k)] = string(v)
}
return ab
}

View File

@ -78,6 +78,14 @@ func (p *PublicProfile) SetAttribute(name string, value string) {
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.
func (p *PublicProfile) GetAttribute(name string) (value string, exists bool) {
p.lock.Lock()

View File

@ -48,7 +48,7 @@ type CwtchPeer interface {
DeleteContact(string)
DeleteGroup(string)
AddServer(string)
AddServer(string) error
JoinServer(string)
SendMessageToGroup(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))
}
func (cp *cwtchPeer) AddServer(serverSpecification string) {
func (cp *cwtchPeer) AddServer(serverSpecification string) error {
keyBundle := new(model.KeyBundle)
json.Unmarshal([]byte(serverSpecification), &keyBundle)
err := json.Unmarshal([]byte(serverSpecification), &keyBundle)
log.Debugf("Got new key bundle %v", keyBundle)
if keyBundle.HasKey(model.KeyTypeOnion) {
onionKey, _ := keyBundle.GetKey(model.KeyTypeOnion)
if keyBundle.HasKeyType(model.KeyTypeServerOnion) {
onionKey, _ := keyBundle.GetKey(model.KeyTypeServerOnion)
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)
pd, _ := json.Marshal(pp)
cp.eventBus.Publish(event.NewEvent(event.PeerCreated, map[event.Field]string{
event.Data: string(pd),
event.RemotePeer: onion,
}))
if cp.GetContact(onion) == nil {
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}
// 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))
cp.Profile.AddContact(onion, pp)
pd, _ := json.Marshal(pp)
cp.eventBus.Publish(event.NewEvent(event.PeerCreated, map[event.Field]string{
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
}
// Default to Deleting Peer History
cp.eventBus.Publish(event.NewEventList(event.SetPeerAttribute, event.RemotePeer, onion, event.SaveHistoryKey, event.DeleteHistoryDefault))
// Server Already Exists
return errors.New("a contact already exists with the given onion address")
}
return err
}
// 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
func (cp *cwtchPeer) JoinServer(onion string) {
if cp.GetContact(onion) != nil {
tokenY, yExists := cp.GetContact(onion).GetAttribute(model.KeyTypePrivacyPass)
tokenOnion, onionExists := cp.GetContact(onion).GetAttribute(model.KeyTypeTokenOnion)
tokenY, yExists := cp.GetContact(onion).GetAttribute(string(model.KeyTypePrivacyPass))
tokenOnion, onionExists := cp.GetContact(onion).GetAttribute(string(model.KeyTypeTokenOnion))
if yExists && onionExists {
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)
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()
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.KeyTypePrivacyPass] = model.Key(s.tokenServer.Y.String())
return kb