aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lava_results_app/models.py33
-rw-r--r--lava_results_app/views/query/views.py10
-rw-r--r--lava_scheduler_app/managers.py88
-rw-r--r--lava_scheduler_app/models.py9
-rwxr-xr-xsetup.py2
5 files changed, 131 insertions, 11 deletions
diff --git a/lava_results_app/models.py b/lava_results_app/models.py
index fc829817d..c9961e759 100644
--- a/lava_results_app/models.py
+++ b/lava_results_app/models.py
@@ -49,6 +49,12 @@ from lava_scheduler_app.models import (
Device,
DeviceType
)
+from lava_scheduler_app.managers import (
+ RestrictedTestJobQuerySet,
+ RestrictedTestCaseQuerySet,
+ RestrictedTestSuiteQuerySet
+)
+
from lava_results_app.utils import help_max_length
# TODO: this may need to be ported - clashes if redefined
@@ -117,6 +123,9 @@ class TestSuite(models.Model):
Top level grouping of results from a job.
Directly linked to a single TestJob, the job can have multiple TestSets.
"""
+
+ objects = models.Manager.from_queryset(RestrictedTestSuiteQuerySet)()
+
job = models.ForeignKey(
TestJob,
)
@@ -180,6 +189,9 @@ class TestCase(models.Model):
Result of an individual test case.
lava-test-case or action result
"""
+
+ objects = models.Manager.from_queryset(RestrictedTestCaseQuerySet)()
+
RESULT_PASS = 0
RESULT_FAIL = 1
RESULT_SKIP = 2
@@ -490,6 +502,8 @@ def TestJobViewFactory(query):
class TestJobMaterializedView(QueryMaterializedView, TestJob):
+ objects = models.Manager.from_queryset(RestrictedTestJobQuerySet)()
+
class Meta(QueryMaterializedView.Meta):
db_table = '%s%s' % (QueryMaterializedView.QUERY_VIEW_PREFIX,
query.id)
@@ -501,6 +515,8 @@ def TestCaseViewFactory(query):
class TestCaseMaterializedView(QueryMaterializedView, TestCase):
+ objects = models.Manager.from_queryset(RestrictedTestCaseQuerySet)()
+
class Meta(QueryMaterializedView.Meta):
db_table = '%s%s' % (QueryMaterializedView.QUERY_VIEW_PREFIX,
query.id)
@@ -512,6 +528,8 @@ def TestSuiteViewFactory(query):
class TestSuiteMaterializedView(QueryMaterializedView, TestSuite):
+ objects = models.Manager.from_queryset(RestrictedTestSuiteQuerySet)()
+
class Meta(QueryMaterializedView.Meta):
db_table = '%s%s' % (QueryMaterializedView.QUERY_VIEW_PREFIX,
query.id)
@@ -592,10 +610,10 @@ class Query(models.Model):
def __unicode__(self):
return "<Query ~%s/%s>" % (self.owner.username, self.name)
- def get_results(self):
+ def get_results(self, user):
if self.is_live:
return Query.get_queryset(self.content_type,
- self.querycondition_set.all())
+ self.querycondition_set.all()).visible_by_user(user)
else:
if self.content_type.model_class() == TestJob:
view = TestJobViewFactory(self)
@@ -604,10 +622,15 @@ class Query(models.Model):
elif self.content_type.model_class() == TestSuite:
view = TestSuiteViewFactory(self)
- return view.__class__.objects.all()
+ return view.__class__.objects.all().visible_by_user(user)
@classmethod
def get_queryset(cls, content_type, conditions):
+ """ Return list of QuerySet objects for class 'content_type'.
+
+ Be mindful when using this method directly as it does not apply the
+ visibility rules.
+ """
logger = logging.getLogger('lava_results_app')
filters = {}
@@ -731,8 +754,8 @@ class Query(models.Model):
super(Query, self).delete(*args, **kwargs)
def is_accessible_by(self, user):
- if user.is_superuser or query.user == user or \
- query.group in user.groups.all():
+ if user.is_superuser or self.owner == user or \
+ self.group in user.groups.all():
return True
return False
diff --git a/lava_results_app/views/query/views.py b/lava_results_app/views/query/views.py
index 2af7563ee..a0a3aaed8 100644
--- a/lava_results_app/views/query/views.py
+++ b/lava_results_app/views/query/views.py
@@ -142,7 +142,8 @@ class QueryCustomResultView(LavaView):
super(QueryCustomResultView, self).__init__(request, **kwargs)
def get_queryset(self):
- return Query.get_queryset(self.content_type, self.conditions)
+ return Query.get_queryset(self.content_type,
+ self.conditions).visible_by_user(user)
class QueryResultView(LavaView):
@@ -153,7 +154,7 @@ class QueryResultView(LavaView):
super(QueryResultView, self).__init__(request, **kwargs)
def get_queryset(self):
- return self.query.get_results()
+ return self.query.get_results(self.request.user)
@BreadCrumb("Queries", parent=index)
@@ -437,7 +438,7 @@ def query_export(request, username, name):
"""
query = get_object_or_404(Query, owner__username=username, name=name)
- results = query.get_results()
+ results = query.get_results(request.user)
filename = "query_%s_%s_export" % (query.owner.username, query.name)
return _export_query(results, query.content_type, filename)
@@ -463,7 +464,8 @@ def query_export_custom(request):
filename = "query_%s_export" % (content_type)
try:
- results = Query.get_queryset(content_type, conditions)
+ results = Query.get_queryset(content_type, conditions).visible_by_user(
+ user)
except FieldError:
raise InvalidConditionsError("Conditions URL incorrect: Field does "
"not exist. Please refer to query docs.")
diff --git a/lava_scheduler_app/managers.py b/lava_scheduler_app/managers.py
new file mode 100644
index 000000000..640c019da
--- /dev/null
+++ b/lava_scheduler_app/managers.py
@@ -0,0 +1,88 @@
+# Copyright (C) 2015 Linaro Limited
+#
+# Author: Stevan Radakovic <stevan.radakovic@linaro.org>
+#
+# This file is part of Lava Server.
+#
+# Lava Server is free software: you can redistribute it and/or modify
+# it under the terms of the GNU Affero General Public License version 3
+# as published by the Free Software Foundation
+#
+# Lava Server is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU Affero General Public License
+# along with Lava Server. If not, see <http://www.gnu.org/licenses/>.
+
+from django.db import models
+from django.db.models import Q
+
+from django_restricted_resource.managers import RestrictedResourceQuerySet
+
+from lava_scheduler_app import utils
+
+
+class RestrictedTestJobQuerySet(RestrictedResourceQuerySet):
+
+ def visible_by_user(self, user):
+
+ from lava_scheduler_app.models import TestJob
+ # Legacy jobs.
+ conditions_legacy = Q(is_pipeline=False)
+ if not user:
+ conditions_legacy &= Q(is_public=True)
+ elif not user.is_superuser and not user.has_perm('lava_scheduler_app.cancel_resubmit_testjob'):
+ # continue adding conditions only if user is not superuser and
+ # does not have admin permission for jobs.
+ conditions_legacy &= (Q(is_public=True) |
+ Q(user=user) |
+ Q(submitter=user) |
+ Q(group__in=user.groups.all()))
+
+ # Pipeline jobs.
+ conditions = Q(is_pipeline=True)
+ if not user:
+ conditions_legacy &= Q(is_public=True)
+ elif not user.is_superuser and not user.has_perm('lava_scheduler_app.cancel_resubmit_testjob') and not user.has_perm('lava_scheduler_app.change_device'):
+ # continue adding conditions only if user is not superuser and
+ # does not have admin permission for jobs or devices.
+ conditions &= (
+ Q(is_public=True) |
+ Q(submitter=user) |
+ (~Q(actual_device=None) & Q(actual_device__user=user)) |
+ Q(visibility=TestJob.VISIBLE_PUBLIC) |
+ Q(visibility=TestJob.VISIBLE_PERSONAL, submitter=user) |
+ # NOTE: this supposedly does OR and we need user to be in
+ # all the visibility groups if we allow multiple groups in
+ # field viewing groups.
+ Q(visibility=TestJob.VISIBLE_GROUP,
+ viewing_groups__in=user.groups.all())
+ )
+
+ conditions |= conditions_legacy
+ queryset = self.filter(conditions)
+
+ return queryset
+
+
+class RestrictedTestCaseQuerySet(RestrictedResourceQuerySet):
+
+ def visible_by_user(self, user):
+
+ from lava_scheduler_app.models import TestJob
+ jobs = TestJob.objects.filter(
+ testsuite__testcase__in=self).visible_by_user(user)
+
+ return self.filter(suite__job__in=jobs)
+
+
+class RestrictedTestSuiteQuerySet(models.QuerySet):
+
+ def visible_by_user(self, user):
+
+ from lava_scheduler_app.models import TestJob
+ jobs = TestJob.objects.filter(testsuite__in=self).visible_by_user(user)
+
+ return self.filter(job__in=jobs)
diff --git a/lava_scheduler_app/models.py b/lava_scheduler_app/models.py
index 6338b693d..14475fa60 100644
--- a/lava_scheduler_app/models.py
+++ b/lava_scheduler_app/models.py
@@ -30,7 +30,12 @@ from django_kvstore import models as kvmodels
from django_kvstore import get_kvstore
from django.utils import timezone
-from django_restricted_resource.models import RestrictedResource
+from django_restricted_resource.models import (
+ RestrictedResource,
+ RestrictedResourceManager
+)
+from lava_scheduler_app.managers import RestrictedTestJobQuerySet
+
from dashboard_app.models import Bundle, BundleStream
@@ -1359,6 +1364,8 @@ class TestJob(RestrictedResource):
"""
A test job is a test process that will be run on a Device.
"""
+ objects = RestrictedResourceManager.from_queryset(
+ RestrictedTestJobQuerySet)()
SUBMITTED = 0
RUNNING = 1
diff --git a/setup.py b/setup.py
index 959a4f42b..25cd5d6b8 100755
--- a/setup.py
+++ b/setup.py
@@ -55,7 +55,7 @@ setup(
install_requires=[
'django >= 1.6.1',
'django-openid-auth >= 0.5',
- 'django-restricted-resource >= 0.2.7',
+ 'django-restricted-resource >= 2015.09',
'django-tables2 >= 0.13.0',
'docutils >= 0.6',
'lava-tool >= 0.2',