Getting nowhere

This commit is contained in:
Fergal Moran
2016-01-17 21:13:13 +00:00
parent a6344007cc
commit aedc18c1e0
2 changed files with 79 additions and 76 deletions

View File

@@ -1,96 +1,116 @@
from calendar import timegm from __future__ import unicode_literals
import datetime
import logging
from django.http import HttpResponseBadRequest import datetime
from rest_framework import permissions from calendar import timegm
from rest_framework.response import Response from urllib.parse import parse_qsl
from rest_framework import renderers
import requests
from rest_framework import status
from rest_framework.authtoken.models import Token from rest_framework.authtoken.models import Token
from rest_framework.authtoken.serializers import AuthTokenSerializer from rest_framework.authtoken.serializers import AuthTokenSerializer
from rest_framework.permissions import AllowAny, IsAuthenticated
from rest_framework.response import Response
from rest_framework.views import APIView from rest_framework.views import APIView
from rest_framework.views import status from rest_framework import parsers, renderers
from rest_framework_jwt.settings import api_settings from rest_framework_jwt.settings import api_settings
from rest_framework_jwt.utils import jwt_payload_handler, jwt_encode_handler 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 social.apps.django_app.utils import psa
from social.backends.oauth import BaseOAuth1, BaseOAuth2
logger = logging.getLogger('dss') from dss import settings
BACKENDS = {
'google': 'google-oauth2',
'facebook': 'facebook',
'twitter': 'twitter'
}
@psa() @psa()
def auth_by_token(request, backend): def auth_by_token(request, backend, auth_token):
backend = request.backend """Decorator that creates/authenticates a user with an access_token"""
if isinstance(backend, BaseOAuth1):
token = {
'oauth_token': request.data.get('access_token'),
'oauth_token_secret': request.data.get('access_token_secret'),
}
"""
token = "oauth_token=" + request.data.get('access_token') + "&oauth_token_secret=" + request.data.get(
'access_token_secret')
"""
elif isinstance(backend, BaseOAuth2):
token = request.REQUEST.get('access_token')
else:
raise HttpResponseBadRequest('Wrong backend type')
user = request.backend.do_auth( user = request.backend.do_auth(
token, ajax=True access_token=auth_token
) )
if user:
return user
else:
return None
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 = ''
if backend == 'facebook':
access_token_url = 'https://graph.facebook.com/oauth/access_token'
secret = settings.SOCIAL_AUTH_FACEBOOK_SECRET
if backend == 'twitter':
access_token_url = 'https://api.twitter.com/oauth/request_token'
secret = settings.SOCIAL_AUTH_TWITTER_SECRET
params = {
'client_id': 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
class SocialLoginHandler(APIView): class SocialLoginHandler(APIView):
permission_classes = (permissions.AllowAny,) """View to authenticate users through social media."""
permission_classes = (AllowAny,)
def get(self, request, format=None):
pass
def post(self, request, format=None): def post(self, request, format=None):
auth_token = request.data.get('access_token', None) backend = request.query_params.get(u'backend', None)
backend = BACKENDS.get(request.data.get('backend', None), 'facebook') auth_token = get_access_token(request, backend)
if auth_token and backend: if auth_token and backend:
try: try:
user = auth_by_token(request, backend) # Try to authenticate the user using python-social-auth
except Exception as e: user = auth_by_token(request, backend, auth_token)
logger.exception(e) except Exception:
return Response({ return Response({'status': 'Bad request',
'status': 'Bad request', 'message': 'Could not authenticate with the provided token.'},
'message': e status=status.HTTP_400_BAD_REQUEST)
}, status=status.HTTP_400_BAD_REQUEST)
if user: if user:
if not user.is_active: if not user.is_active:
return Response({ return Response({'status': 'Unauthorized',
'status': 'Unauthorized', 'message': 'The user account is disabled.'}, status=status.HTTP_401_UNAUTHORIZED)
'message': 'User account disabled'
}, status=status.HTTP_401_UNAUTHORIZED)
# This is the part that differs from the normal python-social-auth implementation.
# Return the JWT instead.
# Get the JWT payload for the user.
payload = jwt_payload_handler(user) payload = jwt_payload_handler(user)
# Include original issued at time for a brand new token,
# to allow token refresh
if api_settings.JWT_ALLOW_REFRESH: if api_settings.JWT_ALLOW_REFRESH:
payload['orig_iat'] = timegm( payload['orig_iat'] = timegm(
datetime.datetime.utcnow().utctimetuple() datetime.datetime.utcnow().utctimetuple()
) )
# Create the response object with the JWT payload.
response_data = { response_data = {
'token': jwt_encode_handler(payload), 'token': jwt_encode_handler(payload)
'session': user.userprofile.get_session_id()
} }
return Response(response_data) return Response(response_data)
else: else:
return Response({ return Response({'status': 'Bad request',
'status': 'Bad request', 'message': 'Authentication could not be performed with received data.'},
'message': 'Authentication could not be performed with received data.' status=status.HTTP_400_BAD_REQUEST)
}, status=status.HTTP_400_BAD_REQUEST)
class ObtainUser(APIView): class ObtainUser(APIView):
@@ -115,21 +135,3 @@ class ObtainUser(APIView):
}) })
else: else:
return Response(status=status.HTTP_401_UNAUTHORIZED) return Response(status=status.HTTP_401_UNAUTHORIZED)
"""
class DjangoRESTFrameworkStrategy(DjangoStrategy):
def request_data(self, merge=True):
if not self.request:
return {}
if merge:
data = self.request.REQUEST
elif self.request.method == 'POST':
data = self.request.POST
else:
data = self.request.GET
if data.get('_content'):
data = data.copy()
data.update(data.pop('_content'))
return data
"""

View File

@@ -59,7 +59,8 @@ urlpatterns = patterns(
url(r'_search/$', views.SearchResultsView.as_view()), url(r'_search/$', views.SearchResultsView.as_view()),
url(r'^', include(router.urls)), url(r'^', include(router.urls)),
url(r'^_login/', SocialLoginHandler.as_view()), url(r'^_login', SocialLoginHandler.as_view()),
url(r'^_a', SocialLoginHandler.as_view()),
url(r'^token-refresh/', 'rest_framework_jwt.views.refresh_jwt_token'), url(r'^token-refresh/', 'rest_framework_jwt.views.refresh_jwt_token'),
url(r'^__u/checkslug', helpers.UserSlugCheckHelper.as_view()), url(r'^__u/checkslug', helpers.UserSlugCheckHelper.as_view()),