mirror of
				https://github.com/Tivix/django-rest-auth.git
				synced 2025-10-31 07:47:33 +03:00 
			
		
		
		
	Merge pull request #150 from Tivix/pr/141
Ability to login using e-mail (without allauth)
This commit is contained in:
		
						commit
						d63232224e
					
				|  | @ -7,6 +7,7 @@ Basic | ||||||
| - /rest-auth/login/ (POST) | - /rest-auth/login/ (POST) | ||||||
| 
 | 
 | ||||||
|     - username (string) |     - username (string) | ||||||
|  |     - email (string) | ||||||
|     - password (string) |     - password (string) | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
|  | @ -19,29 +19,31 @@ class LoginSerializer(serializers.Serializer): | ||||||
|     email = serializers.EmailField(required=False, allow_blank=True) |     email = serializers.EmailField(required=False, allow_blank=True) | ||||||
|     password = serializers.CharField(style={'input_type': 'password'}) |     password = serializers.CharField(style={'input_type': 'password'}) | ||||||
| 
 | 
 | ||||||
|     def validate(self, attrs): |     def _validate_email(self, email, password): | ||||||
|         username = attrs.get('username') |         user = None | ||||||
|         email = attrs.get('email') |  | ||||||
|         password = attrs.get('password') |  | ||||||
| 
 | 
 | ||||||
|         if 'allauth' in settings.INSTALLED_APPS: |  | ||||||
|             from allauth.account import app_settings |  | ||||||
|             # Authentication through email |  | ||||||
|             if app_settings.AUTHENTICATION_METHOD == app_settings.AuthenticationMethod.EMAIL: |  | ||||||
|         if email and password: |         if email and password: | ||||||
|             user = authenticate(email=email, password=password) |             user = authenticate(email=email, password=password) | ||||||
|         else: |         else: | ||||||
|             msg = _('Must include "email" and "password".') |             msg = _('Must include "email" and "password".') | ||||||
|             raise exceptions.ValidationError(msg) |             raise exceptions.ValidationError(msg) | ||||||
|             # Authentication through username | 
 | ||||||
|             elif app_settings.AUTHENTICATION_METHOD == app_settings.AuthenticationMethod.USERNAME: |         return user | ||||||
|  | 
 | ||||||
|  |     def _validate_username(self, username, password): | ||||||
|  |         user = None | ||||||
|  | 
 | ||||||
|         if username and password: |         if username and password: | ||||||
|             user = authenticate(username=username, password=password) |             user = authenticate(username=username, password=password) | ||||||
|         else: |         else: | ||||||
|             msg = _('Must include "username" and "password".') |             msg = _('Must include "username" and "password".') | ||||||
|             raise exceptions.ValidationError(msg) |             raise exceptions.ValidationError(msg) | ||||||
|             # Authentication through either username or email | 
 | ||||||
|             else: |         return user | ||||||
|  | 
 | ||||||
|  |     def _validate_username_email(self, username, email, password): | ||||||
|  |         user = None | ||||||
|  | 
 | ||||||
|         if email and password: |         if email and password: | ||||||
|             user = authenticate(email=email, password=password) |             user = authenticate(email=email, password=password) | ||||||
|         elif username and password: |         elif username and password: | ||||||
|  | @ -50,12 +52,40 @@ class LoginSerializer(serializers.Serializer): | ||||||
|             msg = _('Must include either "username" or "email" and "password".') |             msg = _('Must include either "username" or "email" and "password".') | ||||||
|             raise exceptions.ValidationError(msg) |             raise exceptions.ValidationError(msg) | ||||||
| 
 | 
 | ||||||
|         elif username and password: |         return user | ||||||
|             user = authenticate(username=username, password=password) | 
 | ||||||
|  |     def validate(self, attrs): | ||||||
|  |         username = attrs.get('username') | ||||||
|  |         email = attrs.get('email') | ||||||
|  |         password = attrs.get('password') | ||||||
|  | 
 | ||||||
|  |         user = None | ||||||
|  | 
 | ||||||
|  |         if 'allauth' in settings.INSTALLED_APPS: | ||||||
|  |             from allauth.account import app_settings | ||||||
|  | 
 | ||||||
|  |             # Authentication through email | ||||||
|  |             if app_settings.AUTHENTICATION_METHOD == app_settings.AuthenticationMethod.EMAIL: | ||||||
|  |                 user = self._validate_email(email, password) | ||||||
|  | 
 | ||||||
|  |             # Authentication through username | ||||||
|  |             if app_settings.AUTHENTICATION_METHOD == app_settings.AuthenticationMethod.USERNAME: | ||||||
|  |                 user = self._validate_username(username, password) | ||||||
|  | 
 | ||||||
|  |             # Authentication through either username or email | ||||||
|  |             else: | ||||||
|  |                 user = self._validate_username_email(username, email, password) | ||||||
| 
 | 
 | ||||||
|         else: |         else: | ||||||
|             msg = _('Must include "username" and "password".') |             # Authentication without using allauth | ||||||
|             raise exceptions.ValidationError(msg) |             if email: | ||||||
|  |                 try: | ||||||
|  |                     username = UserModel.objects.get(email__iexact=email).username | ||||||
|  |                 except UserModel.DoesNotExist: | ||||||
|  |                     pass | ||||||
|  | 
 | ||||||
|  |             if username: | ||||||
|  |                 user = self._validate_username_email(username, '', password) | ||||||
| 
 | 
 | ||||||
|         # Did we get back an active user? |         # Did we get back an active user? | ||||||
|         if user: |         if user: | ||||||
|  |  | ||||||
|  | @ -2,6 +2,7 @@ from django.core.urlresolvers import reverse | ||||||
| from django.test import TestCase | from django.test import TestCase | ||||||
| from django.contrib.auth import get_user_model | from django.contrib.auth import get_user_model | ||||||
| from django.core import mail | from django.core import mail | ||||||
|  | from django.conf import settings | ||||||
| from django.test.utils import override_settings | from django.test.utils import override_settings | ||||||
| from django.utils.encoding import force_text | from django.utils.encoding import force_text | ||||||
| 
 | 
 | ||||||
|  | @ -90,6 +91,51 @@ class APITestCase1(TestCase, BaseAPITestCase): | ||||||
|         # test empty payload |         # test empty payload | ||||||
|         self.post(self.login_url, data={}, status_code=400) |         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): |     def test_password_change(self): | ||||||
|         login_payload = { |         login_payload = { | ||||||
|             "username": self.USERNAME, |             "username": self.USERNAME, | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue
	
	Block a user