Merge pull request 'goStart' (#53) from goStart into trunk
continuous-integration/drone/push Build is passing Details

Reviewed-on: #53
This commit is contained in:
Sarah Jamie Lewis 2021-06-15 11:07:03 -07:00
commit c5f36a9480
4 changed files with 56 additions and 162 deletions

64
lib.go
View File

@ -58,12 +58,21 @@ type ChatMessage struct {
func c_StartCwtch(dir_c *C.char, len C.int, tor_c *C.char, torLen C.int) int8 { func c_StartCwtch(dir_c *C.char, len C.int, tor_c *C.char, torLen C.int) int8 {
dir := C.GoStringN(dir_c, len) dir := C.GoStringN(dir_c, len)
tor := C.GoStringN(tor_c, torLen) tor := C.GoStringN(tor_c, torLen)
return StartCwtch(dir, tor) return int8(StartCwtch(dir, tor))
} }
func StartCwtch(appDir string, torPath string) int8 { // StartCwtch starts cwtch in the library and initlaizes all data structures
// GetAppbusEvents is always safe to use
// the rest of functions are unsafe until the CwtchStarted event has been received indicating StartCwtch has completed
// returns:
// message: CwtchStarted when start up is complete and app is safe to use
// CwtchStartError message when start up fails (includes event.Error data field)
func StartCwtch(appDir string, torPath string) int {
eventHandler = utils.NewEventHandler()
log.SetLevel(log.LevelInfo) log.SetLevel(log.LevelInfo)
// Quick hack check that we're being called with the correct params
// On android a stale worker could be calling us with "last apps" directory. Best to abort fast so the app can make a new worker
if runtime.GOOS == "android" { if runtime.GOOS == "android" {
fh, err := os.Open(torPath) fh, err := os.Open(torPath)
if err != nil { if err != nil {
@ -73,7 +82,11 @@ func StartCwtch(appDir string, torPath string) int8 {
} }
_ = fh.Close() _ = fh.Close()
} }
go _startCwtch(appDir, torPath)
return 0
}
func _startCwtch(appDir string, torPath string) {
// Exclude Tapir wire Messages (We need a TRACE level) // Exclude Tapir wire Messages (We need a TRACE level)
log.ExcludeFromPattern("service.go") log.ExcludeFromPattern("service.go")
@ -100,8 +113,8 @@ func StartCwtch(appDir string, torPath string) int8 {
acn, err := tor.NewTorACNWithAuth(path.Join(appDir, "/.tor"), torPath, controlPort, tor.HashedPasswordAuthenticator{Password: base64.StdEncoding.EncodeToString(key)}) acn, err := tor.NewTorACNWithAuth(path.Join(appDir, "/.tor"), torPath, controlPort, tor.HashedPasswordAuthenticator{Password: base64.StdEncoding.EncodeToString(key)})
if err != nil { if err != nil {
log.Errorf("\nError connecting to Tor replacing with ErrorACN: %v\n", err) log.Errorf("\nError connecting to Tor replacing with ErrorACN: %v\n", err)
// Replace the nil acn with a stub that will do nothing but report this error to the user... eventHandler.PublishAppEvent(event.NewEventList(utils.CwtchStartError, event.Error, err))
acn = new(utils.ErrorACN) return
} }
globalACN = acn globalACN = acn
newApp := app.NewApp(acn, appDir) newApp := app.NewApp(acn, appDir)
@ -111,7 +124,7 @@ func StartCwtch(appDir string, torPath string) int8 {
newApp.GetPrimaryBus().Subscribe(utils.SetLoggingLevel, acnQueue) newApp.GetPrimaryBus().Subscribe(utils.SetLoggingLevel, acnQueue)
newApp.GetPrimaryBus().Subscribe(event.AppError, acnQueue) newApp.GetPrimaryBus().Subscribe(event.AppError, acnQueue)
eventHandler = utils.NewEventHandler(newApp) eventHandler.HandleApp(newApp)
peer.DefaultEventsToHandle = []event.Type{ peer.DefaultEventsToHandle = []event.Type{
event.EncryptedGroupMessage, event.EncryptedGroupMessage,
@ -137,7 +150,7 @@ func StartCwtch(appDir string, torPath string) int8 {
// Send global settings to the UI... // Send global settings to the UI...
application.GetPrimaryBus().Publish(event.NewEvent(utils.UpdateGlobalSettings, map[event.Field]string{event.Data: string(settingsJson)})) application.GetPrimaryBus().Publish(event.NewEvent(utils.UpdateGlobalSettings, map[event.Field]string{event.Data: string(settingsJson)}))
log.Infof("libcwtch-go application launched") log.Infof("libcwtch-go application launched")
return 0 application.GetPrimaryBus().Publish(event.NewEvent(utils.CwtchStarted, map[event.Field]string{}))
} }
//export c_ReconnectCwtchForeground //export c_ReconnectCwtchForeground
@ -154,20 +167,6 @@ func ReconnectCwtchForeground() {
} }
} }
//export c_ACNEvents
func c_ACNEvents() *C.char {
return C.CString(ACNEvents())
}
func ACNEvents() string {
select {
case myevent := <-acnQueue.OutChan():
return fmt.Sprintf("%v", myevent)
default:
return ""
}
}
//export c_SendAppEvent //export c_SendAppEvent
// A generic method for Rebroadcasting App Events from a UI // A generic method for Rebroadcasting App Events from a UI
func c_SendAppEvent(json_ptr *C.char, json_len C.int) { func c_SendAppEvent(json_ptr *C.char, json_len C.int) {
@ -305,20 +304,6 @@ func GetAppBusEvent() string {
return json return json
} }
//export c_GetProfileRepaintEvent
func c_GetProfileRepaintEvent() int8 {
if GetProfileRepaintEvent() {
return 1
} else {
return 0
}
}
func GetProfileRepaintEvent() bool {
<-acnQueue.OutChan()
return true
}
type Profile struct { type Profile struct {
Name string `json:"name"` Name string `json:"name"`
Onion string `json:"onion"` Onion string `json:"onion"`
@ -356,17 +341,6 @@ func CreateProfile(nick, pass string) {
application.CreatePeer(nick, pass) application.CreatePeer(nick, pass)
} }
//export c_SelectProfile
func c_SelectProfile(onion_ptr *C.char, onion_len C.int) *C.char {
return C.CString(SelectProfile(C.GoStringN(onion_ptr, onion_len)))
}
func SelectProfile(onion string) string {
contactEventsQueue = event.NewQueue()
application.GetEventBus(onion).Subscribe(event.PeerStateChange, contactEventsQueue)
return ""
}
//export c_LoadProfiles //export c_LoadProfiles
func c_LoadProfiles(passwordPtr *C.char, passwordLen C.int) { func c_LoadProfiles(passwordPtr *C.char, passwordLen C.int) {
LoadProfiles(C.GoStringN(passwordPtr, passwordLen)) LoadProfiles(C.GoStringN(passwordPtr, passwordLen))

View File

@ -1,50 +0,0 @@
package utils
import (
"errors"
"git.openprivacy.ca/openprivacy/connectivity"
"git.openprivacy.ca/openprivacy/log"
"net"
)
// ErrorACN is a stub ACN handler used when no other valid ACN can be found. This is a critical error and as such
// this is only used when the only course of action is to close Cwtch and fix the underlying discovery problem...
type ErrorACN struct {
}
func (e ErrorACN) GetBootstrapStatus() (int, string) {
return -1, "could not find tor"
}
func (e ErrorACN) WaitTillBootstrapped() {
// instant
}
func (e ErrorACN) SetStatusCallback(callback func(int, string)) {
callback(-1, "could not find tor please restart cwtch with an active Tor in path")
}
func (e ErrorACN) Restart() {
// does nothing
log.Errorf("Called Restart() on ErrorACN, which does nothing")
}
func (e ErrorACN) Open(hostname string) (net.Conn, string, error) {
return nil, "", errors.New("could not find tor")
}
func (e ErrorACN) Listen(identity connectivity.PrivateKey, port int) (connectivity.ListenService, error) {
return nil, errors.New("could not find tor")
}
func (e ErrorACN) GetPID() (int, error) {
return 0, errors.New("could not find tor")
}
func (e ErrorACN) GetVersion() string {
return "could not find tor"
}
func (e ErrorACN) Close() {
// does nothing
}

View File

@ -23,21 +23,31 @@ type EventHandler struct {
app app.Application app app.Application
appBusQueue event.Queue appBusQueue event.Queue
profileEvents chan EventProfileEnvelope profileEvents chan EventProfileEnvelope
profileQueues map[string]event.Queue profileQueues map[string]event.Queue
} }
func NewEventHandler(application app.Application) *EventHandler { func NewEventHandler() *EventHandler {
appBusQueue := event.NewQueue() eh := &EventHandler{app: nil, appBusQueue: event.NewQueue(), profileQueues: make(map[string]event.Queue), profileEvents: make(chan EventProfileEnvelope)}
application.GetPrimaryBus().Subscribe(event.NewPeer, appBusQueue) return eh
application.GetPrimaryBus().Subscribe(event.PeerError, appBusQueue) }
application.GetPrimaryBus().Subscribe(event.PeerDeleted, appBusQueue)
application.GetPrimaryBus().Subscribe(event.AppError, appBusQueue) // PublishAppEvent is a way for libCwtch-go to publish an event for consumption by a UI before a Cwtch app has been initalized
application.GetPrimaryBus().Subscribe(event.ACNStatus, appBusQueue) // Main use: to signal an error before a cwtch app could be created
application.GetPrimaryBus().Subscribe(event.ReloadDone, appBusQueue) func (eh *EventHandler) PublishAppEvent(event event.Event) {
application.GetPrimaryBus().Subscribe(event.ACNVersion, appBusQueue) eh.appBusQueue.Publish(event)
application.GetPrimaryBus().Subscribe(UpdateGlobalSettings, appBusQueue) }
return &EventHandler{app: application, appBusQueue: appBusQueue, profileQueues: make(map[string]event.Queue), profileEvents: make(chan EventProfileEnvelope)}
func (eh *EventHandler) HandleApp(application app.Application) {
eh.app = application
application.GetPrimaryBus().Subscribe(event.NewPeer, eh.appBusQueue)
application.GetPrimaryBus().Subscribe(event.PeerError, eh.appBusQueue)
application.GetPrimaryBus().Subscribe(event.PeerDeleted, eh.appBusQueue)
application.GetPrimaryBus().Subscribe(event.AppError, eh.appBusQueue)
application.GetPrimaryBus().Subscribe(event.ACNStatus, eh.appBusQueue)
application.GetPrimaryBus().Subscribe(event.ReloadDone, eh.appBusQueue)
application.GetPrimaryBus().Subscribe(event.ACNVersion, eh.appBusQueue)
application.GetPrimaryBus().Subscribe(UpdateGlobalSettings, eh.appBusQueue)
application.GetPrimaryBus().Subscribe(CwtchStarted, eh.appBusQueue)
} }
func (eh *EventHandler) GetNextEvent() string { func (eh *EventHandler) GetNextEvent() string {
@ -211,7 +221,9 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string {
log.Debugf("New Profile Event to Handle: %v", ev) log.Debugf("New Profile Event to Handle: %v", ev)
switch ev.Event.EventType { switch ev.Event.EventType {
/*case event.NetworkStatus: /*
TODO: still handle this somewhere - network info from plugin Network check
case event.NetworkStatus:
online, _ := peer.GetAttribute(attr.GetLocalScope(constants.PeerOnline)) online, _ := peer.GetAttribute(attr.GetLocalScope(constants.PeerOnline))
if e.Data[event.Status] == plugins.NetworkCheckSuccess && online == event.False { if e.Data[event.Status] == plugins.NetworkCheckSuccess && online == event.False {
peer.SetAttribute(attr.GetLocalScope(constants.PeerOnline), event.True) peer.SetAttribute(attr.GetLocalScope(constants.PeerOnline), event.True)
@ -228,31 +240,12 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string {
ev.Event.Data["Picture"] = ph.GetProfilePic(ev.Event.Data["RemotePeer"]) ev.Event.Data["Picture"] = ph.GetProfilePic(ev.Event.Data["RemotePeer"])
case event.PeerAcknowledgement: case event.PeerAcknowledgement:
// No enrichement required // No enrichement required
//Acknowledge(ev.Event.Data[event.RemotePeer], ev.Event.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: case event.PeerCreated:
handle := ev.Event.Data[event.RemotePeer] handle := ev.Event.Data[event.RemotePeer]
err := EnrichNewPeer(handle, ph, ev) err := EnrichNewPeer(handle, ph, ev)
if err != nil { if err != nil {
return "" return ""
} }
/*
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.GroupCreated: case event.GroupCreated:
// This event should only happen after we have validated the invite, as such the error // This event should only happen after we have validated the invite, as such the error
// condition *should* never happen. // condition *should* never happen.
@ -291,45 +284,20 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string {
} }
} }
/*case event.NewRetValMessageFromPeer: case event.NewRetValMessageFromPeer:
onion := e.Data[event.RemotePeer] // auto handled event means the setting is already done, we're just deciding if we need to tell the UI
scope := e.Data[event.Scope] onion := ev.Event.Data[event.RemotePeer]
path := e.Data[event.Path] scope := ev.Event.Data[event.Scope]
val := e.Data[event.Data] path := ev.Event.Data[event.Path]
exists, _ := strconv.ParseBool(e.Data[event.Exists]) //val := ev.Event.Data[event.Data]
exists, _ := strconv.ParseBool(ev.Event.Data[event.Exists])
if exists && scope == attr.PublicScope { if exists && scope == attr.PublicScope {
switch path { if _, exists := peer.GetContactAttribute(onion, attr.GetLocalScope(path)); exists {
case constants.Name: // we have a locally set ovverride, don't pass this remote set public scope update to UI
peer.SetContactAttribute(onion, attr.GetPeerScope(constants.Name), val) return ""
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
*/
} }
json, _ := json.Marshal(unwrap(ev)) json, _ := json.Marshal(unwrap(ev))

View File

@ -12,6 +12,8 @@ import (
) )
const ( const (
CwtchStarted = event.Type("CwtchStarted")
CwtchStartError = event.Type("CwtchStartError")
UpdateGlobalSettings = event.Type("UpdateGlobalSettings") UpdateGlobalSettings = event.Type("UpdateGlobalSettings")
) )