Patched library to support only django-rest-knox tokens.

This commit is contained in:
bartosz 2020-01-18 01:02:07 +01:00 committed by Charles Sekwalor
parent 624ad01afb
commit 2667430e37
8 changed files with 93 additions and 32 deletions

View File

@ -27,10 +27,12 @@ from rest_auth.registration.serializers import (VerifyEmailSerializer,
SocialLoginSerializer,
SocialAccountSerializer,
SocialConnectSerializer)
from rest_auth.serializers import KnoxSerializer
from rest_auth.utils import jwt_encode
from rest_auth.views import LoginView
from .app_settings import RegisterSerializer, register_permission_classes
from ..tests.utils import create_knox_token
sensitive_post_parameters_m = method_decorator(
sensitive_post_parameters('password1', 'password2')
)
@ -56,6 +58,12 @@ class RegisterView(CreateAPIView):
'token': self.token
}
return JWTSerializer(data).data
if getattr(settings, 'REST_USE_KNOX', False):
data = {
'user': user,
'token': self.token[1]
}
return KnoxSerializer(data).data
else:
return TokenSerializer(user.auth_token).data
@ -73,6 +81,8 @@ class RegisterView(CreateAPIView):
user = serializer.save(self.request)
if getattr(settings, 'REST_USE_JWT', False):
self.token = jwt_encode(user)
if getattr(settings, 'REST_USE_KNOX', False):
self.token = create_knox_token(None, user, None)
else:
create_token(self.token_model, user, serializer)

View File

@ -274,3 +274,23 @@ class PasswordChangeSerializer(serializers.Serializer):
if not self.logout_on_password_change:
from django.contrib.auth import update_session_auth_hash
update_session_auth_hash(self.request, self.user)
class KnoxSerializer(serializers.Serializer):
"""
Serializer for Knox authentication.
"""
token = serializers.CharField()
user = UserDetailsSerializer()
def get_token(self, obj):
print(obj)
return obj["token"][1]

View File

@ -3,3 +3,4 @@ responses>=0.3.0
flake8==2.4.0
djangorestframework-jwt>=1.7.2
djangorestframework>=3.6.4
django-rest-knox

View File

