diff --git a/rest_auth/serializers.py b/rest_auth/serializers.py index a2d1a82..5bf1ac2 100644 --- a/rest_auth/serializers.py +++ b/rest_auth/serializers.py @@ -50,11 +50,18 @@ class LoginSerializer(serializers.Serializer): msg = _('Must include either "username" or "email" and "password".') raise exceptions.ValidationError(msg) - elif username and password: - user = authenticate(username=username, password=password) + elif username or email and password: + # Try get username if we have in request email + if email and not username: + try: + username = UserModel.objects.get(email__iexact=email).username + except UserModel.DoesNotExist: + user = None + if username: + user = authenticate(username=username, password=password) else: - msg = _('Must include "username" and "password".') + msg = _('Must include either "username" or "email" and "password".') raise exceptions.ValidationError(msg) # Did we get back an active user? diff --git a/rest_auth/tests/test_api.py b/rest_auth/tests/test_api.py index bb15e01..0cf55a2 100644 --- a/rest_auth/tests/test_api.py +++ b/rest_auth/tests/test_api.py @@ -2,6 +2,7 @@ from django.core.urlresolvers import reverse from django.test import TestCase from django.contrib.auth import get_user_model from django.core import mail +from django.conf import settings from django.test.utils import override_settings from django.utils.encoding import force_text @@ -90,6 +91,51 @@ class APITestCase1(TestCase, BaseAPITestCase): # test empty payload self.post(self.login_url, data={}, status_code=400) + def test_login_by_email(self): + # starting test without allauth app + settings.INSTALLED_APPS.remove('allauth') + + payload = { + "email": self.EMAIL.lower(), + "password": self.PASS + } + # there is no users in db so it should throw error (400) + self.post(self.login_url, data=payload, status_code=400) + + self.post(self.password_change_url, status_code=403) + + # create user + user = get_user_model().objects.create_user(self.USERNAME, self.EMAIL, self.PASS) + + # test auth by email + self.post(self.login_url, data=payload, status_code=200) + self.assertEqual('key' in self.response.json.keys(), True) + self.token = self.response.json['key'] + + # test auth by email in different case + payload = { + "email": self.EMAIL.upper(), + "password": self.PASS + } + self.post(self.login_url, data=payload, status_code=200) + self.assertEqual('key' in self.response.json.keys(), True) + self.token = self.response.json['key'] + + # test inactive user + user.is_active = False + user.save() + self.post(self.login_url, data=payload, status_code=400) + + # test wrong email/password + payload = { + "email": 't' + self.EMAIL, + "password": self.PASS + } + self.post(self.login_url, data=payload, status_code=400) + + # test empty payload + self.post(self.login_url, data={}, status_code=400) + def test_password_change(self): login_payload = { "username": self.USERNAME,