diff --git a/app/wtf_app.go b/app/wtf_app.go index 982979749..8961fd8c0 100644 --- a/app/wtf_app.go +++ b/app/wtf_app.go @@ -17,23 +17,25 @@ import ( // WtfApp is the container for a collection of widgets that are all constructed from a single // configuration file and displayed together type WtfApp struct { - app *tview.Application - config *config.Config - configFilePath string - display *Display - focusTracker FocusTracker - pages *tview.Pages - validator *ModuleValidator - widgets []wtf.Wtfable + app *tview.Application + config *config.Config + configFilePath string + secretsFilePath string + display *Display + focusTracker FocusTracker + pages *tview.Pages + validator *ModuleValidator + widgets []wtf.Wtfable } // NewWtfApp creates and returns an instance of WtfApp -func NewWtfApp(app *tview.Application, config *config.Config, configFilePath string) *WtfApp { +func NewWtfApp(app *tview.Application, config *config.Config, configFilePath string, secretsFilePath string) *WtfApp { wtfApp := WtfApp{ - app: app, - config: config, - configFilePath: configFilePath, - pages: tview.NewPages(), + app: app, + config: config, + configFilePath: configFilePath, + secretsFilePath: secretsFilePath, + pages: tview.NewPages(), } wtfApp.app.SetBeforeDrawFunc(func(s tcell.Screen) bool { @@ -139,7 +141,8 @@ func (wtfApp *WtfApp) watchForConfigChanges() { wtfApp.Stop() config := cfg.LoadWtfConfigFile(wtfApp.configFilePath) - newApp := NewWtfApp(wtfApp.app, config, wtfApp.configFilePath) + secrets := cfg.LoadWtfSecretsFile(wtfApp.secretsFilePath) + newApp := NewWtfApp(wtfApp.app, config, wtfApp.configFilePath, wtfApp.secretsFilePath) newApp.Start() case err := <-watch.Error: diff --git a/cfg/config_files.go b/cfg/config_files.go index 153f02510..8dba06b8b 100644 --- a/cfg/config_files.go +++ b/cfg/config_files.go @@ -23,6 +23,9 @@ const ( // WtfConfigFile defines the name of the default config file WtfConfigFile = "config.yml" + + // WtfSecretsFile defines the file in which to store API Keys and other values you may want to keep out of config.yml + WtfSecretsFile = "secrets.yml" ) /* -------------------- Exported Functions -------------------- */ @@ -70,6 +73,7 @@ func Initialize(hasCustom bool) { if hasCustom == false { createWtfConfigFile() chmodConfigFile() + chmodSecretsFile() } } @@ -96,6 +100,19 @@ func LoadWtfConfigFile(filePath string) *config.Config { return cfg } +// LoadWtfSecretsFile loads the specified secrets file +func LoadWtfSecretsFile(filePath string) *config.Config { + absPath, _ := expandHomeDir(filePath) + + secrets, err := config.ParseYamlFile(absPath) + if err != nil { + displayWtfConfigFileLoadError(absPath, err) + os.Exit(1) + } + + return secrets +} + /* -------------------- Unexported Functions -------------------- */ // chmodConfigFile sets the mode of the config file to r+w for the owner only @@ -114,6 +131,22 @@ func chmodConfigFile() { } } +// chmodSecretsFile sets the mode of the Secrets file to r+w for the owner only +func chmodSecretsFile() { + relPath := fmt.Sprintf("%s%s", WtfConfigDirV2, WtfSecretsFile) + absPath, _ := expandHomeDir(relPath) + + _, err := os.Stat(absPath) + if err != nil && os.IsNotExist(err) { + return + } + + err = os.Chmod(absPath, 0600) + if err != nil { + return + } +} + // createXdgConfigDir creates the necessary base directory for storing the config file // If ~/.config is missing, it will try to create it func createXdgConfigDir() { @@ -162,6 +195,26 @@ func createWtfConfigFile() { } } +// createWtfSecretsFile creates a simple config file in the config directory if +// one does not already exist +func createWtfSecretsFile() { + filePath, err := CreateFile(WtfSecretsFile) + if err != nil { + displayDefaultConfigCreateError(err) + os.Exit(1) + } + + // If the file is empty, write to it + file, _ := os.Stat(filePath) + + if file.Size() == 0 { + if ioutil.WriteFile(filePath, []byte(defaultSecretsFile), 0600) != nil { + displayDefaultConfigWriteError(err) + os.Exit(1) + } + } +} + // Expand expands the path to include the home directory if the path // is prefixed with `~`. If it isn't prefixed with `~`, the path is // returned as-is. diff --git a/cfg/default_config_file.go b/cfg/default_config_file.go index 2caa4e922..eb4d3759c 100644 --- a/cfg/default_config_file.go +++ b/cfg/default_config_file.go @@ -103,3 +103,10 @@ wtf: refreshInterval: 30 type: cmdrunner ` +const defaultSecretsFile = ` +wtf: + keys: + # API keys and other secrets are listed below. For example: + #WTF_GITHUB_TOKEN: AVERYLONGSECRET + +` diff --git a/go.mod b/go.mod index 62996a08d..d7714d6f8 100644 --- a/go.mod +++ b/go.mod @@ -31,6 +31,7 @@ require ( github.com/gogo/protobuf v1.3.0 // indirect github.com/golang/glog v0.0.0-20170312005925-543a34c32e4d // indirect github.com/golang/groupcache v0.0.0-20191002201903-404acd9df4cc // indirect + github.com/google/btree v1.0.0 // indirect github.com/google/go-cmp v0.3.1 // indirect github.com/google/go-github/v26 v26.1.3+incompatible github.com/googleapis/gnostic v0.3.1 // indirect