mirror of
				https://github.com/Tivix/django-rest-auth.git
				synced 2025-10-30 23:37:32 +03:00 
			
		
		
		
	Merge 4e17d07164 into cdd04aa9be
				
					
				
			This commit is contained in:
		
						commit
						a500bc7dd0
					
				|  | @ -83,13 +83,22 @@ class SocialLoginSerializer(serializers.Serializer): | |||
| 
 | ||||
|         # Case 2: We received the authorization code | ||||
|         elif attrs.get('code'): | ||||
|             self.callback_url = getattr(view, 'callback_url', None) | ||||
|             self.client_class = getattr(view, 'client_class', None) | ||||
| 
 | ||||
|             # allow client to potentially pass in a value for `callback_url` | ||||
|             self.callback_url = attrs.get('callback_url') | ||||
| 
 | ||||
|             # or if that is not provided, fall back on an attribute | ||||
|             # on the view | ||||
|             if not self.callback_url: | ||||
|                 self.callback_url = getattr(view, 'callback_url', None) | ||||
| 
 | ||||
|             if not self.callback_url: | ||||
|                 raise serializers.ValidationError( | ||||
|                     _("Define callback_url in view") | ||||
|                 ) | ||||
| 
 | ||||
|             self.client_class = getattr(view, 'client_class', None) | ||||
| 
 | ||||
