Skip to content

Commit

Permalink
Fitbit OAuth 2.0 support
Browse files Browse the repository at this point in the history
  • Loading branch information
robbiet480 committed Sep 28, 2015
1 parent aa66b83 commit 3e5d77f
Show file tree
Hide file tree
Showing 13 changed files with 82 additions and 23 deletions.
2 changes: 1 addition & 1 deletion README.rst
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ or current ones extended):
* Exacttarget OAuth2
* Facebook_ OAuth2 and OAuth2 for Applications
* Fedora_ OpenId http://fedoraproject.org/wiki/OpenID
* Fitbit_ OAuth1
* Fitbit_ OAuth2 and OAuth1
* Flickr_ OAuth1
* Foursquare_ OAuth2
* `Google App Engine`_ Auth
Expand Down
39 changes: 31 additions & 8 deletions docs/backends/fitbit.rst
Original file line number Diff line number Diff line change
@@ -1,15 +1,38 @@
Fitbit
======

Fitbit offers OAuth1 as their auth mechanism. In order to enable it, follow:
Fitbit supports both OAuth 2.0 and OAuth 1.0a logins.
OAuth 2 is preferred for new integrations, as OAuth 1.0a does not support getting heartrate or location and will be deprecated in the future.

- Register a new application at `Fitbit dev portal`_, be sure to select
``Browser`` as the application type. Set the ``Callback URL`` to
``http://<your hostname>//complete/fitbit/``.
1. Register a new OAuth Consumer `here`_

- Fill **Consumer Key** and **Consumer Secret** values::
2. Configure the appropriate settings for OAuth 2.0 or OAuth 1.0a (see below).

SOCIAL_AUTH_FITBIT_KEY = ''
SOCIAL_AUTH_FITBIT_SECRET = ''
OAuth 2.0 or OAuth 1.0a
-----------------------

.. _Fitbit dev portal: https://dev.fitbit.com/apps/new
- Fill ``Consumer Key`` and ``Consumer Secret`` values in the settings::

SOCIAL_AUTH_FITBIT_KEY = '<your-consumer-key>'
SOCIAL_AUTH_FITBIT_SECRET = '<your-consumer-secret>'

OAuth 2.0 specific settings
---------------------------

By default, only the ``profile`` scope is requested. To request more scopes, set SOCIAL_AUTH_FITBIT_SCOPE::

SOCIAL_AUTH_FITBIT_SCOPE = [
'activity',
'heartrate',
'location',
'nutrition',
'profile',
'settings',
'sleep',
'social',
'weight'
]

The above will request all permissions from the user.

