Commit aedd3283 authored by BAIRE Anthony's avatar BAIRE Anthony
Browse files

fix privacy issues in TagList and TagWebappList

webapp lists should never display apps not visible by the request.user

TagWebappList did not implement such a filter. I added the
query_webapps_for_user() helper and use it for TagWebappList, TagList
and WebappList (the list returned by this function is the superset of
webapps that these views are allowed to display).
parent 7eeb477a
Pipeline #45292 failed with stage
in 4 minutes and 21 seconds
......@@ -7,6 +7,7 @@ import re
import redis
import IPy
from django.conf import settings
from django.db.models import Q
import config
from .models import Job, Webapp, AllgoUser
......@@ -201,3 +202,14 @@ def get_request_user(request):
"user", None)
def query_webapps_for_user(user):
"""Return a queryset of all webapps visible by a given user"""
if user.is_superuser:
return Webapp.objects.all()
# select webapps that are either public or owned by the user
return Webapp.objects.filter(Q(private=False) | Q(
......@@ -11,6 +11,7 @@ Attributes:
# Python standard libraries
import glob
import io
import itertools
import json
import logging
import re
......@@ -30,6 +31,7 @@ from django.contrib import messages
from django.contrib.auth.forms import PasswordChangeForm
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User
from django.contrib.contenttypes.models import ContentType
from django.contrib.messages.views import SuccessMessageMixin
from django.core.exceptions import ObjectDoesNotExist
from django.core.urlresolvers import reverse
......@@ -69,7 +71,7 @@ from .forms import (
# Local imports
import config
from .helpers import get_base_url, get_ssh_data, upload_data, notify_controller, lookup_job_file, get_request_user
from .helpers import get_base_url, get_ssh_data, upload_data, notify_controller, lookup_job_file, get_request_user, query_webapps_for_user
from .mixins import IsProviderMixin, JobAuthMixin
from .models import (
......@@ -173,8 +175,9 @@ class WebappList(ListView):
context_object_name = 'webapps'
paginate_by = 10
template_name = 'webapp_list.html'
queryset = Webapp.objects.filter(private=0).order_by('-created_at')
def get_queryset(self):
return query_webapps_for_user(self.request.user).order_by('-created_at')
class UserWebappList(ListView):
"""List of user's webapp
......@@ -721,7 +724,32 @@ class TagList(ListView):
Each tag return as well the number of webapps attached to it
tags = Tag.objects.annotate(num_tag=Count('taggit_taggeditem_items'))
# Compute the list of tags with the count of webapps visible by this user
# We need a raw request because filtering on Count() is not supported
# in django 1.11.
# In django>=2.0 we should be able to write something like:
# tags = Tag.objects.annotate(num_tag=Count('taggit_taggeditem_items',
# filter = Q(...)))
# list of webapp ids visible by the current user
webapp_ids = tuple(itertools.chain(
# webapp content id (to select onl the tags on Webapp objects)
webapp_content_id = ContentType.objects.get(app_label="main", model="Webapp").id
# compute the list of tags with the webapp count (in the webapp_ids subset)
tags = Tag.objects.raw("""
SELECT taggit_tag.*, count(*) as num_tag
FROM taggit_tag JOIN taggit_taggeditem
WHERE content_type_id=%s AND object_id in %s
GROUP BY tag_id
""", (webapp_content_id, webapp_ids))
return tags
......@@ -741,7 +769,8 @@ class TagWebappList(ListView):
template_name = 'tag_webapp_list.html'
def get_queryset(self):
return Webapp.objects.filter(tags__slug=self.kwargs['slug'])
return query_webapps_for_user(self.request.user
def get_context_data(self, **kwargs):
return super().get_context_data(tag=self.kwargs["slug"], **kwargs)
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment