Skip to content

Commit

Permalink
feat: sc-240965/check current access token (#324)
Browse files Browse the repository at this point in the history
Check if access token is set before logging in
  • Loading branch information
dbolson authored Jun 18, 2024
1 parent f24a1ea commit edb3d2d
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 7 deletions.
8 changes: 1 addition & 7 deletions cmd/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -228,13 +228,7 @@ func getConfig() (config.ConfigFile, *viper.Viper, error) {
return config.ConfigFile{}, nil, err
}

data, err := os.ReadFile(v.ConfigFileUsed())
if err != nil {
return config.ConfigFile{}, nil, err
}

var c config.ConfigFile
err = yaml.Unmarshal([]byte(data), &c)
c, err := config.NewConfigFromFile(v.ConfigFileUsed(), os.ReadFile)
if err != nil {
return config.ConfigFile{}, nil, err
}
Expand Down
5 changes: 5 additions & 0 deletions cmd/login/login.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import (
cmdAnalytics "github.com/launchdarkly/ldcli/cmd/analytics"
"github.com/launchdarkly/ldcli/cmd/cliflags"
"github.com/launchdarkly/ldcli/internal/analytics"
"github.com/launchdarkly/ldcli/internal/config"
"github.com/launchdarkly/ldcli/internal/login"
"github.com/launchdarkly/ldcli/internal/output"
)
Expand Down Expand Up @@ -54,6 +55,10 @@ func NewLoginCmd(

func run(client login.Client) func(*cobra.Command, []string) error {
return func(cmd *cobra.Command, args []string) error {
if ok, err := config.AccessTokenIsSet(viper.GetViper().ConfigFileUsed()); !ok {
return err
}

deviceAuthorization, err := login.FetchDeviceAuthorization(
client,
login.ClientID,
Expand Down
30 changes: 30 additions & 0 deletions internal/config/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
"strconv"

"github.com/mitchellh/go-homedir"
"gopkg.in/yaml.v3"

"github.com/launchdarkly/ldcli/cmd/cliflags"
"github.com/launchdarkly/ldcli/internal/errors"
Expand All @@ -26,6 +27,23 @@ type ConfigFile struct {
Project string `json:"project,omitempty" yaml:"project,omitempty"`
}

type ReadFile func(name string) ([]byte, error)

func NewConfigFromFile(f string, readFile ReadFile) (ConfigFile, error) {
data, err := readFile(f)
if err != nil {
return ConfigFile{}, errors.NewError("could not read config file")
}

var c ConfigFile
err = yaml.Unmarshal([]byte(data), &c)
if err != nil {
return ConfigFile{}, errors.NewError("config file is invalid yaml")
}

return c, nil
}

func NewConfig(rawConfig map[string]interface{}) (ConfigFile, error) {
var (
accessToken string
Expand Down Expand Up @@ -91,3 +109,15 @@ func GetConfigFile() string {

return filepath.Join(configFilePath, "config.yml")
}

func AccessTokenIsSet(filename string) (bool, error) {
config, err := NewConfigFromFile(filename, os.ReadFile)
if err != nil {
return false, err
}
if config.AccessToken != "" {
return false, errors.NewError("Your access token is already set. Remove it from the config if you wish to reset it.")
}

return true, nil
}
54 changes: 54 additions & 0 deletions internal/config/config_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,65 @@ import (

"github.com/stretchr/testify/assert"
"github.com/stretchr/testify/require"
"gopkg.in/yaml.v3"

"github.com/launchdarkly/ldcli/internal/config"
"github.com/launchdarkly/ldcli/internal/resources"
)

type mockReadFile struct {
contents []byte
successful bool
}

func (m mockReadFile) readFile(name string) ([]byte, error) {
if !m.successful {
return nil, errors.New("an error")
}

if m.contents != nil {
return yaml.Marshal(m.contents)
}

return yaml.Marshal(map[string]interface{}{
"access-token": "test-access-token",
})
}

func TestNewConfigFromFile(t *testing.T) {
t.Run("with valid input is a valid config", func(t *testing.T) {
mock := mockReadFile{
successful: true,
}

c, err := config.NewConfigFromFile("test-config-file", mock.readFile)

require.NoError(t, err)
assert.Equal(t, "test-access-token", c.AccessToken)
})

t.Run("with invalid file is an error", func(t *testing.T) {
mock := mockReadFile{
successful: false,
}

_, err := config.NewConfigFromFile("test-config-file", mock.readFile)

assert.EqualError(t, err, "could not read config file")
})

t.Run("with invalid formatting in the file contents is an error", func(t *testing.T) {
mock := mockReadFile{
contents: []byte(`invalid`),
successful: true,
}

_, err := config.NewConfigFromFile("test-config-file", mock.readFile)

assert.EqualError(t, err, "config file is invalid yaml")
})
}

func TestNewConfig(t *testing.T) {
t.Run("analytics-opt-out", func(t *testing.T) {
tests := map[string]struct {
Expand Down

0 comments on commit edb3d2d

Please sign in to comment.