From 1af16ae7ba68300ee562d8dc1685af7ba73331fa Mon Sep 17 00:00:00 2001 From: Tevin Joseph K O Date: Wed, 13 Jan 2016 12:43:12 +0530 Subject: [PATCH 1/4] Added a Serializer for Twitter oauth Added a serializer for twitter OAuth to work. If you are not using this it will cause an error ('TwitterOAuthAdapter' object has no attribute 'parse_token'). It happens because method parse_token() is implemented in OAuth2Adapter, but Twitter uses OAuth 1.0, so TwitterOAuthAdapter inherits from OAuthAdapter, which doesn't have parse_token() method. Example usage is given below: class TwitterLogin(LoginView): serializer_class = TwitterLoginSerializer adapter_class = TwitterOAuthAdapter --- rest_auth/social_serializers.py | 78 +++++++++++++++++++++++++++++++++ 1 file changed, 78 insertions(+) create mode 100644 rest_auth/social_serializers.py diff --git a/rest_auth/social_serializers.py b/rest_auth/social_serializers.py new file mode 100644 index 0000000..2aee4ea --- /dev/null +++ b/rest_auth/social_serializers.py @@ -0,0 +1,78 @@ +from django.http import HttpRequest +from rest_framework import serializers +from requests.exceptions import HTTPError +# Import is needed only if we are using social login, in which +# case the allauth.socialaccount will be declared +try: + from allauth.socialaccount.helpers import complete_social_login +except ImportError: + pass + +from allauth.socialaccount.models import SocialToken + + +class TwitterLoginSerializer(serializers.Serializer): + access_token = serializers.CharField(required=True) + token_secret = serializers.CharField(required=True) + + def _get_request(self): + request = self.context.get('request') + if not isinstance(request, HttpRequest): + request = request._request + return request + + def get_social_login(self, adapter, app, token, response): + """ + + :param adapter: allauth.socialaccount Adapter subclass. Usually OAuthAdapter or Auth2Adapter + :param app: `allauth.socialaccount.SocialApp` instance + :param token: `allauth.socialaccount.SocialToken` instance + :param response: Provider's response for OAuth1. Not used in the + :return: :return: A populated instance of the `allauth.socialaccount.SocialLoginView` instance + """ + request = self._get_request() + social_login = adapter.complete_login(request, app, token, response=response) + social_login.token = token + return social_login + + def validate(self, attrs): + view = self.context.get('view') + request = self._get_request() + + if not view: + raise serializers.ValidationError( + 'View is not defined, pass it as a context variable' + ) + + adapter_class = getattr(view, 'adapter_class', None) + if not adapter_class: + raise serializers.ValidationError('Define adapter_class in view') + + adapter = adapter_class() + app = adapter.get_provider().get_app(request) + + if('access_token' in attrs) and ('token_secret' in attrs): + access_token = attrs.get('access_token') + token_secret = attrs.get('token_secret') + else: + raise serializers.ValidationError('Incorrect input. access_token and token_secret are required.') + + request.session['oauth_api.twitter.com_access_token'] = { + 'oauth_token': access_token, + 'oauth_token_secret': token_secret, + } + token = SocialToken(token=access_token, token_secret=token_secret) + token.app = app + + try: + login = self.get_social_login(adapter, app, token, access_token) + complete_social_login(request, login) + except HTTPError: + raise serializers.ValidationError('Incorrect value') + + if not login.is_existing: + login.lookup() + login.save(request, connect=True) + attrs['user'] = login.account.user + + return attrs From e6c5be4b69759df8f9d8d94c3709a6255e9c8cbf Mon Sep 17 00:00:00 2001 From: Tevin Joseph K O Date: Tue, 23 Feb 2016 17:15:57 +0530 Subject: [PATCH 2/4] Updated index.rst with twitter login --- docs/installation.rst | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/docs/installation.rst b/docs/installation.rst index 92251dc..7717fef 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -85,6 +85,8 @@ Using ``django-allauth``, ``django-rest-auth`` provides helpful class for creati ..., 'allauth.socialaccount', 'allauth.socialaccount.providers.facebook', + 'allauth.socialaccount.providers.twitter', + ) 2. Add Social Application in django admin panel @@ -108,4 +110,20 @@ Using ``django-allauth``, ``django-rest-auth`` provides helpful class for creati url(r'^rest-auth/facebook/$', FacebookLogin.as_view(), name='fb_login') ) +5. If you are using Twitter for your social authentication, it is a bit different from + Facebook since Twitter uses OAuth 1.0. + + +6. Create new view as a subclass of ``rest_auth.views.LoginView`` with ``TwitterOAuthAdapter`` adapter and ``TwitterLoginSerializer`` as an attribute: + +.. code-block:: python + + from allauth.socialaccount.providers.twitter.views import TwitterOAuthAdapter + from rest_auth.views import LoginView + from rest_auth.social_serializers import TwitterLoginSerializer + + class TwitterLogin(LoginView): + serializer_class = TwitterLoginSerializer + adapter_class = TwitterOAuthAdapter + .. note:: Starting from v0.21.0, django-allauth has dropped support for context processors. Check out http://django-allauth.readthedocs.org/en/latest/changelog.html#from-0-21-0 for more details. From 8f05f200514bf74f85b695724d08d04ea2720e5b Mon Sep 17 00:00:00 2001 From: Tevin Joseph K O Date: Tue, 23 Feb 2016 17:18:30 +0530 Subject: [PATCH 3/4] Updated api_endpoints.rst with twitter login --- docs/api_endpoints.rst | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/docs/api_endpoints.rst b/docs/api_endpoints.rst index 1f9660f..40fd99f 100644 --- a/docs/api_endpoints.rst +++ b/docs/api_endpoints.rst @@ -70,3 +70,8 @@ Basing on example from installation section :doc:`Installation ` - access_token - code + +- /rest-auth/twitter/ (POST) + + - access_token + - token_secret From ee9e848694b5848761a30962b8a8c378d338d805 Mon Sep 17 00:00:00 2001 From: Tevin Joseph K O Date: Tue, 23 Feb 2016 17:31:11 +0530 Subject: [PATCH 4/4] URL for twitter login added. --- docs/installation.rst | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/installation.rst b/docs/installation.rst index 7717fef..a0723d7 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -126,4 +126,12 @@ Using ``django-allauth``, ``django-rest-auth`` provides helpful class for creati serializer_class = TwitterLoginSerializer adapter_class = TwitterOAuthAdapter +7. Create url for TwitterLogin view: + +.. code-block:: python + + urlpatterns += pattern('', + ..., + url(r'^rest-auth/twitter/$', TwitterLogin.as_view(), name='twitter_login') + ) .. note:: Starting from v0.21.0, django-allauth has dropped support for context processors. Check out http://django-allauth.readthedocs.org/en/latest/changelog.html#from-0-21-0 for more details.