Skip to content

Commit a4ad895

Browse files
authored
Add redirect to ThemeKit Access when password prefix matches pattern (#933)
* Add redirect to ThemeKit Access when password prefix matches pattern * Make themeKitAccessURL a variable and update it in unit tests
1 parent 15f9bef commit a4ad895

2 files changed

Lines changed: 59 additions & 1 deletion

File tree

src/httpify/client.go

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ import (
1515
"github.com/Shopify/themekit/src/release"
1616
)
1717

18+
const themeKitPasswordPrefix = "shptka_"
19+
1820
var (
1921
// ErrConnectionIssue is an error that is thrown when a very specific error is
2022
// returned from our http request that usually implies bad connections.
@@ -27,6 +29,7 @@ var (
2729
httpClient = &http.Client{
2830
Timeout: 30 * time.Second,
2931
}
32+
themeKitAccessURL = "https://theme-kit-access.shopifyapps.com/cli"
3033
)
3134

3235
type proxyHandler func(*http.Request) (*url.URL, error)
@@ -103,7 +106,15 @@ func (client *HTTPClient) Delete(path string, headers map[string]string) (*http.
103106

104107
// do will issue an authenticated json request to shopify.
105108
func (client *HTTPClient) do(method, path string, body interface{}, headers map[string]string) (*http.Response, error) {
106-
req, err := http.NewRequest(method, client.baseURL.String()+path, nil)
109+
appBaseURL := client.baseURL.String()
110+
111+
// redirect to Theme Kit Access
112+
if strings.HasPrefix(client.password, themeKitPasswordPrefix) {
113+
appBaseURL = themeKitAccessURL
114+
}
115+
116+
req, err := http.NewRequest(method, appBaseURL+path, nil)
117+
107118
if err != nil {
108119
return nil, err
109120
}
@@ -112,6 +123,9 @@ func (client *HTTPClient) do(method, path string, body interface{}, headers map[
112123
req.Header.Add("Content-Type", "application/json")
113124
req.Header.Add("Accept", "application/json")
114125
req.Header.Add("User-Agent", fmt.Sprintf("go/themekit (%s; %s; %s)", runtime.GOOS, runtime.GOARCH, release.ThemeKitVersion.String()))
126+
if strings.HasPrefix(client.password, themeKitPasswordPrefix) {
127+
req.Header.Add("X-Shopify-Shop", client.domain)
128+
}
115129
for label, value := range headers {
116130
req.Header.Add(label, value)
117131
}

src/httpify/client_test.go

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,50 @@ func TestClient_do(t *testing.T) {
141141
_, err = client.do("POST", "/assets.json", body, nil)
142142
assert.Contains(t, err.Error(), "request failed after 1 retries", server.URL)
143143
server.Close()
144+
145+
// Client should query Theme Kit Access server instead of Shopify when password starts with a prefix "shptka_"
146+
shopifyServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
147+
148+
themeKitAccessServer := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
149+
assert.Equal(t, r.Header.Get("X-Shopify-Shop"), client.domain)
150+
}))
151+
152+
client, err = NewClient(Params{
153+
Domain: shopifyServer.URL,
154+
Password: "shptka_00000000000000000000000000000000",
155+
})
156+
themeKitAccessURL = themeKitAccessServer.URL
157+
158+
assert.NotNil(t, client)
159+
assert.Nil(t, err)
160+
161+
resp, err = client.Post("/assets.json", body, map[string]string{"X-Custom-Header": "Checksum"})
162+
assert.Nil(t, err)
163+
assert.NotNil(t, resp)
164+
165+
server.Close()
166+
167+
// Client should query Shopify instead of Theme Kit Access server when password has no specified prefix
168+
shopifyServer = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
169+
assert.Empty(t, r.Header.Get("X-Shopify-Shop"))
170+
}))
171+
172+
themeKitAccessServer = httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {}))
173+
174+
client, err = NewClient(Params{
175+
Domain: shopifyServer.URL,
176+
Password: "secret_password",
177+
})
178+
themeKitAccessURL = themeKitAccessServer.URL
179+
180+
assert.NotNil(t, client)
181+
assert.Nil(t, err)
182+
183+
resp, err = client.Post("/assets.json", body, map[string]string{"X-Custom-Header": "Checksum"})
184+
assert.Nil(t, err)
185+
assert.NotNil(t, resp)
186+
187+
server.Close()
144188
}
145189

146190
func TestGenerateHTTPAdapter(t *testing.T) {

0 commit comments

Comments
 (0)