[Python-modules-commits] [python-social-auth] 01/89: Fitbit OAuth 2.0 support

Wolfgang Borgert debacle at moszumanska.debian.org
Sat Dec 24 15:14:50 UTC 2016


This is an automated email from the git hooks/post-receive script.

debacle pushed a commit to tag v0.2.15
in repository python-social-auth.

commit 3e5d77f38d1105da8a62451290a89a957a5bb981
Author: Robbie Trencheny <me at robbiet.us>
Date:   Sun Sep 27 18:01:14 2015 -0700

    Fitbit OAuth 2.0 support
---
 README.rst                                         |  2 +-
 docs/backends/fitbit.rst                           | 39 +++++++++++++++----
 docs/intro.rst                                     |  2 +-
 .../cherrypy_example/local_settings.py.template    |  2 +-
 examples/django_example/example/settings.py        |  2 +-
 examples/django_me_example/example/settings.py     |  2 +-
 examples/flask_example/settings.py                 |  2 +-
 examples/flask_me_example/settings.py              |  2 +-
 examples/pyramid_example/example/settings.py       |  2 +-
 examples/tornado_example/settings.py               |  2 +-
 examples/webpy_example/app.py                      |  2 +-
 social/backends/fitbit.py                          | 44 ++++++++++++++++++++--
 social/tests/backends/test_fitbit.py               |  2 +-
 13 files changed, 82 insertions(+), 23 deletions(-)

diff --git a/README.rst b/README.rst
index 03df9cd..ab96b65 100644
--- a/README.rst
+++ b/README.rst
@@ -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
diff --git a/docs/backends/fitbit.rst b/docs/backends/fitbit.rst
index 4218f6a..8bd3389 100644
--- a/docs/backends/fitbit.rst
+++ b/docs/backends/fitbit.rst
@@ -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
diff --git a/docs/intro.rst b/docs/intro.rst
index b138974..747e22c 100644
--- a/docs/intro.rst
+++ b/docs/intro.rst
@@ -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
diff --git a/examples/cherrypy_example/local_settings.py.template b/examples/cherrypy_example/local_settings.py.template
index e9fe9c0..98c8f8f 100644
--- a/examples/cherrypy_example/local_settings.py.template
+++ b/examples/cherrypy_example/local_settings.py.template
@@ -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',
diff --git a/examples/django_example/example/settings.py b/examples/django_example/example/settings.py
index 58ab9c7..a22562b 100644
--- a/examples/django_example/example/settings.py
+++ b/examples/django_example/example/settings.py
@@ -141,7 +141,7 @@ AUTHENTICATION_BACKENDS = (
     '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',
diff --git a/examples/django_me_example/example/settings.py b/examples/django_me_example/example/settings.py
index 82fd114..7dcdfad 100644
--- a/examples/django_me_example/example/settings.py
+++ b/examples/django_me_example/example/settings.py
@@ -154,7 +154,7 @@ AUTHENTICATION_BACKENDS = (
     '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',
diff --git a/examples/flask_example/settings.py b/examples/flask_example/settings.py
index 8e0df5e..0abaa91 100644
--- a/examples/flask_example/settings.py
+++ b/examples/flask_example/settings.py
@@ -37,7 +37,7 @@ SOCIAL_AUTH_AUTHENTICATION_BACKENDS = (
     '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',
diff --git a/examples/flask_me_example/settings.py b/examples/flask_me_example/settings.py
index 26d9c5c..e4f2338 100644
--- a/examples/flask_me_example/settings.py
+++ b/examples/flask_me_example/settings.py
@@ -42,7 +42,7 @@ SOCIAL_AUTH_AUTHENTICATION_BACKENDS = (
     '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',
diff --git a/examples/pyramid_example/example/settings.py b/examples/pyramid_example/example/settings.py
index 224917f..35a69ad 100644
--- a/examples/pyramid_example/example/settings.py
+++ b/examples/pyramid_example/example/settings.py
@@ -31,7 +31,7 @@ SOCIAL_AUTH_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',
diff --git a/examples/tornado_example/settings.py b/examples/tornado_example/settings.py
index e7e4742..ff6b146 100644
--- a/examples/tornado_example/settings.py
+++ b/examples/tornado_example/settings.py
@@ -30,7 +30,7 @@ SOCIAL_AUTH_AUTHENTICATION_BACKENDS = (
     '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',
diff --git a/examples/webpy_example/app.py b/examples/webpy_example/app.py
index 47d76c4..4109fac 100644
--- a/examples/webpy_example/app.py
+++ b/examples/webpy_example/app.py
@@ -43,7 +43,7 @@ web.config[setting_name('AUTHENTICATION_BACKENDS')] = (
     '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',
diff --git a/social/backends/fitbit.py b/social/backends/fitbit.py
index 655a711..16c4f77 100644
--- a/social/backends/fitbit.py
+++ b/social/backends/fitbit.py
@@ -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'
@@ -26,3 +28,37 @@ class FitbitOAuth(BaseOAuth1):
             '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())
+            ))
+        }
\ No newline at end of file
diff --git a/social/tests/backends/test_fitbit.py b/social/tests/backends/test_fitbit.py
index e12bdaa..ae04730 100644
--- a/social/tests/backends/test_fitbit.py
+++ b/social/tests/backends/test_fitbit.py
@@ -5,7 +5,7 @@ from social.tests.backends.oauth import OAuth1Test
 
 
 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',

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/python-modules/packages/python-social-auth.git



More information about the Python-modules-commits mailing list