diff --git a/api/auth.py b/api/auth.py index 0bf5ec4..7f5c749 100644 --- a/api/auth.py +++ b/api/auth.py @@ -1,6 +1,10 @@ from calendar import timegm + import datetime import logging + +import requests +from requests_oauthlib import OAuth1 from rest_framework import permissions from rest_framework.response import Response from rest_framework import renderers @@ -13,6 +17,9 @@ from rest_framework_jwt.utils import jwt_payload_handler, jwt_encode_handler from rest_framework import parsers from social.apps.django_app.utils import psa +from urllib.parse import parse_qsl + +from dss import settings logger = logging.getLogger('dss') @@ -24,24 +31,73 @@ BACKENDS = { @psa() -def auth_by_token(request, backend): +def auth_by_token(request, backend, auth_token): user = request.backend.do_auth( - access_token=request.data.get('access_token') + access_token=auth_token ) return user if user else None +def get_access_token(request, backend): + """ + Tries to get the access token from an OAuth Provider + :param request: + :param backend: + :return: + """ + access_token_url = '' + secret = '' + + client_id = None + if backend == 'facebook': + access_token_url = 'https://graph.facebook.com/oauth/access_token' + secret = settings.SOCIAL_AUTH_FACEBOOK_SECRET + params = { + 'client_id': client_id or request.data.get('clientId'), + 'redirect_uri': request.data.get('redirectUri'), + 'client_secret': secret, + 'code': request.data.get('code') + } + + # Step 1. Exchange authorization code for access token. + r = requests.get(access_token_url, params=params) + try: + access_token = dict(parse_qsl(r.text))['access_token'] + except KeyError: + access_token = 'FAILED' + return access_token + + elif backend == 'twitter': + request_token_url = 'https://api.twitter.com/oauth/request_token' + access_token_url = 'https://api.twitter.com/oauth/access_token' + + if request.data.get('oauth_token') and request.data.get('oauth_verifier'): + auth = OAuth1(settings.SOCIAL_AUTH_TWITTER_KEY, + settings.SOCIAL_AUTH_TWITTER_SECRET, + resource_owner_key=request.data.get('oauth_token'), + verifier=request.data.get('oauth_verifier')) + r = requests.post(access_token_url, auth=auth) + profile = dict(parse_qsl(r.text)) + else: + oauth = OAuth1(settings.SOCIAL_AUTH_TWITTER_KEY, + client_secret=settings.SOCIAL_AUTH_TWITTER_SECRET, + callback_uri='http://ext-test.deepsouthsounds.com:9000/') + r = requests.post(request_token_url, auth=oauth) + oauth_token = dict(parse_qsl(r.text)) + return oauth_token.get('oauth_token_secret') + + class SocialLoginHandler(APIView): permission_classes = (permissions.AllowAny,) - def post(self, request, format=None): - auth_token = request.data.get('access_token', None) - backend = BACKENDS.get(request.data.get('backend', None), 'facebook') + def post(self, request): + backend = request.query_params.get('backend', None) + auth_token = get_access_token(request, backend) if auth_token and backend: try: - user = auth_by_token(request, backend) + user = auth_by_token(request, backend, auth_token) except Exception as e: logger.exception(e) return Response({ @@ -59,7 +115,7 @@ class SocialLoginHandler(APIView): payload = jwt_payload_handler(user) if api_settings.JWT_ALLOW_REFRESH: payload['orig_iat'] = timegm( - datetime.datetime.utcnow().utctimetuple() + datetime.datetime.utcnow().utctimetuple() ) response_data = { @@ -90,11 +146,11 @@ class ObtainUser(APIView): def get(self, request): if request.user.is_authenticated(): return Response( - status=status.HTTP_200_OK, data={ - 'id': request.user.id, - 'name': request.user.username, - 'slug': request.user.userprofile.slug, - 'userRole': 'user' - }) + status=status.HTTP_200_OK, data={ + 'id': request.user.id, + 'name': request.user.username, + 'slug': request.user.userprofile.slug, + 'userRole': 'user' + }) else: return Response(status=status.HTTP_401_UNAUTHORIZED) diff --git a/api/urls.py b/api/urls.py index cb0bbb6..fda54b8 100755 --- a/api/urls.py +++ b/api/urls.py @@ -60,7 +60,7 @@ urlpatterns = patterns( url(r'_search/$', views.SearchResultsView.as_view()), url(r'^', include(router.urls)), - url(r'^_login/', SocialLoginHandler.as_view()), + url(r'^_login/?$', SocialLoginHandler.as_view()), url(r'^token-refresh/', 'rest_framework_jwt.views.refresh_jwt_token'), url(r'^__u/checkslug', helpers.UserSlugCheckHelper.as_view()), diff --git a/requirements.txt b/requirements.txt index 93fe9c7..580009f 100755 --- a/requirements.txt +++ b/requirements.txt @@ -24,7 +24,7 @@ sorl-thumbnail git+git://github.com/disqus/django-bitfield.git#django-bitfield git+git://github.com/tschellenbach/Django-facebook.git#django-facebook -git+git://github.com/omab/python-social-auth.git#egg=python-social-auth +python-social-auth django-allauth apache-libcloud mandrill