Skip to content

Commit c7238b3

Browse files
committed
Add access_scopes attribute to Session
1 parent 455bd5a commit c7238b3

File tree

3 files changed

+56
-6
lines changed

3 files changed

+56
-6
lines changed

shopify/api_access.py

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,12 @@
11
import re
2+
import sys
3+
4+
5+
def basestring_type():
6+
if sys.version_info[0] < 3: # Backwards compatibility for python < v3.0.0
7+
return basestring
8+
else:
9+
return str
210

311

412
class ApiAccessError(Exception):
@@ -12,7 +20,7 @@ class ApiAccess:
1220
IMPLIED_SCOPE_RE = re.compile(r"\A(?P<unauthenticated>unauthenticated_)?write_(?P<resource>.*)\Z")
1321

1422
def __init__(self, scopes):
15-
if type(scopes) == str:
23+
if isinstance(scopes, basestring_type()):
1624
scopes = scopes.split(self.SCOPE_DELIMITER)
1725

1826
self.__store_scopes(scopes)
@@ -32,7 +40,6 @@ def __eq__(self, other):
3240
def __store_scopes(self, scopes):
3341
sanitized_scopes = frozenset(filter(None, [scope.strip() for scope in scopes]))
3442
self.__validate_scopes(sanitized_scopes)
35-
3643
implied_scopes = frozenset(self.__implied_scope(scope) for scope in sanitized_scopes)
3744
self._compressed_scopes = sanitized_scopes - implied_scopes
3845
self._expanded_scopes = sanitized_scopes.union(implied_scopes)

shopify/session.py

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import re
1111
from contextlib import contextmanager
1212
from six.moves import urllib
13+
from shopify.api_access import ApiAccess
1314
from shopify.api_version import ApiVersion, Release, Unstable
1415
import six
1516

@@ -45,10 +46,11 @@ def temp(cls, domain, version, token):
4546
yield
4647
shopify.ShopifyResource.activate_session(original_session)
4748

48-
def __init__(self, shop_url, version=None, token=None):
49+
def __init__(self, shop_url, version=None, token=None, access_scopes=None):
4950
self.url = self.__prepare_url(shop_url)
5051
self.token = token
5152
self.version = ApiVersion.coerce_to_version(version)
53+
self.access_scopes = access_scopes
5254
return
5355

5456
def create_permission_url(self, scope, redirect_uri, state=None):
@@ -72,7 +74,10 @@ def request_token(self, params):
7274
response = urllib.request.urlopen(request)
7375

7476
if response.code == 200:
75-
self.token = json.loads(response.read().decode("utf-8"))["access_token"]
77+
json_payload = json.loads(response.read().decode("utf-8"))
78+
self.token = json_payload["access_token"]
79+
self.access_scopes = json_payload["scope"]
80+
7681
return self.token
7782
else:
7883
raise Exception(response.msg)
@@ -89,6 +94,17 @@ def site(self):
8994
def valid(self):
9095
return self.url is not None and self.token is not None
9196

97+
@property
98+
def access_scopes(self):
99+
return self._access_scopes
100+
101+
@access_scopes.setter
102+
def access_scopes(self, scopes):
103+
if scopes is None or type(scopes) == ApiAccess:
104+
self._access_scopes = scopes
105+
else:
106+
self._access_scopes = ApiAccess(scopes)
107+
92108
@classmethod
93109
def __prepare_url(cls, url):
94110
if not url or (url.strip() == ""):

test/session_test.py

Lines changed: 29 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -208,7 +208,7 @@ def test_param_validation_of_param_values_with_lists(self):
208208
}
209209
self.assertEqual(True, shopify.Session.validate_hmac(params))
210210

211-
def test_return_token_if_hmac_is_valid(self):
211+
def test_return_token_and_scope_if_hmac_is_valid(self):
212212
shopify.Session.secret = "secret"
213213
params = {"code": "any-code", "timestamp": time.time()}
214214
hmac = shopify.Session.calculate_hmac(params)
@@ -218,12 +218,13 @@ def test_return_token_if_hmac_is_valid(self):
218218
None,
219219
url="https://localhost.myshopify.com/admin/oauth/access_token",
220220
method="POST",
221-
body='{"access_token" : "token"}',
221+
body='{"access_token" : "token", "scope": "read_products,write_orders"}',
222222
has_user_agent=False,
223223
)
224224
session = shopify.Session("http://localhost.myshopify.com", "unstable")
225225
token = session.request_token(params)
226226
self.assertEqual("token", token)
227+
self.assertEqual(shopify.ApiAccess("read_products,write_orders"), session.access_scopes)
227228

228229
def test_raise_error_if_hmac_is_invalid(self):
229230
shopify.Session.secret = "secret"
@@ -257,6 +258,32 @@ def test_raise_error_if_timestamp_is_too_old(self):
257258
session = shopify.Session("http://localhost.myshopify.com", "unstable")
258259
session = session.request_token(params)
259260

261+
def test_access_scopes_are_nil_by_default(self):
262+
session = shopify.Session("testshop.myshopify.com", "unstable", "any-token")
263+
self.assertIsNone(session.access_scopes)
264+
265+
def test_access_scopes_when_valid_scopes_passed_in(self):
266+
session = shopify.Session(
267+
shop_url="testshop.myshopify.com",
268+
version="unstable",
269+
token="any-token",
270+
access_scopes="read_products, write_orders",
271+
)
272+
273+
expected_access_scopes = shopify.ApiAccess("read_products, write_orders")
274+
self.assertEqual(expected_access_scopes, session.access_scopes)
275+
276+
def test_access_scopes_set_with_api_access_object_passed_in(self):
277+
session = shopify.Session(
278+
shop_url="testshop.myshopify.com",
279+
version="unstable",
280+
token="any-token",
281+
access_scopes=shopify.ApiAccess("read_products, write_orders"),
282+
)
283+
284+
expected_access_scopes = shopify.ApiAccess("read_products, write_orders")
285+
self.assertEqual(expected_access_scopes, session.access_scopes)
286+
260287
def normalize_url(self, url):
261288
scheme, netloc, path, query, fragment = urllib.parse.urlsplit(url)
262289
query = "&".join(sorted(query.split("&")))

0 commit comments

Comments
 (0)