Skip to content

Commit

Permalink
Proper http status codes used for logout with wrong token
Browse files Browse the repository at this point in the history
  • Loading branch information
ChristianKreuzberger committed Mar 12, 2017
1 parent f027573 commit 55e2101
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 28 deletions.
29 changes: 19 additions & 10 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,17 +29,26 @@ matrix:
exclude:
- python: "3.3"
# Django 1.9 does not support python 3.3, but 3.4+
env: DJANGO_VERSION=1.9 DJANGO_REST_VERSION=3.4
env: DJANGO_VERSION=1.9 DJANGO_REST_VERSION=3.5
env: DJANGO_VERSION=1.9 DJANGO_REST_VERSION=3.6
env: DJANGO_VERSION=1.10 DJANGO_REST_VERSION=3.4
env: DJANGO_VERSION=1.10 DJANGO_REST_VERSION=3.5
env: DJANGO_VERSION=1.10 DJANGO_REST_VERSION=3.6
env: DJANGO_VERSION=1.11a1 DJANGO_REST_VERSION=3.4
env: DJANGO_VERSION=1.11a1 DJANGO_REST_VERSION=3.5
env: DJANGO_VERSION=1.11a1 DJANGO_REST_VERSION=3.6
- env: DJANGO_VERSION=1.9
env: DJANGO_REST_VERSION=3.4
- env: DJANGO_VERSION=1.9
env: DJANGO_REST_VERSION=3.5
- env: DJANGO_VERSION=1.9
env: DJANGO_REST_VERSION=3.6
- env: DJANGO_VERSION=1.10
env: DJANGO_REST_VERSION=3.4
- env: DJANGO_VERSION=1.10
env: DJANGO_REST_VERSION=3.5
- env: DJANGO_VERSION=1.10
env: DJANGO_REST_VERSION=3.6
- env: DJANGO_VERSION=1.11a1
env: DJANGO_REST_VERSION=3.4
- env: DJANGO_VERSION=1.11a1
env: DJANGO_REST_VERSION=3.5
- env: DJANGO_VERSION=1.11a1
env: DJANGO_REST_VERSION=3.6
- python: "nightly"
env: DJANGO_VERSION=1.8 # Django 1.8 might not work with future versions of python
- env: DJANGO_VERSION=1.8 # Django 1.8 might not work with future versions of python
script:
- python setup.py install
- cd tests/
Expand Down
6 changes: 3 additions & 3 deletions django_rest_multitokenauth/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,9 @@ def post(self, request, *args, **kwargs):
tokens.delete()
return Response({'status': 'logged out'})
else:
return Response({'error': 'invalid token'})
return Response({'error': 'invalid token'}, status=status.HTTP_400_BAD_REQUEST)

return Response({'error': 'not logged in'})
return Response({'error': 'not logged in'}, status=status.HTTP_401_UNAUTHORIZED)


class LoginAndObtainAuthToken(APIView):
Expand Down Expand Up @@ -80,7 +80,7 @@ def post(self, request, *args, **kwargs):

return Response({'token': token.key})
# else:
return Response({'error': 'not logged in'})
return Response({'error': 'not logged in'}, status=status.HTTP_401_UNAUTHORIZED)


class ResetPasswordConfirm(APIView):
Expand Down
2 changes: 1 addition & 1 deletion setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@

