mirror of
				https://github.com/Tivix/django-rest-auth.git
				synced 2025-10-30 23:37:32 +03:00 
			
		
		
		
	Add change in documentation and tests for social connect
This commit is contained in:
		
							parent
							
								
									3eb546f633
								
							
						
					
					
						commit
						6a84d85d91
					
				|  | @ -111,15 +111,11 @@ Facebook | ||||||
| .. code-block:: python | .. code-block:: python | ||||||
| 
 | 
 | ||||||
|     from allauth.socialaccount.providers.facebook.views import FacebookOAuth2Adapter |     from allauth.socialaccount.providers.facebook.views import FacebookOAuth2Adapter | ||||||
|     from rest_auth.registration.views import SocialLoginView, SocialConnectView |     from rest_auth.registration.views import SocialLoginView | ||||||
| 
 | 
 | ||||||
|     class FacebookLogin(SocialLoginView): |     class FacebookLogin(SocialLoginView): | ||||||
|         adapter_class = FacebookOAuth2Adapter |         adapter_class = FacebookOAuth2Adapter | ||||||
| 
 | 
 | ||||||
|     # Add a connect view if you want to allow connecting existing accounts |  | ||||||
|     class FacebookConnect(SocialConnectView): |  | ||||||
|         adapter_class = FacebookOAuth2Adapter |  | ||||||
| 
 |  | ||||||
| 4. Create url for FacebookLogin view: | 4. Create url for FacebookLogin view: | ||||||
| 
 | 
 | ||||||
| .. code-block:: python | .. code-block:: python | ||||||
|  | @ -127,7 +123,6 @@ Facebook | ||||||
|     urlpatterns += [ |     urlpatterns += [ | ||||||
|         ..., |         ..., | ||||||
|         url(r'^rest-auth/facebook/$', FacebookLogin.as_view(), name='fb_login') |         url(r'^rest-auth/facebook/$', FacebookLogin.as_view(), name='fb_login') | ||||||
|         url(r'^rest-auth/facebook/connect/$', FacebookConnect.as_view(), name='fb_connect') |  | ||||||
|     ] |     ] | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | @ -142,18 +137,12 @@ If you are using Twitter for your social authentication, it is a bit different s | ||||||
| 
 | 
 | ||||||
|     from allauth.socialaccount.providers.twitter.views import TwitterOAuthAdapter |     from allauth.socialaccount.providers.twitter.views import TwitterOAuthAdapter | ||||||
|     from rest_auth.registration.views import SocialLoginView |     from rest_auth.registration.views import SocialLoginView | ||||||
|     from rest_auth.social_serializers import TwitterLoginSerializer, TwitterConnectSerializer |     from rest_auth.social_serializers import TwitterLoginSerializer | ||||||
| 
 | 
 | ||||||
|     class TwitterLogin(SocialLoginView): |     class TwitterLogin(SocialLoginView): | ||||||
|         serializer_class = TwitterLoginSerializer |         serializer_class = TwitterLoginSerializer | ||||||
|         adapter_class = TwitterOAuthAdapter |         adapter_class = TwitterOAuthAdapter | ||||||
| 
 | 
 | ||||||
|     # Add a connect view if you want to allow connecting existing accounts |  | ||||||
|     class TwitterConnect(SocialConnectView): |  | ||||||
|         serializer_class = TwitterConnectSerializer |  | ||||||
|         adapter_class = TwitterOAuthAdapter |  | ||||||
| 
 |  | ||||||
| 
 |  | ||||||
| 4. Create url for TwitterLogin view: | 4. Create url for TwitterLogin view: | ||||||
| 
 | 
 | ||||||
| .. code-block:: python | .. code-block:: python | ||||||
|  | @ -168,7 +157,32 @@ If you are using Twitter for your social authentication, it is a bit different s | ||||||
| Additional Social Connect Views | Additional Social Connect Views | ||||||
| ############################### | ############################### | ||||||
| 
 | 
 | ||||||
| If you are using social connect views, you can also use additional views to check all social accounts attached to the current authenticated user and disconnect selected social accounts. | If you want to allow connecting existing accounts in addition to just login, you can use connect views: | ||||||
|  | 
 | ||||||
