From d54567339d27126674aa612163464a410dcfa510 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Fri, 15 Oct 2021 10:59:42 -0700 Subject: [PATCH 01/11] Convert to new ScopedZone Interface --- features/groups/group_functionality.go | 2 +- go.mod | 4 ++ lib.go | 97 +++++++++++++++----------- utils/eventHandler.go | 20 +++--- utils/manager.go | 2 +- 5 files changed, 72 insertions(+), 53 deletions(-) diff --git a/features/groups/group_functionality.go b/features/groups/group_functionality.go index df83f9b..727f5f2 100644 --- a/features/groups/group_functionality.go +++ b/features/groups/group_functionality.go @@ -96,7 +96,7 @@ func (gf *GroupFunctionality) HandleImportString(peer peer.CwtchPeer, importStri if len(bundle) == 2 { err := gf.HandleImportString(peer, bundle[0][len(tofuBundlePrefix):]) // if the server import failed then abort the whole process.. - if !strings.HasSuffix(err.Error(), "success") { + if err != nil && !strings.HasSuffix(err.Error(), "success") { return features.ConstructResponse(importBundlePrefix, err.Error()) } return gf.HandleImportString(peer, bundle[1]) diff --git a/go.mod b/go.mod index a3b5288..69df19c 100644 --- a/go.mod +++ b/go.mod @@ -9,4 +9,8 @@ require ( golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554 // indirect golang.org/x/mod v0.5.0 // indirect golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf // indirect +) + +replace ( + cwtch.im/cwtch => /home/sarah/workspace/src/cwtch.im/cwtch ) \ No newline at end of file diff --git a/lib.go b/lib.go index 437e1f0..3d1386d 100644 --- a/lib.go +++ b/lib.go @@ -61,9 +61,9 @@ type ChatMessage struct { //export c_StartCwtch func c_StartCwtch(dir_c *C.char, len C.int, tor_c *C.char, torLen C.int) C.int { - dir := C.GoStringN(dir_c, len) - tor := C.GoStringN(tor_c, torLen) - return C.int(StartCwtch(dir, tor)) + applicationDirectory := C.GoStringN(dir_c, len) + torDirectory := C.GoStringN(tor_c, torLen) + return C.int(StartCwtch(applicationDirectory, torDirectory)) } // StartCwtch starts cwtch in the library and initlaizes all data structures @@ -75,8 +75,8 @@ func c_StartCwtch(dir_c *C.char, len C.int, tor_c *C.char, torLen C.int) C.int { func StartCwtch(appDir string, torPath string) int { if logfile := os.Getenv("LOG_FILE"); logfile != "" { filelog, err := log.NewFile(log.LevelInfo, logfile) - filelog.SetUseColor(false) if err == nil { + filelog.SetUseColor(false) log.SetStd(filelog) } else { // not so likely to be seen since we're usually creating file log in situations we can't access console logs... @@ -139,7 +139,11 @@ func _startCwtch(appDir string, torPath string) { eventHandler.PublishAppEvent(event.NewEventList(utils.CwtchStartError, event.Error, fmt.Sprintf("Error creating appDir %v: %v", appDir, err))) return } - utils.InitGlobalSettingsFile(appDir, constants.DefactoPasswordForUnencryptedProfiles) + + err = utils.InitGlobalSettingsFile(appDir, constants.DefactoPasswordForUnencryptedProfiles) + if err != nil { + log.Errorf("error initializing global settings file %. Global settings might not be loaded or saves", err) + } log.Infof("Loading Cwtch Directory %v and tor path: %v", appDir, torPath) @@ -155,8 +159,22 @@ func _startCwtch(appDir string, torPath string) { } log.Infof("making directory %v", appDir) - os.MkdirAll(filepath.Join(appDir, "tor"), 0700) - tor.NewTorrc().WithSocksPort(port).WithOnionTrafficOnly().WithControlPort(controlPort).WithHashedPassword(base64.StdEncoding.EncodeToString(key)).Build(filepath.Join(appDir, "tor", "torrc")) + err = os.MkdirAll(filepath.Join(appDir, "tor"), 0700) + + if err != nil { + log.Errorf("error creating tor data directory: %v. Aborting app start up", err) + eventHandler.PublishAppEvent(event.NewEventList(utils.CwtchStartError, event.Error, fmt.Sprintf("Error connecting to Tor: %v", err))) + return + } + + err = tor.NewTorrc().WithSocksPort(port).WithOnionTrafficOnly().WithControlPort(controlPort).WithHashedPassword(base64.StdEncoding.EncodeToString(key)).Build(filepath.Join(appDir, "tor", "torrc")) + + if err != nil { + log.Errorf("error constructing torrc: %v", err) + eventHandler.PublishAppEvent(event.NewEventList(utils.CwtchStartError, event.Error, fmt.Sprintf("Error connecting to Tor: %v", err))) + return + } + acn, err := tor.NewTorACNWithAuth(appDir, torPath, controlPort, tor.HashedPasswordAuthenticator{Password: base64.StdEncoding.EncodeToString(key)}) if err != nil { log.Errorf("Error connecting to Tor replacing with ErrorACN: %v\n", err) @@ -310,7 +328,7 @@ func SendAppEvent(eventJson string) { case utils.SetLoggingLevel: _, warn := new_event.Data[utils.Warn] - _, error := new_event.Data[utils.Error] + _, err := new_event.Data[utils.Error] _, debug := new_event.Data[utils.Debug] _, info := new_event.Data[utils.Info] // Assign logging level in priority order. The highest logging level wins in the @@ -319,7 +337,7 @@ func SendAppEvent(eventJson string) { log.SetLevel(log.LevelInfo) } else if warn { log.SetLevel(log.LevelWarn) - } else if error { + } else if err { log.SetLevel(log.LevelError) } else if debug { log.SetLevel(log.LevelDebug) @@ -405,12 +423,6 @@ func GetAppBusEvent() string { return json } -type Profile struct { - Name string `json:"name"` - Onion string `json:"onion"` - ImagePath string `json:"imagePath"` -} - //export c_CreateProfile func c_CreateProfile(nick_ptr *C.char, nick_len C.int, pass_ptr *C.char, pass_len C.int) { CreateProfile(C.GoStringN(nick_ptr, nick_len), C.GoStringN(pass_ptr, pass_len)) @@ -672,17 +684,20 @@ func SendInvitation(profileOnion, handle, target string) { func c_ShareFile(profile_ptr *C.char, profile_len C.int, handle_ptr *C.char, handle_len C.int, filepath_ptr *C.char, filepath_len C.int) { profile := C.GoStringN(profile_ptr, profile_len) handle := C.GoStringN(handle_ptr, handle_len) - filepath := C.GoStringN(filepath_ptr, filepath_len) - ShareFile(profile, handle, filepath) + sharefilepath := C.GoStringN(filepath_ptr, filepath_len) + ShareFile(profile, handle, sharefilepath) } -func ShareFile(profileOnion, handle, filepath string) { +func ShareFile(profileOnion, handle, sharefilepath string) { profile := application.GetPeer(profileOnion) fh, err := filesharing.FunctionalityGate(utils.ReadGlobalSettings().Experiments) if err != nil { log.Errorf("file sharing error: %v", err) } else { - fh.ShareFile(filepath, profile, handle) + err = fh.ShareFile(sharefilepath, profile, handle) + if err != nil { + log.Errorf("error sharing file: %v", err) + } } } @@ -690,10 +705,10 @@ func ShareFile(profileOnion, handle, filepath string) { func c_DownloadFile(profile_ptr *C.char, profile_len C.int, handle_ptr *C.char, handle_len C.int, filepath_ptr *C.char, filepath_len C.int, manifestpath_ptr *C.char, manifestpath_len C.int, filekey_ptr *C.char, filekey_len C.int) { profile := C.GoStringN(profile_ptr, profile_len) handle := C.GoStringN(handle_ptr, handle_len) - filepath := C.GoStringN(filepath_ptr, filepath_len) + downloadfilepath := C.GoStringN(filepath_ptr, filepath_len) manifestpath := C.GoStringN(manifestpath_ptr, manifestpath_len) filekey := C.GoStringN(filekey_ptr, filekey_len) - DownloadFile(profile, handle, filepath, manifestpath, filekey) + DownloadFile(profile, handle, downloadfilepath, manifestpath, filekey) } func DownloadFile(profileOnion, handle, filepath, manifestpath, filekey string) { @@ -713,7 +728,7 @@ func c_CheckDownloadStatus(profilePtr *C.char, profileLen C.int, fileKeyPtr *C.c func CheckDownloadStatus(profileOnion, fileKey string) { profile := application.GetPeer(profileOnion) - if path, exists := profile.GetAttribute(attr.GetLocalScope(fileKey)); exists { + if path, exists := profile.GetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fileKey); exists { eventHandler.Push(event.NewEvent(event.FileDownloaded, map[event.Field]string{ ProfileOnion: profileOnion, event.FileKey: fileKey, @@ -741,17 +756,17 @@ func c_CreateGroup(profile_ptr *C.char, profile_len C.int, server_ptr *C.char, s } // CreateGroup takes in a profile and server in addition to a name and creates a new group. -func CreateGroup(profile string, server string, name string) { - peer := application.GetPeer(profile) +func CreateGroup(profileHandle string, server string, name string) { + profile := application.GetPeer(profileHandle) _, err := groups.ExperimentGate(utils.ReadGlobalSettings().Experiments) if err == nil { - gid, _, err := peer.StartGroup(server) + gid, _, err := profile.StartGroup(server) if err == nil { - log.Debugf("created group %v on %v: $v", profile, server, gid) + log.Debugf("created group %v on %v: $v", profileHandle, server, gid) // set the group name - peer.SetGroupAttribute(gid, attr.GetLocalScope("name"), name) + profile.SetGroupAttribute(gid, attr.GetLocalScope("name"), name) } else { - log.Errorf("error creating group or %v on server %v: %v", profile, server, err) + log.Errorf("error creating group or %v on server %v: %v", profileHandle, server, err) } } } @@ -775,20 +790,20 @@ func DeleteProfile(profile string, password string) { } //export c_ArchiveConversation -func c_ArchiveConversation(profile_ptr *C.char, profile_len C.int, contact_ptr *C.char, contact_len C.int) { +func c_ArchiveConversation(profile_ptr *C.char, profile_len C.int, handle_ptr *C.char, handle_len C.int) { profile := C.GoStringN(profile_ptr, profile_len) - contact := C.GoStringN(contact_ptr, contact_len) - ArchiveConversation(profile, contact) + handle := C.GoStringN(handle_ptr, handle_len) + ArchiveConversation(profile, handle) } // ArchiveConversation sets the conversation to archived -func ArchiveConversation(profile string, handle string) { - peer := application.GetPeer(profile) - ph := utils.NewPeerHelper(peer) +func ArchiveConversation(profileHandle string, handle string) { + profile := application.GetPeer(profileHandle) + ph := utils.NewPeerHelper(profile) if ph.IsGroup(handle) { - peer.SetGroupAttribute(handle, attr.GetLocalScope(constants.Archived), event.True) + profile.SetGroupAttribute(handle, attr.GetLocalScope(constants.Archived), event.True) } else { - peer.SetContactAttribute(handle, attr.GetLocalScope(constants.Archived), event.True) + profile.SetContactAttribute(handle, attr.GetLocalScope(constants.Archived), event.True) } } @@ -800,16 +815,16 @@ func c_DeleteContact(profile_ptr *C.char, profile_len C.int, hanlde_ptr *C.char, } // DeleteContact removes all trace of the contact from the profile -func DeleteContact(profile string, handle string) { - peer := application.GetPeer(profile) - ph := utils.NewPeerHelper(peer) +func DeleteContact(profileHandle string, handle string) { + profile := application.GetPeer(profileHandle) + ph := utils.NewPeerHelper(profile) if ph.IsGroup(handle) { _, err := groups.ExperimentGate(utils.ReadGlobalSettings().Experiments) if err == nil { - peer.DeleteGroup(handle) + profile.DeleteGroup(handle) } } else { - peer.DeleteContact(handle) + profile.DeleteContact(handle) } } diff --git a/utils/eventHandler.go b/utils/eventHandler.go index 931dc33..392281a 100644 --- a/utils/eventHandler.go +++ b/utils/eventHandler.go @@ -93,12 +93,12 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string { } if e.Data[event.Created] == event.True { - name, _ := profile.GetAttribute(attr.GetLocalScope(constants.Name)) - profile.SetAttribute(attr.GetPublicScope(constants.Name), name) - profile.SetAttribute(attr.GetPublicScope(constants.Picture), ImageToString(NewImage(RandomProfileImage(onion), TypeImageDistro))) + name, _ := profile.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.Name) + profile.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, name) + profile.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Picture, ImageToString(NewImage(RandomProfileImage(onion), TypeImageDistro))) } if e.Data[event.Status] != event.StorageRunning || e.Data[event.Created] == event.True { - profile.SetAttribute(attr.GetLocalScope(constants.PeerOnline), event.False) + profile.SetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.PeerOnline, event.False) eh.app.AddPeerPlugin(onion, plugins.CONNECTIONRETRY) eh.app.AddPeerPlugin(onion, plugins.NETWORKCHECK) @@ -119,12 +119,12 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string { } } - nick, exists := profile.GetAttribute(attr.GetPublicScope(constants.Name)) + nick, exists := profile.GetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name) if !exists { nick = onion } - picVal, ok := profile.GetAttribute(attr.GetPublicScope(constants.Picture)) + picVal, ok := profile.GetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Picture) if !ok { picVal = ImageToString(NewImage(RandomProfileImage(onion), TypeImageDistro)) } @@ -313,8 +313,8 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string { //uiManager.UpdateContactStatus(contact.Onion, int(cxnState), false) if cxnState == connections.AUTHENTICATED { // if known and authed, get vars - peer.SendGetValToPeer(ev.Event.Data[event.RemotePeer], attr.PublicScope, constants.Name) - peer.SendGetValToPeer(ev.Event.Data[event.RemotePeer], attr.PublicScope, constants.Picture) + peer.SendScopedZonedGetValToContact(ev.Event.Data[event.RemotePeer], attr.PublicScope, attr.ProfileZone, constants.Name) + peer.SendScopedZonedGetValToContact(ev.Event.Data[event.RemotePeer], attr.PublicScope, attr.ProfileZone, constants.Picture) } } @@ -326,9 +326,9 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string { //val := ev.Event.Data[event.Data] exists, _ := strconv.ParseBool(ev.Event.Data[event.Exists]) - if exists && scope == attr.PublicScope { + if exists && attr.IntoScope(scope) == attr.PublicScope { if _, exists := peer.GetContactAttribute(onion, attr.GetLocalScope(path)); exists { - // we have a locally set ovverride, don't pass this remote set public scope update to UI + // we have a locally set override, don't pass this remote set public scope update to UI return "" } } diff --git a/utils/manager.go b/utils/manager.go index f87d943..4e2ea8e 100644 --- a/utils/manager.go +++ b/utils/manager.go @@ -114,7 +114,7 @@ func (p *PeerHelper) GetNick(id string) string { // re-request if authenticated // TODO: This check probably doesn't belong here... if contact := p.peer.GetContact(id); contact != nil && contact.State == connections.ConnectionStateName[connections.AUTHENTICATED] { - p.peer.SendGetValToPeer(id, attr.PublicScope, constants.Name) + p.peer.SendScopedZonedGetValToContact(id, attr.PublicScope, attr.ProfileZone, constants.Name) } } } From 2f14966051bdc0af6e6bef15fd0fa2e5c9ce5ba4 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Fri, 15 Oct 2021 13:09:36 -0700 Subject: [PATCH 02/11] For SetProfileAttribute to declar a proper zone --- go.mod | 6 +----- go.sum | 2 ++ lib.go | 28 +++++++++++++++++++--------- utils/eventHandler.go | 39 +++++++++++++++++---------------------- 4 files changed, 39 insertions(+), 36 deletions(-) diff --git a/go.mod b/go.mod index 69df19c..d7750b0 100644 --- a/go.mod +++ b/go.mod @@ -3,14 +3,10 @@ module git.openprivacy.ca/cwtch.im/libcwtch-go go 1.15 require ( - cwtch.im/cwtch v0.11.2 + cwtch.im/cwtch v0.12.0 git.openprivacy.ca/openprivacy/connectivity v1.5.0 git.openprivacy.ca/openprivacy/log v1.0.3 golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554 // indirect golang.org/x/mod v0.5.0 // indirect golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf // indirect -) - -replace ( - cwtch.im/cwtch => /home/sarah/workspace/src/cwtch.im/cwtch ) \ No newline at end of file diff --git a/go.sum b/go.sum index 9e6a0a9..a311ed3 100644 --- a/go.sum +++ b/go.sum @@ -1,5 +1,7 @@ cwtch.im/cwtch v0.11.2 h1:a38zZLSNsKJzLStBDOIoYKKIL56V9ueQvOZfnIEVc5I= cwtch.im/cwtch v0.11.2/go.mod h1:QpTkQK7MqNt0dQK9/pBk5VpkvFhy6xuoxJIn401B8fM= +cwtch.im/cwtch v0.12.0 h1:hEMee2/2s4kUwukGCTBpGww/KfrsE84e9tOLnM8lM78= +cwtch.im/cwtch v0.12.0/go.mod h1:QpTkQK7MqNt0dQK9/pBk5VpkvFhy6xuoxJIn401B8fM= filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU= filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= git.openprivacy.ca/cwtch.im/tapir v0.4.9 h1:LXonlztwvI1F1++0IyomIcDH1/Bxzo+oN8YjGonNvjM= diff --git a/lib.go b/lib.go index 3d1386d..5c8fbaa 100644 --- a/lib.go +++ b/lib.go @@ -230,14 +230,14 @@ func ReconnectCwtchForeground() { } // populate profile list - peerList := application.ListPeers() - for onion := range peerList { + peerList := application.ListProfiles() + for _, onion := range peerList { eventHandler.Push(event.NewEvent(event.NewPeer, map[event.Field]string{event.Identity: onion, event.Created: event.False, "Reload": event.True})) } settings := utils.ReadGlobalSettings() - for profileOnion := range peerList { + for _,profileOnion := range peerList { // fix peerpeercontact message counts contactList := application.GetPeer(profileOnion).GetContacts() for _, handle := range contactList { @@ -307,7 +307,7 @@ func SendAppEvent(eventJson string) { // Group Experiment Refresh groupHandler, err := groups.ExperimentGate(utils.ReadGlobalSettings().Experiments) if err == nil { - for profileOnion := range application.ListPeers() { + for _,profileOnion := range application.ListProfiles() { serverListForOnion := groupHandler.GetServerInfoList(application.GetPeer(profileOnion)) serversListBytes, _ := json.Marshal(serverListForOnion) eventHandler.Push(event.NewEvent(groups.UpdateServerInfo, map[event.Field]string{"ProfileOnion": profileOnion, groups.ServerList: string(serversListBytes)})) @@ -317,11 +317,11 @@ func SendAppEvent(eventJson string) { // Explicitly toggle blocking/unblocking of unknown connections for profiles // that have been loaded. if utils.ReadGlobalSettings().BlockUnknownConnections { - for onion := range application.ListPeers() { + for _,onion := range application.ListProfiles() { application.GetPeer(onion).BlockUnknownConnections() } } else { - for onion := range application.ListPeers() { + for _,onion := range application.ListProfiles() { application.GetPeer(onion).AllowUnknownConnections() } } @@ -384,7 +384,7 @@ func SendProfileEvent(onion string, eventJson string) { eventHandler.Push(event.NewEvent(event.AppError, map[event.Field]string{event.Data: err.Error()})) // DEPRECATED: use SetProfileAttribute() case event.SetAttribute: - peer.SetAttribute(new_event.Data[event.Key], new_event.Data[event.Data]) + log.Errorf("SetAttribute is deprecated.") // DEPRECATED: use SetContactAttribute() case event.SetPeerAttribute: peer.SetContactAttribute(new_event.Data[event.RemotePeer], new_event.Data[event.Key], new_event.Data[event.Data]) @@ -865,10 +865,20 @@ func c_SetProfileAttribute(profile_ptr *C.char, profile_len C.int, key_ptr *C.ch SetProfileAttribute(profileOnion, key, value) } -// SetProfileAttribute provides a wrapper around profile.SetAttribute +// SetProfileAttribute provides a wrapper around profile.SetScopedZonedAttribute +// Key must have the format zone.key where Zone is defined in Cwtch. Unknown zones are not permitted. func SetProfileAttribute(profileOnion string, key string, value string) { profile := application.GetPeer(profileOnion) - profile.SetAttribute(key, value) + + zone,key := attr.ParseZone(key) + if zone != attr.UnknownZone { + // TODO: We only allow Locally scoped attributes to be set here. + // To set a publicly scoped zone you need to write a dedicated handler/functionality + // And this probably belongs in Cwtch + profile.SetScopedZonedAttribute(attr.LocalScope, zone, key, value) + } else { + log.Errorf("attempted to set an attribute with an unknown zone: %v", key) + } } //export c_SetContactAttribute diff --git a/utils/eventHandler.go b/utils/eventHandler.go index 392281a..490cc0e 100644 --- a/utils/eventHandler.go +++ b/utils/eventHandler.go @@ -5,9 +5,10 @@ import ( "cwtch.im/cwtch/app/plugins" "cwtch.im/cwtch/model" "cwtch.im/cwtch/model/attr" + "cwtch.im/cwtch/model/constants" "cwtch.im/cwtch/protocol/connections" "encoding/json" - "git.openprivacy.ca/cwtch.im/libcwtch-go/constants" + constants2 "git.openprivacy.ca/cwtch.im/libcwtch-go/constants" "git.openprivacy.ca/cwtch.im/libcwtch-go/features/groups" "git.openprivacy.ca/openprivacy/log" "strconv" @@ -68,7 +69,7 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string { switch e.EventType { case event.ACNStatus: if e.Data[event.Progress] == "100" { - for onion := range eh.app.ListPeers() { + for _, onion := range eh.app.ListProfiles() { // launch a listen thread (internally this does a check that the protocol engine is not listening) // and as such is safe to call. eh.app.GetPeer(onion).Listen() @@ -83,22 +84,18 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string { eh.startHandlingPeer(onion) } - tag, isTagged := profile.GetAttribute(app.AttributeTag) - if isTagged { - e.Data[app.AttributeTag] = tag - } else { - // Assume encrypted for non-tagged profiles - this isn't always true, but all post-beta profiles - // are tagged on creation. - e.Data[app.AttributeTag] = constants.ProfileTypeV1Password - } + // CwtchPeer will always set this now... + tag,_ := profile.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.Tag) + e.Data[constants.Tag] = tag + if e.Data[event.Created] == event.True { name, _ := profile.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.Name) profile.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, name) - profile.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Picture, ImageToString(NewImage(RandomProfileImage(onion), TypeImageDistro))) + profile.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants2.Picture, ImageToString(NewImage(RandomProfileImage(onion), TypeImageDistro))) } if e.Data[event.Status] != event.StorageRunning || e.Data[event.Created] == event.True { - profile.SetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.PeerOnline, event.False) + profile.SetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants2.PeerOnline, event.False) eh.app.AddPeerPlugin(onion, plugins.CONNECTIONRETRY) eh.app.AddPeerPlugin(onion, plugins.NETWORKCHECK) @@ -124,7 +121,7 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string { nick = onion } - picVal, ok := profile.GetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Picture) + picVal, ok := profile.GetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants2.Picture) if !ok { picVal = ImageToString(NewImage(RandomProfileImage(onion), TypeImageDistro)) } @@ -134,12 +131,10 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string { } picPath := GetPicturePath(pic) - //tag, _ := profile.GetAttribute(app.AttributeTag) - - online, _ := profile.GetAttribute(attr.GetLocalScope(constants.PeerOnline)) + online, _ := profile.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants2.PeerOnline) e.Data[constants.Name] = nick - e.Data[constants.Picture] = picPath + e.Data[constants2.Picture] = picPath e.Data["Online"] = online var contacts []Contact @@ -166,7 +161,7 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string { if !set { saveHistory = event.DeleteHistoryDefault } - isArchived, set := contactInfo.GetAttribute(attr.GetLocalScope(constants.Archived)) + isArchived, set := contactInfo.GetAttribute(attr.GetLocalScope(constants2.Archived)) if !set { isArchived = event.False } @@ -201,7 +196,7 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string { if group.Accepted { authorization = model.AuthApproved } - isArchived, set := group.GetAttribute(attr.GetLocalScope(constants.Archived)) + isArchived, set := group.GetAttribute(attr.GetLocalScope(constants2.Archived)) if !set { isArchived = event.False } @@ -266,12 +261,12 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string { // only needs contact nickname and picture, for displaying on popup notifications ev.Event.Data["Nick"] = ph.GetNick(ev.Event.Data["RemotePeer"]) ev.Event.Data["Picture"] = ph.GetProfilePic(ev.Event.Data["RemotePeer"]) - peer.SetContactAttribute(ev.Event.Data["RemotePeer"], attr.GetLocalScope(constants.Archived), event.False) + peer.SetContactAttribute(ev.Event.Data["RemotePeer"], attr.GetLocalScope(constants2.Archived), event.False) case event.NewMessageFromGroup: // only needs contact nickname and picture, for displaying on popup notifications ev.Event.Data["Nick"] = ph.GetNick(ev.Event.Data[event.GroupID]) ev.Event.Data["Picture"] = ph.GetProfilePic(ev.Event.Data[event.GroupID]) - peer.SetGroupAttribute(ev.Event.Data[event.GroupID], attr.GetLocalScope(constants.Archived), event.False) + peer.SetGroupAttribute(ev.Event.Data[event.GroupID], attr.GetLocalScope(constants2.Archived), event.False) case event.PeerAcknowledgement: // No enrichement required case event.PeerCreated: @@ -314,7 +309,7 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string { if cxnState == connections.AUTHENTICATED { // if known and authed, get vars peer.SendScopedZonedGetValToContact(ev.Event.Data[event.RemotePeer], attr.PublicScope, attr.ProfileZone, constants.Name) - peer.SendScopedZonedGetValToContact(ev.Event.Data[event.RemotePeer], attr.PublicScope, attr.ProfileZone, constants.Picture) + peer.SendScopedZonedGetValToContact(ev.Event.Data[event.RemotePeer], attr.PublicScope, attr.ProfileZone, constants2.Picture) } } From 0f5d0389cadd2dd42d62de425bca277f9461734e Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Fri, 15 Oct 2021 13:19:14 -0700 Subject: [PATCH 03/11] Use localname when loading a profile as public name may not have been set... --- lib.go | 10 +++++----- utils/eventHandler.go | 11 +++++++---- 2 files changed, 12 insertions(+), 9 deletions(-) diff --git a/lib.go b/lib.go index 5c8fbaa..0ecd34c 100644 --- a/lib.go +++ b/lib.go @@ -237,7 +237,7 @@ func ReconnectCwtchForeground() { settings := utils.ReadGlobalSettings() - for _,profileOnion := range peerList { + for _, profileOnion := range peerList { // fix peerpeercontact message counts contactList := application.GetPeer(profileOnion).GetContacts() for _, handle := range contactList { @@ -307,7 +307,7 @@ func SendAppEvent(eventJson string) { // Group Experiment Refresh groupHandler, err := groups.ExperimentGate(utils.ReadGlobalSettings().Experiments) if err == nil { - for _,profileOnion := range application.ListProfiles() { + for _, profileOnion := range application.ListProfiles() { serverListForOnion := groupHandler.GetServerInfoList(application.GetPeer(profileOnion)) serversListBytes, _ := json.Marshal(serverListForOnion) eventHandler.Push(event.NewEvent(groups.UpdateServerInfo, map[event.Field]string{"ProfileOnion": profileOnion, groups.ServerList: string(serversListBytes)})) @@ -317,11 +317,11 @@ func SendAppEvent(eventJson string) { // Explicitly toggle blocking/unblocking of unknown connections for profiles // that have been loaded. if utils.ReadGlobalSettings().BlockUnknownConnections { - for _,onion := range application.ListProfiles() { + for _, onion := range application.ListProfiles() { application.GetPeer(onion).BlockUnknownConnections() } } else { - for _,onion := range application.ListProfiles() { + for _, onion := range application.ListProfiles() { application.GetPeer(onion).AllowUnknownConnections() } } @@ -870,7 +870,7 @@ func c_SetProfileAttribute(profile_ptr *C.char, profile_len C.int, key_ptr *C.ch func SetProfileAttribute(profileOnion string, key string, value string) { profile := application.GetPeer(profileOnion) - zone,key := attr.ParseZone(key) + zone, key := attr.ParseZone(key) if zone != attr.UnknownZone { // TODO: We only allow Locally scoped attributes to be set here. // To set a publicly scoped zone you need to write a dedicated handler/functionality diff --git a/utils/eventHandler.go b/utils/eventHandler.go index 490cc0e..1b89bd5 100644 --- a/utils/eventHandler.go +++ b/utils/eventHandler.go @@ -85,10 +85,9 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string { } // CwtchPeer will always set this now... - tag,_ := profile.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.Tag) + tag, _ := profile.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.Tag) e.Data[constants.Tag] = tag - if e.Data[event.Created] == event.True { name, _ := profile.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.Name) profile.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, name) @@ -116,12 +115,12 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string { } } - nick, exists := profile.GetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name) + nick, exists := profile.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.Name) if !exists { nick = onion } - picVal, ok := profile.GetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants2.Picture) + picVal, ok := profile.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants2.Picture) if !ok { picVal = ImageToString(NewImage(RandomProfileImage(onion), TypeImageDistro)) } @@ -131,6 +130,10 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string { } picPath := GetPicturePath(pic) + // Set publicly scopes attributes + profile.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, nick) + profile.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants2.Picture, picPath) + online, _ := profile.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants2.PeerOnline) e.Data[constants.Name] = nick From a3e3c221cad006984eeec8082f4d35da38427a7e Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Fri, 15 Oct 2021 13:48:05 -0700 Subject: [PATCH 04/11] upgrade cwtch --- go.mod | 2 +- go.sum | 4 ++++ lib.go | 13 ++++++++----- utils/eventHandler.go | 11 ++--------- 4 files changed, 15 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index d7750b0..50b42fa 100644 --- a/go.mod +++ b/go.mod @@ -3,7 +3,7 @@ module git.openprivacy.ca/cwtch.im/libcwtch-go go 1.15 require ( - cwtch.im/cwtch v0.12.0 + cwtch.im/cwtch v0.12.2 git.openprivacy.ca/openprivacy/connectivity v1.5.0 git.openprivacy.ca/openprivacy/log v1.0.3 golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554 // indirect diff --git a/go.sum b/go.sum index a311ed3..df5c7a2 100644 --- a/go.sum +++ b/go.sum @@ -2,6 +2,10 @@ cwtch.im/cwtch v0.11.2 h1:a38zZLSNsKJzLStBDOIoYKKIL56V9ueQvOZfnIEVc5I= cwtch.im/cwtch v0.11.2/go.mod h1:QpTkQK7MqNt0dQK9/pBk5VpkvFhy6xuoxJIn401B8fM= cwtch.im/cwtch v0.12.0 h1:hEMee2/2s4kUwukGCTBpGww/KfrsE84e9tOLnM8lM78= cwtch.im/cwtch v0.12.0/go.mod h1:QpTkQK7MqNt0dQK9/pBk5VpkvFhy6xuoxJIn401B8fM= +cwtch.im/cwtch v0.12.1 h1:3+OZtzZ9Kg+3Es/ntyPeg7Ku9XzOlSXcvC6rdezmuIM= +cwtch.im/cwtch v0.12.1/go.mod h1:QpTkQK7MqNt0dQK9/pBk5VpkvFhy6xuoxJIn401B8fM= +cwtch.im/cwtch v0.12.2 h1:I+ndKadCRCITw4SPbd+1cpRv+z/7iHjjTUv8OzRwTrE= +cwtch.im/cwtch v0.12.2/go.mod h1:QpTkQK7MqNt0dQK9/pBk5VpkvFhy6xuoxJIn401B8fM= filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU= filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= git.openprivacy.ca/cwtch.im/tapir v0.4.9 h1:LXonlztwvI1F1++0IyomIcDH1/Bxzo+oN8YjGonNvjM= diff --git a/lib.go b/lib.go index 0ecd34c..2fec057 100644 --- a/lib.go +++ b/lib.go @@ -866,16 +866,19 @@ func c_SetProfileAttribute(profile_ptr *C.char, profile_len C.int, key_ptr *C.ch } // SetProfileAttribute provides a wrapper around profile.SetScopedZonedAttribute +// WARNING: Because this function is potentially dangerous all keys and zones must be added +// explicitly. If you are attempting to added behaviour to the UI that requires the existence of new keys +// you probably want to be building out functionality/subsystem in the UI itself. // Key must have the format zone.key where Zone is defined in Cwtch. Unknown zones are not permitted. func SetProfileAttribute(profileOnion string, key string, value string) { profile := application.GetPeer(profileOnion) zone, key := attr.ParseZone(key) - if zone != attr.UnknownZone { - // TODO: We only allow Locally scoped attributes to be set here. - // To set a publicly scoped zone you need to write a dedicated handler/functionality - // And this probably belongs in Cwtch - profile.SetScopedZonedAttribute(attr.LocalScope, zone, key, value) + + // TODO We only allow public.profile.zone to be set for now. + // All other scopes and zones need to be added explicitly or handled by Cwtch. + if zone == attr.ProfileZone && key == constants.Name { + profile.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, value) } else { log.Errorf("attempted to set an attribute with an unknown zone: %v", key) } diff --git a/utils/eventHandler.go b/utils/eventHandler.go index 1b89bd5..db5baa5 100644 --- a/utils/eventHandler.go +++ b/utils/eventHandler.go @@ -89,8 +89,6 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string { e.Data[constants.Tag] = tag if e.Data[event.Created] == event.True { - name, _ := profile.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.Name) - profile.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, name) profile.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants2.Picture, ImageToString(NewImage(RandomProfileImage(onion), TypeImageDistro))) } if e.Data[event.Status] != event.StorageRunning || e.Data[event.Created] == event.True { @@ -115,11 +113,6 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string { } } - nick, exists := profile.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.Name) - if !exists { - nick = onion - } - picVal, ok := profile.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants2.Picture) if !ok { picVal = ImageToString(NewImage(RandomProfileImage(onion), TypeImageDistro)) @@ -131,12 +124,12 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string { picPath := GetPicturePath(pic) // Set publicly scopes attributes - profile.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name, nick) profile.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants2.Picture, picPath) online, _ := profile.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants2.PeerOnline) - e.Data[constants.Name] = nick + // Name always exists + e.Data[constants.Name], _ = profile.GetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name) e.Data[constants2.Picture] = picPath e.Data["Online"] = online From a36e439589d1b925576f96bbf0fd6a08b0461034 Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Mon, 1 Nov 2021 14:11:30 -0700 Subject: [PATCH 05/11] Upgrade Cwtch - rely on Cwtch methods for fetching group timelines. --- features/contacts/contact_functionality.go | 7 +++-- features/groups/group_functionality.go | 2 +- go.mod | 4 +-- lib.go | 31 ++++++++++------------ 4 files changed, 22 insertions(+), 22 deletions(-) diff --git a/features/contacts/contact_functionality.go b/features/contacts/contact_functionality.go index 431f921..ce7d2b7 100644 --- a/features/contacts/contact_functionality.go +++ b/features/contacts/contact_functionality.go @@ -22,8 +22,11 @@ func FunctionalityGate(experimentMap map[string]bool) (*Functionality, error) { // SendMessage handles sending messages to contacts func (pf *Functionality) SendMessage(peer peer.SendMessages, handle string, message string) features.Response { - eventID := peer.SendMessageToPeer(handle, message) - return features.ConstructResponse(sendMessagePrefix, eventID) + err := peer.SendMessage(handle, message) + if err == nil { + return features.ConstructResponse(sendMessagePrefix, "success") + } + return features.ConstructResponse(sendMessagePrefix, err.Error()) } // HandleImportString handles contact import strings diff --git a/features/groups/group_functionality.go b/features/groups/group_functionality.go index 727f5f2..4620ac2 100644 --- a/features/groups/group_functionality.go +++ b/features/groups/group_functionality.go @@ -56,7 +56,7 @@ func (gf *GroupFunctionality) SendMessage(peer peer.CwtchPeer, handle string, me return "", err } } - return peer.SendMessageToGroupTracked(handle, message) + return "", peer.SendMessage(handle, message) } // ValidPrefix returns true if an import string contains a prefix that indicates it contains information about a diff --git a/go.mod b/go.mod index 50b42fa..1bf45ba 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,10 @@ module git.openprivacy.ca/cwtch.im/libcwtch-go go 1.15 require ( - cwtch.im/cwtch v0.12.2 + cwtch.im/cwtch v0.13.0 git.openprivacy.ca/openprivacy/connectivity v1.5.0 git.openprivacy.ca/openprivacy/log v1.0.3 golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554 // indirect golang.org/x/mod v0.5.0 // indirect golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf // indirect -) \ No newline at end of file +) diff --git a/lib.go b/lib.go index 2fec057..4a9a58a 100644 --- a/lib.go +++ b/lib.go @@ -255,7 +255,7 @@ func ReconnectCwtchForeground() { // fix peergroupcontact message counts groupList := application.GetPeer(profileOnion).GetGroups() for _, groupID := range groupList { - totalMessages := application.GetPeer(profileOnion).GetGroup(groupID).Timeline.Len() + len(application.GetPeer(profileOnion).GetGroup(groupID).UnacknowledgedMessages) + totalMessages := len(application.GetPeer(profileOnion).GetGroup(groupID).GetTimeline()) eventHandler.Push(event.NewEvent(event.MessageCounterResync, map[event.Field]string{ event.Identity: profileOnion, event.GroupID: groupID, @@ -537,7 +537,7 @@ type EnhancedMessage struct { ContactImage string } -func GetMessage(profileOnion, handle string, message_index int) string { +func GetMessage(profileOnion, handle string, messageIndex int) string { var message EnhancedMessage // There is an edge case that can happen on Android when the app is shutdown while fetching messages... // The worker threads that are spawned can become activated again when the app is opened attempt to finish their job... @@ -549,28 +549,25 @@ func GetMessage(profileOnion, handle string, message_index int) string { ph := utils.NewPeerHelper(profile) if ph.IsGroup(handle) { if profile.GetGroup(handle) != nil { - // If we are safely within the limits of the timeline just grab the message at the index.. - if len(profile.GetGroup(handle).Timeline.Messages) > message_index { - message.Message = profile.GetGroup(handle).Timeline.Messages[message_index] + + exists, timelineMessage, length := profile.GetGroup(handle).GetMessage(messageIndex) + if exists { + message.Message = timelineMessage message.ContactImage = ph.GetProfilePic(message.Message.PeerID) } else { - // Message Index Request exceeded Timeline, most likely reason is this is a request for an - // unacknowledged sent message (it can take a many seconds for a message to be confirmed in the worst - // case). - offset := message_index - len(profile.GetGroup(handle).Timeline.Messages) - if len(profile.GetGroup(handle).UnacknowledgedMessages) > offset { - message.Message = profile.GetGroup(handle).UnacknowledgedMessages[offset] - message.ContactImage = ph.GetProfilePic(message.Message.PeerID) - } else { - log.Errorf("Couldn't find message in timeline or unacked messages, probably transient threading issue, but logging for visibility..") - } + eventHandler.Push(event.NewEvent(event.MessageCounterResync, map[event.Field]string{ + event.Identity: profileOnion, + event.GroupID: handle, + event.Data: strconv.Itoa(length), + })) + log.Errorf("Couldn't find message in timeline %v / %v or unacked messages, probably transient threading issue, but logging for visibility..", messageIndex, length) } } } else { if profile.GetContact(handle) != nil { // If we are safely within the limits of the timeline just grab the message at the index.. - if len(profile.GetContact(handle).Timeline.Messages) > message_index { - message.Message = profile.GetContact(handle).Timeline.Messages[message_index] + if len(profile.GetContact(handle).Timeline.Messages) > messageIndex { + message.Message = profile.GetContact(handle).Timeline.Messages[messageIndex] message.ContactImage = ph.GetProfilePic(handle) } else { // Otherwise Send a counter resync event...this shouldn't really happen for p2p messages so we From a237314d5fcb0244d7dfd06be204dec33d8ff6c2 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Thu, 7 Oct 2021 17:11:50 -0700 Subject: [PATCH 06/11] first pass of server functionality API --- constants/server_manager_events.go | 26 ----- go.mod | 1 + go.sum | 15 +++ lib.go | 143 +++++++++++++++++++++++++++- utils/manager.go | 146 +---------------------------- 5 files changed, 157 insertions(+), 174 deletions(-) delete mode 100644 constants/server_manager_events.go diff --git a/constants/server_manager_events.go b/constants/server_manager_events.go deleted file mode 100644 index 75982c3..0000000 --- a/constants/server_manager_events.go +++ /dev/null @@ -1,26 +0,0 @@ -package constants - -import "cwtch.im/cwtch/event" - -// The server manager defines its own events, most should be self-explanatory: -const ( - NewServer = event.Type("NewServer") - - // Force a UI update - ListServers = event.Type("ListServers") - - // Takes an Onion, used to toggle off/on Server availability - StartServer = event.Type("StartServer") - StopServer = event.Type("StopServer") - - // Takes an Onion and a AutoStartEnabled boolean - AutoStart = event.Type("AutoStart") - - // Get the status of a particular server (takes an Onion) - CheckServerStatus = event.Type("CheckServerStatus") - ServerStatusUpdate = event.Type("ServerStatusUpdate") -) - -const ( - AutoStartEnabled = event.Field("AutoStartEnabled") -) diff --git a/go.mod b/go.mod index 1bf45ba..7a70518 100644 --- a/go.mod +++ b/go.mod @@ -4,6 +4,7 @@ go 1.15 require ( cwtch.im/cwtch v0.13.0 + git.openprivacy.ca/cwtch.im/server v1.1.2 git.openprivacy.ca/openprivacy/connectivity v1.5.0 git.openprivacy.ca/openprivacy/log v1.0.3 golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554 // indirect diff --git a/go.sum b/go.sum index df5c7a2..a880360 100644 --- a/go.sum +++ b/go.sum @@ -1,3 +1,4 @@ +cwtch.im/cwtch v0.8.5/go.mod h1:5GHxaaeVnKeXSU64IvtCKzkqhU8DRiLoVM+tiBT8kkc= cwtch.im/cwtch v0.11.2 h1:a38zZLSNsKJzLStBDOIoYKKIL56V9ueQvOZfnIEVc5I= cwtch.im/cwtch v0.11.2/go.mod h1:QpTkQK7MqNt0dQK9/pBk5VpkvFhy6xuoxJIn401B8fM= cwtch.im/cwtch v0.12.0 h1:hEMee2/2s4kUwukGCTBpGww/KfrsE84e9tOLnM8lM78= @@ -8,12 +9,18 @@ cwtch.im/cwtch v0.12.2 h1:I+ndKadCRCITw4SPbd+1cpRv+z/7iHjjTUv8OzRwTrE= cwtch.im/cwtch v0.12.2/go.mod h1:QpTkQK7MqNt0dQK9/pBk5VpkvFhy6xuoxJIn401B8fM= filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU= filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= +git.openprivacy.ca/cwtch.im/server v1.1.2/go.mod h1:F0+c77ptKgn5olYsHS0R/AfhjiU5e2HbUIcRc9NASnU= +git.openprivacy.ca/cwtch.im/tapir v0.4.2/go.mod h1:eH6dZxXrhW0C4KZX18ksUa6XJCrEvtg8cJJ/Fy6gv+E= +git.openprivacy.ca/cwtch.im/tapir v0.4.4/go.mod h1:qMFTdmDZITc1BLP1jSW0gVpLmvpg+Zjsh5ek8StwbFE= git.openprivacy.ca/cwtch.im/tapir v0.4.9 h1:LXonlztwvI1F1++0IyomIcDH1/Bxzo+oN8YjGonNvjM= git.openprivacy.ca/cwtch.im/tapir v0.4.9/go.mod h1:p4bHo3DAO8wwimU6JAeZXbfPQ4jnoA2bV+4YvknWTNQ= git.openprivacy.ca/openprivacy/bine v0.0.4 h1:CO7EkGyz+jegZ4ap8g5NWRuDHA/56KKvGySR6OBPW+c= git.openprivacy.ca/openprivacy/bine v0.0.4/go.mod h1:13ZqhKyqakDsN/ZkQkIGNULsmLyqtXc46XBcnuXm/mU= +git.openprivacy.ca/openprivacy/connectivity v1.4.3/go.mod h1:bR0Myx9nm2YzWtsThRelkNMV4Pp7sPDa123O1qsAbVo= +git.openprivacy.ca/openprivacy/connectivity v1.4.5/go.mod h1:JVRCIdL+lAG6ohBFWiKeC/MN42nnC0sfFszR9XG6vPQ= git.openprivacy.ca/openprivacy/connectivity v1.5.0 h1:ZxsR/ZaVKXIkD2x6FlajZn62ciNQjamrI4i/5xIpdoQ= git.openprivacy.ca/openprivacy/connectivity v1.5.0/go.mod h1:UjQiGBnWbotmBzIw59B8H6efwDadjkKzm3RPT1UaIRw= +git.openprivacy.ca/openprivacy/log v1.0.1/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw= git.openprivacy.ca/openprivacy/log v1.0.2/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw= git.openprivacy.ca/openprivacy/log v1.0.3 h1:E/PMm4LY+Q9s3aDpfySfEDq/vYQontlvNj/scrPaga0= git.openprivacy.ca/openprivacy/log v1.0.3/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw= @@ -32,6 +39,8 @@ github.com/kr/pty v1.1.1 h1:VkoXIwSboBpnk99O/KFauAEILuNHv5DVFKZMBN/gUgw= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI= +github.com/mattn/go-sqlite3 v1.14.7 h1:fxWBnXkxfM6sRiuH3bqJ4CfzZojMOLVc0UTsTglEghA= +github.com/mattn/go-sqlite3 v1.14.7/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643 h1:hLDRPB66XQT/8+wG9WsDpiCvZf1yKO7sz7scAjSlBa0= github.com/mimoo/StrobeGo v0.0.0-20181016162300-f8f6d4d2b643/go.mod h1:43+3pMjjKimDBf5Kr4ZFNGbLql1zKkbImw+fZbw3geM= github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e h1:fD57ERR4JtEqsWbfPhv4DMiApHyliiK5xCTNVSPiaAs= @@ -42,6 +51,9 @@ github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/struCoder/pidusage v0.1.3/go.mod h1:pWBlW3YuSwRl6h7R5KbvA4N8oOqe9LjaKW5CwT1SPjI= +github.com/struCoder/pidusage v0.2.1 h1:dFiEgUDkubeIj0XA1NpQ6+8LQmKrLi7NiIQl86E6BoY= +github.com/struCoder/pidusage v0.2.1/go.mod h1:bewtP2KUA1TBUyza5+/PCpSQ6sc/H6jJbIKAzqW86BA= github.com/yuin/goldmark v1.3.5 h1:dPmz1Snjq0kmkz159iL7S6WzdahUTHnHB5M56WFVifs= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg= @@ -57,10 +69,12 @@ golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9t golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= +golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554 h1:3In5TnfvnuXTF/uflgpYxSCEGP2NdYT37KsPh3VjZYU= golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554/go.mod h1:jFTmtFYCV0MFtXBU+J5V/+5AUeVS0ON/0WkE/KSrl6E= golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0 h1:UG21uOlmZabA4fW5i7ZX6bjw1xELEGg/ZLgZq9auk/Q= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= @@ -90,6 +104,7 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= golang.org/x/tools v0.1.2 h1:kRBLX7v7Af8W7Gdbbc908OJcdgtK8bOz9Uaj8/F1ACA= golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= diff --git a/lib.go b/lib.go index 4a9a58a..931dc43 100644 --- a/lib.go +++ b/lib.go @@ -10,6 +10,8 @@ import ( "crypto/rand" "encoding/json" "fmt" + "git.openprivacy.ca/cwtch.im/libcwtch-go/features/servers" + "git.openprivacy.ca/cwtch.im/server" "os/user" "runtime" "strconv" @@ -45,6 +47,7 @@ const ( ) var application app.Application +var globalAppDir string var eventHandler *utils.EventHandler var globalACN connectivity.ACN @@ -86,7 +89,8 @@ func StartCwtch(appDir string, torPath string) int { if runtime.GOOS == "android" { log.SetUseColor(false) } - + log.SetLevel(log.LevelInfo) + log.AddEverythingFromPattern("libcwtch-go") if logLevel := os.Getenv("LOG_LEVEL"); strings.ToLower(logLevel) == "debug" { log.SetLevel(log.LevelDebug) } @@ -181,8 +185,10 @@ func _startCwtch(appDir string, torPath string) { eventHandler.PublishAppEvent(event.NewEventList(utils.CwtchStartError, event.Error, fmt.Sprintf("Error connecting to Tor: %v", err))) return } + globalAppDir = appDir globalACN = acn newApp := app.NewApp(acn, appDir) + servers.InitServers(acn, appDir) eventHandler.HandleApp(newApp) @@ -304,8 +310,18 @@ func SendAppEvent(eventJson string) { log.Debugf("New Settings %v", globalSettings) utils.WriteGlobalSettings(globalSettings) + settings := utils.ReadGlobalSettings() + + serverHandler, err := servers.ExperimentGate(settings.Experiments) + if err == nil { + serverHandler.LoadServers(constants.DefactoPasswordForUnencryptedProfiles) + serverHandler.LaunchServers() + } else { + servers.DeactivateServers() + } + // Group Experiment Refresh - groupHandler, err := groups.ExperimentGate(utils.ReadGlobalSettings().Experiments) + groupHandler, err := groups.ExperimentGate(settings.Experiments) if err == nil { for _, profileOnion := range application.ListProfiles() { serverListForOnion := groupHandler.GetServerInfoList(application.GetPeer(profileOnion)) @@ -316,7 +332,7 @@ func SendAppEvent(eventJson string) { // Explicitly toggle blocking/unblocking of unknown connections for profiles // that have been loaded. - if utils.ReadGlobalSettings().BlockUnknownConnections { + if settings.BlockUnknownConnections { for _, onion := range application.ListProfiles() { application.GetPeer(onion).BlockUnknownConnections() } @@ -938,5 +954,126 @@ func ShutdownCwtch() { } } +//***** Server APIs ***** + +//export c_LoadServers +func c_LoadServers(passwordPtr *C.char, passwordLen C.int) { + LoadServers(C.GoStringN(passwordPtr, passwordLen)) +} + +func LoadServers(password string) { + serversHandler, err := servers.ExperimentGate(utils.ReadGlobalSettings().Experiments) + if err == nil { + serversList, err := serversHandler.LoadServers(password) + if err != nil { + log.Errorf("Error attempting to load servers :%s\n", err) + application.GetPrimaryBus().Publish(event.NewEventList(servers.ZeroServersLoaded)) + } else if len(serversList) == 0 { + application.GetPrimaryBus().Publish(event.NewEventList(servers.ZeroServersLoaded)) + } else { + for _, serverOnion := range serversList { + json := serversHandler.SeverToJson(serverOnion) + application.GetPrimaryBus().Publish(event.NewEventList(servers.NewServer, event.Data, json)) + } + } + } +} + +//export c_CreateServer +func c_CreateServer(passwordPtr *C.char, passwordLen C.int) { + CreateServer(C.GoStringN(passwordPtr, passwordLen)) +} + +func CreateServer(password string) { + serversHandler, err := servers.ExperimentGate(utils.ReadGlobalSettings().Experiments) + if err == nil { + server, err := serversHandler.CreateServer(password) + if err != nil { + log.Errorf("Could not create new server: %s\n", err) + } else { + json := serversHandler.SeverToJson(server.Onion()) + application.GetPrimaryBus().Publish(event.NewEventList(servers.NewServer, event.Data, json)) + } + } +} + +//export c_DeleteServer +func c_DeleteServer(onionPtr *C.char, onionLen C.int, currentPasswordPtr *C.char, currentPasswordLen C.int) { + DeleteServer(C.GoStringN(onionPtr, onionLen), C.GoStringN(currentPasswordPtr, currentPasswordLen)) +} + +func DeleteServer(onion string, currentPassword string) { + serversHandler, err := servers.ExperimentGate(utils.ReadGlobalSettings().Experiments) + if err == nil { + serversHandler.ShutdownServer(onion) + application.GetPrimaryBus().Publish(event.NewEventList(servers.ServerIntentUpdate, servers.Intent, servers.IntentDisabled)) + serversHandler.DeleteServer(onion, currentPassword) + // TODO HANDLE err from DeletServer? + } +} + +//export c_LaunchServers +func c_LaunchServers() { + LaunchServers() +} + +func LaunchServers() { + serversHandler, err := servers.ExperimentGate(utils.ReadGlobalSettings().Experiments) + if err == nil { + for _, onion := range serversHandler.ListServers() { + autostart := false + if s := serversHandler.GetServer(onion); s != nil { + autostart = s.GetAttribute(server.AttrAutostart) == "true" + } + if autostart { + LaunchServer(onion) + } + } + } +} + +//export c_LaunchServer +func c_LaunchServer(onionPtr *C.char, onionLen C.int) { + LaunchServer(C.GoStringN(onionPtr, onionLen)) +} + +func LaunchServer(onion string) { + serversHandler, err := servers.ExperimentGate(utils.ReadGlobalSettings().Experiments) + if err == nil { + serversHandler.LaunchServer(onion) + application.GetPrimaryBus().Publish(event.NewEventList(servers.ServerIntentUpdate, servers.Intent, servers.IntentEnabled)) + } +} + + +//export c_ShutdownServer +func c_ShutdownServer(onionPtr *C.char, onionLen C.int) { + ShutdownServer(C.GoStringN(onionPtr, onionLen)) +} + +func ShutdownServer(onion string) { + serversHandler, err := servers.ExperimentGate(utils.ReadGlobalSettings().Experiments) + if err == nil { + serversHandler.ShutdownServer(onion) + application.GetPrimaryBus().Publish(event.NewEventList(servers.ServerIntentUpdate, servers.Intent, servers.IntentDisabled)) + } +} + +//export c_ShutdownServers +func c_ShutdownServers() { + ShutdownServers() +} + +func ShutdownServers() { + serversHandler, err := servers.ExperimentGate(utils.ReadGlobalSettings().Experiments) + if err == nil { + for _, onion := range serversHandler.ListServers() { + ShutdownServer(onion) + } + } +} + +// ***** END Server APIs ***** + // Leave as is, needed by ffi func main() {} diff --git a/utils/manager.go b/utils/manager.go index 4e2ea8e..056c23a 100644 --- a/utils/manager.go +++ b/utils/manager.go @@ -202,74 +202,6 @@ func getLastMessageTime(tl *model.Timeline) int { return int(tl.Messages[len(tl.Messages)-1].Timestamp.Unix()) } -/* -// AddProfile adds a new profile to the UI -func AddProfile(gcd *GrandCentralDispatcher, handle string) { - p := the.CwtchApp.GetPeer(handle) - if p != nil { - nick, exists := p.GetAttribute(attr.GetPublicScope(constants.Name)) - if !exists { - nick = handle - } - - picVal, ok := p.GetAttribute(attr.GetPublicScope(constants.Picture)) - if !ok { - picVal = ImageToString(NewImage(RandomProfileImage(handle), TypeImageDistro)) - } - pic, err := StringToImage(picVal) - if err != nil { - pic = NewImage(RandomProfileImage(handle), TypeImageDistro) - } - picPath := getPicturePath(pic) - - tag, _ := p.GetAttribute(app.AttributeTag) - - online, _ := p.GetAttribute(attr.GetLocalScope(constants.PeerOnline)) - - log.Debugf("AddProfile %v %v %v %v %v\n", handle, nick, picPath, tag, online) - gcd.AddProfile(handle, nick, picPath, tag, online == event.True) - } -}*/ -/* -type manager struct { - gcd *GrandCentralDispatcher - profile string -} - -// Manager is a middleware helper for entities like peer event listeners wishing to trigger ui changes (via the gcd) -// each manager is for one profile/peer -// manager takes minimal arguments and builds the full struct of data (usually pulled from a cwtch peer) required to call the GCD to perform the ui action -// manager also performs call filtering based on UI state: users of manager can safely always call it on events and not have to worry about weather the relevant ui is active -// ie: you can always safely call AddMessage even if in the ui a different profile is selected. manager will check with gcd, and if the correct conditions are not met, it will not call on gcd to update the ui incorrectly -type Manager interface { - Acknowledge(handle, mID string) - AddContact(Handle string) - AddSendMessageError(peer string, signature string, err string) - AddMessage(handle string, from string, message string, fromMe bool, messageID string, timestamp time.Time, Acknowledged bool) - - ReloadProfiles() - - UpdateContactDisplayName(handle string) - UpdateContactPicture(handle string) - UpdateContactStatus(handle string, status int, loading bool) - UpdateContactAttribute(handle, key, value string) - - ChangePasswordResponse(error bool) - - AboutToAddMessage() - MessageJustAdded() - StoreAndNotify(peer.CwtchPeer, string, string, time.Time, string) - - UpdateNetworkStatus(online bool) -} - -// NewManager returns a new Manager interface for a profile to the gcd -func NewManager(profile string, gcd *GrandCentralDispatcher) Manager { - return &manager{gcd: gcd, profile: profile} -} - - -*/ // EnrichNewPeer populates required data for use by frontend // uiManager.AddContact(onion) // (handle string, displayName string, image string, badge int, status int, authorization string, loading bool, lastMsgTime int) @@ -316,80 +248,4 @@ func EnrichNewPeer(handle string, ph *PeerHelper, ev *EventProfileEnvelope) erro return errors.New("not a peer or group") } return nil -} - -/* -// AddSendMessageError adds an error not and icon to a message in a conversation in the ui for the message identified by the peer/sig combo -func (this *manager) AddSendMessageError(peer string, signature string, err string) { - this.gcd.DoIfProfile(this.profile, func() { - this.gcd.DoIfConversation(peer, func() { - log.Debugf("Received Error Sending Message: %v", err) - // FIXME: Sometimes, for the first Peer message we send our error beats our message to the UI - time.Sleep(time.Second * 1) - this.gcd.GroupSendError(signature, err) - }) - }) -} - -func (this *manager) AboutToAddMessage() { - this.gcd.TimelineInterface.AddMessage(this.gcd.TimelineInterface.num()) -} - -func (this *manager) MessageJustAdded() { - this.gcd.TimelineInterface.RequestEIR() -}*/ - -/* -// AddMessage adds a message to the message pane for the supplied conversation if it is active -func (this *manager) AddMessage(handle string, from string, message string, fromMe bool, messageID string, timestamp time.Time, Acknowledged bool) { - this.gcd.DoIfProfile(this.profile, func() { - this.gcd.DoIfConversation(handle, func() { - updateLastReadTime(handle) - // If the message is not from the user then add it, otherwise, just acknowledge. - if !fromMe || !Acknowledged { - this.gcd.TimelineInterface.AddMessage(this.gcd.TimelineInterface.num() - 1) - this.gcd.TimelineInterface.RequestEIR() - } else { - this.gcd.Acknowledged(messageID) - } - }) - this.gcd.IncContactUnreadCount(handle) - }) - if !fromMe { - this.gcd.Notify(handle) - } -} - -func (this *manager) ReloadProfiles() { - this.gcd.reloadProfileList() -} - -// UpdateContactDisplayName updates a contact's display name in the contact list and conversations -func (this *manager) UpdateContactDisplayName(handle string) { - this.gcd.DoIfProfile(this.profile, func() { - this.gcd.UpdateContactDisplayName(handle, GetNick(handle)) - }) -} - -// UpdateContactPicture updates a contact's picture in the contact list and conversations -func (this *manager) UpdateContactPicture(handle string) { - this.gcd.DoIfProfile(this.profile, func() { - this.gcd.UpdateContactPicture(handle, GetProfilePic(handle)) - }) -} - -// UpdateContactAttribute update's a contacts attribute in the ui -func (this *manager) UpdateContactAttribute(handle, key, value string) { - this.gcd.DoIfProfile(this.profile, func() { - this.gcd.UpdateContactAttribute(handle, key, value) - }) -} - -func (this *manager) ChangePasswordResponse(error bool) { - this.gcd.ChangePasswordResponse(error) -} - -func (this *manager) UpdateNetworkStatus(online bool) { - this.gcd.UpdateProfileNetworkStatus(this.profile, online) -} -*/ +} \ No newline at end of file From 5b72edebadee0fe4a17e2df991bdecd2caec2459 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Fri, 29 Oct 2021 16:14:08 -0700 Subject: [PATCH 07/11] cleaning up server API --- go.mod | 4 +--- go.sum | 50 ++--------------------------------------- lib.go | 52 ++++++++++++++++++++++++++++++++++++++----- utils/eventHandler.go | 2 ++ 4 files changed, 51 insertions(+), 57 deletions(-) diff --git a/go.mod b/go.mod index 7a70518..75f508f 100644 --- a/go.mod +++ b/go.mod @@ -4,10 +4,8 @@ go 1.15 require ( cwtch.im/cwtch v0.13.0 - git.openprivacy.ca/cwtch.im/server v1.1.2 + git.openprivacy.ca/cwtch.im/server v1.3.1 git.openprivacy.ca/openprivacy/connectivity v1.5.0 git.openprivacy.ca/openprivacy/log v1.0.3 - golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554 // indirect - golang.org/x/mod v0.5.0 // indirect golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf // indirect ) diff --git a/go.sum b/go.sum index a880360..7f78350 100644 --- a/go.sum +++ b/go.sum @@ -1,31 +1,18 @@ -cwtch.im/cwtch v0.8.5/go.mod h1:5GHxaaeVnKeXSU64IvtCKzkqhU8DRiLoVM+tiBT8kkc= -cwtch.im/cwtch v0.11.2 h1:a38zZLSNsKJzLStBDOIoYKKIL56V9ueQvOZfnIEVc5I= -cwtch.im/cwtch v0.11.2/go.mod h1:QpTkQK7MqNt0dQK9/pBk5VpkvFhy6xuoxJIn401B8fM= -cwtch.im/cwtch v0.12.0 h1:hEMee2/2s4kUwukGCTBpGww/KfrsE84e9tOLnM8lM78= -cwtch.im/cwtch v0.12.0/go.mod h1:QpTkQK7MqNt0dQK9/pBk5VpkvFhy6xuoxJIn401B8fM= -cwtch.im/cwtch v0.12.1 h1:3+OZtzZ9Kg+3Es/ntyPeg7Ku9XzOlSXcvC6rdezmuIM= -cwtch.im/cwtch v0.12.1/go.mod h1:QpTkQK7MqNt0dQK9/pBk5VpkvFhy6xuoxJIn401B8fM= cwtch.im/cwtch v0.12.2 h1:I+ndKadCRCITw4SPbd+1cpRv+z/7iHjjTUv8OzRwTrE= cwtch.im/cwtch v0.12.2/go.mod h1:QpTkQK7MqNt0dQK9/pBk5VpkvFhy6xuoxJIn401B8fM= filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU= filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= -git.openprivacy.ca/cwtch.im/server v1.1.2/go.mod h1:F0+c77ptKgn5olYsHS0R/AfhjiU5e2HbUIcRc9NASnU= -git.openprivacy.ca/cwtch.im/tapir v0.4.2/go.mod h1:eH6dZxXrhW0C4KZX18ksUa6XJCrEvtg8cJJ/Fy6gv+E= -git.openprivacy.ca/cwtch.im/tapir v0.4.4/go.mod h1:qMFTdmDZITc1BLP1jSW0gVpLmvpg+Zjsh5ek8StwbFE= +git.openprivacy.ca/cwtch.im/server v1.2.0 h1:0upP6XkGXoQW6J+jXyzPqjdEvtjaZEgVQgmucPBH/i8= +git.openprivacy.ca/cwtch.im/server v1.2.0/go.mod h1:gps6glXDt/ra66Do491csrm0TwatAc2lMLOAKCkh5Vw= git.openprivacy.ca/cwtch.im/tapir v0.4.9 h1:LXonlztwvI1F1++0IyomIcDH1/Bxzo+oN8YjGonNvjM= git.openprivacy.ca/cwtch.im/tapir v0.4.9/go.mod h1:p4bHo3DAO8wwimU6JAeZXbfPQ4jnoA2bV+4YvknWTNQ= git.openprivacy.ca/openprivacy/bine v0.0.4 h1:CO7EkGyz+jegZ4ap8g5NWRuDHA/56KKvGySR6OBPW+c= git.openprivacy.ca/openprivacy/bine v0.0.4/go.mod h1:13ZqhKyqakDsN/ZkQkIGNULsmLyqtXc46XBcnuXm/mU= -git.openprivacy.ca/openprivacy/connectivity v1.4.3/go.mod h1:bR0Myx9nm2YzWtsThRelkNMV4Pp7sPDa123O1qsAbVo= -git.openprivacy.ca/openprivacy/connectivity v1.4.5/go.mod h1:JVRCIdL+lAG6ohBFWiKeC/MN42nnC0sfFszR9XG6vPQ= git.openprivacy.ca/openprivacy/connectivity v1.5.0 h1:ZxsR/ZaVKXIkD2x6FlajZn62ciNQjamrI4i/5xIpdoQ= git.openprivacy.ca/openprivacy/connectivity v1.5.0/go.mod h1:UjQiGBnWbotmBzIw59B8H6efwDadjkKzm3RPT1UaIRw= -git.openprivacy.ca/openprivacy/log v1.0.1/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw= git.openprivacy.ca/openprivacy/log v1.0.2/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw= git.openprivacy.ca/openprivacy/log v1.0.3 h1:E/PMm4LY+Q9s3aDpfySfEDq/vYQontlvNj/scrPaga0= git.openprivacy.ca/openprivacy/log v1.0.3/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802 h1:1BDTz0u9nC3//pOCMdNH+CiXJVYJh5UQNCOBG7jbELc= -github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -51,42 +38,18 @@ github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0= github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/struCoder/pidusage v0.1.3/go.mod h1:pWBlW3YuSwRl6h7R5KbvA4N8oOqe9LjaKW5CwT1SPjI= github.com/struCoder/pidusage v0.2.1 h1:dFiEgUDkubeIj0XA1NpQ6+8LQmKrLi7NiIQl86E6BoY= github.com/struCoder/pidusage v0.2.1/go.mod h1:bewtP2KUA1TBUyza5+/PCpSQ6sc/H6jJbIKAzqW86BA= -github.com/yuin/goldmark v1.3.5 h1:dPmz1Snjq0kmkz159iL7S6WzdahUTHnHB5M56WFVifs= -github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg= go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= -golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= -golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee h1:4yd7jl+vXjalO5ztz6Vc1VADv+S/80LGJmyl1ROJ2AI= golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= -golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56 h1:estk1glOnSVeJ9tdEZZc5mAMDZk5lNJNyJ6DvrBkTEU= -golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= -golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b h1:+qEpEAPhDZ1o0x3tHzZTQDArnOixOzGD9HUJfcg0mb4= -golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= -golang.org/x/lint v0.0.0-20210508222113-6edffad5e616/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY= -golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= -golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554 h1:3In5TnfvnuXTF/uflgpYxSCEGP2NdYT37KsPh3VjZYU= -golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554/go.mod h1:jFTmtFYCV0MFtXBU+J5V/+5AUeVS0ON/0WkE/KSrl6E= -golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= -golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg= -golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= -golang.org/x/mod v0.5.0 h1:UG21uOlmZabA4fW5i7ZX6bjw1xELEGg/ZLgZq9auk/Q= -golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= -golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= -golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c h1:5KslGYwFpkhGh+Q16bwMP3cOontH8FOep7tGV86Y7SQ= -golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -102,15 +65,6 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= -golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= -golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= -golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28= -golang.org/x/tools v0.1.2 h1:kRBLX7v7Af8W7Gdbbc908OJcdgtK8bOz9Uaj8/F1ACA= -golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= -golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE= -golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= diff --git a/lib.go b/lib.go index 931dc43..9f9721b 100644 --- a/lib.go +++ b/lib.go @@ -213,6 +213,8 @@ func _startCwtch(appDir string, torPath string) { newApp.LoadProfiles(constants.DefactoPasswordForUnencryptedProfiles) application = newApp + LoadServers(constants.DefactoPasswordForUnencryptedProfiles) + LaunchServers() // Send global settings to the UI... application.GetPrimaryBus().Publish(event.NewEvent(utils.UpdateGlobalSettings, map[event.Field]string{event.Data: string(settingsJson)})) @@ -273,7 +275,15 @@ func ReconnectCwtchForeground() { serversListBytes, _ := json.Marshal(serverListForOnion) eventHandler.Push(event.NewEvent(groups.UpdateServerInfo, map[event.Field]string{"ProfileOnion": profileOnion, groups.ServerList: string(serversListBytes)})) } + } + serversHandler, err := servers.ExperimentGate(utils.ReadGlobalSettings().Experiments) + if err == nil { + serversList := serversHandler.ListServers() + for _, server := range serversList { + json := serversHandler.SeverToJson(server) + application.GetPrimaryBus().Publish(event.NewEventList(servers.NewServer, event.Data, json)) + } } settingsJson, _ := json.Marshal(settings) @@ -314,8 +324,9 @@ func SendAppEvent(eventJson string) { serverHandler, err := servers.ExperimentGate(settings.Experiments) if err == nil { + servers.InitServers(globalACN, globalAppDir) serverHandler.LoadServers(constants.DefactoPasswordForUnencryptedProfiles) - serverHandler.LaunchServers() + LaunchServers() } else { servers.DeactivateServers() } @@ -973,6 +984,7 @@ func LoadServers(password string) { } else { for _, serverOnion := range serversList { json := serversHandler.SeverToJson(serverOnion) + log.Debugf("Load Server NewServer event: %s", json) application.GetPrimaryBus().Publish(event.NewEventList(servers.NewServer, event.Data, json)) } } @@ -980,18 +992,31 @@ func LoadServers(password string) { } //export c_CreateServer -func c_CreateServer(passwordPtr *C.char, passwordLen C.int) { - CreateServer(C.GoStringN(passwordPtr, passwordLen)) +func c_CreateServer(passwordPtr *C.char, passwordLen C.int, descPtr *C.char, descLen C.int, autostart C.char) { + CreateServer(C.GoStringN(passwordPtr, passwordLen), C.GoStringN(descPtr, descLen), autostart == 1) } -func CreateServer(password string) { +func CreateServer(password string, description string, autostart bool) { serversHandler, err := servers.ExperimentGate(utils.ReadGlobalSettings().Experiments) if err == nil { - server, err := serversHandler.CreateServer(password) + s, err := serversHandler.CreateServer(password) if err != nil { log.Errorf("Could not create new server: %s\n", err) } else { - json := serversHandler.SeverToJson(server.Onion()) + s.SetAttribute(server.AttrDescription, description) + if autostart { + s.SetAttribute(server.AttrAutostart, "true") + LaunchServer(s.Onion()) + } else { + s.SetAttribute(server.AttrAutostart, "false") + } + if password == constants.DefactoPasswordForUnencryptedProfiles { + s.SetAttribute(server.AttrStorageType, server.StorageTypeDefaultPassword) + } else { + s.SetAttribute(server.AttrStorageType, server.StorageTypePassword) + } + json := serversHandler.SeverToJson(s.Onion()) + log.Debugf("Creating Server NewServer event: %s", json) application.GetPrimaryBus().Publish(event.NewEventList(servers.NewServer, event.Data, json)) } } @@ -1073,6 +1098,21 @@ func ShutdownServers() { } } +//export c_SetServerAttribute +func c_SetServerAttribute(onionPtr *C.char, onionLen C.int, keyPtr *C.char, keyLen C.int, valPtr *C.char, valLen C.int) { + SetServerAttribute(C.GoStringN(onionPtr, onionLen), C.GoStringN(keyPtr, keyLen), C.GoStringN(valPtr, valLen)) +} + +func SetServerAttribute(onion string, key string, val string) { + serversHandler, err := servers.ExperimentGate(utils.ReadGlobalSettings().Experiments) + if err == nil { + server := serversHandler.GetServer(onion) + if server != nil { + server.SetAttribute(key, val) + } + } +} + // ***** END Server APIs ***** // Leave as is, needed by ffi diff --git a/utils/eventHandler.go b/utils/eventHandler.go index db5baa5..34b2392 100644 --- a/utils/eventHandler.go +++ b/utils/eventHandler.go @@ -10,6 +10,7 @@ import ( "encoding/json" constants2 "git.openprivacy.ca/cwtch.im/libcwtch-go/constants" "git.openprivacy.ca/cwtch.im/libcwtch-go/features/groups" + "git.openprivacy.ca/cwtch.im/libcwtch-go/features/servers" "git.openprivacy.ca/openprivacy/log" "strconv" ) @@ -49,6 +50,7 @@ func (eh *EventHandler) HandleApp(application app.Application) { application.GetPrimaryBus().Subscribe(event.ACNVersion, eh.appBusQueue) application.GetPrimaryBus().Subscribe(UpdateGlobalSettings, eh.appBusQueue) application.GetPrimaryBus().Subscribe(CwtchStarted, eh.appBusQueue) + application.GetPrimaryBus().Subscribe(servers.NewServer, eh.appBusQueue) } func (eh *EventHandler) GetNextEvent() string { From c8f19b3e4c6f013b89ba36f5d7f36cb473bf91ef Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Mon, 1 Nov 2021 09:10:56 -0700 Subject: [PATCH 08/11] incluce features/servers --- features/servers/servers_functionality.go | 98 +++++++++++++++++++++++ go.mod | 2 + go.sum | 7 ++ lib.go | 7 +- 4 files changed, 111 insertions(+), 3 deletions(-) create mode 100644 features/servers/servers_functionality.go diff --git a/features/servers/servers_functionality.go b/features/servers/servers_functionality.go new file mode 100644 index 0000000..3b93611 --- /dev/null +++ b/features/servers/servers_functionality.go @@ -0,0 +1,98 @@ +package servers + +import ( + "cwtch.im/cwtch/event" + "encoding/json" + "fmt" + "git.openprivacy.ca/openprivacy/connectivity" + "path" + "sync" +) +import "git.openprivacy.ca/cwtch.im/server" + +const serversExperiment = "servers-experiment" + +const ( + ZeroServersLoaded = event.Type("ZeroServersLoaded") + NewServer = event.Type("NewServer") + ServerIntentUpdate = event.Type("ServerIntentUpdate") +) + +const ( + Intent = event.Field("Intent") +) + +const ( + IntentEnabled = "enabled" + IntentDisabled = "disabled" +) + +var lock sync.Mutex +var appServers server.Servers + +func InitServers(acn connectivity.ACN, appdir string) { + lock.Lock() + defer lock.Unlock() + if appServers == nil { + appServers = server.NewServers(acn, path.Join(appdir, "servers")) + } +} + +func DeactivateServers() { + appServers.Shutdown() +} + +// ServersFunctionality provides experiment gated server functionality +type ServersFunctionality struct { +} + +// ExperimentGate returns ServersFunctionality if the experiment is enabled, and an error otherwise. +func ExperimentGate(experimentMap map[string]bool) (*ServersFunctionality, error) { + if experimentMap[serversExperiment] { + lock.Lock() + defer lock.Unlock() + return &ServersFunctionality{}, nil + } + return nil, fmt.Errorf("gated by %v", serversExperiment) +} + +func (sf *ServersFunctionality) LoadServers(password string) ([]string, error) { + return appServers.LoadServers(password) +} + +func (sf *ServersFunctionality) CreateServer(password string) (server.Server, error) { + return appServers.CreateServer(password) +} + +func (sf *ServersFunctionality) GetServer(onion string) server.Server { + return appServers.GetServer(onion) +} + +func (sf *ServersFunctionality) ListServers() []string { + return appServers.ListServers() +} + +func (sf *ServersFunctionality) DeleteServer(onion string, currentPassword string) error { + return appServers.DeleteServer(onion, currentPassword) +} + +func (sf *ServersFunctionality) LaunchServer(onion string) { + appServers.LaunchServer(onion) +} + +func (sf *ServersFunctionality) ShutdownServer(onion string) { + appServers.ShutdownServer(onion) +} + +func (sf *ServersFunctionality) SeverToJson(onion string) string { + s := sf.GetServer(onion) + hash := make(map[string]string) + hash["onion"] = s.Onion() + hash["serverbundle"] = s.ServerBundle() + hash[server.AttrAutostart] = s.GetAttribute(server.AttrAutostart) + hash[server.AttrEnabled] = s.GetAttribute(server.AttrEnabled) + hash[server.AttrDescription] = s.GetAttribute(server.AttrDescription) + hash[server.AttrStorageType] = s.GetAttribute(server.AttrStorageType) + json, _ := json.Marshal(hash) + return string(json) +} \ No newline at end of file diff --git a/go.mod b/go.mod index 75f508f..2168528 100644 --- a/go.mod +++ b/go.mod @@ -7,5 +7,7 @@ require ( git.openprivacy.ca/cwtch.im/server v1.3.1 git.openprivacy.ca/openprivacy/connectivity v1.5.0 git.openprivacy.ca/openprivacy/log v1.0.3 + golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554 // indirect + golang.org/x/mod v0.5.0 // indirect golang.org/x/sys v0.0.0-20210823070655-63515b42dcdf // indirect ) diff --git a/go.sum b/go.sum index 7f78350..425ba71 100644 --- a/go.sum +++ b/go.sum @@ -46,6 +46,13 @@ golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACk golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee h1:4yd7jl+vXjalO5ztz6Vc1VADv+S/80LGJmyl1ROJ2AI= golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= +golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554 h1:3In5TnfvnuXTF/uflgpYxSCEGP2NdYT37KsPh3VjZYU= +golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554/go.mod h1:jFTmtFYCV0MFtXBU+J5V/+5AUeVS0ON/0WkE/KSrl6E= +golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= +golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= +golang.org/x/mod v0.5.0 h1:UG21uOlmZabA4fW5i7ZX6bjw1xELEGg/ZLgZq9auk/Q= +golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= diff --git a/lib.go b/lib.go index 9f9721b..324f735 100644 --- a/lib.go +++ b/lib.go @@ -10,25 +10,26 @@ import ( "crypto/rand" "encoding/json" "fmt" - "git.openprivacy.ca/cwtch.im/libcwtch-go/features/servers" - "git.openprivacy.ca/cwtch.im/server" "os/user" "runtime" "strconv" "strings" "unsafe" + "git.openprivacy.ca/openprivacy/connectivity" "cwtch.im/cwtch/app" "cwtch.im/cwtch/event" "cwtch.im/cwtch/functionality/filesharing" "cwtch.im/cwtch/model" "cwtch.im/cwtch/model/attr" "cwtch.im/cwtch/peer" + "git.openprivacy.ca/cwtch.im/server" "git.openprivacy.ca/cwtch.im/libcwtch-go/constants" contact "git.openprivacy.ca/cwtch.im/libcwtch-go/features/contacts" "git.openprivacy.ca/cwtch.im/libcwtch-go/features/groups" + "git.openprivacy.ca/cwtch.im/libcwtch-go/features/servers" + "git.openprivacy.ca/cwtch.im/libcwtch-go/utils" - "git.openprivacy.ca/openprivacy/connectivity" "encoding/base64" mrand "math/rand" From 063ad61e363f8bed05fa35bdd9daa45bd7b37f68 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Mon, 1 Nov 2021 18:48:00 -0700 Subject: [PATCH 09/11] move from Shutdown to Stop/Destroy, remove enabled in favor of running from CheckStatus --- features/servers/servers_functionality.go | 63 +++++++++++++++------ go.sum | 23 +++++++- lib.go | 68 ++++++++++++++--------- utils/eventHandler.go | 1 + 4 files changed, 111 insertions(+), 44 deletions(-) diff --git a/features/servers/servers_functionality.go b/features/servers/servers_functionality.go index 3b93611..0f679d1 100644 --- a/features/servers/servers_functionality.go +++ b/features/servers/servers_functionality.go @@ -2,13 +2,12 @@ package servers import ( "cwtch.im/cwtch/event" - "encoding/json" "fmt" + "git.openprivacy.ca/cwtch.im/server" "git.openprivacy.ca/openprivacy/connectivity" "path" "sync" ) -import "git.openprivacy.ca/cwtch.im/server" const serversExperiment = "servers-experiment" @@ -23,10 +22,19 @@ const ( ) const ( - IntentEnabled = "enabled" - IntentDisabled = "disabled" + IntentRunning = "running" + IntentStopped = "stopped" ) +type ServerInfo struct { + Onion string + ServerBundle string + Autostart bool + Running bool + Description string + StorageType string +} + var lock sync.Mutex var appServers server.Servers @@ -39,7 +47,7 @@ func InitServers(acn connectivity.ACN, appdir string) { } func DeactivateServers() { - appServers.Shutdown() + appServers.Stop() } // ServersFunctionality provides experiment gated server functionality @@ -80,19 +88,40 @@ func (sf *ServersFunctionality) LaunchServer(onion string) { appServers.LaunchServer(onion) } -func (sf *ServersFunctionality) ShutdownServer(onion string) { - appServers.ShutdownServer(onion) +func (sf *ServersFunctionality) StopServer(onion string) { + appServers.StopServer(onion) } -func (sf *ServersFunctionality) SeverToJson(onion string) string { +func (sf *ServersFunctionality) DestroyServers() { + appServers.Destroy() +} + +func (sf *ServersFunctionality) GetServerInfo(onion string) *ServerInfo { s := sf.GetServer(onion) - hash := make(map[string]string) - hash["onion"] = s.Onion() - hash["serverbundle"] = s.ServerBundle() - hash[server.AttrAutostart] = s.GetAttribute(server.AttrAutostart) - hash[server.AttrEnabled] = s.GetAttribute(server.AttrEnabled) - hash[server.AttrDescription] = s.GetAttribute(server.AttrDescription) - hash[server.AttrStorageType] = s.GetAttribute(server.AttrStorageType) - json, _ := json.Marshal(hash) - return string(json) + var serverInfo ServerInfo + serverInfo.Onion = s.Onion() + serverInfo.ServerBundle = s.ServerBundle() + serverInfo.Autostart = s.GetAttribute(server.AttrAutostart) == "true" + running, _ := s.CheckStatus() + serverInfo.Running = running + serverInfo.Description = s.GetAttribute(server.AttrDescription) + serverInfo.StorageType = s.GetAttribute(server.AttrStorageType) + return &serverInfo +} + +func (si *ServerInfo) EnrichEvent(e *event.Event) { + e.Data["Onion"] = si.Onion + e.Data["ServerBundle"] = si.ServerBundle + e.Data["Description"] = si.Description + e.Data["StorageType"] = si.StorageType + if si.Autostart { + e.Data["Autostart"] = "true" + } else { + e.Data["Autostart"] = "false" + } + if si.Running { + e.Data["Running"] = "true" + } else { + e.Data["Running"] = "false" + } } \ No newline at end of file diff --git a/go.sum b/go.sum index 425ba71..678cfdb 100644 --- a/go.sum +++ b/go.sum @@ -1,9 +1,11 @@ cwtch.im/cwtch v0.12.2 h1:I+ndKadCRCITw4SPbd+1cpRv+z/7iHjjTUv8OzRwTrE= cwtch.im/cwtch v0.12.2/go.mod h1:QpTkQK7MqNt0dQK9/pBk5VpkvFhy6xuoxJIn401B8fM= +cwtch.im/cwtch v0.13.0 h1:9WhLG9czfyRceZnHSqfTAq0vfmDC/E20mziJb9+Skrg= +cwtch.im/cwtch v0.13.0/go.mod h1:QpTkQK7MqNt0dQK9/pBk5VpkvFhy6xuoxJIn401B8fM= filippo.io/edwards25519 v1.0.0-rc.1 h1:m0VOOB23frXZvAOK44usCgLWvtsxIoMCTBGJZlpmGfU= filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns= -git.openprivacy.ca/cwtch.im/server v1.2.0 h1:0upP6XkGXoQW6J+jXyzPqjdEvtjaZEgVQgmucPBH/i8= -git.openprivacy.ca/cwtch.im/server v1.2.0/go.mod h1:gps6glXDt/ra66Do491csrm0TwatAc2lMLOAKCkh5Vw= +git.openprivacy.ca/cwtch.im/server v1.3.1 h1:Kt4TnlGxGPk1KTjvs1cXtnFWDx+hYqu8w+2eIaqt+F4= +git.openprivacy.ca/cwtch.im/server v1.3.1/go.mod h1:gps6glXDt/ra66Do491csrm0TwatAc2lMLOAKCkh5Vw= git.openprivacy.ca/cwtch.im/tapir v0.4.9 h1:LXonlztwvI1F1++0IyomIcDH1/Bxzo+oN8YjGonNvjM= git.openprivacy.ca/cwtch.im/tapir v0.4.9/go.mod h1:p4bHo3DAO8wwimU6JAeZXbfPQ4jnoA2bV+4YvknWTNQ= git.openprivacy.ca/openprivacy/bine v0.0.4 h1:CO7EkGyz+jegZ4ap8g5NWRuDHA/56KKvGySR6OBPW+c= @@ -13,6 +15,7 @@ git.openprivacy.ca/openprivacy/connectivity v1.5.0/go.mod h1:UjQiGBnWbotmBzIw59B git.openprivacy.ca/openprivacy/log v1.0.2/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw= git.openprivacy.ca/openprivacy/log v1.0.3 h1:E/PMm4LY+Q9s3aDpfySfEDq/vYQontlvNj/scrPaga0= git.openprivacy.ca/openprivacy/log v1.0.3/go.mod h1:gGYK8xHtndRLDymFtmjkG26GaMQNgyhioNS82m812Iw= +github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -40,12 +43,18 @@ github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= github.com/struCoder/pidusage v0.2.1 h1:dFiEgUDkubeIj0XA1NpQ6+8LQmKrLi7NiIQl86E6BoY= github.com/struCoder/pidusage v0.2.1/go.mod h1:bewtP2KUA1TBUyza5+/PCpSQ6sc/H6jJbIKAzqW86BA= +github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= go.etcd.io/bbolt v1.3.4 h1:hi1bXHMVrlQh6WwxAy+qZCV/SYIlqo+Ushwdpa4tAKg= go.etcd.io/bbolt v1.3.4/go.mod h1:G5EMThwa9y8QZGBClrRx5EY+Yw9kAhnjy3bSjsnlVTQ= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190510104115-cbcb75029529/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee h1:4yd7jl+vXjalO5ztz6Vc1VADv+S/80LGJmyl1ROJ2AI= golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= +golang.org/x/exp v0.0.0-20190731235908-ec7cb31e5a56/go.mod h1:JhuoJpWY28nO4Vef9tZUw9qufEGTyX1+7lmHxV5q5G4= +golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMxlp+ypCbDeSB+sBbTgSJuh5dn5js= +golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0= golang.org/x/mobile v0.0.0-20190312151609-d3739f865fa6/go.mod h1:z+o9i4GpDbdi3rU15maQ/Ox0txvL9dWGYEHz965HBQE= golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554 h1:3In5TnfvnuXTF/uflgpYxSCEGP2NdYT37KsPh3VjZYU= golang.org/x/mobile v0.0.0-20210716004757-34ab1303b554/go.mod h1:jFTmtFYCV0MFtXBU+J5V/+5AUeVS0ON/0WkE/KSrl6E= @@ -53,10 +62,14 @@ golang.org/x/mod v0.1.0/go.mod h1:0QHyrYULN0/3qlju5TqG8bIK38QM8yzMo5ekMj3DlcY= golang.org/x/mod v0.4.2/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA= golang.org/x/mod v0.5.0 h1:UG21uOlmZabA4fW5i7ZX6bjw1xELEGg/ZLgZq9auk/Q= golang.org/x/mod v0.5.0/go.mod h1:5OXOZSfqPIIbmVBIIKWRFfZjPR0E5r58TLhUjH0a2Ro= +golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201010224723-4f7140c49acb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4 h1:4nGaVu0QrbjT/AK2PRLuQfQuh6DJve+pELhqTdAj3x0= golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -72,6 +85,12 @@ golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k= golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20190312151545-0bb0c0a6e846/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.2/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f h1:BLraFXnmrev5lT+xlilqcH8XK9/i0At2xKjWk4p6zsU= diff --git a/lib.go b/lib.go index 324f735..6e0616c 100644 --- a/lib.go +++ b/lib.go @@ -16,18 +16,18 @@ import ( "strings" "unsafe" - "git.openprivacy.ca/openprivacy/connectivity" "cwtch.im/cwtch/app" "cwtch.im/cwtch/event" "cwtch.im/cwtch/functionality/filesharing" "cwtch.im/cwtch/model" "cwtch.im/cwtch/model/attr" "cwtch.im/cwtch/peer" - "git.openprivacy.ca/cwtch.im/server" "git.openprivacy.ca/cwtch.im/libcwtch-go/constants" contact "git.openprivacy.ca/cwtch.im/libcwtch-go/features/contacts" "git.openprivacy.ca/cwtch.im/libcwtch-go/features/groups" "git.openprivacy.ca/cwtch.im/libcwtch-go/features/servers" + "git.openprivacy.ca/cwtch.im/server" + "git.openprivacy.ca/openprivacy/connectivity" "git.openprivacy.ca/cwtch.im/libcwtch-go/utils" @@ -282,8 +282,10 @@ func ReconnectCwtchForeground() { if err == nil { serversList := serversHandler.ListServers() for _, server := range serversList { - json := serversHandler.SeverToJson(server) - application.GetPrimaryBus().Publish(event.NewEventList(servers.NewServer, event.Data, json)) + serverInfo := serversHandler.GetServerInfo(server) + ev := event.NewEvent(servers.NewServer, make(map[event.Field]string)) + serverInfo.EnrichEvent(&ev) + application.GetPrimaryBus().Publish(ev) } } @@ -984,9 +986,11 @@ func LoadServers(password string) { application.GetPrimaryBus().Publish(event.NewEventList(servers.ZeroServersLoaded)) } else { for _, serverOnion := range serversList { - json := serversHandler.SeverToJson(serverOnion) - log.Debugf("Load Server NewServer event: %s", json) - application.GetPrimaryBus().Publish(event.NewEventList(servers.NewServer, event.Data, json)) + serverInfo := serversHandler.GetServerInfo(serverOnion) + log.Debugf("Load Server NewServer event: %s", serverInfo) + ev := event.NewEvent(servers.NewServer, make(map[event.Field]string)) + serverInfo.EnrichEvent(&ev) + application.GetPrimaryBus().Publish(ev) } } } @@ -1016,9 +1020,11 @@ func CreateServer(password string, description string, autostart bool) { } else { s.SetAttribute(server.AttrStorageType, server.StorageTypePassword) } - json := serversHandler.SeverToJson(s.Onion()) - log.Debugf("Creating Server NewServer event: %s", json) - application.GetPrimaryBus().Publish(event.NewEventList(servers.NewServer, event.Data, json)) + serverInfo := serversHandler.GetServerInfo(s.Onion()) + log.Debugf("Creating Server NewServer event: %s", serverInfo) + ev := event.NewEvent(servers.NewServer, make(map[event.Field]string)) + serverInfo.EnrichEvent(&ev) + application.GetPrimaryBus().Publish(ev) } } } @@ -1031,10 +1037,10 @@ func c_DeleteServer(onionPtr *C.char, onionLen C.int, currentPasswordPtr *C.char func DeleteServer(onion string, currentPassword string) { serversHandler, err := servers.ExperimentGate(utils.ReadGlobalSettings().Experiments) if err == nil { - serversHandler.ShutdownServer(onion) - application.GetPrimaryBus().Publish(event.NewEventList(servers.ServerIntentUpdate, servers.Intent, servers.IntentDisabled)) + serversHandler.StopServer(onion) + application.GetPrimaryBus().Publish(event.NewEventList(servers.ServerIntentUpdate, event.Identity, onion, servers.Intent, servers.IntentStopped)) serversHandler.DeleteServer(onion, currentPassword) - // TODO HANDLE err from DeletServer? + // TODO HANDLE err from DeleteServer? } } @@ -1067,38 +1073,50 @@ func LaunchServer(onion string) { serversHandler, err := servers.ExperimentGate(utils.ReadGlobalSettings().Experiments) if err == nil { serversHandler.LaunchServer(onion) - application.GetPrimaryBus().Publish(event.NewEventList(servers.ServerIntentUpdate, servers.Intent, servers.IntentEnabled)) + application.GetPrimaryBus().Publish(event.NewEventList(servers.ServerIntentUpdate, event.Identity, onion, servers.Intent, servers.IntentRunning)) } } -//export c_ShutdownServer -func c_ShutdownServer(onionPtr *C.char, onionLen C.int) { - ShutdownServer(C.GoStringN(onionPtr, onionLen)) +//export c_StopServer +func c_StopServer(onionPtr *C.char, onionLen C.int) { + StopServer(C.GoStringN(onionPtr, onionLen)) } -func ShutdownServer(onion string) { +func StopServer(onion string) { serversHandler, err := servers.ExperimentGate(utils.ReadGlobalSettings().Experiments) if err == nil { - serversHandler.ShutdownServer(onion) - application.GetPrimaryBus().Publish(event.NewEventList(servers.ServerIntentUpdate, servers.Intent, servers.IntentDisabled)) + serversHandler.StopServer(onion) + application.GetPrimaryBus().Publish(event.NewEventList(servers.ServerIntentUpdate, event.Identity, onion, servers.Intent, servers.IntentStopped)) } } -//export c_ShutdownServers -func c_ShutdownServers() { - ShutdownServers() +//export c_StopServers +func c_StopServers() { + StopServers() } -func ShutdownServers() { +func StopServers() { serversHandler, err := servers.ExperimentGate(utils.ReadGlobalSettings().Experiments) if err == nil { for _, onion := range serversHandler.ListServers() { - ShutdownServer(onion) + StopServer(onion) } } } +//export c_DestroyServers +func c_DestroyServers() { + DestroyServers() +} + +func DestroyServers() { + serversHandler, err := servers.ExperimentGate(utils.ReadGlobalSettings().Experiments) + if err == nil { + serversHandler.DestroyServers() + } +} + //export c_SetServerAttribute func c_SetServerAttribute(onionPtr *C.char, onionLen C.int, keyPtr *C.char, keyLen C.int, valPtr *C.char, valLen C.int) { SetServerAttribute(C.GoStringN(onionPtr, onionLen), C.GoStringN(keyPtr, keyLen), C.GoStringN(valPtr, valLen)) diff --git a/utils/eventHandler.go b/utils/eventHandler.go index 34b2392..8657202 100644 --- a/utils/eventHandler.go +++ b/utils/eventHandler.go @@ -51,6 +51,7 @@ func (eh *EventHandler) HandleApp(application app.Application) { application.GetPrimaryBus().Subscribe(UpdateGlobalSettings, eh.appBusQueue) application.GetPrimaryBus().Subscribe(CwtchStarted, eh.appBusQueue) application.GetPrimaryBus().Subscribe(servers.NewServer, eh.appBusQueue) + application.GetPrimaryBus().Subscribe(servers.ServerIntentUpdate, eh.appBusQueue) } func (eh *EventHandler) GetNextEvent() string { From f3b753827ffe048b6a6ac816d1f61feb3648eb1f Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Mon, 1 Nov 2021 19:36:14 -0700 Subject: [PATCH 10/11] better support reloading servers on experiment enable/disable --- features/servers/servers_functionality.go | 8 +++++++- lib.go | 22 +++++++++++++--------- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/features/servers/servers_functionality.go b/features/servers/servers_functionality.go index 0f679d1..ff9cdbe 100644 --- a/features/servers/servers_functionality.go +++ b/features/servers/servers_functionality.go @@ -3,6 +3,7 @@ package servers import ( "cwtch.im/cwtch/event" "fmt" + "git.openprivacy.ca/cwtch.im/libcwtch-go/constants" "git.openprivacy.ca/cwtch.im/server" "git.openprivacy.ca/openprivacy/connectivity" "path" @@ -43,11 +44,16 @@ func InitServers(acn connectivity.ACN, appdir string) { defer lock.Unlock() if appServers == nil { appServers = server.NewServers(acn, path.Join(appdir, "servers")) + appServers.LoadServers(constants.DefactoPasswordForUnencryptedProfiles) } } func DeactivateServers() { - appServers.Stop() + lock.Lock() + defer lock.Unlock() + if appServers == nil { + appServers.Stop() + } } // ServersFunctionality provides experiment gated server functionality diff --git a/lib.go b/lib.go index 6e0616c..2db08a3 100644 --- a/lib.go +++ b/lib.go @@ -214,7 +214,7 @@ func _startCwtch(appDir string, torPath string) { newApp.LoadProfiles(constants.DefactoPasswordForUnencryptedProfiles) application = newApp - LoadServers(constants.DefactoPasswordForUnencryptedProfiles) + publishLoadedServers() LaunchServers() // Send global settings to the UI... @@ -278,6 +278,16 @@ func ReconnectCwtchForeground() { } } + publishLoadedServers() + + settingsJson, _ := json.Marshal(settings) + application.GetPrimaryBus().Publish(event.NewEvent(utils.UpdateGlobalSettings, map[event.Field]string{event.Data: string(settingsJson)})) + application.GetPrimaryBus().Publish(event.NewEvent(utils.CwtchStarted, map[event.Field]string{})) + application.QueryACNStatus() + application.QueryACNVersion() +} + +func publishLoadedServers() { serversHandler, err := servers.ExperimentGate(utils.ReadGlobalSettings().Experiments) if err == nil { serversList := serversHandler.ListServers() @@ -288,12 +298,6 @@ func ReconnectCwtchForeground() { application.GetPrimaryBus().Publish(ev) } } - - settingsJson, _ := json.Marshal(settings) - application.GetPrimaryBus().Publish(event.NewEvent(utils.UpdateGlobalSettings, map[event.Field]string{event.Data: string(settingsJson)})) - application.GetPrimaryBus().Publish(event.NewEvent(utils.CwtchStarted, map[event.Field]string{})) - application.QueryACNStatus() - application.QueryACNVersion() } //export c_SendAppEvent @@ -325,10 +329,10 @@ func SendAppEvent(eventJson string) { settings := utils.ReadGlobalSettings() - serverHandler, err := servers.ExperimentGate(settings.Experiments) + _, err = servers.ExperimentGate(settings.Experiments) if err == nil { servers.InitServers(globalACN, globalAppDir) - serverHandler.LoadServers(constants.DefactoPasswordForUnencryptedProfiles) + publishLoadedServers() LaunchServers() } else { servers.DeactivateServers() From f9f074a65ceaf0723ec9d5f080498a07e7c426e4 Mon Sep 17 00:00:00 2001 From: Dan Ballard Date: Mon, 1 Nov 2021 21:30:03 -0700 Subject: [PATCH 11/11] LoadServers launches autolaunchers --- lib.go | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib.go b/lib.go index 2db08a3..9d1feea 100644 --- a/lib.go +++ b/lib.go @@ -995,6 +995,9 @@ func LoadServers(password string) { ev := event.NewEvent(servers.NewServer, make(map[event.Field]string)) serverInfo.EnrichEvent(&ev) application.GetPrimaryBus().Publish(ev) + if serverInfo.Autostart { + LaunchServer(serverOnion) + } } } }