Skip to content

Commit b6e991e

Browse files
committed
Merge pull request #154 from tevinjoseph/master
Added a Serializer for Twitter oauth
2 parents b34ef24 + ee9e848 commit b6e991e

File tree

3 files changed

+109
-0
lines changed

3 files changed

+109
-0
lines changed

docs/api_endpoints.rst

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,3 +72,8 @@ Basing on example from installation section :doc:`Installation </installation>`
7272

7373
- access_token
7474
- code
75+
76+
- /rest-auth/twitter/ (POST)
77+
78+
- access_token
79+
- token_secret

docs/installation.rst

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,8 @@ Using ``django-allauth``, ``django-rest-auth`` provides helpful class for creati
8585
...,
8686
'allauth.socialaccount',
8787
'allauth.socialaccount.providers.facebook',
88+
'allauth.socialaccount.providers.twitter',
89+
8890
)
8991
9092
2. Add Social Application in django admin panel
@@ -108,4 +110,28 @@ Using ``django-allauth``, ``django-rest-auth`` provides helpful class for creati
108110
url(r'^rest-auth/facebook/$', FacebookLogin.as_view(), name='fb_login')
109111
)
110112
113+
5. If you are using Twitter for your social authentication, it is a bit different from
114+
Facebook since Twitter uses OAuth 1.0.
115+
116+
117+
6. Create new view as a subclass of ``rest_auth.views.LoginView`` with ``TwitterOAuthAdapter`` adapter and ``TwitterLoginSerializer`` as an attribute:
118+
119+
.. code-block:: python
120+
121+
from allauth.socialaccount.providers.twitter.views import TwitterOAuthAdapter
122+
from rest_auth.views import LoginView
123+
from rest_auth.social_serializers import TwitterLoginSerializer
124+
125+
class TwitterLogin(LoginView):
126+
serializer_class = TwitterLoginSerializer
127+
adapter_class = TwitterOAuthAdapter
128+
129+
7. Create url for TwitterLogin view:
130+
131+
.. code-block:: python
132+
133+
urlpatterns += pattern('',
134+
...,
135+
url(r'^rest-auth/twitter/$', TwitterLogin.as_view(), name='twitter_login')
136+
)
111137
.. 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.

rest_auth/social_serializers.py

Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
from django.http import HttpRequest
2+
from rest_framework import serializers
3+
from requests.exceptions import HTTPError
4+
# Import is needed only if we are using social login, in which
5+
# case the allauth.socialaccount will be declared
6+
try:
7+
from allauth.socialaccount.helpers import complete_social_login
8+
except ImportError:
9+
pass
10+
11+
from allauth.socialaccount.models import SocialToken
12+
13+
14+
class TwitterLoginSerializer(serializers.Serializer):
15+
access_token = serializers.CharField(required=True)
16+
token_secret = serializers.CharField(required=True)
17+
18+
def _get_request(self):
19+
request = self.context.get('request')
20+
if not isinstance(request, HttpRequest):
21+
request = request._request
22+
return request
23+
24+
def get_social_login(self, adapter, app, token, response):
25+
"""
26+
27+
:param adapter: allauth.socialaccount Adapter subclass. Usually OAuthAdapter or Auth2Adapter
28+
:param app: `allauth.socialaccount.SocialApp` instance
29+
:param token: `allauth.socialaccount.SocialToken` instance
30+
:param response: Provider's response for OAuth1. Not used in the
31+
:return: :return: A populated instance of the `allauth.socialaccount.SocialLoginView` instance
32+
"""
33+
request = self._get_request()
34+
social_login = adapter.complete_login(request, app, token, response=response)
35+
social_login.token = token
36+
return social_login
37+
38+
def validate(self, attrs):
39+
view = self.context.get('view')
40+
request = self._get_request()
41+
42+
if not view:
43+
raise serializers.ValidationError(
44+
'View is not defined, pass it as a context variable'
45+
)
46+
47+
adapter_class = getattr(view, 'adapter_class', None)
48+
if not adapter_class:
49+
raise serializers.ValidationError('Define adapter_class in view')
50+
51+
adapter = adapter_class()
52+
app = adapter.get_provider().get_app(request)
53+
54+
if('access_token' in attrs) and ('token_secret' in attrs):
55+
access_token = attrs.get('access_token')
56+
token_secret = attrs.get('token_secret')
57+
else:
58+
raise serializers.ValidationError('Incorrect input. access_token and token_secret are required.')
59+
60+
request.session['oauth_api.twitter.com_access_token'] = {
61+
'oauth_token': access_token,
62+
'oauth_token_secret': token_secret,
63+
}
64+
token = SocialToken(token=access_token, token_secret=token_secret)
65+
token.app = app
66+
67+
try:
68+
login = self.get_social_login(adapter, app, token, access_token)
69+
complete_social_login(request, login)
70+
except HTTPError:
71+
raise serializers.ValidationError('Incorrect value')
72+
73+
if not login.is_existing:
74+
login.lookup()
75+
login.save(request, connect=True)
76+
attrs['user'] = login.account.user
77+
78+
return attrs

0 commit comments

Comments
 (0)