Skip to content

Commit

Permalink
Add Infra for PUT
Browse files Browse the repository at this point in the history
Added authentications and validation of the data for PUT of the result
  • Loading branch information
shubhamdotjain committed Aug 8, 2018
1 parent 0706a69 commit aeb5f6a
Show file tree
Hide file tree
Showing 3 changed files with 137 additions and 4 deletions.
47 changes: 43 additions & 4 deletions api/rest.py
Expand Up @@ -26,6 +26,9 @@
from mbox import addr_db_to_rest, MboxMessage
from rest_framework.parsers import JSONParser, BaseParser
from rest_framework.authentication import SessionAuthentication
from rest_framework.exceptions import ValidationError
import re
import mod

class CsrfExemptSessionAuthentication(SessionAuthentication):

Expand Down Expand Up @@ -65,8 +68,9 @@ def has_group_permission(self, request, view):

def has_generic_permission(self, request, view):
return (request.method in permissions.SAFE_METHODS) or \
self.is_superuser(request) or \
self.has_group_permission(request, view)
self.is_superuser(request) or \
self.has_group_permission(request, view) or \
self.has_result_group_permission(request, view)

def has_permission(self, request, view):
return self.has_generic_permission(request, view) or \
Expand All @@ -78,7 +82,22 @@ def has_object_permission(self, request, view, obj):
(isinstance(obj, Message) and \
self.has_message_permission(request, view, obj)) or \
(isinstance(obj, Project) and \
self.has_project_permission(request, view, obj))
self.has_project_permission(request, view, obj)) or \
(isinstance(obj, Result) and \
self.has_result_permission(request, view, obj))

def has_result_group_permission(self, request, view):
name = request.resolver_match.kwargs.get('name')
if name:
found = re.match("^[^.]*", name)
module = mod.get_module(found.group(0)) if found else None
for grp in request.user.groups.all():
if grp.name in module.allowed_groups:
return True
return False

def has_result_permission(self, request, view, result_obj):
return self.has_object_permission(request, view, result_obj.project)

class ImportPermission(PatchewPermission):
allowed_groups = ('importers',)
Expand Down Expand Up @@ -475,6 +494,14 @@ def get_log_url(self, obj):
request = self.context['request']
return obj.get_log_url(request)

def validate(self, data):
found = re.match("^[^.]*", self.instance.name)
module = mod.get_module(found.group(0)) if found else None
is_valid = module.result_data_serializer_class(data=data['data']).is_valid(raise_exception=True)
if found is None and not is_valid:
raise ValidationError("Invalid")
return data

class ResultSerializerFull(ResultSerializer):
class Meta:
model = Result
Expand All @@ -484,18 +511,30 @@ class Meta:
log = CharField(required=False)

class ResultsViewSet(mixins.ListModelMixin, mixins.RetrieveModelMixin,
viewsets.GenericViewSet):
mixins.UpdateModelMixin, viewsets.GenericViewSet):
lookup_field = 'name'
lookup_value_regex = '[^/]+'
filter_backends = (filters.OrderingFilter,)
ordering_fields = ('name',)
ordering = ('name',)
authentication_classes = (CsrfExemptSessionAuthentication, )
permission_classes = (PatchewPermission, )

def get_serializer_class(self, *args, **kwargs):
if self.lookup_field in self.kwargs:
return ResultSerializerFull
return ResultSerializer

@property
def project(self):
if hasattr(self, '__project'):
return self.__project
try:
self.__project = Project.objects.get(id=self.kwargs['projects_pk'])
except:
self.__project = None
return self.__project

class ProjectResultsViewSet(ResultsViewSet):
def get_queryset(self):
return ProjectResult.objects.filter(project=self.kwargs['projects_pk'])
Expand Down
47 changes: 47 additions & 0 deletions tests/test_git.py
Expand Up @@ -15,6 +15,7 @@
import shutil
import subprocess
from api.models import Message, Result
import json

class GitTest(PatchewTestCase):

Expand Down Expand Up @@ -101,6 +102,52 @@ def test_rest_need_apply(self):
self.assertEqual(resp.data['log_url'], None)
self.assertEqual(resp.data['log'], None)

def test_auth_importer(self):
self.cli_import("0013-foo-patch.mbox.gz")
MESSAGE_ID = '20160628014747.20971-1-famz@redhat.com'
test = self.create_user(username="test", password="userpass", groups=['importers'])
self.api_client.login(username="test", password="userpass")
data = {
"name": "testing.a",
"status": "failure",
"data": {"tag": "test_tag", "url": "test_url", "repo": "test_repo", "base": "test_base"},
"log": "test",
"last_update": '2018-08-07T03:51:13.262213'}

