Skip to content

Commit

Permalink
Merge pull request #145 from Shopify/support_password_config_var_inte…
Browse files Browse the repository at this point in the history
…rchangeable_with_access_token

Support 'password' in config, interchangeable with access_token
  • Loading branch information
chrisbutcher committed Mar 9, 2016
2 parents 6df5722 + 0c47910 commit e5b4b2a
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 34 deletions.
12 changes: 9 additions & 3 deletions cmd/theme/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -196,22 +196,24 @@ func WatchCommandParser(cmd string, args []string) (result map[string]interface{
func ConfigurationCommandParser(cmd string, args []string) (result map[string]interface{}, set *flag.FlagSet) {
result = make(map[string]interface{})
currentDir, _ := os.Getwd()
var directory, environment, domain, accessToken string
var directory, environment, domain, password, access_token string
var bucketSize, refillRate int

set = makeFlagSet(cmd)
set.StringVar(&directory, "dir", currentDir, "directory to create config.yml")
set.StringVar(&environment, "env", themekit.DefaultEnvironment, "environment for this configuration")
set.StringVar(&domain, "domain", "", "your myshopify domain")
set.StringVar(&accessToken, "access_token", "", "accessToken (or password) to make successful API calls")
set.StringVar(&password, "password", "", "password (or access token) to make successful API calls")
set.StringVar(&access_token, "access_token", "", "access_token to make successful API calls (optional, and soon to be deprecated in favour of 'password')")
set.IntVar(&bucketSize, "bucketSize", themekit.DefaultBucketSize, "leaky bucket capacity")
set.IntVar(&refillRate, "refillRate", themekit.DefaultRefillRate, "leaky bucket refill rate / second")
set.Parse(args)

result["directory"] = directory
result["environment"] = environment
result["domain"] = domain
result["access_token"] = accessToken
result["password"] = password
result["access_token"] = access_token
result["bucket_size"] = bucketSize
result["refill_rate"] = refillRate
return
Expand Down Expand Up @@ -273,6 +275,10 @@ func loadThemeClientWithRetry(directory, env string, isRetry bool) (themekit.The
return themekit.ThemeClient{}, err
}

if len(config.AccessToken) > 0 {
fmt.Println("DEPRECATION WARNING: 'access_token' (in conf.yml) will soon be deprecated. Use 'password' instead, with the same Password value obtained from https://<your-subdomain>.myshopify.com/admin/apps/private/<app_id>")
}

return themekit.NewThemeClient(config), nil
}

Expand Down
17 changes: 9 additions & 8 deletions commands/configure.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,18 +17,16 @@ type ConfigurationOptions struct {
Environment string
Domain string
AccessToken string
Password string
BucketSize int
RefillRate int
}

func (co ConfigurationOptions) areInvalid() bool {
return co.Domain == "" || co.AccessToken == ""
}

func (co ConfigurationOptions) defaultConfigurationOptions() themekit.Configuration {
return themekit.Configuration{
Domain: co.Domain,
AccessToken: co.AccessToken,
Password: co.Password,
BucketSize: co.BucketSize,
RefillRate: co.RefillRate,
}
Expand All @@ -39,8 +37,8 @@ func (co ConfigurationOptions) configurationErrors() error {
if len(co.Domain) <= 0 {
errs = append(errs, "\t-domain cannot be blank")
}
if len(co.AccessToken) <= 0 {
errs = append(errs, "\t-access_token cannot be blank")
if len(co.AccessToken) <= 0 && len(co.Password) <= 0 {
errs = append(errs, "\t-password or access_token cannot be blank")
}
if len(errs) > 0 {
fullPath := filepath.Join(co.Directory, "config.yml")
Expand All @@ -54,6 +52,7 @@ func defaultOptions() ConfigurationOptions {
return ConfigurationOptions{
Domain: "",
AccessToken: "",
Password: "",
Directory: currentDir,
Environment: themekit.DefaultEnvironment,
BucketSize: themekit.DefaultBucketSize,
Expand All @@ -68,12 +67,14 @@ func ConfigureCommand(args map[string]interface{}) chan bool {
extractString(&options.Directory, "directory", args)
extractString(&options.Domain, "domain", args)
extractString(&options.AccessToken, "access_token", args)
extractString(&options.Password, "password", args)
extractInt(&options.BucketSize, "bucket_size", args)
extractInt(&options.RefillRate, "refill_rate", args)
extractEventLog(&options.EventLog, args)

if options.areInvalid() {
themekit.NotifyError(options.configurationErrors())
if err := options.configurationErrors(); err != nil {
themekit.NotifyError(err)
return nil
}

Configure(options)
Expand Down
23 changes: 18 additions & 5 deletions configuration.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,19 @@ package themekit

import (
"fmt"
"gopkg.in/yaml.v1"
"io"
"net/http"
"os"
"runtime"
"strings"

"gopkg.in/yaml.v1"
)

type Configuration struct {
ThemeId int64 `yaml:"theme_id,omitempty"`
AccessToken string `yaml:"access_token"`
AccessToken string `yaml:"access_token,omitempty"`
Password string `yaml:"password,omitempty"`
Domain string `yaml:"store"`
Url string `yaml:"-"`
IgnoredFiles []string `yaml:"ignore_files,omitempty"`
Expand Down Expand Up @@ -54,9 +57,12 @@ func (conf Configuration) Initialize() (Configuration, error) {

if len(conf.Domain) == 0 {
return conf, fmt.Errorf("missing domain")
} else if !strings.HasSuffix(conf.Domain, "myshopify.com") && !strings.HasSuffix(conf.Domain, "myshopify.io") {
return conf, fmt.Errorf("invalid domain, must end in '.myshopify.com'")
}
if len(conf.AccessToken) == 0 {
return conf, fmt.Errorf("missing access_token")

if len(conf.AccessToken) == 0 && len(conf.Password) == 0 {
return conf, fmt.Errorf("missing password or access_token (using 'password' is encouraged. 'access_token', which does the same thing will be deprecated soon)")
}
return conf, nil
}
Expand Down Expand Up @@ -87,7 +93,14 @@ func (conf Configuration) AssetPath() string {
}

func (conf Configuration) AddHeaders(req *http.Request) {
req.Header.Add("X-Shopify-Access-Token", conf.AccessToken)
var accessToken string
if len(conf.Password) > 0 {
accessToken = conf.Password
} else {
accessToken = conf.AccessToken
}

req.Header.Add("X-Shopify-Access-Token", accessToken)
req.Header.Add("Content-Type", "application/json")
req.Header.Add("Accept", "application/json")
req.Header.Add("User-Agent", fmt.Sprintf("go/themekit (%s; %s)", runtime.GOOS, runtime.GOARCH))
Expand Down
40 changes: 24 additions & 16 deletions configuration_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,19 @@ package themekit

import (
"bytes"
"github.com/stretchr/testify/assert"
"net/http"
"runtime"
"strings"
"testing"

"github.com/stretchr/testify/assert"
)

func TestLoadingAValidConfiguration(t *testing.T) {
config, err := LoadConfiguration([]byte(validConfiguration))
assert.Nil(t, err)
assert.Equal(t, "example.myshopify.com", config.Domain)
assert.Equal(t, "abracadabra", config.AccessToken)
assert.Equal(t, "abracadabra", config.Password)
assert.Equal(t, "https://example.myshopify.com/admin", config.Url)
assert.Equal(t, "https://example.myshopify.com/admin/assets.json", config.AssetPath())
assert.Equal(t, 4, config.Concurrency)
Expand All @@ -24,31 +25,32 @@ func TestLoadingAValidConfigurationWithIgnoredFiles(t *testing.T) {
config, err := LoadConfiguration([]byte(validConfigurationWithIgnoredFiles))
assert.Nil(t, err)
assert.Equal(t, "example.myshopify.com", config.Domain)
assert.Equal(t, "abracadabra", config.AccessToken)
assert.Equal(t, "abracadabra", config.Password)
assert.Equal(t, []string{"charmander", "bulbasaur", "squirtle"}, config.IgnoredFiles)
}

func TestLoadingAValidConfigurationWithAThemeId(t *testing.T) {
config, err := LoadConfiguration([]byte(validConfigurationWithThemeId))
config, err := LoadConfiguration([]byte(validConfigurationWithThemeID))
assert.Nil(t, err)
assert.Equal(t, 1234, config.ThemeId)
assert.Equal(t, "https://example.myshopify.com/admin/themes/1234", config.Url)
assert.Equal(t, "https://example.myshopify.com/admin/themes/1234/assets.json", config.AssetPath())
}

func TestLoadingAnUnsupportedConfiguration(t *testing.T) {
config, err := LoadConfiguration([]byte(unsupportedConfiguration))
func TestLoadingSupportedConfiguration(t *testing.T) {
config, err := LoadConfiguration([]byte(supportedConfiguration))
assert.Nil(t, err)
assert.Equal(t, "example.myshopify.com", config.Domain)
assert.Equal(t, "abracadabra", config.AccessToken)
assert.Equal(t, "abracadabra", config.Password)
}

func TestLoadingConfigurationWithMissingFields(t *testing.T) {
tests := []struct {
src, expectedError string
}{
{configurationWithoutAccessToken, "missing access_token"},
{configurationWithoutAccessTokenAndPassword, "missing password or access_token (using 'password' is encouraged. 'access_token', which does the same thing will be deprecated soon)"},
{configurationWithoutDomain, "missing domain"},
{configurationWithInvalidDomain, "invalid domain, must end in '.myshopify.com'"},
}

for _, data := range tests {
Expand Down Expand Up @@ -86,37 +88,43 @@ func TestAddHeadersAddsPlatformAndArchitecture(t *testing.T) {
const (
validConfiguration = `
store: example.myshopify.com
access_token: abracadabra
password: abracadabra
concurrency: 4
`

validConfigurationWithThemeId = `
validConfigurationWithThemeID = `
store: example.myshopify.com
access_token: abracadabra
password: abracadabra
theme_id: 1234
`

validConfigurationWithIgnoredFiles = `
store: example.myshopify.com
access_token: abracadabra
password: abracadabra
ignore_files:
- charmander
- bulbasaur
- squirtle
`

unsupportedConfiguration = `
supportedConfiguration = `
store: example.myshopify.com
access_token: abracadabra
password: abracadabra
theme_id: 12345
`

configurationWithoutAccessToken = `
configurationWithoutAccessTokenAndPassword = `
store: foo.myshopify.com
theme_id: 123
`

configurationWithoutDomain = `
access_token: foobar
password: foobar
`

configurationWithInvalidDomain = `
store: example.something.net
password: abracadabra
theme_id: 12345
`
)
5 changes: 3 additions & 2 deletions version.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,14 @@ import (
_ "crypto/md5"
"encoding/hex"
"fmt"
"github.com/inconshreveable/go-update"
"net/http"
"strconv"
"strings"

"github.com/inconshreveable/go-update"
)

var TKVersion Version = Version{Major: 0, Minor: 3, Patch: 5}
var TKVersion Version = Version{Major: 0, Minor: 3, Patch: 6}
var ThemeKitVersion string = TKVersion.String()

type VersionComparisonResult int
Expand Down

0 comments on commit e5b4b2a

Please sign in to comment.