From b81f868cac91aa2897cd076ac383dfee504944c3 Mon Sep 17 00:00:00 2001 From: Sam Date: Tue, 16 Mar 2021 13:24:25 +0000 Subject: [PATCH] more work on social login --- README.md | 21 +++++++++++++++++ back_latienda/settings/base.py | 14 ++++++++---- back_latienda/urls.py | 2 +- core/tests.py | 42 ++++++++++++++++++++++++++++++++++ example.env | 11 ++++++++- requirements.txt | 2 +- 6 files changed, 85 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index b45a011..ed67e04 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,7 @@ This README aims to document functionality of backend as well as required steps - [First Steps](#first-steps) - [Load location data](#load-location-data) - [Load taxonomy data](#load-taxonomy-data) +- [Social Auth](#social-auth) - [Company Endpoints](#company-endpoints) - [Product Endpoints](#product-endpoints) - [Core Endpoints](#core-endpoints) @@ -61,6 +62,26 @@ This data serves as initial Tags To load initial set of tags: `python manage.py addtaxonomy` + +## Social Auth + +Use your credentials from social media network to create acount and log in. + +Backend must be registered with every service that we want to use it with. + +During registration, provide a `Callback URL`, where the app can receive requests. +You are given `client key` and `client secret` tokens, used to validate login requests. + +### Facebook + +- Go to `developers.facebook.com/` +- click on `My Apps` +- On `Add a New App`, click on `Website` +- Click on `Create App ID` +- On the next screen click on `Skip Quick Start` +- grab the `App ID` and `App Secret` +- in `Settings / Basic`, click on the button `+ Add Platform` and add a website, and other info + ## Company Endpoints ### CompanyViewSet diff --git a/back_latienda/settings/base.py b/back_latienda/settings/base.py index e1ab88b..290c4a5 100644 --- a/back_latienda/settings/base.py +++ b/back_latienda/settings/base.py @@ -57,7 +57,9 @@ INSTALLED_APPS = [ 'storages', 'mapwidgets', 'django_admin_listfilter_dropdown', + 'oauth2_provider', 'social_django', + 'rest_framework_social_oauth2', # local apps 'core', @@ -130,13 +132,14 @@ AUTH_PASSWORD_VALIDATORS = [ AUTH_USER_MODEL = 'core.CustomUser' AUTHENTICATION_BACKENDS = ( - 'social_core.backends.github.GithubOAuth2', - 'social_core.backends.twitter.TwitterOAuth', - 'social_core.backends.facebook.FacebookOAuth2', - + 'rest_framework_social_oauth2.backends.DjangoOAuth2', 'django.contrib.auth.backends.ModelBackend', ) +DRFSO2_PROPRIETARY_BACKEND_NAME = os.getenv('DRFSO2_PROPRIETARY_BACKEND_NAME') # E.g. Facebook +DRFSO2_URL_NAMESPACE = os.getenv('DRFSO2_URL_NAMESPACE') # namespace for reversing URLs + + # DRF Options REST_FRAMEWORK = { 'DEFAULT_PERMISSION_CLASSES': [ @@ -144,6 +147,9 @@ REST_FRAMEWORK = { ], 'DEFAULT_AUTHENTICATION_CLASSES': [ 'rest_framework_simplejwt.authentication.JWTAuthentication', + + 'oauth2_provider.contrib.rest_framework.OAuth2Authentication', + 'rest_framework_social_oauth2.authentication.SocialAuthentication', ], 'DEFAULT_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'], 'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination', diff --git a/back_latienda/urls.py b/back_latienda/urls.py index 0d58a53..809426e 100644 --- a/back_latienda/urls.py +++ b/back_latienda/urls.py @@ -31,7 +31,7 @@ admin.site.site_header = 'LaTiendaCOOP Administration' urlpatterns = [ path('admin/', admin.site.urls), path('activate///',core_views.activate_user, name='activate_user'), - path('api/v1/oauth/', include('social_django.urls', namespace='social')), + path('api/v1/social-auth/', include('rest_framework_social_oauth2.urls')), path('api/v1/token/', TokenObtainPairView.as_view(), name='token_obtain_pair'), path('api/v1/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'), path('api/v1/token/verify/', TokenVerifyView.as_view(), name='token_verify'), diff --git a/core/tests.py b/core/tests.py index 6144a64..10174aa 100644 --- a/core/tests.py +++ b/core/tests.py @@ -722,3 +722,45 @@ class AdminStatsTest(APITestCase): for name in expected_entries: self.assertTrue(name in payload) + +class SocialLoginTest(APITestCase): + + def setUp(self): + self.endpoint = '/api/v1/admin_stats/' + self.factory = factories.CustomUserFactory + self.model = models.CustomUser + # create user + self.email = "user@mail.com" + self.password = ''.join(random.choices(string.ascii_uppercase, k = 10)) + self.user = self.factory(email=self.email, is_active=True) + self.user.set_password(self.password) + self.user.save() + + def test_user_can_login_facebook(self): + url = f'https://facebook.com/auth? \ + response_type=code& \ + client_id={settings.FACEBOOK_ID}& \ + redirect_uri=CALLBACK_URI& \ + scope=profile& \ + scope=email' + + response = self.client.get(url) + + # assertions + self.assertEquals(response.status_code, 200) + + def test_user_can_login_google(self): + url = f'https://google.com/auth? \ + response_type=code& \ + client_id={settings.GOOGLE_CLIENT_ID}& \ + redirect_uri=CALLBACK_URI& \ + scope=profile& \ + scope=email' + + response = self.client.get(url) + + # assertions + self.assertEquals(response.status_code, 200) + + def test_bad_login(self): + pass diff --git a/example.env b/example.env index 87e699b..ea51289 100644 --- a/example.env +++ b/example.env @@ -16,4 +16,13 @@ WC_SECRET = '' # GOOGLE MAPS GOOGLE_MAP_API_KEY = '' # USER ACTIVATION REDIRECTION -ACTIVATION_REDIRECT = '' \ No newline at end of file +ACTIVATION_REDIRECT = '' +# SOCIAL LOGIN +SOCIAL_AUTH_GITHUB_KEY = '' +SOCIAL_AUTH_GITHUB_SECRET = '' +SOCIAL_AUTH_FACEBOOK_KEY = '' +SOCIAL_AUTH_FACEBOOK_SECRET = '' +DRFSO2_PROPRIETARY_BACKEND_NAME = '' # E.g. Facebook +DRFSO2_URL_NAMESPACE = '' # namespace for reversing URLs +GOOGLE_CLIENT_ID='' +FACEBOOK_ID='' \ No newline at end of file diff --git a/requirements.txt b/requirements.txt index 88b7bac..153a02a 100644 --- a/requirements.txt +++ b/requirements.txt @@ -18,7 +18,7 @@ django-autocomplete-light==3.8.2 # manually install `pip install --default-timeout=100 future` to avoid wcapi to timeout django-map-widgets==0.3.0 django-admin-list-filter-dropdown==1.0.3 -social-auth-app-django==4.0.0 +django-rest-framework-social-oauth2==1.1.0 # required for production django-anymail[amazon_ses]==8.2 boto3==1.17.11