From ef63736d745ab4673a0cbd34623dc4ebde13ca5f Mon Sep 17 00:00:00 2001 From: Sarah Jamie Lewis Date: Wed, 10 Mar 2021 09:41:09 -0800 Subject: [PATCH] Read/Write Global Settings --- lib.go | 36 +++++++++++++++++ utils/eventHandler.go | 4 +- utils/settings.go | 92 +++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 130 insertions(+), 2 deletions(-) create mode 100644 utils/settings.go diff --git a/lib.go b/lib.go index 352f6b0..36beaf9 100644 --- a/lib.go +++ b/lib.go @@ -41,6 +41,8 @@ func StartCwtch(appDir string, torPath string) { log.SetLevel(log.LevelDebug) //log.ExcludeFromPattern("service.go") + utils.InitGlobalSettingsFile(appDir, "be gay do crime") + log.Infof("Loading Cwtch Directory %v and tor path: %v", appDir, torPath) mrand.Seed(int64(time.Now().Nanosecond())) @@ -66,6 +68,7 @@ func StartCwtch(appDir string, torPath string) { newApp := app.NewApp(acn, appDir) acnQueue = event.NewQueue() newApp.GetPrimaryBus().Subscribe(event.ACNStatus, acnQueue) + newApp.GetPrimaryBus().Subscribe(utils.UpdateGlobalSettings, acnQueue) eventHandler = utils.NewEventHandler(newApp) @@ -82,10 +85,13 @@ func StartCwtch(appDir string, torPath string) { event.NewGroupInvite, event.ServerStateChange, } + settings := utils.ReadGlobalSettings() + settingsJson, _ := json.Marshal(settings) newApp.LoadProfiles("be gay do crime") newApp.LaunchPeers() application = newApp + application.GetPrimaryBus().Publish(event.NewEvent(utils.UpdateGlobalSettings, map[event.Field]string{event.Data: string(settingsJson)})) log.Infof("libcwtch-go application SET\n") } @@ -103,6 +109,36 @@ func ACNEvents() string { } } +//export c_SendAppEvent +// A generic method for Rebroadcasting App Events from a UI +func c_SendAppEvent(json_ptr *C.char, json_len C.int) { + eventJson := C.GoStringN(json_ptr, json_len) + SendAppEvent(eventJson) +} + +// SendAppEvent is a generic method for Rebroadcasting App Events from a UI +func SendAppEvent(eventJson string) { + // Convert the Event Json back to a typed Event Struct, this will make the + // rest of the logic nicer. + var new_event event.Event + json.Unmarshal([]byte(eventJson), &new_event) + log.Infof("Event: %v", new_event) + + // We need to update the local cache + // Ideally I think this would be pusgit hed back into Cwtch + switch new_event.EventType { + case utils.UpdateGlobalSettings: + var globalSettings utils.GlobalSettings + err := json.Unmarshal([]byte(new_event.Data[event.Data]), &globalSettings) + if err != nil { + log.Errorf("Error Unmarshalling Settings %v [%v]", err, new_event.Data[event.Data]) + } + log.Debugf("New Settings %v", globalSettings) + utils.WriteGlobalSettings(globalSettings) + default: // do nothing + } +} + //export c_SendProfileEvent // A generic method for Rebroadcasting Profile Events from a UI func c_SendProfileEvent(onion_ptr *C.char, onion_len C.int, json_ptr *C.char, json_len C.int) { diff --git a/utils/eventHandler.go b/utils/eventHandler.go index c34a7b8..056eb0e 100644 --- a/utils/eventHandler.go +++ b/utils/eventHandler.go @@ -32,8 +32,8 @@ func NewEventHandler(application app.Application) *EventHandler { application.GetPrimaryBus().Subscribe(event.ACNStatus, appBusQueue) application.GetPrimaryBus().Subscribe(event.ReloadDone, appBusQueue) application.GetPrimaryBus().Subscribe(event.ACNVersion, appBusQueue) - - return &EventHandler{appBusQueue: appBusQueue, profileQueues: make(map[string]event.Queue), profileEvents: make(chan EventProfileEnvelope)} + application.GetPrimaryBus().Subscribe(UpdateGlobalSettings, appBusQueue) + return &EventHandler{app: application, appBusQueue: appBusQueue, profileQueues: make(map[string]event.Queue), profileEvents: make(chan EventProfileEnvelope)} } func (eh *EventHandler) GetNextEvent() string { diff --git a/utils/settings.go b/utils/settings.go new file mode 100644 index 0000000..76c548a --- /dev/null +++ b/utils/settings.go @@ -0,0 +1,92 @@ +package utils + +import ( + "cwtch.im/cwtch/event" + "cwtch.im/cwtch/storage/v1" + + "encoding/json" + "git.openprivacy.ca/openprivacy/log" + "io/ioutil" + "os" + "path" +) + +const ( + UpdateGlobalSettings = event.Type("UpdateGlobalSettings") +) + +var GlobalSettingsFile v1.FileStore + +const GlobalSettingsFilename = "ui.globals" +const saltFile = "SALT" + +type GlobalSettings struct { + Locale string + Theme string + PreviousPid int64 + ExperimentsEnabled bool + Experiments map[string]bool + StateRootPane int + FirstTime bool +} + +var DefaultGlobalSettings = GlobalSettings{ + Locale: "en", + Theme: "light", + PreviousPid: -1, + ExperimentsEnabled: false, + Experiments: make(map[string]bool), + StateRootPane: 0, + FirstTime: true, +} + +func InitGlobalSettingsFile(directory string, password string) error { + var key [32]byte + salt, err := ioutil.ReadFile(path.Join(directory, saltFile)) + if err != nil { + var newSalt [128]byte + key, newSalt, err = v1.CreateKeySalt(password) + if err != nil { + return err + } + os.Mkdir(directory, 0700) + err := ioutil.WriteFile(path.Join(directory, saltFile), newSalt[:], 0600) + if err != nil { + return err + } + } else { + key = v1.CreateKey(password, salt) + } + + GlobalSettingsFile = v1.NewFileStore(directory, GlobalSettingsFilename, key) + return nil +} + +func ReadGlobalSettings() *GlobalSettings { + settings := DefaultGlobalSettings + + settingsBytes, err := GlobalSettingsFile.Read() + if err != nil { + log.Errorf("Could not read global ui settings: %v\n", err) + return &settings //firstTime = true + } + + err = json.Unmarshal(settingsBytes, &settings) + if err != nil { + log.Errorf("Could not parse global ui settings: %v\n", err) + return &settings //firstTime = true + } + + log.Debugf("Settings: %#v", settings) + return &settings +} + +func WriteGlobalSettings(globalSettings GlobalSettings) { + bytes, _ := json.Marshal(globalSettings) + // override first time setting + globalSettings.FirstTime = true + err := GlobalSettingsFile.Write(bytes) + if err != nil { + log.Errorf("Could not write global ui settings: %v\n", err) + } +}