mirror of
https://github.com/Tivix/django-rest-auth.git
synced 2024-11-11 03:36:35 +03:00
commit
14261d69ed
|
@ -21,3 +21,5 @@ script:
|
|||
- coverage run --source=rest_auth setup.py test
|
||||
after_success:
|
||||
- coveralls
|
||||
before_script:
|
||||
- flake8 . --config=flake8
|
||||
|
|
4
flake8
Normal file
4
flake8
Normal file
|
@ -0,0 +1,4 @@
|
|||
[flake8]
|
||||
max-line-length = 160
|
||||
exclude = docs/*,demo/*
|
||||
ignore = F403
|
|
@ -24,16 +24,22 @@ LoginSerializer = import_callable(
|
|||
)
|
||||
|
||||
PasswordResetSerializer = import_callable(
|
||||
serializers.get('PASSWORD_RESET_SERIALIZER',
|
||||
DefaultPasswordResetSerializer)
|
||||
serializers.get(
|
||||
'PASSWORD_RESET_SERIALIZER',
|
||||
DefaultPasswordResetSerializer
|
||||
)
|
||||
)
|
||||
|
||||
PasswordResetConfirmSerializer = import_callable(
|
||||
serializers.get('PASSWORD_RESET_CONFIRM_SERIALIZER',
|
||||
DefaultPasswordResetConfirmSerializer)
|
||||
serializers.get(
|
||||
'PASSWORD_RESET_CONFIRM_SERIALIZER',
|
||||
DefaultPasswordResetConfirmSerializer
|
||||
)
|
||||
)
|
||||
|
||||
PasswordChangeSerializer = import_callable(
|
||||
serializers.get('PASSWORD_CHANGE_SERIALIZER',
|
||||
DefaultPasswordChangeSerializer)
|
||||
serializers.get(
|
||||
'PASSWORD_CHANGE_SERIALIZER',
|
||||
DefaultPasswordChangeSerializer
|
||||
)
|
||||
)
|
||||
|
|
|
@ -21,7 +21,9 @@ class CustomRequestAuthenticationForm(AuthenticationForm):
|
|||
|
||||
@never_cache
|
||||
def remote_user_auth_view(request):
|
||||
"Dummy view for remote user tests"
|
||||
"""
|
||||
Dummy view for remote user tests
|
||||
"""
|
||||
t = Template("Username is {{ user }}.")
|
||||
c = RequestContext(request, {})
|
||||
return HttpResponse(t.render(c))
|
||||
|
@ -100,4 +102,4 @@ urlpatterns += [
|
|||
|
||||
# This line is only required to render the password reset with is_admin=True
|
||||
url(r'^admin/', include(admin.site.urls)),
|
||||
]
|
||||
]
|
||||
|
|
|
@ -16,8 +16,10 @@ class SocialLoginSerializer(serializers.Serializer):
|
|||
request = request._request
|
||||
|
||||
if not view:
|
||||
raise serializers.ValidationError('View is not defined, pass it ' +
|
||||
'as a context variable')
|
||||
raise serializers.ValidationError(
|
||||
'View is not defined, pass it as a context variable'
|
||||
)
|
||||
|
||||
self.adapter_class = getattr(view, 'adapter_class', None)
|
||||
|
||||
if not self.adapter_class:
|
||||
|
|
|
@ -3,7 +3,8 @@ from django.conf.urls import patterns, url
|
|||
|
||||
from .views import Register, VerifyEmail
|
||||
|
||||
urlpatterns = patterns('',
|
||||
urlpatterns = patterns(
|
||||
'',
|
||||
url(r'^$', Register.as_view(), name='rest_register'),
|
||||
url(r'^verify-email/$', VerifyEmail.as_view(), name='rest_verify_email'),
|
||||
|
||||
|
@ -21,4 +22,3 @@ urlpatterns = patterns('',
|
|||
url(r'^account-confirm-email/(?P<key>\w+)/$', TemplateView.as_view(),
|
||||
name='account_confirm_email'),
|
||||
)
|
||||
|
||||
|
|
|
@ -78,7 +78,6 @@ class PasswordResetSerializer(serializers.Serializer):
|
|||
|
||||
|
||||
class PasswordResetConfirmSerializer(serializers.Serializer):
|
||||
|
||||
"""
|
||||
Serializer for requesting a password reset e-mail.
|
||||
"""
|
||||
|
@ -107,8 +106,9 @@ class PasswordResetConfirmSerializer(serializers.Serializer):
|
|||
|
||||
self.custom_validation(attrs)
|
||||
# Construct SetPasswordForm instance
|
||||
self.set_password_form = self.set_password_form_class(user=self.user,
|
||||
data=attrs)
|
||||
self.set_password_form = self.set_password_form_class(
|
||||
user=self.user, data=attrs
|
||||
)
|
||||
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']):
|
||||
|
@ -129,8 +129,9 @@ class PasswordChangeSerializer(serializers.Serializer):
|
|||
set_password_form_class = SetPasswordForm
|
||||
|
||||
def __init__(self, *args, **kwargs):
|
||||
self.old_password_field_enabled = getattr(settings,
|
||||
'OLD_PASSWORD_FIELD_ENABLED', False)
|
||||
self.old_password_field_enabled = getattr(
|
||||
settings, 'OLD_PASSWORD_FIELD_ENABLED', False
|
||||
)
|
||||
super(PasswordChangeSerializer, self).__init__(*args, **kwargs)
|
||||
|
||||
if not self.old_password_field_enabled:
|
||||
|
@ -140,14 +141,20 @@ class PasswordChangeSerializer(serializers.Serializer):
|
|||
self.user = getattr(self.request, 'user', None)
|
||||
|
||||
def validate_old_password(self, value):
|
||||
if self.old_password_field_enabled and self.user and \
|
||||
not self.user.check_password(value):
|
||||
invalid_password_conditions = (
|
||||
self.old_password_field_enabled,
|
||||
self.user,
|
||||
not self.user.check_password(value)
|
||||
)
|
||||
|
||||
if all(invalid_password_conditions):
|
||||
raise serializers.ValidationError('Invalid password')
|
||||
return value
|
||||
|
||||
def validate(self, attrs):
|
||||
self.set_password_form = self.set_password_form_class(user=self.user,
|
||||
data=attrs)
|
||||
self.set_password_form = self.set_password_form_class(
|
||||
user=self.user, data=attrs
|
||||
)
|
||||
|
||||
if not self.set_password_form.is_valid():
|
||||
raise serializers.ValidationError(self.set_password_form.errors)
|
||||
|
|
|
@ -11,7 +11,8 @@ from rest_auth.registration.views import SocialLogin
|
|||
class FacebookLogin(SocialLogin):
|
||||
adapter_class = FacebookOAuth2Adapter
|
||||
|
||||
urlpatterns += patterns('',
|
||||
urlpatterns += patterns(
|
||||
'',
|
||||
url(r'^rest-registration/', include('rest_auth.registration.urls')),
|
||||
url(r'^test-admin/', include(rest_auth.django_test_urls)),
|
||||
url(r'^account-email-verification-sent/$', TemplateView.as_view(),
|
||||
|
|
|
@ -35,7 +35,7 @@ class BaseAPITestCase(object):
|
|||
def send_request(self, request_method, *args, **kwargs):
|
||||
request_func = getattr(self.client, request_method)
|
||||
status_code = None
|
||||
if not 'content_type' in kwargs and request_method != 'get':
|
||||
if 'content_type' not in kwargs and request_method != 'get':
|
||||
kwargs['content_type'] = 'application/json'
|
||||
if 'data' in kwargs and request_method != 'get' and kwargs['content_type'] == 'application/json':
|
||||
data = kwargs.get('data', '')
|
||||
|
@ -216,8 +216,11 @@ class APITestCase1(TestCase, BaseAPITestCase):
|
|||
"new_password1": "new_person",
|
||||
"new_password2": "new_person"
|
||||
}
|
||||
self.post(self.password_change_url, data=new_password_payload,
|
||||
status_code=200)
|
||||
self.post(
|
||||
self.password_change_url,
|
||||
data=new_password_payload,
|
||||
status_code=200
|
||||
)
|
||||
|
||||
# user should not be able to login using old password
|
||||
self.post(self.login_url, data=login_payload, status_code=400)
|
||||
|
@ -231,8 +234,11 @@ class APITestCase1(TestCase, BaseAPITestCase):
|
|||
"new_password1": "new_person1",
|
||||
"new_password2": "new_person"
|
||||
}
|
||||
self.post(self.password_change_url, data=new_password_payload,
|
||||
status_code=400)
|
||||
self.post(
|
||||
self.password_change_url,
|
||||
data=new_password_payload,
|
||||
status_code=400
|
||||
)
|
||||
|
||||
# send empty payload
|
||||
self.post(self.password_change_url, data={}, status_code=400)
|
||||
|
@ -252,16 +258,22 @@ class APITestCase1(TestCase, BaseAPITestCase):
|
|||
"new_password1": "new_person",
|
||||
"new_password2": "new_person"
|
||||
}
|
||||
self.post(self.password_change_url, data=new_password_payload,
|
||||
status_code=400)
|
||||
self.post(
|
||||
self.password_change_url,
|
||||
data=new_password_payload,
|
||||
status_code=400
|
||||
)
|
||||
|
||||
new_password_payload = {
|
||||
"old_password": self.PASS,
|
||||
"new_password1": "new_person",
|
||||
"new_password2": "new_person"
|
||||
}
|
||||
self.post(self.password_change_url, data=new_password_payload,
|
||||
status_code=200)
|
||||
self.post(
|
||||
self.password_change_url,
|
||||
data=new_password_payload,
|
||||
status_code=200
|
||||
)
|
||||
|
||||
# user should not be able to login using old password
|
||||
self.post(self.login_url, data=login_payload, status_code=400)
|
||||
|
@ -364,11 +376,17 @@ class APITestCase1(TestCase, BaseAPITestCase):
|
|||
mail_count = len(mail.outbox)
|
||||
|
||||
# test empty payload
|
||||
self.post(self.register_url, data={},
|
||||
status_code=status.HTTP_400_BAD_REQUEST)
|
||||
self.post(
|
||||
self.register_url,
|
||||
data={},
|
||||
status_code=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
self.post(self.register_url, data=self.REGISTRATION_DATA_WITH_EMAIL,
|
||||
status_code=status.HTTP_201_CREATED)
|
||||
self.post(
|
||||
self.register_url,
|
||||
data=self.REGISTRATION_DATA_WITH_EMAIL,
|
||||
status_code=status.HTTP_201_CREATED
|
||||
)
|
||||
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')
|
||||
|
@ -379,14 +397,20 @@ class APITestCase1(TestCase, BaseAPITestCase):
|
|||
"username": self.USERNAME,
|
||||
"password": self.PASS
|
||||
}
|
||||
self.post(self.login_url, data=payload,
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
self.post(
|
||||
self.login_url,
|
||||
data=payload,
|
||||
status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
# veirfy email
|
||||
# verify email
|
||||
email_confirmation = new_user.emailaddress_set.get(email=self.EMAIL)\
|
||||
.emailconfirmation_set.order_by('-created')[0]
|
||||
self.post(self.veirfy_email_url, data={"key": email_confirmation.key},
|
||||
status_code=status.HTTP_200_OK)
|
||||
self.post(
|
||||
self.veirfy_email_url,
|
||||
data={"key": email_confirmation.key},
|
||||
status_code=status.HTTP_200_OK
|
||||
)
|
||||
|
||||
# try to login again
|
||||
self._login()
|
||||
|
@ -423,8 +447,13 @@ class TestSocialAuth(TestCase, BaseAPITestCase):
|
|||
@responses.activate
|
||||
def test_failed_social_auth(self):
|
||||
# fake response
|
||||
responses.add(responses.GET, self.graph_api_url, body='', status=400,
|
||||
content_type='application/json')
|
||||
responses.add(
|
||||
responses.GET,
|
||||
self.graph_api_url,
|
||||
body='',
|
||||
status=400,
|
||||
content_type='application/json'
|
||||
)
|
||||
|
||||
payload = {
|
||||
'access_token': 'abc123'
|
||||
|
@ -434,9 +463,14 @@ class TestSocialAuth(TestCase, BaseAPITestCase):
|
|||
@responses.activate
|
||||
def test_social_auth(self):
|
||||
# fake response for facebook call
|
||||
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}'
|
||||
responses.add(responses.GET, self.graph_api_url, body=resp_body,
|
||||
status=200, content_type='application/json')
|
||||
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 = {
|
||||
|
@ -459,24 +493,34 @@ class TestSocialAuth(TestCase, BaseAPITestCase):
|
|||
REST_SESSION_LOGIN=False
|
||||
)
|
||||
def test_edge_case(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,"email":"%s"}'
|
||||
responses.add(responses.GET, self.graph_api_url,
|
||||
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,"email":"%s"}' # noqa
|
||||
responses.add(
|
||||
responses.GET,
|
||||
self.graph_api_url,
|
||||
body=resp_body % self.EMAIL,
|
||||
status=200, content_type='application/json')
|
||||
status=200,
|
||||
content_type='application/json'
|
||||
)
|
||||
|
||||
# test empty payload
|
||||
self.post(self.register_url, data={}, status_code=400)
|
||||
|
||||
self.post(self.register_url, data=self.REGISTRATION_DATA,
|
||||
status_code=201)
|
||||
self.post(
|
||||
self.register_url,
|
||||
data=self.REGISTRATION_DATA,
|
||||
status_code=201
|
||||
)
|
||||
new_user = get_user_model().objects.latest('id')
|
||||
self.assertEqual(new_user.username, self.REGISTRATION_DATA['username'])
|
||||
|
||||
# veirfy email
|
||||
# verify email
|
||||
email_confirmation = new_user.emailaddress_set.get(email=self.EMAIL)\
|
||||
.emailconfirmation_set.order_by('-created')[0]
|
||||
self.post(self.veirfy_email_url, data={"key": email_confirmation.key},
|
||||
status_code=status.HTTP_200_OK)
|
||||
self.post(
|
||||
self.veirfy_email_url,
|
||||
data={"key": email_confirmation.key},
|
||||
status_code=status.HTTP_200_OK
|
||||
)
|
||||
|
||||
self._login()
|
||||
self._logout()
|
||||
|
|
|
@ -1,9 +1,12 @@
|
|||
from django.conf.urls import patterns, url
|
||||
|
||||
from rest_auth.views import (Login, Logout, UserDetails, PasswordChange,
|
||||
PasswordReset, PasswordResetConfirm)
|
||||
from rest_auth.views import (
|
||||
Login, Logout, UserDetails, PasswordChange,
|
||||
PasswordReset, PasswordResetConfirm
|
||||
)
|
||||
|
||||
urlpatterns = patterns('',
|
||||
urlpatterns = patterns(
|
||||
'',
|
||||
# URLs that do not require a session or valid token
|
||||
url(r'^password/reset/$', PasswordReset.as_view(),
|
||||
name='rest_password_reset'),
|
||||
|
|
|
@ -13,4 +13,3 @@ 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)
|
||||
|
||||
|
|
|
@ -9,9 +9,11 @@ from rest_framework.permissions import IsAuthenticated, AllowAny
|
|||
from rest_framework.authtoken.models import Token
|
||||
from rest_framework.generics import RetrieveUpdateAPIView
|
||||
|
||||
from .app_settings import (TokenSerializer, UserDetailsSerializer,
|
||||
LoginSerializer, PasswordResetSerializer, PasswordResetConfirmSerializer,
|
||||
PasswordChangeSerializer)
|
||||
from .app_settings import (
|
||||
TokenSerializer, UserDetailsSerializer, LoginSerializer,
|
||||
PasswordResetSerializer, PasswordResetConfirmSerializer,
|
||||
PasswordChangeSerializer
|
||||
)
|
||||
|
||||
|
||||
class Login(GenericAPIView):
|
||||
|
@ -38,12 +40,14 @@ class Login(GenericAPIView):
|
|||
login(self.request, self.user)
|
||||
|
||||
def get_response(self):
|
||||
return Response(self.response_serializer(self.token).data,
|
||||
status=status.HTTP_200_OK)
|
||||
return Response(
|
||||
self.response_serializer(self.token).data, status=status.HTTP_200_OK
|
||||
)
|
||||
|
||||
def get_error_response(self):
|
||||
return Response(self.serializer.errors,
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
return Response(
|
||||
self.serializer.errors, status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
self.serializer = self.get_serializer(data=self.request.DATA)
|
||||
|
@ -114,8 +118,10 @@ class PasswordReset(GenericAPIView):
|
|||
status=status.HTTP_400_BAD_REQUEST)
|
||||
serializer.save()
|
||||
# Return the success message with OK HTTP status
|
||||
return Response({"success": "Password reset e-mail has been sent."},
|
||||
status=status.HTTP_200_OK)
|
||||
return Response(
|
||||
{"success": "Password reset e-mail has been sent."},
|
||||
status=status.HTTP_200_OK
|
||||
)
|
||||
|
||||
|
||||
class PasswordResetConfirm(GenericAPIView):
|
||||
|
@ -134,8 +140,9 @@ class PasswordResetConfirm(GenericAPIView):
|
|||
def post(self, request):
|
||||
serializer = self.get_serializer(data=request.DATA)
|
||||
if not serializer.is_valid():
|
||||
return Response(serializer.errors,
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
return Response(
|
||||
serializer.errors, status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
serializer.save()
|
||||
return Response({"success": "Password has been reset with the new password."})
|
||||
|
||||
|
@ -155,7 +162,8 @@ class PasswordChange(GenericAPIView):
|
|||
def post(self, request):
|
||||
serializer = self.get_serializer(data=request.DATA)
|
||||
if not serializer.is_valid():
|
||||
return Response(serializer.errors,
|
||||
status=status.HTTP_400_BAD_REQUEST)
|
||||
return Response(
|
||||
serializer.errors, status=status.HTTP_400_BAD_REQUEST
|
||||
)
|
||||
serializer.save()
|
||||
return Response({"success": "New password has been saved."})
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
# This file mainly exists to allow python setup.py test to work.
|
||||
# flake8: noqa
|
||||
import os
|
||||
import sys
|
||||
|
||||
|
|
|
@ -1,2 +1,3 @@
|
|||
django-allauth>=0.19.1
|
||||
responses>=0.3.0
|
||||
flake8==2.3.0
|
||||
|
|
Loading…
Reference in New Issue
Block a user