|             if not self.client_class: | ||||
|                 raise serializers.ValidationError( | ||||
|                     _("Define client_class in view") | ||||
|  |  | |||
|  | @ -87,6 +87,7 @@ class TestsMixin(object): | |||
|         self.user_url = reverse('rest_user_details') | ||||
|         self.verify_email_url = reverse('rest_verify_email') | ||||
|         self.fb_login_url = reverse('fb_login') | ||||
|         self.fb_login_auth_code_url = reverse('fb_login_auth_code') | ||||
|         self.tw_login_url = reverse('tw_login') | ||||
|         self.tw_login_no_view_url = reverse('tw_login_no_view') | ||||
|         self.tw_login_no_adapter_url = reverse('tw_login_no_adapter') | ||||
|  |  | |||
|  | @ -1,5 +1,7 @@ | |||
| import json | ||||
| 
 | ||||
| from allauth.socialaccount.providers.facebook.views import FacebookOAuth2Adapter | ||||
| 
 | ||||
| from django.test import TestCase | ||||
| from django.contrib.auth import get_user_model | ||||
| from django.test.utils import override_settings | ||||
|  | @ -19,6 +21,21 @@ from rest_framework import status | |||
| from .mixins import TestsMixin | ||||
| 
 | ||||
| 
 | ||||
| facebook_resp_body = { | ||||
|     "id": "123123123123", | ||||
|     "first_name": "John", | ||||
|     "gender": "male", | ||||
|     "last_name": "Smith", | ||||
|     "link": "https://www.facebook.com/john.smith", | ||||
|     "locale": "en_US", | ||||
|     "name": "John Smith", | ||||
|     "timezone": 2, | ||||
|     "updated_time": "2014-08-13T10:14:38+0000", | ||||
|     "username": "john.smith", | ||||
|     "verified": True | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| @override_settings(ROOT_URLCONF="tests.urls") | ||||
| class TestSocialAuth(TestsMixin, TestCase): | ||||
| 
 | ||||
|  | @ -73,25 +90,10 @@ class TestSocialAuth(TestsMixin, TestCase): | |||
| 
 | ||||
|     @responses.activate | ||||
|     def test_social_auth(self): | ||||
|         # fake response for facebook call | ||||
|         resp_body = { | ||||
|             "id": "123123123123", | ||||
|             "first_name": "John", | ||||
|             "gender": "male", | ||||
|             "last_name": "Smith", | ||||
|             "link": "https://www.facebook.com/john.smith", | ||||
|             "locale": "en_US", | ||||
|             "name": "John Smith", | ||||
|             "timezone": 2, | ||||
|             "updated_time": "2014-08-13T10:14:38+0000", | ||||
|             "username": "john.smith", | ||||
|             "verified": True | ||||
|         } | ||||
| 
 | ||||
|         responses.add( | ||||
|             responses.GET, | ||||
|             self.graph_api_url, | ||||
|             body=json.dumps(resp_body), | ||||
|             body=json.dumps(facebook_resp_body), | ||||
|             status=200, | ||||
|             content_type='application/json' | ||||
|         ) | ||||
|  | @ -110,6 +112,75 @@ class TestSocialAuth(TestsMixin, TestCase): | |||
|         self.assertIn('key', self.response.json.keys()) | ||||
|         self.assertEqual(get_user_model().objects.all().count(), users_count + 1) | ||||
| 
 | ||||
|     @responses.activate | ||||
|     def test_social_auth_with_code(self): | ||||
|         # fake response exchanging the authorization code for an access token | ||||
|         responses.add( | ||||
|             responses.Response( | ||||
|                 responses.POST, | ||||
|                 FacebookOAuth2Adapter.access_token_url, | ||||
|                 json={'access_token': 'donkeyface'}, | ||||
|                 status=200, | ||||
|             ) | ||||
|         ) | ||||
|         # fake response for facebook call | ||||
|         responses.add( | ||||
|             responses.GET, | ||||
|             self.graph_api_url, | ||||
|             body=json.dumps(facebook_resp_body), | ||||
|             status=200, | ||||
|             content_type='application/json' | ||||
|         ) | ||||
|         users_count = get_user_model().objects.all().count() | ||||
|         payload = { | ||||
|             'code': 'abc123', | ||||
|         } | ||||
| 
 | ||||
|         self.post(self.fb_login_auth_code_url, data=payload, status_code=200) | ||||
|         self.assertIn('key', self.response.json.keys()) | ||||
|         self.assertEqual(get_user_model().objects.all().count(), users_count + 1) | ||||
| 
 | ||||
|         # make sure that second request will not create a new user | ||||
|         self.post(self.fb_login_auth_code_url, data=payload, status_code=200) | ||||
|         self.assertIn('key', self.response.json.keys()) | ||||
|         self.assertEqual(get_user_model().objects.all().count(), users_count + 1) | ||||
| 
 | ||||
|     @responses.activate | ||||
|     def test_social_auth_with_code_and_invalid_callback(self): | ||||
|         payload = { | ||||
|             'code': 'abc123', | ||||
|             'callback_url': 'Iamnotaurl', | ||||
|         } | ||||
|         response = self.post(self.fb_login_auth_code_url, data=payload, status_code=400) | ||||
|         self.assertIn('callback_url', response.json) | ||||
| 
 | ||||
|     @responses.activate | ||||
|     def test_social_auth_with_code_and_valid_callback(self): | ||||
|         # fake response exchanging the authorization code for an access token | ||||
|         responses.add( | ||||
|             responses.Response( | ||||
|                 responses.POST, | ||||
|                 FacebookOAuth2Adapter.access_token_url, | ||||
|                 json={'access_token': 'donkeyface'}, | ||||
|                 status=200, | ||||
|             ) | ||||
|         ) | ||||
|         # fake response for facebook call | ||||
|         responses.add( | ||||
|             responses.GET, | ||||
|             self.graph_api_url, | ||||
|             body=json.dumps(facebook_resp_body), | ||||
|             status=200, | ||||
|             content_type='application/json' | ||||
|         ) | ||||
|         payload = { | ||||
|             'code': 'abc123', | ||||
|             'callback_url': 'https://another.1231sda1D123.url.com/', | ||||
|         } | ||||
|         self.post(self.fb_login_auth_code_url, data=payload, status_code=200) | ||||
|         # test that the custom callback URL has been used in the code exchange | ||||
|         self.assertIn('1231sda1D123', responses.calls[0].request.body) | ||||
| 
 | ||||
|     def _twitter_social_auth(self): | ||||
|         # fake response for twitter call | ||||
|         resp_body = { | ||||
|  |  | |||
|  | @ -3,8 +3,9 @@ from django.views.generic import TemplateView | |||
| from . import django_urls | ||||
| 
 | ||||
| from allauth.socialaccount.providers.facebook.views import FacebookOAuth2Adapter | ||||
| from allauth.socialaccount.providers.oauth2.client import OAuth2Client | ||||
| from allauth.socialaccount.providers.twitter.views import TwitterOAuthAdapter | ||||
| 
 | ||||
| from rest_framework import serializers | ||||
| from rest_framework.decorators import api_view | ||||
| 
 | ||||
| from rest_auth.urls import urlpatterns | ||||
|  | @ -12,6 +13,7 @@ from rest_auth.registration.views import ( | |||
|     SocialLoginView, SocialConnectView, SocialAccountListView, | ||||
|     SocialAccountDisconnectView | ||||
| ) | ||||
| from rest_auth.registration.serializers import SocialLoginSerializer | ||||
| from rest_auth.social_serializers import ( | ||||
|     TwitterLoginSerializer, TwitterConnectSerializer | ||||
| ) | ||||
|  | @ -21,6 +23,19 @@ class FacebookLogin(SocialLoginView): | |||
|     adapter_class = FacebookOAuth2Adapter | ||||
| 
 | ||||
| 
 | ||||
| class SocialLoginWithClientCallbackSerializer(SocialLoginSerializer): | ||||
|     # An example of a serializer allowing the client to supply their | ||||
|     # own `callback_url` value | ||||
|     callback_url = serializers.URLField(required=False) | ||||
| 
 | ||||
| 
 | ||||
| class FacebookAuthCodeLogin(SocialLoginView): | ||||
|     adapter_class = FacebookOAuth2Adapter | ||||
|     serializer_class = SocialLoginWithClientCallbackSerializer | ||||
|     callback_url = 'https://some.test.url.com' | ||||
|     client_class = OAuth2Client | ||||
| 
 | ||||
| 
 | ||||
| class TwitterLogin(SocialLoginView): | ||||
|     adapter_class = TwitterOAuthAdapter | ||||
|     serializer_class = TwitterLoginSerializer | ||||
|  | @ -60,6 +75,7 @@ urlpatterns += [ | |||
|     url(r'^account-confirm-email/(?P<key>[-:\w]+)/$', TemplateView.as_view(), | ||||
|         name='account_confirm_email'), | ||||
|     url(r'^social-login/facebook/$', FacebookLogin.as_view(), name='fb_login'), | ||||
|     url(r'^social-login/facebook-authcode/$', FacebookAuthCodeLogin.as_view(), name='fb_login_auth_code'), | ||||
|     url(r'^social-login/twitter/$', TwitterLogin.as_view(), name='tw_login'), | ||||
|     url(r'^social-login/twitter-no-view/$', twitter_login_view, name='tw_login_no_view'), | ||||
|     url(r'^social-login/twitter-no-adapter/$', TwitterLoginNoAdapter.as_view(), name='tw_login_no_adapter'), | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	Block a user