resp= self.api_client.put('%sseries/%s/results/git/' % (self.PROJECT_BASE, MESSAGE_ID), data=json.dumps(data), content_type='application/json')
self.assertEquals(resp.status_code, 200)
self.assertEquals(resp.data['log'], "test")

def test_data_validation(self):
self.cli_import("0013-foo-patch.mbox.gz")
MESSAGE_ID = '20160628014747.20971-1-famz@redhat.com'
test = self.create_user(username="test", password="userpass", groups=['importers'])
self.api_client.login(username="test", password="userpass")
data = {
"name": "testing.a",
"status": "failure",
"data": "",
"log": "test",
"last_update": '2018-08-07T03:51:13.262213'}

resp= self.api_client.put('%sseries/%s/results/git/' % (self.PROJECT_BASE, MESSAGE_ID), data=json.dumps(data), content_type='application/json')
self.assertEquals(resp.status_code, 400)

def test_auth_without_permission(self):
self.cli_import("0013-foo-patch.mbox.gz")
MESSAGE_ID = '20160628014747.20971-1-famz@redhat.com'
test = self.create_user(username="test", password="userpass")
self.api_client.login(username="test", password="userpass")
data = {
"name": "testing.a",
"status": "failure",
"data": {"tag": "test_tag", "url": "test_url", "repo": "test_repo", "base": "test_base"},
"log": "test",
"last_update": '2018-08-07T03:51:13.262213'}

resp= self.api_client.put('%sseries/%s/results/git/' % (self.PROJECT_BASE, MESSAGE_ID), data=json.dumps(data), content_type='application/json')
self.assertEquals(resp.status_code, 403)

def test_rest_git_base(self):
self.cli_import("0013-foo-patch.mbox.gz")
self.do_apply()
Expand Down
47 changes: 47 additions & 0 deletions tests/test_testing.py
Expand Up @@ -15,6 +15,7 @@
sys.path.append(os.path.dirname(__file__))
from tests.patchewtest import PatchewTestCase, main
from api.models import Message, Result
import json

def create_test(project, name):
prefix = "testing.tests." + name + "."
Expand Down Expand Up @@ -214,6 +215,7 @@ def setUp(self):

self.p1 = self.add_project("QEMU", "qemu-devel@nongnu.org")
create_test(self.p1, "a")
self.PROJECT_BASE = '%sprojects/%d/' % (self.REST_BASE, self.p1.id)
self.p2 = self.add_project("UMEQ", "qemu-devel@nongnu.org")
create_test(self.p2, "b")

Expand Down Expand Up @@ -248,6 +250,51 @@ def update_head(self, p):
cwd=self.repo).decode()
p.set_property("git.head", head)

def test_auth_tester(self):
resp = self.api_client.get('%sresults/' % (
self.PROJECT_BASE))
test = self.create_user(username="test", password="userpass", groups=['testers'])
self.api_client.login(username="test", password="userpass")
data = {
"name": "testing.a",
"status": "failure",
"data": {"head": "test_head", "tester": "test_tester", "is_timeout": False},
"log": "test",
"last_update": '2018-08-07T03:51:13.262213'}

resp1= self.api_client.put(resp.data['results'][0]['resource_uri'],data=json.dumps(data), content_type='application/json')
self.assertEquals(resp1.status_code, 200)
self.assertEquals(resp1.data['log'], "test")

def test_data_validation(self):
resp = self.api_client.get('%sresults/' % (
self.PROJECT_BASE))
test = self.create_user(username="test", password="userpass", groups=['testers'])
self.api_client.login(username="test", password="userpass")
data = {
"name":"testing.a",
"status":"failure",
"data":"",
"log":"test",
"last_update": '2018-08-07T03:51:13.262213'}
resp1= self.api_client.put(resp.data['results'][0]['resource_uri'],data=json.dumps(data), content_type='application/json')
self.assertEquals(resp1.status_code, 400)

def test_auth_without_permission(self):
resp = self.api_client.get('%sresults/' % (
self.PROJECT_BASE))
test = self.create_user(username="test", password="userpass")
self.api_client.login(username="test", password="userpass")
data = {
"name": "testing.a",
"status": "failure",
"data": {"head": "test_head", "tester": "test_tester", "is_timeout": False},
"log": "test",
"last_update": '2018-08-07T03:51:13.262213'}

resp1= self.api_client.put(resp.data['results'][0]['resource_uri'],data=json.dumps(data), content_type='application/json')
self.assertEquals(resp1.status_code, 403)

def test_tester(self):
self.cli_login()
out, err = self.check_cli(["tester", "-p", "QEMU,UMEQ",
Expand Down

0 comments on commit aeb5f6a

Please sign in to comment.