Skip to content

Commit

Permalink
wip #893: some input sanity checks for user API's
Browse files Browse the repository at this point in the history
  • Loading branch information
rafalp committed Oct 4, 2017
1 parent b0b2d33 commit e24149a
Show file tree
Hide file tree
Showing 5 changed files with 67 additions and 1 deletion.
14 changes: 14 additions & 0 deletions misago/core/decorators.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
from rest_framework import serializers

from .errorpages import not_allowed


Expand All @@ -19,3 +21,15 @@ def decorator(request, *args, **kwargs):
return f(request, *args, **kwargs)

return decorator


def require_dict_data(f):
def decorator(request, *args, **kwargs):
if request.method == 'POST':
DummySerializer(data=request.data).is_valid(raise_exception=True)
return f(request, *args, **kwargs)
return decorator


class DummySerializer(serializers.Serializer):
pass
5 changes: 5 additions & 0 deletions misago/users/api/auth.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@
from django.views.decorators.csrf import csrf_protect

from misago.conf import settings
from misago.core.decorators import require_dict_data
from misago.core.mail import mail_user
from misago.users.bans import get_user_ban
from misago.users.forms.auth import AuthenticationForm, ResendActivationForm, ResetPasswordForm
Expand All @@ -32,6 +33,7 @@ def gateway(request):
@api_view(['POST'])
@permission_classes((UnbannedAnonOnly, ))
@csrf_protect
@require_dict_data
def login(request):
"""
POST /auth/ with CSRF, username and password
Expand Down Expand Up @@ -85,6 +87,7 @@ def get_criteria(request):
@api_view(['POST'])
@permission_classes((UnbannedAnonOnly, ))
@csrf_protect
@require_dict_data
def send_activation(request):
"""
POST /auth/send-activation/ with CSRF token and email
Expand Down Expand Up @@ -123,6 +126,7 @@ def send_activation(request):
@api_view(['POST'])
@permission_classes((UnbannedOnly, ))
@csrf_protect
@require_dict_data
def send_password_form(request):
"""
POST /auth/send-password-form/ with CSRF token and email
Expand Down Expand Up @@ -167,6 +171,7 @@ class PasswordChangeFailed(Exception):
@api_view(['POST'])
@permission_classes((UnbannedOnly, ))
@csrf_protect
@require_dict_data
def change_forgotten_password(request, pk, token):
"""
POST /auth/change-password/user/token/ with CSRF and new password
Expand Down
2 changes: 2 additions & 0 deletions misago/users/api/userendpoints/avatar.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,12 +7,14 @@
from django.utils.translation import ugettext as _

from misago.conf import settings
from misago.core.decorators import require_dict_data
from misago.core.utils import format_plaintext_for_html
from misago.users import avatars
from misago.users.models import AvatarGallery
from misago.users.serializers import ModerateAvatarSerializer


@require_dict_data
def avatar_endpoint(request, pk=None):
if request.user.is_avatar_locked:
if request.user.avatar_lock_user_message:
Expand Down
38 changes: 37 additions & 1 deletion misago/users/tests/test_auth_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,15 @@ def test_submit_empty(self):
response = self.client.post('/api/auth/')
self.assertContains(response, 'empty_data', status_code=400)

def test_submit_invalid(self):
"""login api errors for invalid data"""
response = self.client.post(
'/api/auth/',
'false',
content_type="application/json",
)
self.assertContains(response, "Invalid data.", status_code=400)

def test_login_banned(self):
"""login api fails to sign banned user in"""
UserModel.objects.create_user('Bob', '[email protected]', 'Pass.123')
Expand Down Expand Up @@ -279,7 +288,16 @@ def test_submit_empty(self):

self.assertTrue(not mail.outbox)

def test_submit_invalid(self):
def test_submit_invalid_data(self):
"""login api errors for invalid data"""
response = self.client.post(
self.link,
'false',
content_type="application/json",
)
self.assertContains(response, "Invalid data.", status_code=400)

def test_submit_invalid_email(self):
"""request activation link api errors for invalid email"""
response = self.client.post(
self.link,
Expand Down Expand Up @@ -403,6 +421,15 @@ def test_submit_invalid(self):

self.assertTrue(not mail.outbox)

def test_submit_invalid_data(self):
"""login api errors for invalid data"""
response = self.client.post(
self.link,
'false',
content_type="application/json",
)
self.assertContains(response, "Invalid data.", status_code=400)

def test_submit_inactive_user(self):
"""request change password form link api errors for inactive users"""
self.user.requires_activation = 1
Expand Down Expand Up @@ -462,6 +489,15 @@ def test_submit_with_whitespaces(self):
user = UserModel.objects.get(id=self.user.pk)
self.assertTrue(user.check_password(' n3wp4ss! '))

def test_submit_invalid_data(self):
"""login api errors for invalid data"""
response = self.client.post(
self.link % (self.user.pk, make_password_change_token(self.user)),
'false',
content_type="application/json",
)
self.assertContains(response, "Invalid data.", status_code=400)

def test_invalid_token_link(self):
"""api errors on invalid user id link"""
response = self.client.post(self.link % (self.user.pk, 'asda7ad89sa7d9s789as'))
Expand Down
9 changes: 9 additions & 0 deletions misago/users/tests/test_user_create_api.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,15 @@ def test_empty_request(self):
response = self.client.post(self.api_link)
self.assertEqual(response.status_code, 400)

def test_invalid_data(self):
"""invalid request data errors with code 400"""
response = self.client.post(
self.api_link,
'false',
content_type="application/json",
)
self.assertEqual(response.status_code, 400)

def test_authenticated_request(self):
"""authentiated user request errors with code 403"""
self.login_user(self.get_authenticated_user())
Expand Down

0 comments on commit e24149a

Please sign in to comment.