|  | .. code-block:: python | ||||||
|  | 
 | ||||||
|  |     from allauth.socialaccount.providers.facebook.views import FacebookOAuth2Adapter | ||||||
|  |     from rest_auth.registration.views import SocialConnectView | ||||||
|  |     from rest_auth.social_serializers import TwitterConnectSerializer | ||||||
|  | 
 | ||||||
|  |     class FacebookConnect(SocialConnectView): | ||||||
|  |         adapter_class = FacebookOAuth2Adapter | ||||||
|  | 
 | ||||||
|  |     class TwitterConnect(SocialConnectView): | ||||||
|  |         serializer_class = TwitterConnectSerializer | ||||||
|  |         adapter_class = TwitterOAuthAdapter | ||||||
|  | 
 | ||||||
|  | In urls.py: | ||||||
|  | 
 | ||||||
|  | .. code-block:: python | ||||||
|  | 
 | ||||||
|  |     urlpatterns += [ | ||||||
|  |         ..., | ||||||
|  |         url(r'^rest-auth/facebook/connect/$', FacebookConnect.as_view(), name='fb_connect') | ||||||
|  |         url(r'^rest-auth/twitter/connect/$', TwitterConnect.as_view(), name='twitter_connect') | ||||||
|  |     ] | ||||||
|  | 
 | ||||||
|  | You can also use additional views to check all social accounts attached to the current authenticated user and disconnect selected social accounts. | ||||||
| 
 | 
 | ||||||
| .. code-block:: python | .. code-block:: python | ||||||
|      |      | ||||||
|  |  | ||||||
|  | @ -90,6 +90,9 @@ class TestsMixin(object): | ||||||
|         self.tw_login_url = reverse('tw_login') |         self.tw_login_url = reverse('tw_login') | ||||||
|         self.tw_login_no_view_url = reverse('tw_login_no_view') |         self.tw_login_no_view_url = reverse('tw_login_no_view') | ||||||
|         self.tw_login_no_adapter_url = reverse('tw_login_no_adapter') |         self.tw_login_no_adapter_url = reverse('tw_login_no_adapter') | ||||||
|  |         self.fb_connect_url = reverse('fb_connect') | ||||||
|  |         self.tw_connect_url = reverse('tw_connect') | ||||||
|  |         self.social_account_list_url = reverse('social_account_list') | ||||||
| 
 | 
 | ||||||