@ -62,10 +62,11 @@ TEMPLATES = [
},
]
REST_AUTH_TOKEN_MODEL = 'knox.models.AuthToken'
REST_USE_KNOX = True
REST_FRAMEWORK = {
'DEFAULT_AUTHENTICATION_CLASSES': (
'rest_framework.authentication.SessionAuthentication',
'rest_framework_jwt.authentication.JSONWebTokenAuthentication',
'knox.auth.TokenAuthentication',
)
}
@ -78,6 +79,7 @@ INSTALLED_APPS = [
'django.contrib.sites',
'django.contrib.sitemaps',
'django.contrib.staticfiles',
'django.contrib.messages',
'allauth',
'allauth.account',
@ -86,6 +88,7 @@ INSTALLED_APPS = [
'allauth.socialaccount.providers.twitter',
'rest_framework',
'knox',
'rest_framework.authtoken',
'rest_auth',
@ -104,3 +107,8 @@ AUTHENTICATION_BACKENDS = (
# `allauth` specific authentication methods, such as login by e-mail
'allauth.account.auth_backends.AuthenticationBackend',
)
REST_AUTH_SERIALIZERS = {
'USER_DETAILS_SERIALIZER': 'rest_auth.serializers.UserDetailsSerializer',
'TOKEN_SERIALIZER': 'rest_auth.serializers.KnoxSerializer',
}

View File

@ -103,31 +103,32 @@ class APIBasicTests(TestsMixin, TestCase):
# 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)
self.post(self.password_change_url, status_code=401)
# create user
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)
self.token = self.response.json['key']
self.assertEqual('token' in self.response.json.keys(), True)
self.token = self.response.json['token']
self.post(self.password_change_url, status_code=400)
# test inactive user
user.is_active = False
user.save()
self.post(self.login_url, data=payload, status_code=400)
self.post(self.login_url, data=payload, status_code=401)
# test wrong username/password
payload = {
"username": self.USERNAME + '?',
"password": self.PASS
}
self.post(self.login_url, data=payload, status_code=400)
self.post(self.login_url, data=payload, status_code=401)
# test empty payload
self.post(self.login_url, data={}, status_code=400)
self.post(self.login_url, data={}, status_code=401)
@override_settings(ACCOUNT_AUTHENTICATION_METHOD=account_app_settings.AuthenticationMethod.EMAIL)
def test_allauth_login_with_email(self):
@ -138,7 +139,7 @@ class APIBasicTests(TestsMixin, TestCase):
# 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)
self.post(self.password_change_url, status_code=401)
# create user
get_user_model().objects.create_user(self.EMAIL, email=self.EMAIL, password=self.PASS)
@ -168,15 +169,15 @@ class APIBasicTests(TestsMixin, TestCase):
# 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)
self.post(self.password_change_url, status_code=401)
# 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']
self.assertEqual('token' in self.response.json.keys(), True)
self.token = self.response.json['token']
# test auth by email in different case
payload = {
@ -184,23 +185,23 @@ class APIBasicTests(TestsMixin, TestCase):
"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']
self.assertEqual('token' in self.response.json.keys(), True)
self.token = self.response.json['token']
# test inactive user
user.is_active = False
user.save()
self.post(self.login_url, data=payload, status_code=400)
self.post(self.login_url, data=payload, status_code=401)
# test wrong email/password
payload = {
"email": 't' + self.EMAIL,
"password": self.PASS
}
self.post(self.login_url, data=payload, status_code=400)
self.post(self.login_url, data=payload, status_code=401)
# test empty payload
self.post(self.login_url, data={}, status_code=400)
self.post(self.login_url, data={}, status_code=401)
# bring back allauth
settings.INSTALLED_APPS.append('allauth')
@ -212,7 +213,7 @@ class APIBasicTests(TestsMixin, TestCase):
}
get_user_model().objects.create_user(self.USERNAME, '', self.PASS)
self.post(self.login_url, data=login_payload, status_code=200)
self.token = self.response.json['key']
self.token = self.response.json['token']
new_password_payload = {
"new_password1": "new_person",
@ -253,7 +254,7 @@ class APIBasicTests(TestsMixin, TestCase):
}
get_user_model().objects.create_user(self.USERNAME, '', self.PASS)
self.post(self.login_url, data=login_payload, status_code=200)
self.token = self.response.json['key']
self.token = self.response.json['token']
new_password_payload = {
"old_password": "%s!" % self.PASS, # wrong password
@ -367,7 +368,7 @@ class APIBasicTests(TestsMixin, TestCase):
"password": self.PASS
}
self.post(self.login_url, data=payload, status_code=200)
self.token = self.response.json['key']
self.token = self.response.json['token']
self.get(self.user_url, status_code=200)
self.patch(self.user_url, data=self.BASIC_USER_DATA, status_code=200)
@ -378,6 +379,7 @@ class APIBasicTests(TestsMixin, TestCase):
@override_settings(REST_USE_JWT=True)
def test_user_details_using_jwt(self):
self.skipTest('Support only knox right now')
user = get_user_model().objects.create_user(self.USERNAME, self.EMAIL, self.PASS)
payload = {
"username": self.USERNAME,
@ -398,7 +400,7 @@ class APIBasicTests(TestsMixin, TestCase):
self.post(self.register_url, data={}, status_code=400)
result = self.post(self.register_url, data=self.REGISTRATION_DATA, status_code=201)
self.assertIn('key', result.data)
self.assertIn('token', result.data)
self.assertEqual(get_user_model().objects.all().count(), user_count + 1)
new_user = get_user_model().objects.latest('id')
@ -461,7 +463,7 @@ class APIBasicTests(TestsMixin, TestCase):
data=self.REGISTRATION_DATA_WITH_EMAIL,
status_code=status.HTTP_201_CREATED
)
self.assertNotIn('key', result.data)
self.assertNotIn('token', result.data)
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')

View File

@ -102,12 +102,12 @@ class TestSocialAuth(TestsMixin, TestCase):
}
self.post(self.fb_login_url, data=payload, status_code=200)
self.assertIn('key', self.response.json.keys())
self.assertIn('token', self.response.json.keys())
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.assertIn('token', self.response.json.keys())
self.assertEqual(get_user_model().objects.all().count(), users_count + 1)
def _twitter_social_auth(self):
@ -132,12 +132,12 @@ class TestSocialAuth(TestsMixin, TestCase):
self.post(self.tw_login_url, data=payload)
self.assertIn('key', self.response.json.keys())
self.assertIn('token', self.response.json.keys())
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.tw_login_url, data=payload, status_code=200)
self.assertIn('key', self.response.json.keys())
self.assertIn('token', self.response.json.keys())
self.assertEqual(get_user_model().objects.all().count(), users_count + 1)
@responses.activate
@ -172,7 +172,7 @@ class TestSocialAuth(TestsMixin, TestCase):
}
self.post(self.tw_login_url, data=payload, status_code=400)
self.assertNotIn('key', self.response.json.keys())
self.assertNotIn('token', self.response.json.keys())
self.assertEqual(get_user_model().objects.all().count(), users_count)
@responses.activate
@ -359,17 +359,18 @@ class TestSocialConnectAuth(TestsMixin, TestCase):
payload = {
'access_token': 'abc123'
}
self.post(self.fb_connect_url, data=payload, status_code=403)
self.post(self.tw_connect_url, data=payload, status_code=403)
self.post(self.fb_connect_url, data=payload, status_code=401)
self.post(self.tw_connect_url, data=payload, status_code=401)
@responses.activate
def test_social_connect(self):
# register user
self.post(
response = self.post(
self.register_url,
data=self.REGISTRATION_DATA,
status_code=201
)
self.token = response.json['token']
# Test Facebook
resp_body = {
@ -398,7 +399,7 @@ class TestSocialConnectAuth(TestsMixin, TestCase):
'access_token': 'abc123'
}
self.post(self.fb_connect_url, data=payload, status_code=200)
self.assertIn('key', self.response.json.keys())
self.assertIn('token', self.response.json.keys())
# Test Twitter
resp_body = {
@ -420,7 +421,7 @@ class TestSocialConnectAuth(TestsMixin, TestCase):
self.post(self.tw_connect_url, data=payload)
self.assertIn('key', self.response.json.keys())
self.assertIn('token', self.response.json.keys())
# Check current social accounts
self.get(self.social_account_list_url)

6
rest_auth/tests/utils.py Normal file
View File

@ -0,0 +1,6 @@
from knox.models import AuthToken
def create_knox_token(token_model, user, serializer):
token = AuthToken.objects.create(user=user)
return token

View File

@ -15,6 +15,8 @@ from rest_framework.response import Response
from rest_framework.generics import GenericAPIView, RetrieveUpdateAPIView
from rest_framework.permissions import IsAuthenticated, AllowAny
from rest_auth.serializers import KnoxSerializer
from rest_auth.tests.utils import create_knox_token
from .app_settings import (
TokenSerializer, UserDetailsSerializer, LoginSerializer,
PasswordResetSerializer, PasswordResetConfirmSerializer,
@ -54,6 +56,8 @@ class LoginView(GenericAPIView):
def get_response_serializer(self):
if getattr(settings, 'REST_USE_JWT', False):
response_serializer = JWTSerializer
elif getattr(settings, 'REST_USE_KNOX', False):
response_serializer = KnoxSerializer
else:
response_serializer = TokenSerializer
return response_serializer
@ -63,6 +67,8 @@ class LoginView(GenericAPIView):
if getattr(settings, 'REST_USE_JWT', False):
self.token = jwt_encode(self.user)
if getattr(settings, 'REST_USE_KNOX', False):
self.token = create_knox_token(None, self.user, None)
else:
self.token = create_token(self.token_model, self.user,
self.serializer)
@ -80,6 +86,13 @@ class LoginView(GenericAPIView):
}
serializer = serializer_class(instance=data,
context={'request': self.request})
elif getattr(settings, 'REST_USE_KNOX', False):
data = {
'user': self.user,
'token': self.token[1]
}
serializer = serializer_class(instance=data,
context={'request': self.request})
else:
serializer = serializer_class(instance=self.token,
context={'request': self.request})