package main import ( "encoding/json" "fmt" "github.com/spf13/cobra" "golang.org/x/crypto/ssh/terminal" "os" "strings" "syscall" ) type ServerSettings struct { URL string Username string Password string } type Settings struct { EWS ServerSettings CalDAV ServerSettings Anonymize struct { Title string } } func ensurePassword(password *string, name string) { if *password != "" { // Nothing to do. Password already set. return } print(name + " password: ") b, err := terminal.ReadPassword(int(syscall.Stdin)) println() if err != nil { panic(err) } *password = string(b) } func LoadSettings() Settings { f, err := os.Open("calanonsync.json") if err != nil { panic(err) } settings := Settings{} err = json.NewDecoder(f).Decode(&settings) if err != nil { panic(err) } if settings.CalDAV.URL != "" && !strings.HasSuffix(settings.CalDAV.URL, "/") { settings.CalDAV.URL += "/" } ensurePassword(&settings.EWS.Password, "EWS") ensurePassword(&settings.CalDAV.Password, "CalDAV") return settings } func InitSettingsCmd() *cobra.Command { settingsCmd := &cobra.Command{ Use: "settings", Short: "Manage settings.", } encryptCmd := &cobra.Command{ Use: "encrypt", Short: "Encrypt the passwords in the settings file.", Long: `This will encrypt the passwords in the settings file that are not empty. It will generate a new "master" password and store that alongside the settings file. This is NOT secure, it just helps to prevent over-the-shoulder "attacks".`, Run: func(cmd *cobra.Command, args []string) { fmt.Println("Encrypt") }, } decryptCmd := &cobra.Command{ Use: "decrypt", Short: "Decrypt a previously encrypted settings file.", Run: func(cmd *cobra.Command, args []string) { fmt.Println("Decrypt") }, } settingsCmd.AddCommand(encryptCmd, decryptCmd) return settingsCmd }