Skip to content

Commit

Permalink
Implement POST /group-field/{pk}/validate to check if data is validat…
Browse files Browse the repository at this point in the history
…ed by a filter + related tests.
  • Loading branch information
TheBirdie authored and TheBirdie committed Jan 29, 2016
1 parent 6838caf commit 73929a6
Show file tree
Hide file tree
Showing 3 changed files with 94 additions and 2 deletions.
4 changes: 2 additions & 2 deletions sigma_core/models/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ def get_validator_by_name(name):
validator = { validate_fields: vf, validate_input: vi }
Where:
- vf(fields)
returns True iif the specified fields are valid - or returns False/raises exceptions
Raises a ValidationError if given fields are not valid for this validator
- vi(fields, user_input)
Throws a ValidationError if given input is not valid for this validator
Expand All @@ -30,7 +30,7 @@ def text_validate_fields(fields):
try:
re.compile(fields['regex'])
except re.error:
raise ValidationError("Invalid Regex syntax")
raise ValidationError(fields['message'] + " (invalid Regex syntax)")

# Protection against Evil Regex. Only 50ms to evaluate regex - should be enough.
@timeout_decorator.timeout(0.05, use_signals=False)
Expand Down
67 changes: 67 additions & 0 deletions sigma_core/tests/test_group_field.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ def setUpTestData(self):
GroupMemberFactory(user=self.users[3], group=self.group, perm_rank=Group.ADMINISTRATOR_RANK)
]
self.validator_none = Validator.objects.all().get(html_name=Validator.VALIDATOR_NONE)
self.validator_text = Validator.objects.all().get(html_name=Validator.VALIDATOR_TEXT)
self.group_field = GroupFieldFactory(group=self.group, validator=self.validator_none, validator_values={})

# Misc
Expand Down Expand Up @@ -181,3 +182,69 @@ def test_create_invalid_regex(self):
def test_create_valid_regex(self):
self.assertEqual(self.try_create(self.users[3], self.new_field_data_email_validator),
status.HTTP_201_CREATED)


class GroupFieldValidatorTests(APITestCase):
fixtures = ['fixtures_prod.json']
@classmethod
def setUpTestData(self):
super(APITestCase, self).setUpTestData()

# Routes
self.group_field_url = "/group-field/"

# Group open to anyone
self.group = GroupFactory()

# Users already in group
# User[0]: Not in Group
# User[1]: Requested join, not accepted
# User[2]: Group member
# User[3]: Group admin
self.users = [UserFactory(), UserFactory(), UserFactory(), UserFactory()]
# Associated GroupMember
self.group_member = [
None,
GroupMemberFactory(user=self.users[1], group=self.group, perm_rank=0),
GroupMemberFactory(user=self.users[2], group=self.group, perm_rank=1),
GroupMemberFactory(user=self.users[3], group=self.group, perm_rank=Group.ADMINISTRATOR_RANK)
]
self.validator_none = Validator.objects.all().get(html_name=Validator.VALIDATOR_NONE)

# If you need to test validators more in deep, see test_validators.py
self.validator_text = Validator.objects.all().get(html_name=Validator.VALIDATOR_TEXT)
self.email_vdtor = GroupFieldFactory(group=self.group,
validator=self.validator_text,
validator_values={"regex": "[a-z0-9]*@[a-z0-9]*.[a-z]{2,3}", "message": "Invalid email"})

#################### ../{pk}/validate ########################
def _test_validate_input(self, user, validatorId, input, expectHttp, isInputValid):
self.client.force_authenticate(user=user)
resp = self.client.post("%s%d/validate/" % (self.group_field_url, validatorId), {"value": input})
self.assertEqual(resp.status_code, expectHttp)
if resp.status_code == status.HTTP_200_OK:
if isInputValid:
self.assertEqual(resp.data['status'], "ok")
else:
self.assertEqual(resp.data['status'], "ko")

def test_validate_route_not_authed(self):
self._test_validate_input(None, self.email_vdtor.id, "input@lol.fr", status.HTTP_401_UNAUTHORIZED, True)

def test_validate_route_not_group_member(self):
self._test_validate_input(self.users[0], self.email_vdtor.id, "input@lol.fr", status.HTTP_404_NOT_FOUND, True)

def test_validate_route_not_accepted_ok(self):
self._test_validate_input(self.users[1], self.email_vdtor.id, "input@lol.fr", status.HTTP_200_OK, True)

def test_validate_route_not_admin_ok(self):
self._test_validate_input(self.users[2], self.email_vdtor.id, "input@lol.fr", status.HTTP_200_OK, True)

def test_validate_route_admin_ok(self):
self._test_validate_input(self.users[3], self.email_vdtor.id, "input@lol.fr", status.HTTP_200_OK, True)

def test_validate_route_bad_email(self):
self._test_validate_input(self.users[3], self.email_vdtor.id, "ThisIsNoAnEmail", status.HTTP_200_OK, False)

def test_validate_route_bad_validator(self):
self._test_validate_input(self.users[3], -1, "input@lol.fr", status.HTTP_404_NOT_FOUND, True)
25 changes: 25 additions & 0 deletions sigma_core/views/group_field.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
from django.http import Http404, HttpResponseForbidden
from django.core.exceptions import ValidationError

from rest_framework import viewsets, decorators, status, mixins
from rest_framework.response import Response
Expand Down Expand Up @@ -40,3 +41,27 @@ def create(self, request):

serializer.save()
return Response(serializer.data, status=status.HTTP_201_CREATED)

@decorators.detail_route(methods=['post'])
def validate(self, request, pk):
"""
For given custom field $pk, we check if the client input passes the Validation
"""
from sigma_core.models.group_field import GroupField
if not request.user.is_authenticated():
return Response(status=status.HTTP_401_UNAUTHORIZED)
client_input = request.data.get('value')
if client_input is None:
return Response("No value given", status=status.HTTP_400_BAD_REQUEST)

try:
gf = self.get_queryset().get(id=pk)
try:
gf.validator.validate_input(gf.validator_values, client_input)
return Response({"status": "ok"}, status=status.HTTP_200_OK)
except ValidationError as err:
return Response({"status": "ko", "message": err.messages}, status=status.HTTP_200_OK)
except:
return Response({"status": "ko", "message": "Invalid input"}, status=status.HTTP_200_OK)
except:
return Response(status=status.HTTP_404_NOT_FOUND)

0 comments on commit 73929a6

Please sign in to comment.