From aac61972e369d91b644984f7113650f056d63f4d Mon Sep 17 00:00:00 2001 From: Andrey Date: Thu, 3 May 2018 16:58:27 +0300 Subject: [PATCH] stat part 1 --- access/views.py | 5 ++++- lms/settings.py | 16 +++++++++------- lms/tools.py | 4 ++++ lms/utils.py | 50 +++++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 67 insertions(+), 8 deletions(-) diff --git a/access/views.py b/access/views.py index cda626c..b510394 100644 --- a/access/views.py +++ b/access/views.py @@ -5,6 +5,7 @@ import logging from django.contrib import auth from django.conf import settings +from rest_framework_jwt.settings import api_settings from django.contrib.auth import get_user_model from django.core.mail import send_mail, EmailMessage from django.db.models import Q @@ -280,7 +281,9 @@ class LogoutView(APIView): def post(request): if request.user.is_authenticated(): auth.logout(request) - return Response(status=204) + response = Response(status=204) + response.delete_cookie(api_settings.JWT_AUTH_COOKIE) + return response class MinUserView(APIView): diff --git a/lms/settings.py b/lms/settings.py index 842a003..6db857d 100644 --- a/lms/settings.py +++ b/lms/settings.py @@ -128,12 +128,14 @@ MIDDLEWARE_CLASSES = [ REST_FRAMEWORK = { 'DEFAULT_AUTHENTICATION_CLASSES': ( + 'lms.utils.JSONWebTokenAuthentication', 'rest_framework.authentication.SessionAuthentication', + 'rest_framework.authentication.BasicAuthentication', ), 'DEFAULT_PARSER_CLASSES': [ - 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', - 'rest_framework.authentication.SessionAuthentication', - 'rest_framework.authentication.BasicAuthentication', + 'rest_framework.parsers.FormParser', + 'rest_framework.parsers.MultiPartParser', + 'rest_framework.parsers.JSONParser', ], } @@ -268,11 +270,11 @@ JWT_AUTH = { 'JWT_PAYLOAD_HANDLER': 'lms.utils.custom_jwt_payload_handler', - 'JWT_PAYLOAD_GET_USER_ID_HANDLER': - 'rest_framework_jwt.utils.jwt_get_user_id_from_payload_handler', + 'JWT_PAYLOAD_GET_USERNAME_HANDLER': + 'lms.tools.custom_jwt_get_user_email', 'JWT_RESPONSE_PAYLOAD_HANDLER': - 'rest_framework_jwt.utils.jwt_response_payload_handler', + 'lms.utils.jwt_response_payload_handler', 'JWT_SECRET_KEY': SECRET_KEY, 'JWT_GET_USER_SECRET_KEY': None, @@ -282,7 +284,7 @@ JWT_AUTH = { 'JWT_VERIFY': True, 'JWT_VERIFY_EXPIRATION': True, 'JWT_LEEWAY': 0, - 'JWT_EXPIRATION_DELTA': datetime.timedelta(seconds=300), + 'JWT_EXPIRATION_DELTA': datetime.timedelta(days=1), 'JWT_AUDIENCE': 'Skillbox_Login', 'JWT_ISSUER': 'LMS', diff --git a/lms/tools.py b/lms/tools.py index 51b0807..9021070 100644 --- a/lms/tools.py +++ b/lms/tools.py @@ -28,6 +28,10 @@ def get_empty_list(): return [] +def custom_jwt_get_user_email(payload): + return payload.get('email') + + EXAMPLE_BASE64 = "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAQAAAAEACAYAAABccqhmAAANHUlEQVR42u3dXagdd9XH8e8Kh1A" \ "OIYRSQwhFDiWmMTeNELQq2ChCk1rbaIO9eNIXNeJNXxSkvlRaLNQoemGqXmgs1BeQSqux0Scq0saCNpRSWiv1mJRykBJC6EUII" \ "bbHw1le7BFrq/XkdF7+M/P9QK6SzJ7932v99szsWXsHA5KZK4FLqz9vATYB64HVwCrgPKT/7SXgDHAaOA7MAseAI8CRiJgfyhONA" \ diff --git a/lms/utils.py b/lms/utils.py index c3857fe..9d16680 100644 --- a/lms/utils.py +++ b/lms/utils.py @@ -1,6 +1,14 @@ from datetime import datetime from calendar import timegm + +from django.utils.encoding import smart_text +from django.utils.translation import ugettext as _ +from rest_framework.authentication import get_authorization_header +from rest_framework_jwt.authentication import BaseJSONWebTokenAuthentication from rest_framework_jwt.settings import api_settings +from rest_framework import exceptions + +from access.serializers import UserSelfSerializer def custom_jwt_payload_handler(user): @@ -23,3 +31,45 @@ def custom_jwt_payload_handler(user): payload['iss'] = api_settings.JWT_ISSUER return payload + + +class JSONWebTokenAuthentication(BaseJSONWebTokenAuthentication): + """ + Clients should authenticate by passing the token key in the "Authorization" + HTTP header, prepended with the string specified in the setting + `JWT_AUTH_HEADER_PREFIX`. For example: + + Authorization: JWT eyJhbGciOiAiSFMyNTYiLCAidHlwIj + """ + www_authenticate_realm = 'api' + + def get_jwt_value(self, request): + auth = get_authorization_header(request).split() + auth_header_prefix = api_settings.JWT_AUTH_HEADER_PREFIX.lower() + + if auth or auth == []: + if api_settings.JWT_AUTH_COOKIE: + return request.COOKIES.get(api_settings.JWT_AUTH_COOKIE) + return None + + if smart_text(auth[0].lower()) != auth_header_prefix: + return None + + if len(auth) == 1: + msg = _('Invalid Authorization header. No credentials provided.') + raise exceptions.AuthenticationFailed(msg) + elif len(auth) > 2: + msg = _('Invalid Authorization header. Credentials string ' + 'should not contain spaces.') + raise exceptions.AuthenticationFailed(msg) + + return auth[1] + + def authenticate_header(self, request): + return '{0} realm="{1}"'.format(api_settings.JWT_AUTH_HEADER_PREFIX, self.www_authenticate_realm) + + +def jwt_response_payload_handler(token, user=None, request=None): + serialized_user = UserSelfSerializer(user).data + serialized_user['is_i'] = True + return serialized_user