diff --git a/cmd/config-serverurl.go b/cmd/config-serverurl.go index 3c39ecf..e48bc49 100644 --- a/cmd/config-serverurl.go +++ b/cmd/config-serverurl.go @@ -35,7 +35,7 @@ Example: pleasant-cli config serverurl `, Args: cobra.MatchAll(cobra.MinimumNArgs(1)), Run: func(cmd *cobra.Command, args []string) { - err := pleasant.WriteConfigFile(cfgFile, args[0]) + err := pleasant.WriteConfigFile(cfgFile, "ServerUrl", args[0]) if err != nil { fmt.Println(err) return diff --git a/cmd/config-timeout.go b/cmd/config-timeout.go new file mode 100644 index 0000000..ec62dc6 --- /dev/null +++ b/cmd/config-timeout.go @@ -0,0 +1,48 @@ +/* +Copyright © 2023 Martijn Evers + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ +package cmd + +import ( + "fmt" + + "github.com/marevers/pleasant-cli/pleasant" + "github.com/spf13/cobra" +) + +// timeoutCmd represents the timeout command +var timeoutCmd = &cobra.Command{ + Use: "timeout", + Short: "Sets the Pleasant Password server timeout for pleasant-cli", + Long: `Sets the Pleasant Password server timeout for pleasant-cli +It is specified as seconds and the default value (when it is unconfigured / set to 0 in the config file) is 20 seconds. + +Example: +pleasant-cli config timeout 30`, + Args: cobra.MatchAll(cobra.MinimumNArgs(1)), + Run: func(cmd *cobra.Command, args []string) { + err := pleasant.WriteConfigFile(cfgFile, "Timeout", args[0]) + if err != nil { + fmt.Println(err) + return + } + + fmt.Println("Timeout saved to:", cfgFile) + }, +} + +func init() { + configCmd.AddCommand(timeoutCmd) +} diff --git a/cmd/login.go b/cmd/login.go index 7492c3a..93e9d05 100644 --- a/cmd/login.go +++ b/cmd/login.go @@ -37,6 +37,10 @@ Examples: pleasant-cli login pleasant-cli login --username --password `, Run: func(cmd *cobra.Command, args []string) { + if !pleasant.CheckPrerequisites(pleasant.IsServerUrlSet()) { + return + } + var username string var password string diff --git a/pleasant/helpers.go b/pleasant/helpers.go index d0ebfde..13b8017 100644 --- a/pleasant/helpers.go +++ b/pleasant/helpers.go @@ -24,6 +24,8 @@ import ( "net/http" "net/url" "os" + "reflect" + "strconv" "strings" "syscall" "time" @@ -62,7 +64,7 @@ func IsTokenValid() *prerequisite { } func IsServerUrlSet() *prerequisite { - b := viper.IsSet("serverurl") + b := (viper.IsSet("serverurl") && viper.GetString("serverurl") != "") pr := &prerequisite{ Message: "Server URL is not set. Please set it with 'pleasant-cli config serverurl '.", @@ -107,12 +109,27 @@ func PasswordPrompt(label string) string { return s } -func WriteConfigFile(file, serverUrl string) error { - t := &ConfigFile{ - ServerUrl: serverUrl, +func WriteConfigFile(file, key string, value string) error { + c := &ConfigFile{} + + b, err := os.ReadFile(file) + if err == nil { + err = yaml.Unmarshal(b, c) + if err != nil { + return err + } } - b, err := yaml.Marshal(t) + v := reflect.ValueOf(c).Elem() + fv := v.FieldByName(key) + + if i, err := strconv.Atoi(value); err != nil { + fv.SetString(value) + } else { + fv.SetInt(int64(i)) + } + + b, err = yaml.Marshal(c) if err != nil { return err } @@ -150,9 +167,14 @@ func LoadConfig() (string, string) { return viper.GetString("serverurl"), viper.GetString("bearertoken.accesstoken") } -func newHttpClient() *http.Client { +func newHttpClient(to int) *http.Client { + // Set timeout to 20 if no timeout is specified + if to == 0 { + to = 20 + } + return &http.Client{ - Timeout: 20 * time.Second, + Timeout: time.Duration(to) * time.Second, } } @@ -168,7 +190,9 @@ func getRequest(baseUrl, path, bearerToken string) (*http.Response, error) { req.Header.Add("Authorization", "Bearer "+bearerToken) } - client := newHttpClient() + to := viper.GetInt("timeout") + + client := newHttpClient(to) res, err := client.Do(req) if err != nil { @@ -212,7 +236,9 @@ func postRequestForm(baseUrl, path string, urlValues url.Values) (*http.Response req.Header.Set("Content-Type", "application/json; charset=UTF-8") - client := newHttpClient() + to := viper.GetInt("timeout") + + client := newHttpClient(to) res, err := client.Do(req) if err != nil { @@ -240,7 +266,9 @@ func postRequestJsonString(baseUrl, path, jsonString, bearerToken string) (*http req.Header.Set("Content-Type", "application/json; charset=UTF-8") - client := newHttpClient() + to := viper.GetInt("timeout") + + client := newHttpClient(to) res, err := client.Do(req) if err != nil { @@ -267,7 +295,9 @@ func patchRequestJsonString(baseUrl, path, jsonString, bearerToken string) (*htt req.Header.Set("Content-Type", "application/json; charset=UTF-8") - client := newHttpClient() + to := viper.GetInt("timeout") + + client := newHttpClient(to) res, err := client.Do(req) if err != nil { @@ -295,7 +325,9 @@ func deleteRequestJsonString(baseUrl, path, jsonString, bearerToken string) (*ht req.Header.Set("Content-Type", "application/json; charset=UTF-8") - client := newHttpClient() + to := viper.GetInt("timeout") + + client := newHttpClient(to) res, err := client.Do(req) if err != nil { diff --git a/pleasant/models.go b/pleasant/models.go index 99bd31c..419ca04 100644 --- a/pleasant/models.go +++ b/pleasant/models.go @@ -17,6 +17,7 @@ package pleasant type ConfigFile struct { ServerUrl string `yaml:"serverurl"` + Timeout int `yaml:"timeout"` } type TokenFile struct {