.. _here: https://dev.fitbit.com/apps/new
2 changes: 1 addition & 1 deletion docs/intro.rst
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ or extend current one):
* Dropbox_ OAuth1
* Evernote_ OAuth1
* Facebook_ OAuth2 and OAuth2 for Applications
* Fitbit_ OAuth1
* Fitbit_ OAuth2 and OAuth1
* Flickr_ OAuth1
* Foursquare_ OAuth2
* `Google App Engine`_ Auth
Expand Down
2 changes: 1 addition & 1 deletion examples/cherrypy_example/local_settings.py.template
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ SOCIAL_SETTINGS = {
'social.backends.dropbox.DropboxOAuth',
'social.backends.eveonline.EVEOnlineOAuth2',
'social.backends.evernote.EvernoteSandboxOAuth',
'social.backends.fitbit.FitbitOAuth',
'social.backends.fitbit.FitbitOAuth2',
'social.backends.flickr.FlickrOAuth',
'social.backends.livejournal.LiveJournalOpenId',
'social.backends.soundcloud.SoundcloudOAuth2',
Expand Down
2 changes: 1 addition & 1 deletion examples/django_example/example/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -141,7 +141,7 @@
'social.backends.facebook.FacebookAppOAuth2',
'social.backends.facebook.FacebookOAuth2',
'social.backends.fedora.FedoraOpenId',
'social.backends.fitbit.FitbitOAuth',
'social.backends.fitbit.FitbitOAuth2',
'social.backends.flickr.FlickrOAuth',
'social.backends.foursquare.FoursquareOAuth2',
'social.backends.github.GithubOAuth2',
Expand Down
2 changes: 1 addition & 1 deletion examples/django_me_example/example/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@
'social.backends.dropbox.DropboxOAuth',
'social.backends.eveonline.EVEOnlineOAuth2',
'social.backends.evernote.EvernoteSandboxOAuth',
'social.backends.fitbit.FitbitOAuth',
'social.backends.fitbit.FitbitOAuth2',
'social.backends.flickr.FlickrOAuth',
'social.backends.livejournal.LiveJournalOpenId',
'social.backends.soundcloud.SoundcloudOAuth2',
Expand Down
2 changes: 1 addition & 1 deletion examples/flask_example/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@
'social.backends.dropbox.DropboxOAuth',
'social.backends.eveonline.EVEOnlineOAuth2',
'social.backends.evernote.EvernoteSandboxOAuth',
'social.backends.fitbit.FitbitOAuth',
'social.backends.fitbit.FitbitOAuth2',
'social.backends.flickr.FlickrOAuth',
'social.backends.livejournal.LiveJournalOpenId',
'social.backends.soundcloud.SoundcloudOAuth2',
Expand Down
2 changes: 1 addition & 1 deletion examples/flask_me_example/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@
'social.backends.dropbox.DropboxOAuth',
'social.backends.eveonline.EVEOnlineOAuth2',
'social.backends.evernote.EvernoteSandboxOAuth',
'social.backends.fitbit.FitbitOAuth',
'social.backends.fitbit.FitbitOAuth2',
'social.backends.flickr.FlickrOAuth',
'social.backends.livejournal.LiveJournalOpenId',
'social.backends.soundcloud.SoundcloudOAuth2',
Expand Down
2 changes: 1 addition & 1 deletion examples/pyramid_example/example/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@
'social.backends.dropbox.DropboxOAuth',
'social.backends.eveonline.EVEOnlineOAuth2',
'social.backends.evernote.EvernoteSandboxOAuth',
'social.backends.fitbit.FitbitOAuth',
'social.backends.fitbit.FitbitOAuth2',
'social.backends.flickr.FlickrOAuth',
'social.backends.livejournal.LiveJournalOpenId',
'social.backends.soundcloud.SoundcloudOAuth2',
Expand Down
2 changes: 1 addition & 1 deletion examples/tornado_example/settings.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@
'social.backends.dropbox.DropboxOAuth',
'social.backends.eveonline.EVEOnlineOAuth2',
'social.backends.evernote.EvernoteSandboxOAuth',
'social.backends.fitbit.FitbitOAuth',
'social.backends.fitbit.FitbitOAuth2',
'social.backends.flickr.FlickrOAuth',
'social.backends.livejournal.LiveJournalOpenId',
'social.backends.soundcloud.SoundcloudOAuth2',
Expand Down
2 changes: 1 addition & 1 deletion examples/webpy_example/app.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@
'social.backends.dropbox.DropboxOAuth',
'social.backends.eveonline.EVEOnlineOAuth2',
'social.backends.evernote.EvernoteSandboxOAuth',
'social.backends.fitbit.FitbitOAuth',
'social.backends.fitbit.FitbitOAuth2',
'social.backends.flickr.FlickrOAuth',
'social.backends.livejournal.LiveJournalOpenId',
'social.backends.soundcloud.SoundcloudOAuth2',
Expand Down
44 changes: 40 additions & 4 deletions social/backends/fitbit.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
"""
Fitbit OAuth1 backend, docs at:
Fitbit OAuth backend, docs at:
http://psa.matiasaguirre.net/docs/backends/fitbit.html
"""
from social.backends.oauth import BaseOAuth1
import base64

from social.backends.oauth import BaseOAuth1, BaseOAuth2

class FitbitOAuth(BaseOAuth1):
"""Fitbit OAuth authentication backend"""

class FitbitOAuth1(BaseOAuth1):
"""Fitbit OAuth1 authentication backend"""
name = 'fitbit'
AUTHORIZATION_URL = 'https://www.fitbit.com/oauth/authorize'
REQUEST_TOKEN_URL = 'https://api.fitbit.com/oauth/request_token'
Expand All @@ -26,3 +28,37 @@ def user_data(self, access_token, *args, **kwargs):
'https://api.fitbit.com/1/user/-/profile.json',
auth=self.oauth_auth(access_token)
)['user']

class FitbitOAuth2(BaseOAuth2):
"""Fitbit OAuth2 authentication backend"""
name = 'fitbit'
AUTHORIZATION_URL = 'https://www.fitbit.com/oauth2/authorize'
ACCESS_TOKEN_URL = 'https://api.fitbit.com/oauth2/token'
ACCESS_TOKEN_METHOD = 'POST'
REFRESH_TOKEN_URL = 'https://api.fitbit.com/oauth2/token'
DEFAULT_SCOPE = ['profile']
ID_KEY = 'encodedId'
REDIRECT_STATE = False
EXTRA_DATA = [('expires_in', 'expires'),
('refresh_token', 'refresh_token', True),
('encodedId', 'id'),
('displayName', 'username')]

def get_user_details(self, response):
"""Return user details from Fitbit account"""
return {'username': response.get('displayName'),
'email': ''}

def user_data(self, access_token, *args, **kwargs):
"""Loads user data from service"""
auth_header = {"Authorization": "Bearer %s" % access_token}
return self.get_json(
'https://api.fitbit.com/1/user/-/profile.json',
headers=auth_header
)['user']
def auth_headers(self):
return {
'Authorization': 'Basic {0}'.format(base64.urlsafe_b64encode(
('{0}:{1}'.format(*self.get_key_and_secret()).encode())
))
}
2 changes: 1 addition & 1 deletion social/tests/backends/test_fitbit.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


class FitbitOAuth1Test(OAuth1Test):
backend_path = 'social.backends.fitbit.FitbitOAuth'
backend_path = 'social.backends.fitbit.FitbitOAuth1'
expected_username = 'foobar'
access_token_body = urlencode({
'oauth_token_secret': 'a-secret',
Expand Down

0 comments on commit 3e5d77f

Please sign in to comment.