216 lines
7.9 KiB
Go
216 lines
7.9 KiB
Go
package handlers
|
|
|
|
import (
|
|
"cwtch.im/cwtch/app"
|
|
"cwtch.im/cwtch/app/plugins"
|
|
"cwtch.im/cwtch/event"
|
|
"cwtch.im/cwtch/model"
|
|
"cwtch.im/cwtch/model/attr"
|
|
peerC "cwtch.im/cwtch/peer"
|
|
"cwtch.im/cwtch/protocol/connections"
|
|
"cwtch.im/ui/go/constants"
|
|
"cwtch.im/ui/go/the"
|
|
"cwtch.im/ui/go/ui"
|
|
"encoding/hex"
|
|
"git.openprivacy.ca/openprivacy/log"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
func PeerHandler(onion string, uiManager ui.Manager, subscribed chan bool) {
|
|
peer := the.CwtchApp.GetPeer(onion)
|
|
upgradeSchema(peer)
|
|
|
|
eventBus := the.CwtchApp.GetEventBus(onion)
|
|
q := event.NewQueue()
|
|
eventBus.Subscribe(event.NewMessageFromPeer, q)
|
|
eventBus.Subscribe(event.PeerAcknowledgement, q)
|
|
eventBus.Subscribe(event.NewMessageFromGroup, q)
|
|
eventBus.Subscribe(event.NewGroupInvite, q)
|
|
eventBus.Subscribe(event.SendMessageToGroupError, q)
|
|
eventBus.Subscribe(event.SendMessageToPeerError, q)
|
|
eventBus.Subscribe(event.ServerStateChange, q)
|
|
eventBus.Subscribe(event.PeerStateChange, q)
|
|
eventBus.Subscribe(event.PeerCreated, q)
|
|
eventBus.Subscribe(event.NetworkStatus, q)
|
|
eventBus.Subscribe(event.ChangePasswordSuccess, q)
|
|
eventBus.Subscribe(event.ChangePasswordError, q)
|
|
eventBus.Subscribe(event.NewRetValMessageFromPeer, q)
|
|
|
|
subscribed <- true
|
|
|
|
for {
|
|
e := q.Next()
|
|
|
|
switch e.EventType {
|
|
|
|
case event.NetworkStatus:
|
|
online, _ := peer.GetAttribute(attr.GetLocalScope(constants.PeerOnline))
|
|
if e.Data[event.Status] == plugins.NetworkCheckSuccess && online == event.False {
|
|
peer.SetAttribute(attr.GetLocalScope(constants.PeerOnline), event.True)
|
|
uiManager.UpdateNetworkStatus(true)
|
|
// TODO we may have to reinitialize the peer
|
|
} else if e.Data[event.Status] == plugins.NetworkCheckError && online == event.True {
|
|
peer.SetAttribute(attr.GetLocalScope(constants.PeerOnline), event.False)
|
|
uiManager.UpdateNetworkStatus(false)
|
|
}
|
|
|
|
case event.NewMessageFromPeer: //event.TimestampReceived, event.RemotePeer, event.Data
|
|
ts, _ := time.Parse(time.RFC3339Nano, e.Data[event.TimestampReceived])
|
|
uiManager.StoreAndNotify(peer, e.Data[event.RemotePeer], e.Data[event.Data], ts, onion)
|
|
|
|
case event.PeerAcknowledgement:
|
|
uiManager.Acknowledge(e.Data[event.RemotePeer], e.Data[event.EventID])
|
|
|
|
case event.NewMessageFromGroup: //event.TimestampReceived, event.TimestampSent, event.Data, event.GroupID, event.RemotePeer
|
|
ts, _ := time.Parse(time.RFC3339Nano, e.Data[event.TimestampSent])
|
|
uiManager.AddMessage(e.Data[event.GroupID], e.Data[event.RemotePeer], e.Data[event.Data], e.Data[event.RemotePeer] == peer.GetOnion(), hex.EncodeToString([]byte(e.Data[event.Signature])), ts, true)
|
|
|
|
case event.NewGroupInvite:
|
|
gid, err := peer.ProcessInvite(e.Data[event.GroupInvite], e.Data[event.RemotePeer])
|
|
group := peer.GetGroup(gid)
|
|
if err == nil && group != nil {
|
|
uiManager.AddContact(gid)
|
|
}
|
|
case event.PeerCreated:
|
|
onion := e.Data[event.RemotePeer]
|
|
uiManager.AddContact(onion)
|
|
case event.SendMessageToGroupError:
|
|
uiManager.AddSendMessageError(e.Data[event.GroupServer], e.Data[event.Signature], e.Data[event.Error])
|
|
case event.SendMessageToPeerError:
|
|
uiManager.AddSendMessageError(e.Data[event.RemotePeer], e.Data[event.EventID], e.Data[event.Error])
|
|
case event.PeerStateChange:
|
|
cxnState := connections.ConnectionStateToType[e.Data[event.ConnectionState]]
|
|
|
|
// New connection established
|
|
if cxnState == connections.AUTHENTICATED {
|
|
// if it's not in the peer it's new
|
|
if contact := peer.GetContact(e.Data[event.RemotePeer]); contact == nil {
|
|
// Contact does not exist, we will add them
|
|
peer.AddContact(e.Data[event.RemotePeer], e.Data[event.RemotePeer], model.AuthUnknown)
|
|
uiManager.AddContact(e.Data[event.RemotePeer])
|
|
}
|
|
}
|
|
|
|
// if it's in the.PeerHandler its either existing and needs an update or not in the UI and needs to be added
|
|
if contact := peer.GetContact(e.Data[event.RemotePeer]); contact != nil {
|
|
contact.State = e.Data[event.ConnectionState]
|
|
uiManager.UpdateContactStatus(contact.Onion, int(cxnState), false)
|
|
if cxnState == connections.AUTHENTICATED {
|
|
peer.SendGetValToPeer(e.Data[event.RemotePeer], attr.PublicScope, constants.Name)
|
|
peer.SendGetValToPeer(e.Data[event.RemotePeer], attr.PublicScope, constants.Picture)
|
|
}
|
|
}
|
|
case event.NewRetValMessageFromPeer:
|
|
onion := e.Data[event.RemotePeer]
|
|
scope := e.Data[event.Scope]
|
|
path := e.Data[event.Path]
|
|
val := e.Data[event.Data]
|
|
exists, _ := strconv.ParseBool(e.Data[event.Exists])
|
|
|
|
if exists && scope == attr.PublicScope {
|
|
switch path {
|
|
case constants.Name:
|
|
peer.SetContactAttribute(onion, attr.GetPeerScope(constants.Name), val)
|
|
uiManager.UpdateContactDisplayName(onion)
|
|
case constants.Picture:
|
|
peer.SetContactAttribute(onion, attr.GetPeerScope(constants.Picture), val)
|
|
uiManager.UpdateContactPicture(onion)
|
|
}
|
|
}
|
|
|
|
case event.ServerStateChange:
|
|
serverOnion := e.Data[event.GroupServer]
|
|
state := connections.ConnectionStateToType[e.Data[event.ConnectionState]]
|
|
groups := peer.GetGroups()
|
|
for _, groupID := range groups {
|
|
group := peer.GetGroup(groupID)
|
|
if group != nil && group.GroupServer == serverOnion {
|
|
group.State = e.Data[event.ConnectionState]
|
|
loading := false
|
|
if state == connections.AUTHENTICATED {
|
|
loading = true
|
|
}
|
|
uiManager.UpdateContactStatus(groupID, int(state), loading)
|
|
uiManager.UpdateContactStatus(serverOnion, int(state), loading)
|
|
}
|
|
}
|
|
case event.DeletePeer:
|
|
log.Infof("PeerHandler got DeletePeer, SHUTTING down!\n")
|
|
uiManager.ReloadProfiles()
|
|
return
|
|
case event.ChangePasswordSuccess:
|
|
peer.SetAttribute(app.AttributeTag, constants.ProfileTypeV1Password)
|
|
uiManager.ChangePasswordResponse(false)
|
|
case event.ChangePasswordError:
|
|
uiManager.ChangePasswordResponse(true)
|
|
}
|
|
}
|
|
}
|
|
|
|
func upgradeSchema(p peerC.CwtchPeer) {
|
|
schemaVerVal, exists := p.GetAttribute(constants.SchemaVersion)
|
|
if !exists {
|
|
schemaVerVal = "0"
|
|
}
|
|
schemaVer, err := strconv.Atoi(schemaVerVal)
|
|
if err != nil {
|
|
schemaVer = 0
|
|
}
|
|
|
|
if schemaVer < 1 {
|
|
upgradeSchema1(p)
|
|
}
|
|
}
|
|
|
|
func upgradeSchema1(p peerC.CwtchPeer) {
|
|
log.Infof("UpgradeSchema 1\n")
|
|
p.SetAttribute(attr.GetPublicScope(constants.Name), p.GetName())
|
|
|
|
if picture, exists := p.GetAttribute("picture"); exists {
|
|
p.SetAttribute(attr.GetPublicScope(constants.Picture), ui.ImageToString(ui.NewImage(picture, ui.TypeImageDistro)))
|
|
}
|
|
|
|
if locale, exists := p.GetAttribute("settings.locale"); exists {
|
|
p.SetAttribute(attr.GetSettingsScope(constants.LocaleSetting), locale)
|
|
}
|
|
|
|
if zoom, exists := p.GetAttribute("settings.zoom"); exists {
|
|
p.SetAttribute(attr.GetSettingsScope(constants.ZoomSetting), zoom)
|
|
}
|
|
|
|
if blockunknown, exists := p.GetAttribute("settings.blockunknownpeers"); exists {
|
|
p.SetAttribute(attr.GetSettingsScope(constants.BlockUnknownPeersSetting), blockunknown)
|
|
}
|
|
|
|
for _, contactID := range p.GetContacts() {
|
|
if nick, exists := p.GetContactAttribute(contactID, "nick"); exists {
|
|
p.SetContactAttribute(contactID, attr.GetLocalScope(constants.Name), nick)
|
|
}
|
|
|
|
if picture, exists := p.GetContactAttribute(contactID, "picture"); exists {
|
|
p.SetContactAttribute(contactID, attr.GetLocalScope(constants.Picture), ui.ImageToString(ui.NewImage(picture, ui.TypeImageDistro)))
|
|
}
|
|
|
|
if lastRead, exists := p.GetContactAttribute(contactID, "last-read"); exists {
|
|
p.SetContactAttribute(contactID, attr.GetLocalScope(constants.LastRead), lastRead)
|
|
}
|
|
}
|
|
|
|
for _, gID := range p.GetGroups() {
|
|
if nick, exists := p.GetGroupAttribute(gID, "nick"); exists {
|
|
p.SetGroupAttribute(gID, attr.GetLocalScope(constants.Name), nick)
|
|
}
|
|
|
|
if picture, exists := p.GetGroupAttribute(gID, "picture"); exists {
|
|
p.SetGroupAttribute(gID, attr.GetLocalScope(constants.Picture), ui.ImageToString(ui.NewImage(picture, ui.TypeImageDistro)))
|
|
}
|
|
|
|
if lastRead, exists := p.GetGroupAttribute(gID, "last-read"); exists {
|
|
p.SetGroupAttribute(gID, attr.GetLocalScope(constants.LastRead), lastRead)
|
|
}
|
|
}
|
|
|
|
p.SetAttribute(constants.SchemaVersion, "1")
|
|
}
|