From 19e234d1dc3cfde37e3494faad4fd1ad29973cd3 Mon Sep 17 00:00:00 2001 From: Jon Gregorowicz Date: Mon, 4 Jan 2016 12:45:33 -0500 Subject: [PATCH 1/9] * Added support for REST_USE_JWT * Added JWTSerializer * Added JWT encoding support, based on django-rest-framework-jwt * Tests for JWT authentication --- docs/configuration.rst | 4 +++- rest_auth/app_settings.py | 4 ++++ rest_auth/registration/views.py | 38 +++++++++++++++++++++++++------ rest_auth/serializers.py | 7 +++++- rest_auth/tests/requirements.pip | 1 + rest_auth/tests/settings.py | 11 ++++++++- rest_auth/tests/test_api.py | 30 ++++++++++++++++++++++++ rest_auth/tests/test_base.py | 5 +++- rest_auth/tests/test_social.py | 26 +++++++++++++++++++++ rest_auth/utils.py | 12 ++++++++++ rest_auth/views.py | 39 ++++++++++++++++++++++++-------- 11 files changed, 157 insertions(+), 20 deletions(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index 282f326..040c1cf 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -29,10 +29,12 @@ Configuration ... } - - **REST_SESSION_LOGIN** - Enable session login in Login API view (default: True) - **OLD_PASSWORD_FIELD_ENABLED** - set it to True if you want to have old password verification on password change enpoint (default: False) - **LOGOUT_ON_PASSWORD_CHANGE** - set to False if you want to keep the current user logged in after a password change + +- **REST_USE_JWT** - If enabled, this will use `django-rest-framework-jwt ` as a backend, and instead of session based tokens or Social Login keys, it will return a JWT. + diff --git a/rest_auth/app_settings.py b/rest_auth/app_settings.py index e0340b7..b52064f 100644 --- a/rest_auth/app_settings.py +++ b/rest_auth/app_settings.py @@ -2,6 +2,7 @@ from django.conf import settings from rest_auth.serializers import ( TokenSerializer as DefaultTokenSerializer, + JWTSerializer as DefaultJWTSerializer, UserDetailsSerializer as DefaultUserDetailsSerializer, LoginSerializer as DefaultLoginSerializer, PasswordResetSerializer as DefaultPasswordResetSerializer, @@ -15,6 +16,9 @@ serializers = getattr(settings, 'REST_AUTH_SERIALIZERS', {}) TokenSerializer = import_callable( serializers.get('TOKEN_SERIALIZER', DefaultTokenSerializer)) +JWTSerializer = import_callable( + serializers.get('JWT_SERIALIZER', DefaultJWTSerializer)) + UserDetailsSerializer = import_callable( serializers.get('USER_DETAILS_SERIALIZER', DefaultUserDetailsSerializer) ) diff --git a/rest_auth/registration/views.py b/rest_auth/registration/views.py index e700706..ce68a86 100644 --- a/rest_auth/registration/views.py +++ b/rest_auth/registration/views.py @@ -1,4 +1,6 @@ from django.http import HttpRequest +from django.conf import settings + from rest_framework.views import APIView from rest_framework.response import Response from rest_framework.permissions import AllowAny @@ -13,6 +15,8 @@ from rest_auth.app_settings import TokenSerializer from rest_auth.registration.serializers import SocialLoginSerializer from rest_auth.views import LoginView +from rest_auth.utils import jwt_encode + class RegisterView(APIView, SignupView): """ @@ -28,7 +32,12 @@ class RegisterView(APIView, SignupView): permission_classes = (AllowAny,) allowed_methods = ('POST', 'OPTIONS', 'HEAD') token_model = Token - serializer_class = TokenSerializer + + def get_serializer_class(self): + if getattr(settings, 'REST_USE_JWT', False): + return JWTSerializer + else: + return TokenSerializer def get(self, *args, **kwargs): return Response({}, status=status.HTTP_405_METHOD_NOT_ALLOWED) @@ -38,9 +47,14 @@ class RegisterView(APIView, SignupView): def form_valid(self, form): self.user = form.save(self.request) - self.token, created = self.token_model.objects.get_or_create( - user=self.user - ) + + if getattr(settings, 'REST_USE_JWT', False): + self.token = jwt_encode(self.user) + + else: + self.token, created = self.token_model.objects.get_or_create( + user=self.user + ) if isinstance(self.request, HttpRequest): request = self.request else: @@ -65,9 +79,19 @@ class RegisterView(APIView, SignupView): return self.get_response_with_errors() def get_response(self): - # serializer = self.user_serializer_class(instance=self.user) - serializer = self.serializer_class(instance=self.token, - context={'request': self.request}) + serializer_class = self.get_serializer_class() + + if getattr(settings, 'REST_USE_JWT', False): + data = { + 'user': self.user, + 'token': self.token + } + serializer = serializer_class(instance=data, + context={'request': self.request}) + else: + serializer = serializer_class(instance=self.token, + context={'request': self.request}) + return Response(serializer.data, status=status.HTTP_201_CREATED) def get_response_with_errors(self): diff --git a/rest_auth/serializers.py b/rest_auth/serializers.py index a2d1a82..1145826 100644 --- a/rest_auth/serializers.py +++ b/rest_auth/serializers.py @@ -87,7 +87,6 @@ class TokenSerializer(serializers.ModelSerializer): model = Token fields = ('key',) - class UserDetailsSerializer(serializers.ModelSerializer): """ @@ -98,6 +97,12 @@ class UserDetailsSerializer(serializers.ModelSerializer): fields = ('username', 'email', 'first_name', 'last_name') read_only_fields = ('email', ) +class JWTSerializer(serializers.Serializer): + """ + Serializer for JWT authentication. + """ + token = serializers.CharField() + user = UserDetailsSerializer() class PasswordResetSerializer(serializers.Serializer): diff --git a/rest_auth/tests/requirements.pip b/rest_auth/tests/requirements.pip index bb8d844..4040970 100644 --- a/rest_auth/tests/requirements.pip +++ b/rest_auth/tests/requirements.pip @@ -1,3 +1,4 @@ django-allauth>=0.19.1 responses>=0.3.0 flake8==2.4.0 +djangorestframework-jwt>=1.7.2 \ No newline at end of file diff --git a/rest_auth/tests/settings.py b/rest_auth/tests/settings.py index b09b496..aab38d3 100644 --- a/rest_auth/tests/settings.py +++ b/rest_auth/tests/settings.py @@ -45,6 +45,13 @@ TEMPLATE_CONTEXT_PROCESSORS = [ "allauth.socialaccount.context_processors.socialaccount", ] +REST_FRAMEWORK = { + 'DEFAULT_AUTHENTICATION_CLASSES': ( + 'rest_framework.authentication.SessionAuthentication', + 'rest_framework_jwt.authentication.JSONWebTokenAuthentication', + ) +} + INSTALLED_APPS = [ 'django.contrib.admin', 'django.contrib.auth', @@ -64,7 +71,9 @@ INSTALLED_APPS = [ 'rest_framework.authtoken', 'rest_auth', - 'rest_auth.registration' + 'rest_auth.registration', + + 'rest_framework_jwt' ] SECRET_KEY = "38dh*skf8sjfhs287dh&^hd8&3hdg*j2&sd" diff --git a/rest_auth/tests/test_api.py b/rest_auth/tests/test_api.py index b64cf8c..3f844f9 100644 --- a/rest_auth/tests/test_api.py +++ b/rest_auth/tests/test_api.py @@ -90,6 +90,19 @@ class APITestCase1(TestCase, BaseAPITestCase): # test empty payload self.post(self.login_url, data={}, status_code=400) + @override_settings(REST_USE_JWT=True) + def test_login_jwt(self): + payload = { + "username": self.USERNAME, + "password": self.PASS + } + # no users in db so it should throw an error + user = get_user_model().objects.create_user(self.USERNAME, '', self.PASS) + self.post(self.login_url, data=payload, status_code=200) + self.assertEqual('user' in self.response.json.keys(), True) + self.assertEqual('token' in self.response.json.keys(), True) + + def test_password_change(self): login_payload = { "username": self.USERNAME, @@ -258,6 +271,23 @@ class APITestCase1(TestCase, BaseAPITestCase): self.assertEqual(user.last_name, self.response.json['last_name']) self.assertEqual(user.email, self.response.json['email']) + @override_settings(REST_USE_JWT=True) + def test_user_details_jwt(self): + user = get_user_model().objects.create_user(self.USERNAME, self.EMAIL, self.PASS) + payload = { + 'username': self.USERNAME, + 'password': self.PASS + } + self.post(self.login_url, data=payload, status_code=200) + self.token = self.response.json['token'] + self.get(self.user_url, status_code=200) + + self.patch(self.user_url, data=self.BASIC_USER_DATA, status_code=200) + user = get_user_model().objects.get(pk=user.pk) + self.assertEqual(user.first_name, self.response.json['first_name']) + self.assertEqual(user.last_name, self.response.json['last_name']) + self.assertEqual(user.email, self.response.json['email']) + def test_registration(self): user_count = get_user_model().objects.all().count() diff --git a/rest_auth/tests/test_base.py b/rest_auth/tests/test_base.py index ed8ffeb..97dfa31 100644 --- a/rest_auth/tests/test_base.py +++ b/rest_auth/tests/test_base.py @@ -37,7 +37,10 @@ class BaseAPITestCase(object): # check_headers = kwargs.pop('check_headers', True) if hasattr(self, 'token'): - kwargs['HTTP_AUTHORIZATION'] = 'Token %s' % self.token + if getattr(settings, 'REST_USE_JWT', False): + kwargs['HTTP_AUTHORIZATION'] = 'JWT %s' % self.token + else: + kwargs['HTTP_AUTHORIZATION'] = 'Token %s' % self.token self.response = request_func(*args, **kwargs) is_json = bool( diff --git a/rest_auth/tests/test_social.py b/rest_auth/tests/test_social.py index 0bb10f5..ad43b7d 100644 --- a/rest_auth/tests/test_social.py +++ b/rest_auth/tests/test_social.py @@ -126,3 +126,29 @@ class TestSocialAuth(TestCase, BaseAPITestCase): self.post(self.fb_login_url, data=payload, status_code=200) self.assertIn('key', self.response.json.keys()) + + @responses.activate + @override_settings( + REST_USE_JWT=True + ) + def test_jwt(self): + resp_body = '{"id":"123123123123","first_name":"John","gender":"male","last_name":"Smith","link":"https:\\/\\/www.facebook.com\\/john.smith","locale":"en_US","name":"John Smith","timezone":2,"updated_time":"2014-08-13T10:14:38+0000","username":"john.smith","verified":true}' # noqa + responses.add( + responses.GET, + self.graph_api_url, + body=resp_body, + status=200, + content_type='application/json' + ) + + users_count = get_user_model().objects.all().count() + payload = { + 'access_token': 'abc123' + } + + self.post(self.fb_login_url, data=payload, status_code=200) + self.assertIn('token', self.response.json.keys()) + self.assertIn('user', self.response.json.keys()) + + self.assertEqual(get_user_model().objects.all().count(), users_count + 1) + diff --git a/rest_auth/utils.py b/rest_auth/utils.py index a32da60..8b6e8c1 100644 --- a/rest_auth/utils.py +++ b/rest_auth/utils.py @@ -9,3 +9,15 @@ def import_callable(path_or_callable): assert isinstance(path_or_callable, string_types) package, attr = path_or_callable.rsplit('.', 1) return getattr(import_module(package), attr) + +def jwt_encode(user): + try: + from rest_framework_jwt.settings import api_settings + except ImportError: + raise ImportError('rest_framework_jwt needs to be installed') + + jwt_payload_handler = api_settings.JWT_PAYLOAD_HANDLER + jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER + + payload = jwt_payload_handler(user) + return jwt_encode_handler(payload) diff --git a/rest_auth/views.py b/rest_auth/views.py index 3af1557..16c6439 100644 --- a/rest_auth/views.py +++ b/rest_auth/views.py @@ -13,9 +13,11 @@ from rest_framework.generics import RetrieveUpdateAPIView from .app_settings import ( TokenSerializer, UserDetailsSerializer, LoginSerializer, PasswordResetSerializer, PasswordResetConfirmSerializer, - PasswordChangeSerializer + PasswordChangeSerializer, JWTSerializer ) +from .utils import jwt_encode + class LoginView(GenericAPIView): @@ -31,19 +33,38 @@ class LoginView(GenericAPIView): permission_classes = (AllowAny,) serializer_class = LoginSerializer token_model = Token - response_serializer = TokenSerializer + + def get_response_serializer(self): + if getattr(settings, 'REST_USE_JWT', False): + response_serializer = JWTSerializer + else: + response_serializer = TokenSerializer + return response_serializer def login(self): self.user = self.serializer.validated_data['user'] - self.token, created = self.token_model.objects.get_or_create( - user=self.user) - if getattr(settings, 'REST_SESSION_LOGIN', True): - login(self.request, self.user) + + if getattr(settings, 'REST_USE_JWT', False): + self.token = jwt_encode(self.user) + else: + self.token, created = self.token_model.objects.get_or_create( + user=self.user) + if getattr(settings, 'REST_SESSION_LOGIN', True): + login(self.request, self.user) def get_response(self): - return Response( - self.response_serializer(self.token).data, status=status.HTTP_200_OK - ) + serializer_class = self.get_response_serializer() + + if getattr(settings, 'REST_USE_JWT', False): + data = { + 'user': self.user, + 'token': self.token + } + serializer = serializer_class(instance=data) + else: + serializer = serializer_class(instance=self.token) + + return Response(serializer.data, status=status.HTTP_200_OK) def post(self, request, *args, **kwargs): self.serializer = self.get_serializer(data=self.request.data) From 317db1b811d633699ebe3006221b417a1b072e7a Mon Sep 17 00:00:00 2001 From: Jon Gregorowicz Date: Mon, 4 Jan 2016 13:57:38 -0500 Subject: [PATCH 2/9] Bump version --- docs/changelog.rst | 4 ++++ setup.py | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index 735b936..41e982d 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -1,6 +1,10 @@ Changelog ========= +0.7.0 +----- +- added support for django-rest-framework-jwt + 0.6.0 ----- - dropped support for Python 2.6 diff --git a/setup.py b/setup.py index 6b61e1c..bb83cde 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ f.close() setup( name='django-rest-auth', - version='0.6.0', + version='0.7.0', author='Sumit Chachra', author_email='chachra@tivix.com', url='http://github.com/Tivix/django-rest-auth', From e3a1ba520ed316c87c7cfb6055e4a61b750cd09f Mon Sep 17 00:00:00 2001 From: Jon Gregorowicz Date: Tue, 16 Feb 2016 00:42:18 -0500 Subject: [PATCH 3/9] Added tests for JWT, fixed merge issues --- docs/configuration.rst | 4 +++ docs/installation.rst | 15 ++++++++++++ rest_auth/registration/views.py | 15 ++++++++++-- rest_auth/tests/test_api.py | 43 +++++++++++++++++++++++++++++++++ rest_auth/views.py | 16 ++++++------ 5 files changed, 82 insertions(+), 11 deletions(-) diff --git a/docs/configuration.rst b/docs/configuration.rst index 3746234..d726a99 100644 --- a/docs/configuration.rst +++ b/docs/configuration.rst @@ -10,6 +10,8 @@ Configuration - TOKEN_SERIALIZER - response for successful authentication in ``rest_auth.views.LoginView``, default value ``rest_auth.serializers.TokenSerializer`` + - JWT_SERIALIZER - (Using REST_USE_JWT=True) response for successful authentication in ``rest_auth.views.LoginView``, default value ``rest_auth.serializers.JWTSerializer`` + - USER_DETAILS_SERIALIZER - serializer class in ``rest_auth.views.UserDetailsView``, default value ``rest_auth.serializers.UserDetailsSerializer`` - PASSWORD_RESET_SERIALIZER - serializer class in ``rest_auth.views.PasswordResetView``, default value ``rest_auth.serializers.PasswordResetSerializer`` @@ -42,6 +44,8 @@ Configuration - **REST_SESSION_LOGIN** - Enable session login in Login API view (default: True) +- **REST_USE_JWT** - Enable JWT Authentication instead of Token/Session based. This is built on top of django-rest-framework-jwt http://getblimp.github.io/django-rest-framework-jwt/ , which much also be installed. (default: False) + - **OLD_PASSWORD_FIELD_ENABLED** - set it to True if you want to have old password verification on password change enpoint (default: False) - **LOGOUT_ON_PASSWORD_CHANGE** - set to False if you want to keep the current user logged in after a password change diff --git a/docs/installation.rst b/docs/installation.rst index 92251dc..1118826 100644 --- a/docs/installation.rst +++ b/docs/installation.rst @@ -109,3 +109,18 @@ Using ``django-allauth``, ``django-rest-auth`` provides helpful class for creati ) .. note:: Starting from v0.21.0, django-allauth has dropped support for context processors. Check out http://django-allauth.readthedocs.org/en/latest/changelog.html#from-0-21-0 for more details. + + +JWT Support (optional) +---------------------- + +By default, ``django-rest-auth`` uses Django's Token-based authentication. If you want to use JWT authentication, you need to install the following: + +1. Install ``django-rest-framework-jwt`` http://getblimp.github.io/django-rest-framework-jwt/ . Right now this is the only supported JWT library. + +2. Add the following to your settings + +.. code-block:: python + + REST_USE_JWT = True + diff --git a/rest_auth/registration/views.py b/rest_auth/registration/views.py index dc96a50..30a79bb 100644 --- a/rest_auth/registration/views.py +++ b/rest_auth/registration/views.py @@ -12,6 +12,7 @@ from allauth.account.utils import complete_signup from allauth.account import app_settings as allauth_settings from rest_auth.app_settings import (TokenSerializer, + JWTSerializer, create_token) from rest_auth.registration.serializers import (SocialLoginSerializer, VerifyEmailSerializer) @@ -31,7 +32,14 @@ class RegisterView(CreateAPIView): allauth_settings.EmailVerificationMethod.MANDATORY: return {} - return TokenSerializer(user.auth_token).data + if getattr(settings, 'REST_USE_JWT', False): + data = { + 'user': user, + 'token': self.token + } + return JWTSerializer(data).data + else: + return TokenSerializer(user.auth_token).data def create(self, request, *args, **kwargs): serializer = self.get_serializer(data=request.data) @@ -43,7 +51,10 @@ class RegisterView(CreateAPIView): def perform_create(self, serializer): user = serializer.save(self.request) - create_token(self.token_model, user, serializer) + if getattr(settings, 'REST_USE_JWT', False): + self.token = jwt_encode(user) + else: + create_token(self.token_model, user, serializer) complete_signup(self.request._request, user, allauth_settings.EMAIL_VERIFICATION, None) diff --git a/rest_auth/tests/test_api.py b/rest_auth/tests/test_api.py index f6cc839..9903c9d 100644 --- a/rest_auth/tests/test_api.py +++ b/rest_auth/tests/test_api.py @@ -91,6 +91,19 @@ class APITestCase1(TestCase, BaseAPITestCase): # test empty payload self.post(self.login_url, data={}, status_code=400) + @override_settings(REST_USE_JWT=True) + def test_login_jwt(self): + payload = { + "username": self.USERNAME, + "password": self.PASS + } + user = get_user_model().objects.create_user(self.USERNAME, '', self.PASS) + + self.post(self.login_url, data=payload, status_code=200) + self.assertEqual('token' in self.response.json.keys(), True) + self.token = self.response.json['token'] + + def test_login_by_email(self): # starting test without allauth app settings.INSTALLED_APPS.remove('allauth') @@ -307,6 +320,22 @@ class APITestCase1(TestCase, BaseAPITestCase): self.assertEqual(user.last_name, self.response.json['last_name']) self.assertEqual(user.email, self.response.json['email']) + @override_settings(REST_USE_JWT=True) + def test_user_details_using_jwt(self): + user = get_user_model().objects.create_user(self.USERNAME, self.EMAIL, self.PASS) + payload = { + "username": self.USERNAME, + "password": self.PASS + } + self.post(self.login_url, data=payload, status_code=200) + self.token = self.response.json['token'] + self.get(self.user_url, status_code=200) + + self.patch(self.user_url, data=self.BASIC_USER_DATA, status_code=200) + user = get_user_model().objects.get(pk=user.pk) + self.assertEqual(user.email, self.response.json['email']) + + def test_registration(self): user_count = get_user_model().objects.all().count() @@ -323,6 +352,20 @@ class APITestCase1(TestCase, BaseAPITestCase): self._login() self._logout() + @override_settings(REST_USE_JWT=True) + def test_registration_with_jwt(self): + user_count = get_user_model().objects.all().count() + + self.post(self.register_url, data={}, status_code=400) + + result = self.post(self.register_url, data=self.REGISTRATION_DATA, status_code=201) + self.assertIn('token', result.data) + self.assertEqual(get_user_model().objects.all().count(), user_count + 1) + + self._login() + self._logout() + + def test_registration_with_invalid_password(self): data = self.REGISTRATION_DATA.copy() data['password2'] = 'foobar' diff --git a/rest_auth/views.py b/rest_auth/views.py index 331642c..f1aa6a7 100644 --- a/rest_auth/views.py +++ b/rest_auth/views.py @@ -12,7 +12,7 @@ from rest_framework.generics import RetrieveUpdateAPIView from .app_settings import ( TokenSerializer, UserDetailsSerializer, LoginSerializer, PasswordResetSerializer, PasswordResetConfirmSerializer, - PasswordChangeSerializer, create_token + PasswordChangeSerializer, JWTSerializer, create_token ) from .models import TokenModel @@ -43,17 +43,15 @@ class LoginView(GenericAPIView): def login(self): self.user = self.serializer.validated_data['user'] - self.token = create_token(self.token_model, self.user, self.serializer) - if getattr(settings, 'REST_SESSION_LOGIN', True): - login(self.request, self.user) - + if getattr(settings, 'REST_USE_JWT', False): self.token = jwt_encode(self.user) else: - self.token, created = self.token_model.objects.get_or_create( - user=self.user) - if getattr(settings, 'REST_SESSION_LOGIN', True): - login(self.request, self.user) + self.token = create_token(self.token_model, self.user, self.serializer) + + if getattr(settings, 'REST_SESSION_LOGIN', True): + login(self.request, self.user) + def get_response(self): serializer_class = self.get_response_serializer() From 8b5e5173d0a2d881101d82f56997398da23c86ab Mon Sep 17 00:00:00 2001 From: Jon Gregorowicz Date: Tue, 16 Feb 2016 00:43:19 -0500 Subject: [PATCH 4/9] Added newline to pip file --- rest_auth/tests/requirements.pip | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/rest_auth/tests/requirements.pip b/rest_auth/tests/requirements.pip index 4040970..de66892 100644 --- a/rest_auth/tests/requirements.pip +++ b/rest_auth/tests/requirements.pip @@ -1,4 +1,4 @@ django-allauth>=0.19.1 responses>=0.3.0 flake8==2.4.0 -djangorestframework-jwt>=1.7.2 \ No newline at end of file +djangorestframework-jwt>=1.7.2 From 511329c30a768a47d016154732dc5aac5c64273f Mon Sep 17 00:00:00 2001 From: Jon Gregorowicz Date: Tue, 16 Feb 2016 00:49:41 -0500 Subject: [PATCH 5/9] Fixing merge tool induced file endings --- rest_auth/registration/views.py | 2 +- rest_auth/utils.py | 2 +- rest_auth/views.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/rest_auth/registration/views.py b/rest_auth/registration/views.py index 30a79bb..2689ec2 100644 --- a/rest_auth/registration/views.py +++ b/rest_auth/registration/views.py @@ -102,4 +102,4 @@ class SocialLoginView(LoginView): ------------- """ - serializer_class = SocialLoginSerializer \ No newline at end of file + serializer_class = SocialLoginSerializer diff --git a/rest_auth/utils.py b/rest_auth/utils.py index 13df03e..5cb94d7 100644 --- a/rest_auth/utils.py +++ b/rest_auth/utils.py @@ -25,4 +25,4 @@ def jwt_encode(user): jwt_encode_handler = api_settings.JWT_ENCODE_HANDLER payload = jwt_payload_handler(user) - return jwt_encode_handler(payload) \ No newline at end of file + return jwt_encode_handler(payload) diff --git a/rest_auth/views.py b/rest_auth/views.py index f1aa6a7..5951a93 100644 --- a/rest_auth/views.py +++ b/rest_auth/views.py @@ -175,4 +175,4 @@ class PasswordChangeView(GenericAPIView): serializer = self.get_serializer(data=request.data) serializer.is_valid(raise_exception=True) serializer.save() - return Response({"success": "New password has been saved."}) \ No newline at end of file + return Response({"success": "New password has been saved."}) From b4c122ee5da818ea2cc2874be6cbf5e343024a5d Mon Sep 17 00:00:00 2001 From: Jon Gregorowicz Date: Mon, 29 Feb 2016 07:47:47 -0500 Subject: [PATCH 6/9] Bump --- setup.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/setup.py b/setup.py index 49deb9a..9b33b7f 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,7 @@ f.close() setup( name='django-rest-auth', - version='0.7.0', + version='0.8.0', author='Sumit Chachra', author_email='chachra@tivix.com', url='http://github.com/Tivix/django-rest-auth', From 1eb4b45e509810f2cbeefffbdb5105da5f9a636c Mon Sep 17 00:00:00 2001 From: Jon Gregorowicz Date: Mon, 29 Feb 2016 07:57:54 -0500 Subject: [PATCH 7/9] Fixing tests --- rest_auth/registration/views.py | 1 + 1 file changed, 1 insertion(+) diff --git a/rest_auth/registration/views.py b/rest_auth/registration/views.py index 40316dd..2862c60 100644 --- a/rest_auth/registration/views.py +++ b/rest_auth/registration/views.py @@ -1,4 +1,5 @@ from django.utils.translation import ugettext_lazy as _ +from django.conf import settings from rest_framework.views import APIView from rest_framework.response import Response From 4ba9841bc5700f5874eaa49b21f1bceed195a03d Mon Sep 17 00:00:00 2001 From: Jon Gregorowicz Date: Mon, 29 Feb 2016 08:01:39 -0500 Subject: [PATCH 8/9] Merge changes --- docs/changelog.rst | 2 +- rest_auth/registration/views.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/changelog.rst b/docs/changelog.rst index d1f64a3..043a943 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -4,6 +4,7 @@ Changelog 0.8.0 ----- - added support for django-rest-framework-jwt + 0.7.0 ----- - Wrapped API returned strings in ugettext_lazy @@ -67,4 +68,3 @@ Changelog - changed password reset confim url - uid and token should be sent in POST - increase test coverage - made compatibile with django 1.7 -- removed user profile support \ No newline at end of file diff --git a/rest_auth/registration/views.py b/rest_auth/registration/views.py index 2862c60..d1d8d37 100644 --- a/rest_auth/registration/views.py +++ b/rest_auth/registration/views.py @@ -103,4 +103,4 @@ class SocialLoginView(LoginView): ------------- """ - serializer_class = SocialLoginSerializer \ No newline at end of file + serializer_class = SocialLoginSerializer From 9baeb2883b10131852738084a38a07f046885e08 Mon Sep 17 00:00:00 2001 From: Jon Gregorowicz Date: Mon, 29 Feb 2016 08:02:50 -0500 Subject: [PATCH 9/9] Docs comment --- docs/changelog.rst | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/changelog.rst b/docs/changelog.rst index 043a943..a24d7f5 100644 --- a/docs/changelog.rst +++ b/docs/changelog.rst @@ -68,3 +68,4 @@ Changelog - changed password reset confim url - uid and token should be sent in POST - increase test coverage - made compatibile with django 1.7 +- removed user profile support