merge commit with upstream

This commit is contained in:
Philippe Luickx 2015-04-30 13:22:17 +03:00
commit a6a2e122da
18 changed files with 140 additions and 62 deletions

View File

@ -21,3 +21,5 @@ script:
- coverage run --source=rest_auth setup.py test
after_success:
- coveralls
before_script:
- flake8 . --config=flake8

View File

@ -1,4 +1,4 @@
django>=1.5.0
django-rest-auth==0.3.4
django-rest-auth==0.4.0
django-allauth==0.19.1
six==1.9.0

View File

@ -1,6 +1,10 @@
Changelog
=========
0.4.0
-----
- Django 1.8 compatiblity fixes
0.3.4
-----
- fixed bug in PasswordResetConfirmation serializer (token field wasn't validated)

View File

@ -107,5 +107,5 @@ Using ``django-allauth``, ``django-rest-auth`` provides helpful class for creati
urlpatterns += pattern('',
...,
url(r'^/rest-auth/facebook/$', FacebookLogin.as_view(), name='fb_login')
url(r'^rest-auth/facebook/$', FacebookLogin.as_view(), name='fb_login')
)

4
flake8 Normal file
View File

@ -0,0 +1,4 @@
[flake8]
max-line-length = 160
exclude = docs/*,demo/*
ignore = F403

View File

@ -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
)
)

View File

@ -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))

View File

@ -18,8 +18,7 @@ class SocialLoginSerializer(serializers.Serializer):
if not view:
raise serializers.ValidationError(
'View is not defined, pass it ' +
'as a context variable'
'View is not defined, pass it as a context variable'
)
self.adapter_class = getattr(view, 'adapter_class', None)

View File

@ -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'),
)

View File

@ -155,7 +155,6 @@ class PasswordResetSerializer(serializers.Serializer):
class PasswordResetConfirmSerializer(serializers.Serializer):
"""
Serializer for requesting a password reset e-mail.
"""
@ -184,8 +183,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']):
@ -206,8 +206,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:
@ -217,14 +218,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)

View File

@ -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(),

View File

@ -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()

View File

@ -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'),

View File

@ -1,5 +1,9 @@
from six import string_types
import sys
if sys.version_info < (2, 7):
from django.utils.importlib import import_module
else:
from importlib import import_module
def import_callable(path_or_callable):
@ -9,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)

View File

@ -27,6 +27,7 @@ class EverybodyCanAuthentication(SessionAuthentication):
class Login(GenericAPIView):
"""
Check the credentials and return the REST Token
and the user object

View File

@ -1,4 +1,5 @@
# This file mainly exists to allow python setup.py test to work.
# flake8: noqa
import os
import sys

View File

@ -18,7 +18,7 @@ f.close()
setup(
name='django-rest-auth',
version='0.3.4',
version='0.4.0',
author='Sumit Chachra',
author_email='chachra@tivix.com',
url='http://github.com/Tivix/django-rest-auth',

View File

@ -1,2 +1,3 @@
django-allauth>=0.19.1
responses>=0.3.0
flake8==2.4.0