diff --git a/api/auth.py b/api/auth.py index 6d4caf8..201ce3a 100644 --- a/api/auth.py +++ b/api/auth.py @@ -1 +1,93 @@ -__author__ = 'fergalm' +from calendar import timegm +import datetime +from rest_framework import permissions +from rest_framework.authtoken.serializers import AuthTokenSerializer +from rest_framework.response import Response +from rest_framework import renderers +from rest_framework.authtoken.models import Token +from rest_framework.authtoken.serializers import AuthTokenSerializer +from rest_framework.views import APIView +from rest_framework.views import status +from rest_framework_jwt.settings import api_settings +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 dss import settings + + +@psa() +def auth_by_token(request, backend): + token = request.data.get('access_token') + user = request.user + user = request.backend.do_auth( + access_token=request.data.get('access_token') + ) + + return user if user else None + + +class FacebookView(APIView): + permission_classes = (permissions.AllowAny,) + + def post(self, request, format=None): + auth_token = request.data.get('access_token', None) + backend = request.data.get('backend', None) + + if auth_token and backend: + try: + user = auth_by_token(request, backend) + except Exception, e: + return Response({ + 'status': 'Bad request', + 'message': 'Could not authenticate with the provided token' if settings.DEBUG else e.message + }, status=status.HTTP_400_BAD_REQUEST) + + if user: + if not user.is_active: + return Response({ + 'status': 'Unauthorized', + 'message': 'User account disabled' + }, status=status.HTTP_401_UNAUTHORIZED) + + payload = jwt_payload_handler(user) + if api_settings.JWT_ALLOW_REFRESH: + payload['orig_iat'] = timegm( + datetime.datetime.utcnow().utctimetuple() + ) + + response_data = { + 'token': jwt_encode_handler(payload) + } + + return Response(response_data) + + else: + return Response({ + 'status': 'Bad request', + 'message': 'Authentication could not be performed with received data.' + }, status=status.HTTP_400_BAD_REQUEST) + + +class ObtainUser(APIView): + throttle_classes = () + permission_classes = () + parser_classes = (parsers.FormParser, parsers.MultiPartParser, parsers.JSONParser,) + renderer_classes = (renderers.JSONRenderer,) + serializer_class = AuthTokenSerializer + model = Token + + def post(self, request): + return self.get(request) + + 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' + }) + else: + return Response(status=status.HTTP_401_UNAUTHORIZED) diff --git a/api/helpers.py b/api/helpers.py index 2aa1d3b..32b3e32 100644 --- a/api/helpers.py +++ b/api/helpers.py @@ -24,8 +24,8 @@ class ChatHelper(ActivityHelper): user = self.get_session(request) - chat.post_chat(request.DATA['user'], request.DATA['message']) - return Response(request.DATA['message'], HTTP_201_CREATED) + chat.post_chat(request.data['user'], request.data['message']) + return Response(request.data['message'], HTTP_201_CREATED) class ActivityPlayHelper(ActivityHelper): diff --git a/api/urls.py b/api/urls.py index d0b1b0a..043c535 100755 --- a/api/urls.py +++ b/api/urls.py @@ -2,6 +2,7 @@ from django.conf.urls import patterns, url, include from rest_framework.routers import DefaultRouter from api import views, auth, helpers +from api.auth import FacebookView router = DefaultRouter() # trailing_slash=True) @@ -25,8 +26,8 @@ urlpatterns = patterns( url(r'_search/$', views.SearchResultsView.as_view()), url(r'^', include(router.urls)), - url(r'^login/', auth.ObtainAuthToken.as_view()), - url(r'^logout/', auth.ObtainLogout.as_view()), + #url(r'^login/', auth.ObtainAuthToken.as_view()), + #url(r'^logout/', auth.ObtainLogout.as_view()), # url(r'^_tr/', RefreshToken.as_view()), url(r'^__u/checkslug', helpers.UserSlugCheckHelper.as_view()), @@ -35,6 +36,7 @@ urlpatterns = patterns( url(r'^_act/play', helpers.ActivityPlayHelper.as_view()), url(r'^_chat/', helpers.ChatHelper.as_view()), + url(r'^_login/', FacebookView.as_view()), url('', include('social.apps.django_app.urls', namespace='social')), ) diff --git a/api/views.py b/api/views.py index e6546e9..12948a5 100755 --- a/api/views.py +++ b/api/views.py @@ -51,9 +51,9 @@ class CommentViewSet(viewsets.ModelViewSet): ) def perform_create(self, serializer): - if 'mix_id' in self.request.DATA: + if 'mix_id' in self.request.data: try: - mix = Mix.objects.get(pk=self.request.DATA['mix_id']) + mix = Mix.objects.get(pk=self.request.data['mix_id']) if mix is not None: serializer.save( mix=mix, @@ -121,11 +121,11 @@ class AttachedImageUploadView(views.APIView): parser_classes = (FileUploadParser,) def post(self, request): - if request.FILES['file'] is None or request.DATA.get('data') is None: + if request.FILES['file'] is None or request.data.get('data') is None: return Response(status=HTTP_400_BAD_REQUEST) file_obj = request.FILES['file'] - file_hash = request.DATA.get('data') + file_hash = request.data.get('data') try: mix = Mix.objects.get(uid=file_hash) if mix: diff --git a/dss/settings.py b/dss/settings.py index 3a933af..605277d 100755 --- a/dss/settings.py +++ b/dss/settings.py @@ -201,7 +201,9 @@ REST_FRAMEWORK = { 'rest_framework.filters.OrderingFilter', ), 'DEFAULT_AUTHENTICATION_CLASSES': ( - 'rest_framework.authentication.TokenAuthentication', + 'rest_framework.authentication.SessionAuthentication', + 'rest_framework.authentication.BasicAuthentication', + 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', ), 'PAGINATE_BY': 12, # Default to 10 'PAGINATE_BY_PARAM': 'limit', # Allow client to override, using `?page_size=xxx`. diff --git a/requirements.txt b/requirements.txt index bb51a4d..c8d12d2 100755 --- a/requirements.txt +++ b/requirements.txt @@ -32,6 +32,7 @@ mandrill djrill djangorestframework +djangorestframework-jwt drf-nested-routers django-celery pillow