Skip to content

Commit

Permalink
rebuild auth flow
Browse files Browse the repository at this point in the history
  • Loading branch information
mkb79 committed Jun 2, 2020
1 parent 5a72b28 commit fa76752
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 39 deletions.
22 changes: 21 additions & 1 deletion src/audible/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,9 +97,11 @@ def sign_request(path: str, method: str, body: str, adp_token: str,
}


class BaseAuthenticator(MutableMapping):
class BaseAuthenticator(MutableMapping, httpx.Auth):
"""Base Class for retrieve and handle credentials."""

requires_request_body = True

def __init__(self):
raise NotImplementedError()

Expand Down Expand Up @@ -130,6 +132,24 @@ def __len__(self):
def __repr__(self):
return f"{type(self).__name__}({self.__dict__})"

def auth_flow(self, request):
return self.sign_request(request)

def sign_request(self, request):
method = request.method
path = request.url.path
query = request.url.query
body = request.content if request.content else None

if query:
path += f"?{query}"

headers = sign_request(path, method, body, self.adp_token,
self.device_private_key)

request.headers.update(headers)
yield request

def to_file(self, filename=None, password=None, encryption="default",
indent=4, set_default=True, **kwargs):

Expand Down
40 changes: 4 additions & 36 deletions src/audible/client.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
import json
import logging
from typing import Union, Optional
from urllib.parse import urlencode, urlparse

import httpx

Expand All @@ -23,18 +22,15 @@ class AudibleAPI:
def __init__(self, auth: Optional[Union[LoginAuthenticator, FileAuthenticator]] = None,
session=None, is_async=False, **options) -> None:
self.auth = auth
self.adp_token = options.get("adp_token", auth.adp_token)
self.device_private_key = options.get(
"device_private_key", auth.device_private_key
)

self.is_async = is_async
self.session = (session or (httpx.AsyncClient() if is_async
else httpx.Client()))
self.headers = {
headers = {
"Accept": "application/json",
"Content-Type": "application/json"
}
self.session.headers.update(headers)

locale = test_convert("locale", options.get("locale", auth.locale))
domain = options.get("domain", locale.domain)
Expand Down Expand Up @@ -76,8 +72,6 @@ def marketplace(self):

def switch_user(self, auth: Union[LoginAuthenticator, FileAuthenticator]):
self.auth = auth
self.adp_token = auth.get("adp_token")
self.device_private_key = auth.get("device_private_key")

def get_user_profile(self):
self.auth.refresh_access_token()
Expand Down Expand Up @@ -115,30 +109,11 @@ def _raise_for_status(self, resp, text, *, method=None):
else:
raise UnexpectedError(resp, data)

def _sign_request(self, method, url, params, json_data):
path = urlparse(url).path
query = urlencode(params)
json_body = json.dumps(json_data) if json_data else None

if query:
path += f"?{query}"

return sign_request(path, method, json_body, self.adp_token,
self.device_private_key)

async def _arequest(self, method, url, **kwargs):
params = kwargs.get("params", {})
json_data = kwargs.get('json', {})
timeout = kwargs.pop('timeout', self.timeout)

headers = kwargs.pop("headers", {})
signed_headers = self._sign_request(method, url, params, json_data)
headers.update(self.headers)
headers.update(signed_headers)

try:
resp = await self.session.request(
method, url, timeout=timeout, headers=headers, **kwargs
method, url, timeout=timeout, auth=self.auth, **kwargs
)
return self._raise_for_status(resp, resp.text, method=method)
except (httpx.ConnectTimeout,
Expand All @@ -154,18 +129,11 @@ async def _arequest(self, method, url, **kwargs):
def _request(self, method, url, **kwargs):
if self.is_async: # return a coroutine
return self._arequest(method, url, **kwargs)
params = kwargs.get("params", {})
json_data = kwargs.get('json', {})
timeout = kwargs.pop('timeout', self.timeout)

headers = kwargs.pop("headers", {})
signed_headers = self._sign_request(method, url, params, json_data)
headers.update(self.headers)
headers.update(signed_headers)

try:
resp = self.session.request(
method, url, timeout=timeout, headers=headers, **kwargs
method, url, timeout=timeout, auth=self.auth, **kwargs
)
return self._raise_for_status(resp, resp.text, method=method)
except (httpx.ConnectTimeout,
Expand Down
4 changes: 2 additions & 2 deletions src/audible/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ class StatusError(RequestError):
"""
def __init__(self, resp, data):
self.response = resp
self.code = getattr(resp, 'status', None) or getattr(resp, 'status_code')
self.code = getattr(resp, 'status_code')
self.method = getattr(resp, 'method', None)
self.reason = resp.reason
self.reason = resp.reason_phrase
if isinstance(data, dict):
self.error = data.get('error')
if 'message' in data:
Expand Down

0 comments on commit fa76752

Please sign in to comment.