setup(
name='django-rest-multitokenauth',
version='0.2.6',
version='0.2.7',
packages=find_packages(),
include_package_data=True,
license='BSD License',
Expand Down
79 changes: 65 additions & 14 deletions tests/test.py
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,8 @@ def rest_do_login(self, username, password, HTTP_USER_AGENT='', REMOTE_ADDR='127
)

def rest_do_logout(self, token, HTTP_USER_AGENT='', REMOTE_ADDR='127.0.0.1'):
self.set_client_credentials(token)
if token:
self.set_client_credentials(token)

# call logout
return self.client.post(
Expand All @@ -72,7 +73,7 @@ def login_and_obtain_token(self, username, password, HTTP_USER_AGENT='', REMOTE
return token

def test_login_and_logout(self):
""" tests login and logout """
""" tests login and logout for a single user """
# there should be zero tokens
self.assertEqual(MultiToken.objects.all().count(), 0)

Expand All @@ -94,6 +95,7 @@ def test_login_and_logout(self):
self.assertEqual(MultiToken.objects.all().count(), 0)

def test_login_multiple_times(self):
""" tests login with the same user for several times """
# there should be zero tokens
self.assertEqual(MultiToken.objects.all().count(), 0)

Expand Down Expand Up @@ -131,7 +133,7 @@ def test_login_multiple_times(self):

# Now logout with token2 and verify that token1 and token3 are still in database
response = self.rest_do_logout(token2)
self.assertEqual(response.status_code, 200)
self.assertEqual(response.status_code, status.HTTP_200_OK)
# should be two tokens left
self.assertEqual(MultiToken.objects.all().count(), 2)
# verify that these two are token1 and token3
Expand All @@ -141,36 +143,85 @@ def test_login_multiple_times(self):
)

def test_login_with_invalid_credentials(self):
""" tests login with invalid credentials """
# log in one time, just to be sure that the login works
self.login_and_obtain_token("user1", "secret1")
# there should be one token
self.assertEqual(MultiToken.objects.all().count(), 1)

# correct username, but wrong password
response = self.rest_do_login("user1", "wrongpassword")
content = json.loads(response.content.decode())
self.assertEqual(response.status_code, 400)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertTrue('non_field_errors' in content)

# there should be zero tokens
self.assertEqual(MultiToken.objects.all().count(), 0)
# there should be one token
self.assertEqual(MultiToken.objects.all().count(), 1)

# wrong username, but correct password
response = self.rest_do_login("userOne", "secret1")
content = json.loads(response.content.decode())
self.assertEqual(response.status_code, 400)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertTrue('non_field_errors' in content)

# there should be zero tokens
self.assertEqual(MultiToken.objects.all().count(), 0)
# there should be one token
self.assertEqual(MultiToken.objects.all().count(), 1)

# wrong username, wrong password
response = self.rest_do_login("userOne", "wrongpassword")
content = json.loads(response.content.decode())
self.assertEqual(response.status_code, 400)
self.assertEqual(response.status_code, status.HTTP_400_BAD_REQUEST)
self.assertTrue('non_field_errors' in content)
self.assertFalse('token' in content, msg="There should not be a token in the response")

# there should be zero tokens
self.assertEqual(MultiToken.objects.all().count(), 0)

# there should be one token
self.assertEqual(MultiToken.objects.all().count(), 1)

def test_login_multiple_users(self):
pass
""" Login with multiple accounts and obtain several tokens """
token1 = self.login_and_obtain_token("user1", "secret1")
# there should be one token
self.assertEqual(MultiToken.objects.all().count(), 1)
# check that token1 is assigned to user1
self.assertEqual(MultiToken.objects.filter(key=token1).first().user.username, "user1")

token2 = self.login_and_obtain_token("user2", "secret2")
# there should be two tokens
self.assertEqual(MultiToken.objects.all().count(), 2)
# check that token1 is assigned to user1
self.assertEqual(MultiToken.objects.filter(key=token1).first().user.username, "user1")
# check that token2 is assigned to user2
self.assertEqual(MultiToken.objects.filter(key=token2).first().user.username, "user2")

# login again with user1
token3 = self.login_and_obtain_token("user1", "secret1")
# there should be three tokens
self.assertEqual(MultiToken.objects.all().count(), 3)
# check that token1 is assigned to user1
self.assertEqual(MultiToken.objects.filter(key=token1).first().user.username, "user1")
# check that token2 is assigned to user2
self.assertEqual(MultiToken.objects.filter(key=token2).first().user.username, "user2")
# check that token3 is assigned to user1
self.assertEqual(MultiToken.objects.filter(key=token3).first().user.username, "user1")

def test_logout_with_invalid_token(self):
token = self.login_and_obtain_token("user1", "secret1")
# there should be one token
self.assertEqual(MultiToken.objects.all().count(), 1)

# logout with an invalid token
response = self.rest_do_logout(token + "a")

self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)

# there should be one token
self.assertEqual(MultiToken.objects.all().count(), 1)

def test_logout_without_token(self):
self.reset_client_credentials()
response = self.rest_do_logout(None)
self.assertEqual(response.status_code, status.HTTP_401_UNAUTHORIZED)


def test_reset_password(self):
pass
Expand Down

0 comments on commit 55e2101

Please sign in to comment.