Skip to content

Commit 1af16ae

Browse files
committed
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
1 parent 97dbb52 commit 1af16ae

File tree

1 file changed

+78
-0
lines changed

1 file changed

+78
-0
lines changed

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)