Skip to content

Commit

Permalink
Merge pull request #78 from nbogojevic/master
Browse files Browse the repository at this point in the history
Use OAuth2Session hooks to process reply
  • Loading branch information
vangorra committed Feb 8, 2022
2 parents 1393298 + 8331fec commit f8d7e73
Show file tree
Hide file tree
Showing 2 changed files with 75 additions and 20 deletions.
35 changes: 20 additions & 15 deletions tests/test_init.py
Original file line number Diff line number Diff line change
Expand Up @@ -52,13 +52,16 @@
_UNKNOWN_INT = 1234567
_USERID: Final = 12345
_FETCH_TOKEN_RESPONSE_BODY: Final = {
"access_token": "my_access_token",
"csrf_token": "CSRF_TOKEN",
"expires_in": 11,
"token_type": "Bearer",
"refresh_token": "my_refresh_token",
"scope": "user.metrics,user.activity",
"userid": _USERID,
"status": 0,
"body": {
"access_token": "my_access_token",
"csrf_token": "CSRF_TOKEN",
"expires_in": 11,
"token_type": "Bearer",
"refresh_token": "my_refresh_token",
"scope": "user.metrics,user.activity",
"userid": _USERID,
},
}


Expand Down Expand Up @@ -109,7 +112,7 @@ def test_authorize() -> None:

responses.add(
method=responses.POST,
url="https://account.withings.com/oauth2/token",
url="https://wbsapi.withings.net/v2/oauth2",
json=_FETCH_TOKEN_RESPONSE_BODY,
status=200,
)
Expand Down Expand Up @@ -169,20 +172,22 @@ def test_refresh_token() -> None:

responses.add(
method=responses.POST,
url=re.compile("https://account.withings.com/oauth2.*"),
url=re.compile("https://wbsapi.withings.net/v2/oauth2.*"),
status=200,
json=_FETCH_TOKEN_RESPONSE_BODY,
)
responses.add(
method=responses.POST,
url=re.compile("https://account.withings.com/oauth2.*"),
url=re.compile("https://wbsapi.withings.net/v2/oauth2.*"),
status=200,
json={
"access_token": "my_access_token_refreshed",
"expires_in": 11,
"token_type": "Bearer",
"refresh_token": "my_refresh_token_refreshed",
"userid": _USERID,
"body": {
"access_token": "my_access_token_refreshed",
"expires_in": 11,
"token_type": "Bearer",
"refresh_token": "my_refresh_token_refreshed",
"userid": _USERID,
},
},
)

Expand Down
60 changes: 55 additions & 5 deletions withings_api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,14 @@
"""
from abc import abstractmethod
import datetime
import json
from types import LambdaType
from typing import Any, Callable, Dict, Iterable, Optional, Union, cast

import arrow
from oauthlib.common import to_unicode
from oauthlib.oauth2 import WebApplicationClient
from requests import Response
from requests_oauthlib import OAuth2Session
from typing_extensions import Final

Expand Down Expand Up @@ -54,6 +57,40 @@ def update_params(
params[name] = new_value or current_value


def adjust_withings_token(response: Response) -> Response:
"""Restructures token from withings response::
{
"status": [{integer} Withings API response status],
"body": {
"access_token": [{string} Your new access_token],
"expires_in": [{integer} Access token expiry delay in seconds],
"token_type": [{string] HTTP Authorization Header format: Bearer],
"scope": [{string} Scopes the user accepted],
"refresh_token": [{string} Your new refresh_token],
"userid": [{string} The Withings ID of the user]
}
}
"""
try:
token = json.loads(response.text)
except Exception: # pylint: disable=broad-except
# If there was exception, just return unmodified response
return response
status = token.pop("status", 0)
if status:
# Set the error to the status
token["error"] = 0
body = token.pop("body", None)
if body:
# Put body content at root level
token.update(body)
# pylint: disable=protected-access
response._content = to_unicode(json.dumps(token)).encode("UTF-8")

return response


class AbstractWithingsApi:
"""Abstract class for customizing which requests module you want."""

Expand Down Expand Up @@ -357,13 +394,19 @@ def __init__(
redirect_uri=self._callback_uri,
scope=",".join((scope.value for scope in self._scope)),
)
self._session.register_compliance_hook(
"access_token_response", adjust_withings_token
)
self._session.register_compliance_hook(
"refresh_token_response", adjust_withings_token
)

def get_authorize_url(self) -> str:
"""Generate the authorize url."""
url: Final = str(
self._session.authorization_url("%s/%s" % (WithingsAuth.URL, self.PATH_AUTHORIZE))[
0
]
self._session.authorization_url(
"%s/%s" % (WithingsAuth.URL, self.PATH_AUTHORIZE)
)[0]
)

if self._mode:
Expand All @@ -378,11 +421,12 @@ def get_credentials(self, code: str) -> Credentials2:
code=code,
client_secret=self._consumer_secret,
include_client_id=True,
action="requesttoken",
)

return Credentials2(
**{
**response["body"],
**response,
**dict(
client_id=self._client_id, consumer_secret=self._consumer_secret
),
Expand Down Expand Up @@ -442,6 +486,12 @@ def __init__(
},
token_updater=self._update_token,
)
self._client.register_compliance_hook(
"access_token_response", adjust_withings_token
)
self._client.register_compliance_hook(
"refresh_token_response", adjust_withings_token
)

def _blank_refresh_cb(self, creds: Credentials2) -> None:
"""The default callback which does nothing."""
Expand All @@ -455,7 +505,7 @@ def refresh_token(self) -> None:
token_dict: Final = self._client.refresh_token(
token_url=self._client.auto_refresh_url
)
self._update_token(token=token_dict["body"])
self._update_token(token=token_dict)

def _update_token(self, token: Dict[str, Union[str, int]]) -> None:
"""Set the oauth token."""
Expand Down

0 comments on commit f8d7e73

Please sign in to comment.