diff --git a/client/client.go b/client/client.go index 04685cb..f787d44 100644 --- a/client/client.go +++ b/client/client.go @@ -8,20 +8,61 @@ import ( "io" "mime/multipart" "net/http" + "os" + "path/filepath" "time" "git.t-juice.club/torjus/gpaste/api" "git.t-juice.club/torjus/gpaste/files" "github.com/google/uuid" + "github.com/kirsle/configdir" ) type Client struct { - BaseURL string - AuthToken string + BaseURL string `json:"base_url"` + AuthToken string `json:"auth_token"` httpClient http.Client } +func (c *Client) WriteConfigToWriter(w io.Writer) error { + encoder := json.NewEncoder(w) + return encoder.Encode(c) +} +func (c *Client) WriteConfig() error { + dir := configdir.LocalConfig("gpaste") + // Ensure dir exists + err := os.MkdirAll(dir, os.ModePerm) + if err != nil { + return err + } + path := filepath.Join(dir, "client.json") + f, err := os.Create(path) + if err != nil { + return err + } + defer f.Close() + + return c.WriteConfigToWriter(f) +} + +func (c *Client) LoadConfig() error { + dir := configdir.LocalCache("gpaste") + path := filepath.Join(dir, "client.json") + f, err := os.Open(path) + if err != nil { + return err + } + defer f.Close() + + return c.LoadConfigFromReader(f) +} + +func (c *Client) LoadConfigFromReader(r io.Reader) error { + decoder := json.NewDecoder(r) + return decoder.Decode(c) +} + func (c *Client) Login(ctx context.Context, username, password string) error { url := fmt.Sprintf("%s/api/login", c.BaseURL) // TODO: Change timeout diff --git a/client/client_test.go b/client/client_test.go index 6df4a41..fcaaae8 100644 --- a/client/client_test.go +++ b/client/client_test.go @@ -1,6 +1,7 @@ package client_test import ( + "bytes" "context" "fmt" "io" @@ -15,6 +16,7 @@ import ( "git.t-juice.club/torjus/gpaste/files" "git.t-juice.club/torjus/gpaste/users" "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" "github.com/google/uuid" ) @@ -162,4 +164,31 @@ func TestClient(t *testing.T) { t.Errorf("File contents does not match: %s", cmp.Diff(buf.String(), fileContents)) } }) + t.Run("Save", func(t *testing.T) { + c := client.Client{BaseURL: "http://example.org/gpaste", AuthToken: "tokenpls"} + expectedConfig := "{\"base_url\":\"http://example.org/gpaste\",\"auth_token\":\"tokenpls\"}\n" + buf := new(bytes.Buffer) + err := c.WriteConfigToWriter(buf) + if err != nil { + t.Fatalf("Error writing config: %s", err) + } + + if diff := cmp.Diff(buf.String(), expectedConfig); diff != "" { + t.Errorf("Written config does not match expected: %s", diff) + } + }) + t.Run("Load", func(t *testing.T) { + c := client.Client{} + config := "{\"base_url\":\"http://pasta.example.org\",\"auth_token\":\"tokenpls\"}\n" + expectedClient := client.Client{BaseURL: "http://pasta.example.org", AuthToken: "tokenpls"} + sr := strings.NewReader(config) + if err := c.LoadConfigFromReader(sr); err != nil { + t.Fatalf("Error reading config: %s", err) + } + + if diff := cmp.Diff(c, expectedClient, cmpopts.IgnoreUnexported(client.Client{})); diff != "" { + t.Errorf("Client does not match expected: %s", diff) + } + + }) } diff --git a/cmd/client/actions/actions.go b/cmd/client/actions/actions.go index d72f67c..3270a86 100644 --- a/cmd/client/actions/actions.go +++ b/cmd/client/actions/actions.go @@ -56,6 +56,10 @@ func ActionLogin(c *cli.Context) error { errmsg := fmt.Sprintf("Error logging in: %s", err) return cli.Exit(errmsg, 1) } + if err := clnt.WriteConfig(); err != nil { + errMsg := fmt.Sprintf("Failed to write config: %s", err) + return cli.Exit(errMsg, 1) + } // TODO: Store this somewhere, so we don't need to log in each time fmt.Println("Successfully logged in.") diff --git a/go.mod b/go.mod index 49e2f3c..7b4125f 100644 --- a/go.mod +++ b/go.mod @@ -9,6 +9,7 @@ require github.com/go-chi/chi/v5 v5.0.7 require ( github.com/golang-jwt/jwt v3.2.2+incompatible github.com/google/go-cmp v0.5.6 + github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f github.com/pelletier/go-toml v1.9.4 github.com/urfave/cli/v2 v2.3.0 go.etcd.io/bbolt v1.3.6 @@ -23,4 +24,5 @@ require ( go.uber.org/atomic v1.9.0 // indirect go.uber.org/multierr v1.7.0 // indirect golang.org/x/sys v0.0.0-20220114195835-da31bd327af9 // indirect + golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 // indirect ) diff --git a/go.sum b/go.sum index bb70fbd..ec16159 100644 --- a/go.sum +++ b/go.sum @@ -15,6 +15,8 @@ github.com/google/go-cmp v0.5.6 h1:BKbKCqvP6I+rmFHt06ZmyQtvB8xAkWdhFyr0ZUNZcxQ= github.com/google/go-cmp v0.5.6/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE= github.com/google/uuid v1.3.0 h1:t6JiXgmwXMjEs8VusXIJk2BXHsn+wx8BZdTaoZ5fu7I= github.com/google/uuid v1.3.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo= +github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f h1:dKccXx7xA56UNqOcFIbuqFjAWPVtP688j5QMgmo6OHU= +github.com/kirsle/configdir v0.0.0-20170128060238-e45d2f54772f/go.mod h1:4rEELDSfUAlBSyUjPG0JnaNGjf13JySHFeRdD/3dLP0= github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo= github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ= github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=