New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
New provider: Garmin Connect #3609
base: main
Are you sure you want to change the base?
Conversation
# Conflicts: # test_settings.py
…nd `get_avatar_url` and `to_str` methods
|
||
class GarminConnectOAuthClient(OAuthClient): | ||
|
||
def get_access_token(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This seems like an almost exact copy of OAuthClient.get_access_token()
-- can't we reuse that, if not, can't this be made more DRY?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah I'm not 100% familiar with OAuth1
api, but the major change I made was to explicitly pass verifier
param when constructing oauth
object. I can hop on a debugger and see if we can use vanilla OAuthClient
class later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah verified that using the original implementation results in 400 response from the Garmin server as it expects verifier in the header. Please let me know if you'd like extra data to review.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This likely benefits other providers as well.The base class is already checking for the oauth_verifier
here:
oauth_verifier = get_request_param(self.request, "oauth_verifier") |
Could you change that so that it passes that verifier to the OAuth1 client, if available? Then, you don't need to override the get_access_token()
method here...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Does modifying the base OAuthClient
's get_access_token
method like this work for you?
def get_access_token(self):
"""
Obtain the access token to access private resources at the API
endpoint.
"""
if self.access_token is None:
request_token = self._get_rt_from_session()
at_url = self.access_token_url
# Passing along oauth_verifier is required according to:
# http://groups.google.com/group/twitter-development-talk/browse_frm/thread/472500cfe9e7cdb9#
# Though, the custom oauth_callback seems to work without it?
oauth_verifier = get_request_param(self.request, "oauth_verifier")
if oauth_verifier:
at_url = at_url + "?" + urlencode({"oauth_verifier": oauth_verifier})
oauth = OAuth1(
self.consumer_key,
client_secret=self.consumer_secret,
resource_owner_key=request_token["oauth_token"],
resource_owner_secret=request_token["oauth_token_secret"],
verifier=oauth_verifier,
)
response = get_adapter().get_requests_session().post(url=at_url, auth=oauth)
if response.status_code not in [200, 201]:
raise OAuthError(
_("Invalid response while obtaining access token" ' from "%s".')
% get_token_prefix(self.request_token_url)
)
self.access_token = dict(parse_qsl(response.text))
self.request.session[
"oauth_%s_access_token" % get_token_prefix(self.request_token_url)
] = self.access_token
return self.access_token
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Hmm, seems like Garmin throws a 400 error because of below section. Would be grateful for some help here- would we want to implement an option to not pass this as a URL param?
if oauth_verifier:
at_url = (
at_url + "?" + urlencode({"oauth_verifier": oauth_verifier})
)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@pennersr Sorry to bother you, but would be grateful for some clarification here for implementing get_access_token
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I would suggest to add a access_token_requires_oauth_verifier=True
parameter to the OAuthClient.__init__
, and use this in the code that builds at_url
. Then, alter _get_client()
to copy a similarly named access_token_requires_oauth_verifier
attribute over from the adapter to the client. That way, this functionality is encapsulated in the base class and you do not need to alter _get_client()
yourself.
Submitting Pull Requests
General
Examples:
"fix(google): Fixed foobar bug"
,"feat(accounts): Added foobar feature"
.ChangeLog.rst
.AUTHORS
.Provider Specifics
In case you add a new provider:
test_settings.py::INSTALLED_APPS
anddocs/installation.rst::INSTALLED_APPS
.docs/providers/<provider name>.rst
anddocs/providers/index.rst
Provider Specifics toctree.docs/overview.rst
. -> Couldn't find this file