diff --git a/rest_auth/registration/serializers.py b/rest_auth/registration/serializers.py index c6b5d5b..50f1f99 100644 --- a/rest_auth/registration/serializers.py +++ b/rest_auth/registration/serializers.py @@ -18,7 +18,6 @@ from requests.exceptions import HTTPError if 'allauth.socialaccount' in settings.INSTALLED_APPS: from allauth.socialaccount.helpers import complete_social_login - class SocialLoginSerializer(serializers.Serializer): access_token = serializers.CharField(required=False, allow_blank=True) code = serializers.CharField(required=False, allow_blank=True) @@ -40,7 +39,8 @@ class SocialLoginSerializer(serializers.Serializer): `allauth.socialaccount.SocialLoginView` instance """ request = self._get_request() - social_login = adapter.complete_login(request, app, token, response=response) + social_login = adapter.complete_login( + request, app, token, response=response) social_login.token = token return social_login diff --git a/rest_auth/registration/urls.py b/rest_auth/registration/urls.py index 1004695..9f9371a 100644 --- a/rest_auth/registration/urls.py +++ b/rest_auth/registration/urls.py @@ -5,7 +5,8 @@ from .views import RegisterView, VerifyEmailView urlpatterns = [ url(r'^$', RegisterView.as_view(), name='rest_register'), - url(r'^verify-email/$', VerifyEmailView.as_view(), name='rest_verify_email'), + url(r'^verify-email/$', VerifyEmailView.as_view(), + name='rest_verify_email'), # This url is used by django-allauth and empty TemplateView is # defined just to allow reverse() call inside app, for example when email diff --git a/rest_auth/registration/views.py b/rest_auth/registration/views.py index d6638b6..fda9c1e 100644 --- a/rest_auth/registration/views.py +++ b/rest_auth/registration/views.py @@ -92,6 +92,7 @@ class VerifyEmailView(APIView, ConfirmEmailView): class SocialLoginView(LoginView): + """ class used for social authentications example usage for facebook with access_token diff --git a/rest_auth/serializers.py b/rest_auth/serializers.py index 723cfca..e6b5366 100644 --- a/rest_auth/serializers.py +++ b/rest_auth/serializers.py @@ -1,4 +1,5 @@ from django.contrib.auth import get_user_model, authenticate +from django.core.exceptions import ObjectDoesNotExist from django.conf import settings from django.contrib.auth.forms import PasswordResetForm, SetPasswordForm from django.contrib.auth.tokens import default_token_generator @@ -51,7 +52,8 @@ class LoginSerializer(serializers.Serializer): elif username and password: user = authenticate(username=username, password=password) else: - msg = _('Must include either "username" or "email" and "password".') + msg = _( + 'Must include either "username" or "email" and "password".') raise exceptions.ValidationError(msg) return user @@ -102,7 +104,10 @@ class LoginSerializer(serializers.Serializer): if 'rest_auth.registration' in settings.INSTALLED_APPS: from allauth.account import app_settings if app_settings.EMAIL_VERIFICATION == app_settings.EmailVerificationMethod.MANDATORY: - email_address = user.emailaddress_set.get(email=user.email) + try: + email_address = user.emailaddress_set.get(email=user.email) + except ObjectDoesNotExist: + raise serializers.ValidationError(_('E-mail for this user not created')) if not email_address.verified: raise serializers.ValidationError(_('E-mail is not verified.')) @@ -111,6 +116,7 @@ class LoginSerializer(serializers.Serializer): class TokenSerializer(serializers.ModelSerializer): + """ Serializer for Token model. """ @@ -164,7 +170,8 @@ class PasswordResetSerializer(serializers.Serializer): def validate_email(self, value): # Create PasswordResetForm with the serializer - self.reset_form = self.password_reset_form_class(data=self.initial_data) + self.reset_form = self.password_reset_form_class( + data=self.initial_data) if not self.reset_form.is_valid(): raise serializers.ValidationError(self.reset_form.errors) @@ -184,6 +191,7 @@ class PasswordResetSerializer(serializers.Serializer): class PasswordResetConfirmSerializer(serializers.Serializer): + """ Serializer for requesting a password reset e-mail. """ @@ -205,7 +213,7 @@ class PasswordResetConfirmSerializer(serializers.Serializer): uid = force_text(uid_decoder(attrs['uid'])) self.user = UserModel._default_manager.get(pk=uid) except (TypeError, ValueError, OverflowError, UserModel.DoesNotExist): - raise ValidationError({'uid': ['Invalid value']}) + raise ValidationError({'uid': [_('Invalid value')]}) self.custom_validation(attrs) # Construct SetPasswordForm instance @@ -215,7 +223,7 @@ class PasswordResetConfirmSerializer(serializers.Serializer): if not self.set_password_form.is_valid(): raise serializers.ValidationError(self.set_password_form.errors) if not default_token_generator.check_token(self.user, attrs['token']): - raise ValidationError({'token': ['Invalid value']}) + raise ValidationError({'token': [_('Invalid value')]}) return attrs @@ -253,7 +261,7 @@ class PasswordChangeSerializer(serializers.Serializer): ) if all(invalid_password_conditions): - raise serializers.ValidationError('Invalid password') + raise serializers.ValidationError(_('Invalid password')) return value def validate(self, attrs): diff --git a/rest_auth/tests/django_urls.py b/rest_auth/tests/django_urls.py index c1fb050..4080b9f 100644 --- a/rest_auth/tests/django_urls.py +++ b/rest_auth/tests/django_urls.py @@ -8,7 +8,8 @@ from django.contrib.auth.urls import urlpatterns # special urls for auth test cases urlpatterns += [ - url(r'^logout/custom_query/$', views.logout, dict(redirect_field_name='follow')), + url(r'^logout/custom_query/$', views.logout, + dict(redirect_field_name='follow')), url(r'^logout/next_page/$', views.logout, dict(next_page='/somewhere/')), url(r'^logout/next_page/named/$', views.logout, dict(next_page='password_reset')), url(r'^password_reset_from_email/$', views.password_reset, dict(from_email='staffmember@example.com')), @@ -22,9 +23,12 @@ urlpatterns += [ url(r'^reset/custom/named/(?P[0-9A-Za-z_\-]+)/(?P[0-9A-Za-z]{1,13}-[0-9A-Za-z]{1,20})/$', views.password_reset_confirm, dict(post_reset_redirect='password_reset')), - url(r'^password_change/custom/$', views.password_change, dict(post_change_redirect='/custom/')), - url(r'^password_change/custom/named/$', views.password_change, dict(post_change_redirect='password_reset')), - url(r'^admin_password_reset/$', views.password_reset, dict(is_admin_site=True)), + url(r'^password_change/custom/$', views.password_change, + dict(post_change_redirect='/custom/')), + url(r'^password_change/custom/named/$', views.password_change, + dict(post_change_redirect='password_reset')), + url(r'^admin_password_reset/$', + views.password_reset, dict(is_admin_site=True)), url(r'^login_required/$', login_required(views.password_reset)), url(r'^login_required_login_url/$', login_required(views.password_reset, login_url='/somewhere/')), ] diff --git a/rest_auth/tests/test_api.py b/rest_auth/tests/test_api.py index 0356d19..ce33f13 100644 --- a/rest_auth/tests/test_api.py +++ b/rest_auth/tests/test_api.py @@ -12,6 +12,7 @@ from .test_base import BaseAPITestCase @override_settings(ROOT_URLCONF="tests.urls") class APITestCase1(TestCase, BaseAPITestCase): + """ Case #1: - user profile: defined @@ -97,7 +98,8 @@ class APITestCase1(TestCase, BaseAPITestCase): self.post(self.password_change_url, status_code=403) # create user - user = get_user_model().objects.create_user(self.USERNAME, '', 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('key' in self.response.json.keys(), True) @@ -162,7 +164,8 @@ class APITestCase1(TestCase, BaseAPITestCase): self.post(self.password_change_url, status_code=403) # create user - user = get_user_model().objects.create_user(self.USERNAME, self.EMAIL, self.PASS) + 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) @@ -276,7 +279,8 @@ class APITestCase1(TestCase, BaseAPITestCase): self.post(self.login_url, data=login_payload, status_code=200) def test_password_reset(self): - user = get_user_model().objects.create_user(self.USERNAME, self.EMAIL, self.PASS) + user = get_user_model().objects.create_user( + self.USERNAME, self.EMAIL, self.PASS) # call password reset mail_count = len(mail.outbox) @@ -331,7 +335,8 @@ class APITestCase1(TestCase, BaseAPITestCase): self.post(self.login_url, data=payload, status_code=200) def test_password_reset_with_email_in_different_case(self): - get_user_model().objects.create_user(self.USERNAME, self.EMAIL.lower(), self.PASS) + get_user_model().objects.create_user( + self.USERNAME, self.EMAIL.lower(), self.PASS) # call password reset in upper case mail_count = len(mail.outbox) @@ -343,7 +348,8 @@ class APITestCase1(TestCase, BaseAPITestCase): """ Invalid email should not raise error, as this would leak users """ - get_user_model().objects.create_user(self.USERNAME, self.EMAIL, self.PASS) + get_user_model().objects.create_user( + self.USERNAME, self.EMAIL, self.PASS) # call password reset mail_count = len(mail.outbox) @@ -352,7 +358,8 @@ class APITestCase1(TestCase, BaseAPITestCase): self.assertEqual(len(mail.outbox), mail_count) def test_user_details(self): - user = get_user_model().objects.create_user(self.USERNAME, self.EMAIL, self.PASS) + user = get_user_model().objects.create_user( + self.USERNAME, self.EMAIL, self.PASS) payload = { "username": self.USERNAME, "password": self.PASS @@ -388,9 +395,11 @@ class APITestCase1(TestCase, BaseAPITestCase): # test empty payload self.post(self.register_url, data={}, status_code=400) - result = self.post(self.register_url, data=self.REGISTRATION_DATA, status_code=201) + result = self.post( + self.register_url, data=self.REGISTRATION_DATA, status_code=201) self.assertIn('key', result.data) - self.assertEqual(get_user_model().objects.all().count(), user_count + 1) + self.assertEqual( + get_user_model().objects.all().count(), user_count + 1) new_user = get_user_model().objects.latest('id') self.assertEqual(new_user.username, self.REGISTRATION_DATA['username']) @@ -439,7 +448,8 @@ class APITestCase1(TestCase, BaseAPITestCase): status_code=status.HTTP_201_CREATED ) self.assertNotIn('key', result.data) - self.assertEqual(get_user_model().objects.all().count(), user_count + 1) + self.assertEqual( + get_user_model().objects.all().count(), user_count + 1) self.assertEqual(len(mail.outbox), mail_count + 1) new_user = get_user_model().objects.latest('id') self.assertEqual(new_user.username, self.REGISTRATION_DATA['username']) diff --git a/rest_auth/tests/test_base.py b/rest_auth/tests/test_base.py index 48d94f0..deaa9ad 100644 --- a/rest_auth/tests/test_base.py +++ b/rest_auth/tests/test_base.py @@ -24,6 +24,7 @@ class BaseAPITestCase(object): * easy request calls, f.e.: self.post(url, data), self.get(url) * easy status check, f.e.: self.post(url, data, status_code=200) """ + def send_request(self, request_method, *args, **kwargs): request_func = getattr(self.client, request_method) status_code = None diff --git a/rest_auth/tests/test_social.py b/rest_auth/tests/test_social.py index 47ac0bb..2681a9b 100644 --- a/rest_auth/tests/test_social.py +++ b/rest_auth/tests/test_social.py @@ -98,12 +98,14 @@ class TestSocialAuth(TestCase, BaseAPITestCase): self.post(self.fb_login_url, data=payload, status_code=200) self.assertIn('key', self.response.json.keys()) - self.assertEqual(get_user_model().objects.all().count(), users_count + 1) + self.assertEqual( + get_user_model().objects.all().count(), users_count + 1) # make sure that second request will not create a new user self.post(self.fb_login_url, data=payload, status_code=200) self.assertIn('key', self.response.json.keys()) - self.assertEqual(get_user_model().objects.all().count(), users_count + 1) + self.assertEqual( + get_user_model().objects.all().count(), users_count + 1) def _twitter_social_auth(self): # fake response for twitter call diff --git a/rest_auth/views.py b/rest_auth/views.py index 0493a76..500e046 100644 --- a/rest_auth/views.py +++ b/rest_auth/views.py @@ -71,6 +71,7 @@ class LoginView(GenericAPIView): self.process_login() def get_response(self): + serializer_class = self.get_response_serializer() if getattr(settings, 'REST_USE_JWT', False):