|     def _login(self): |     def _login(self): | ||||||
|         payload = { |         payload = { | ||||||
|  |  | ||||||
|  | @ -5,6 +5,11 @@ from django.contrib.auth import get_user_model | ||||||
| from django.test.utils import override_settings | from django.test.utils import override_settings | ||||||
| from django.contrib.sites.models import Site | from django.contrib.sites.models import Site | ||||||
| 
 | 
 | ||||||
|  | try: | ||||||
|  |     from django.urls import reverse | ||||||
|  | except ImportError: | ||||||
|  |     from django.core.urlresolvers import reverse | ||||||
|  | 
 | ||||||
| from allauth.socialaccount.models import SocialApp | from allauth.socialaccount.models import SocialApp | ||||||
| from allauth.socialaccount.providers.facebook.provider import GRAPH_API_URL | from allauth.socialaccount.providers.facebook.provider import GRAPH_API_URL | ||||||
| import responses | import responses | ||||||
|  | @ -303,3 +308,147 @@ class TestSocialAuth(TestsMixin, TestCase): | ||||||
|         self.assertIn('user', self.response.json.keys()) |         self.assertIn('user', self.response.json.keys()) | ||||||
| 
 | 
 | ||||||
|         self.assertEqual(get_user_model().objects.all().count(), users_count + 1) |         self.assertEqual(get_user_model().objects.all().count(), users_count + 1) | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | @override_settings(ROOT_URLCONF="tests.urls") | ||||||
|  | class TestSocialConnectAuth(TestsMixin, TestCase): | ||||||
|  | 
 | ||||||
|  |     USERNAME = 'person' | ||||||
|  |     PASS = 'person' | ||||||
|  |     EMAIL = "person1@world.com" | ||||||
|  |     REGISTRATION_DATA = { | ||||||
|  |         "username": USERNAME, | ||||||
|  |         "password1": PASS, | ||||||
|  |         "password2": PASS, | ||||||
|  |         "email": EMAIL | ||||||
|  |     } | ||||||
|  |     LOGIN_DATA = { | ||||||
|  |         "username": USERNAME, | ||||||
|  |         "password": PASS, | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     def setUp(self): | ||||||
|  |         self.init() | ||||||
|  | 
 | ||||||
|  |         facebook_social_app = SocialApp.objects.create( | ||||||
|  |             provider='facebook', | ||||||
|  |             name='Facebook', | ||||||
|  |             client_id='123123123', | ||||||
|  |             secret='321321321', | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |         twitter_social_app = SocialApp.objects.create( | ||||||
|  |             provider='twitter', | ||||||
|  |             name='Twitter', | ||||||
|  |             client_id='11223344', | ||||||
|  |             secret='55667788', | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |         site = Site.objects.get_current() | ||||||
|  |         facebook_social_app.sites.add(site) | ||||||
|  |         twitter_social_app.sites.add(site) | ||||||
|  |         self.graph_api_url = GRAPH_API_URL + '/me' | ||||||
|  |         self.twitter_url = 'https://api.twitter.com/1.1/account/verify_credentials.json' | ||||||
|  | 
 | ||||||
|  |     @responses.activate | ||||||
|  |     def test_social_connect_no_auth(self): | ||||||
|  |         responses.add( | ||||||
|  |             responses.GET, | ||||||
|  |             self.graph_api_url, | ||||||
|  |             body='', | ||||||
|  |             status=200, | ||||||
|  |             content_type='application/json' | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |         payload = { | ||||||
|  |             'access_token': 'abc123' | ||||||
|  |         } | ||||||
|  |         self.post(self.fb_connect_url, data=payload, status_code=403) | ||||||
|  |         self.post(self.tw_connect_url, data=payload, status_code=403) | ||||||
|  | 
 | ||||||
|  |     @responses.activate | ||||||
|  |     def test_social_connect(self): | ||||||
|  |         # register user | ||||||
|  |         self.post( | ||||||
|  |             self.register_url, | ||||||
|  |             data=self.REGISTRATION_DATA, | ||||||
|  |             status_code=201 | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |         # Test 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 | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         responses.add( | ||||||
|  |             responses.GET, | ||||||
|  |             self.graph_api_url, | ||||||
|  |             body=json.dumps(resp_body), | ||||||
|  |             status=200, | ||||||
|  |             content_type='application/json' | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |         payload = { | ||||||
|  |             'access_token': 'abc123' | ||||||
|  |         } | ||||||
|  |         self.post(self.fb_connect_url, data=payload, status_code=200) | ||||||
|  |         self.assertIn('key', self.response.json.keys()) | ||||||
|  | 
 | ||||||
|  |         # Test Twitter | ||||||
|  |         self.post(self.logout_url) | ||||||
|  |         self.post(self.login_url, data=self.LOGIN_DATA) | ||||||
|  | 
 | ||||||
|  |         resp_body = { | ||||||
|  |             "id": "123123123123", | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         responses.add( | ||||||
|  |             responses.GET, | ||||||
|  |             self.twitter_url, | ||||||
|  |             body=json.dumps(resp_body), | ||||||
|  |             status=200, | ||||||
|  |             content_type='application/json' | ||||||
|  |         ) | ||||||
|  | 
 | ||||||
|  |         payload = { | ||||||
|  |             'access_token': 'abc123', | ||||||
|  |             'token_secret': '1111222233334444' | ||||||
|  |         } | ||||||
|  | 
 | ||||||
|  |         self.post(self.tw_connect_url, data=payload) | ||||||
|  | 
 | ||||||
|  |         self.assertIn('key', self.response.json.keys()) | ||||||
|  | 
 | ||||||
|  |         # Check current social accounts | ||||||
|  |         self.get(self.social_account_list_url) | ||||||
|  |         self.assertEqual(len(self.response.json), 2) | ||||||
|  |         self.assertEqual(self.response.json[0]['provider'], 'facebook') | ||||||
|  |         self.assertEqual(self.response.json[1]['provider'], 'twitter') | ||||||
|  | 
 | ||||||
|  |         facebook_social_account_id = self.response.json[0]['id'] | ||||||
|  | 
 | ||||||
|  |         # Try disconnecting accounts | ||||||
|  |         self.incorrect_disconnect_url = reverse( | ||||||
|  |             'social_account_disconnect', args=[999] | ||||||
|  |         ) | ||||||
|  |         self.post(self.incorrect_disconnect_url, status_code=404) | ||||||
|  | 
 | ||||||
|  |         self.disconnect_url = reverse( | ||||||
|  |             'social_account_disconnect', args=[facebook_social_account_id] | ||||||
|  |         ) | ||||||
|  |         self.post(self.disconnect_url, status_code=200) | ||||||
|  | 
 | ||||||
|  |         # Check social accounts after disconnecting | ||||||
|  |         self.get(self.social_account_list_url) | ||||||
|  |         self.assertEqual(len(self.response.json), 1) | ||||||
|  |         self.assertEqual(self.response.json[0]['provider'], 'twitter') | ||||||
|  |  | ||||||
|  | @ -8,8 +8,13 @@ from allauth.socialaccount.providers.twitter.views import TwitterOAuthAdapter | ||||||
| from rest_framework.decorators import api_view | from rest_framework.decorators import api_view | ||||||
| 
 | 
 | ||||||
| from rest_auth.urls import urlpatterns | from rest_auth.urls import urlpatterns | ||||||
| from rest_auth.registration.views import SocialLoginView | from rest_auth.registration.views import ( | ||||||
| from rest_auth.social_serializers import TwitterLoginSerializer |     SocialLoginView, SocialConnectView, SocialAccountListView, | ||||||
|  |     SocialAccountDisconnectView | ||||||
|  | ) | ||||||
|  | from rest_auth.social_serializers import ( | ||||||
|  |     TwitterLoginSerializer, TwitterConnectSerializer | ||||||
|  | ) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| class FacebookLogin(SocialLoginView): | class FacebookLogin(SocialLoginView): | ||||||
|  | @ -21,6 +26,15 @@ class TwitterLogin(SocialLoginView): | ||||||
|     serializer_class = TwitterLoginSerializer |     serializer_class = TwitterLoginSerializer | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  | class FacebookConnect(SocialConnectView): | ||||||
|  |     adapter_class = FacebookOAuth2Adapter | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
|  | class TwitterConnect(SocialConnectView): | ||||||
|  |     adapter_class = TwitterOAuthAdapter | ||||||
|  |     serializer_class = TwitterConnectSerializer | ||||||
|  | 
 | ||||||
|  | 
 | ||||||
| class TwitterLoginSerializerFoo(TwitterLoginSerializer): | class TwitterLoginSerializerFoo(TwitterLoginSerializer): | ||||||
|     pass |     pass | ||||||
| 
 | 
 | ||||||
|  | @ -49,5 +63,10 @@ urlpatterns += [ | ||||||
|     url(r'^social-login/twitter/$', TwitterLogin.as_view(), name='tw_login'), |     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-view/$', twitter_login_view, name='tw_login_no_view'), | ||||||
|     url(r'^social-login/twitter-no-adapter/$', TwitterLoginNoAdapter.as_view(), name='tw_login_no_adapter'), |     url(r'^social-login/twitter-no-adapter/$', TwitterLoginNoAdapter.as_view(), name='tw_login_no_adapter'), | ||||||
|  |     url(r'^social-login/facebook/connect/$', FacebookConnect.as_view(), name='fb_connect'), | ||||||
|  |     url(r'^social-login/twitter/connect/$', TwitterConnect.as_view(), name='tw_connect'), | ||||||
|  |     url(r'^socialaccounts/$', SocialAccountListView.as_view(), name='social_account_list'), | ||||||
|  |     url(r'^socialaccounts/(?P<pk>\d+)/disconnect/$', SocialAccountDisconnectView.as_view(), | ||||||
|  |         name='social_account_disconnect'), | ||||||
|     url(r'^accounts/', include('allauth.socialaccount.urls')) |     url(r'^accounts/', include('allauth.socialaccount.urls')) | ||||||
| ] | ] | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user