Merge branch 'development'
This commit is contained in:
21
README.md
21
README.md
@@ -7,6 +7,7 @@ This README aims to document functionality of backend as well as required steps
|
|||||||
- [First Steps](#first-steps)
|
- [First Steps](#first-steps)
|
||||||
- [Load location data](#load-location-data)
|
- [Load location data](#load-location-data)
|
||||||
- [Load taxonomy data](#load-taxonomy-data)
|
- [Load taxonomy data](#load-taxonomy-data)
|
||||||
|
- [Social Auth](#social-auth)
|
||||||
- [Company Endpoints](#company-endpoints)
|
- [Company Endpoints](#company-endpoints)
|
||||||
- [Product Endpoints](#product-endpoints)
|
- [Product Endpoints](#product-endpoints)
|
||||||
- [Core Endpoints](#core-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`
|
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
|
## Company Endpoints
|
||||||
|
|
||||||
### CompanyViewSet
|
### CompanyViewSet
|
||||||
|
|||||||
@@ -57,6 +57,9 @@ INSTALLED_APPS = [
|
|||||||
'storages',
|
'storages',
|
||||||
'mapwidgets',
|
'mapwidgets',
|
||||||
'django_admin_listfilter_dropdown',
|
'django_admin_listfilter_dropdown',
|
||||||
|
'oauth2_provider',
|
||||||
|
'social_django',
|
||||||
|
'rest_framework_social_oauth2',
|
||||||
|
|
||||||
# local apps
|
# local apps
|
||||||
'core',
|
'core',
|
||||||
@@ -77,6 +80,8 @@ MIDDLEWARE = [
|
|||||||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||||||
'django.contrib.messages.middleware.MessageMiddleware',
|
'django.contrib.messages.middleware.MessageMiddleware',
|
||||||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||||||
|
|
||||||
|
'social_django.middleware.SocialAuthExceptionMiddleware',
|
||||||
]
|
]
|
||||||
|
|
||||||
ROOT_URLCONF = 'back_latienda.urls'
|
ROOT_URLCONF = 'back_latienda.urls'
|
||||||
@@ -92,6 +97,9 @@ TEMPLATES = [
|
|||||||
'django.template.context_processors.request',
|
'django.template.context_processors.request',
|
||||||
'django.contrib.auth.context_processors.auth',
|
'django.contrib.auth.context_processors.auth',
|
||||||
'django.contrib.messages.context_processors.messages',
|
'django.contrib.messages.context_processors.messages',
|
||||||
|
|
||||||
|
'social_django.context_processors.backends',
|
||||||
|
'social_django.context_processors.login_redirect',
|
||||||
],
|
],
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
@@ -123,6 +131,15 @@ AUTH_PASSWORD_VALIDATORS = [
|
|||||||
|
|
||||||
AUTH_USER_MODEL = 'core.CustomUser'
|
AUTH_USER_MODEL = 'core.CustomUser'
|
||||||
|
|
||||||
|
AUTHENTICATION_BACKENDS = (
|
||||||
|
'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
|
# DRF Options
|
||||||
REST_FRAMEWORK = {
|
REST_FRAMEWORK = {
|
||||||
'DEFAULT_PERMISSION_CLASSES': [
|
'DEFAULT_PERMISSION_CLASSES': [
|
||||||
@@ -130,6 +147,9 @@ REST_FRAMEWORK = {
|
|||||||
],
|
],
|
||||||
'DEFAULT_AUTHENTICATION_CLASSES': [
|
'DEFAULT_AUTHENTICATION_CLASSES': [
|
||||||
'rest_framework_simplejwt.authentication.JWTAuthentication',
|
'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_FILTER_BACKENDS': ['django_filters.rest_framework.DjangoFilterBackend'],
|
||||||
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
|
'DEFAULT_PAGINATION_CLASS': 'rest_framework.pagination.LimitOffsetPagination',
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ admin.site.site_header = 'LaTiendaCOOP Administration'
|
|||||||
urlpatterns = [
|
urlpatterns = [
|
||||||
path('admin/', admin.site.urls),
|
path('admin/', admin.site.urls),
|
||||||
path('activate/<uidb64>/<token>/',core_views.activate_user, name='activate_user'),
|
path('activate/<uidb64>/<token>/',core_views.activate_user, name='activate_user'),
|
||||||
|
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/', TokenObtainPairView.as_view(), name='token_obtain_pair'),
|
||||||
path('api/v1/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
|
path('api/v1/token/refresh/', TokenRefreshView.as_view(), name='token_refresh'),
|
||||||
path('api/v1/token/verify/', TokenVerifyView.as_view(), name='token_verify'),
|
path('api/v1/token/verify/', TokenVerifyView.as_view(), name='token_verify'),
|
||||||
|
|||||||
@@ -722,3 +722,77 @@ class AdminStatsTest(APITestCase):
|
|||||||
for name in expected_entries:
|
for name in expected_entries:
|
||||||
self.assertTrue(name in payload)
|
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()
|
||||||
|
# data
|
||||||
|
self.callback_uri = 'http://127.0.0.1:8000/'
|
||||||
|
|
||||||
|
def test_user_can_login_facebook(self):
|
||||||
|
# get auth page
|
||||||
|
url = f'https://facebook.com/auth? \
|
||||||
|
response_type=code& \
|
||||||
|
client_id={settings.FACEBOOK_ID}& \
|
||||||
|
redirect_uri={self.callback_uri}& \
|
||||||
|
scope=profile& \
|
||||||
|
scope=email'
|
||||||
|
|
||||||
|
response = self.client.get(url)
|
||||||
|
# make assertions
|
||||||
|
self.assertEquals(response.status_code, 200)
|
||||||
|
|
||||||
|
# authenticate to auth page if not logged in
|
||||||
|
url2 = response.url
|
||||||
|
creds = {
|
||||||
|
'email': 'sam@mail.com',
|
||||||
|
'password': 'supersecret'
|
||||||
|
}
|
||||||
|
response = self.client.post(url2, data=creds)
|
||||||
|
# assertions
|
||||||
|
self.assertEquals(response.status_code, 200)
|
||||||
|
# redirection url
|
||||||
|
redirect = response.url
|
||||||
|
auth_code = redirect.split('=')[-1]
|
||||||
|
|
||||||
|
# authenticate previous query is valid
|
||||||
|
url = f'https://facebook.com/token/?
|
||||||
|
grant_type=authorization_code&\
|
||||||
|
code={auth_code}&\
|
||||||
|
redirect_uri={self.callback_uri}&\
|
||||||
|
client_id={settings.FACEBOOK_ID}&\
|
||||||
|
client_secret=CLIENT_SECRET'
|
||||||
|
|
||||||
|
response = self.client.get(url)
|
||||||
|
# assertions
|
||||||
|
self.assertEquals(response.status_code, 200)
|
||||||
|
# redirection url
|
||||||
|
redirect = response.url
|
||||||
|
auth_code = redirect.split('=')[-1]
|
||||||
|
|
||||||
|
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
|
||||||
|
'''
|
||||||
|
|||||||
@@ -17,3 +17,12 @@ WC_SECRET = ''
|
|||||||
GOOGLE_MAP_API_KEY = ''
|
GOOGLE_MAP_API_KEY = ''
|
||||||
# USER ACTIVATION REDIRECTION
|
# USER ACTIVATION REDIRECTION
|
||||||
ACTIVATION_REDIRECT = ''
|
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=''
|
||||||
@@ -18,6 +18,7 @@ django-autocomplete-light==3.8.2
|
|||||||
# manually install `pip install --default-timeout=100 future` to avoid wcapi to timeout
|
# manually install `pip install --default-timeout=100 future` to avoid wcapi to timeout
|
||||||
django-map-widgets==0.3.0
|
django-map-widgets==0.3.0
|
||||||
django-admin-list-filter-dropdown==1.0.3
|
django-admin-list-filter-dropdown==1.0.3
|
||||||
|
django-rest-framework-social-oauth2==1.1.0
|
||||||
# required for production
|
# required for production
|
||||||
django-anymail[amazon_ses]==8.2
|
django-anymail[amazon_ses]==8.2
|
||||||
boto3==1.17.11
|
boto3==1.17.11
|
||||||
|
|||||||
Reference in New Issue
Block a user