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) } } }