Merge pull request #715 from OpenGeoLabs/user-queues-develop

Queues only visible to user with corresponding rights
This commit is contained in:
Garret Wassermann 2019-02-05 23:18:40 -05:00 committed by GitHub
commit 8c4e094705
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 68 additions and 5 deletions

View File

@ -275,8 +275,11 @@ class TicketForm(AbstractTicketForm):
""" """
Add any custom fields that are defined to the form. Add any custom fields that are defined to the form.
""" """
queue_choices = kwargs.pop("queue_choices")
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.fields['queue'].choices = [('', '--------')] + [(q.id, q.title) for q in Queue.objects.all()]
self.fields['queue'].choices = queue_choices
if helpdesk_settings.HELPDESK_STAFF_ONLY_TICKET_OWNERS: if helpdesk_settings.HELPDESK_STAFF_ONLY_TICKET_OWNERS:
assignable_users = User.objects.filter(is_active=True, is_staff=True).order_by(User.USERNAME_FIELD) assignable_users = User.objects.filter(is_active=True, is_staff=True).order_by(User.USERNAME_FIELD)
else: else:

View File

@ -0,0 +1,12 @@
<h1 style='font-family: "Trebuchet MS", Arial, sans-serif; font-size: 14pt; color: #6593C0'>{% block header %}Helpdesk{% endblock %}</h1>
{% block content %}{% endblock %}
<p style='font-family: "Trebuchet MS", Arial, sans-serif; font-size: 11pt;'>Dobrý den,</p>
<p style='font-family: "Trebuchet MS", Arial, sans-serif; font-size: 11pt;'><b>{{ queue.title }}</b>{% if queue.email_address %}<br><a href='mailto:{{ queue.email_address }}'>{{ queue.email_address }}</a>{% endif %}</p>
<p style='font-family: "Trebuchet MS", Arial, sans-serif; font-size: 9pt; color: #808080;'>
Tento automaticky generovaný e-mail Vám byl odeslán jako uživateli naší podpory
v souladu s naší politikou ochrany soukromých dat.
Prosím napište nám, pokud si myslíte, že posílat Vám tento e-mail je chyba.</p>

View File

@ -0,0 +1,8 @@
Dobrý den,
{{ queue.title }}{% if queue.email_address %}
{{ queue.email_address }}{% endif %}
Tento automaticky generovaný e-mail Vám byl odeslán jako uživateli naší podpory
v souladu s naší politikou ochrany soukromých dat.
Prosím napište nám, pokud si myslíte, že posílat Vám tento e-mail je chyba.

View File

@ -5,6 +5,7 @@ from django.urls import reverse
from django.test import TestCase from django.test import TestCase
from django.test.client import Client from django.test.client import Client
from helpdesk.models import CustomField, Queue, Ticket from helpdesk.models import CustomField, Queue, Ticket
from helpdesk import settings as helpdesk_settings
try: # python 3 try: # python 3
from urllib.parse import urlparse from urllib.parse import urlparse
@ -27,12 +28,21 @@ class TicketActionsTestCase(TestCase):
updated_ticket_cc='update.public@example.com' updated_ticket_cc='update.public@example.com'
) )
self.queue_private = Queue.objects.create(
title='Queue 2',
slug='q2',
allow_public_submission=False,
new_ticket_cc='new.private@example.com',
updated_ticket_cc='update.private@example.com'
)
self.ticket_data = { self.ticket_data = {
'title': 'Test Ticket', 'title': 'Test Ticket',
'description': 'Some Test Ticket', 'description': 'Some Test Ticket',
} }
self.client = Client() self.client = Client()
helpdesk_settings.HELPDESK_ENABLE_PER_QUEUE_STAFF_PERMISSION = False
def loginUser(self, is_staff=True): def loginUser(self, is_staff=True):
"""Create a staff user and login""" """Create a staff user and login"""
@ -143,14 +153,14 @@ class TicketActionsTestCase(TestCase):
initial_data = { initial_data = {
'title': 'Private ticket test', 'title': 'Private ticket test',
'queue': self.queue_public, 'queue': self.queue_private,
'assigned_to': self.user, 'assigned_to': self.user,
'status': Ticket.OPEN_STATUS, 'status': Ticket.OPEN_STATUS,
} }
# create ticket # create ticket
helpdesk_settings.HELPDESK_ENABLE_PER_QUEUE_STAFF_PERMISSION = True
ticket = Ticket.objects.create(**initial_data) ticket = Ticket.objects.create(**initial_data)
self.assertEqual(_is_my_ticket(self.user, ticket), True) self.assertEqual(_is_my_ticket(self.user, ticket), True)
self.assertEqual(_is_my_ticket(self.user2, ticket), False) self.assertEqual(_is_my_ticket(self.user2, ticket), False)

View File

@ -71,6 +71,20 @@ superuser_required = user_passes_test(
lambda u: u.is_authenticated and u.is_active and u.is_superuser) lambda u: u.is_authenticated and u.is_active and u.is_superuser)
def _get_queue_choices(queues):
"""Return list of `choices` array for html form for given queues
idea is to return only one choice if there is only one queue or add empty
choice at the beginning of the list, if there are more queues
"""
queue_choices = []
if len(queues) > 1:
queue_choices = [('', '--------')]
queue_choices += [(q.id, q.title) for q in queues]
return queue_choices
def _get_user_queues(user): def _get_user_queues(user):
"""Return the list of Queues the user can access. """Return the list of Queues the user can access.
@ -78,11 +92,15 @@ def _get_user_queues(user):
:return: A Python list of Queues :return: A Python list of Queues
""" """
all_queues = Queue.objects.all() all_queues = Queue.objects.all()
public_ids = [q.pk for q in
Queue.objects.filter(allow_public_submission=True)]
limit_queues_by_user = \ limit_queues_by_user = \
helpdesk_settings.HELPDESK_ENABLE_PER_QUEUE_STAFF_PERMISSION \ helpdesk_settings.HELPDESK_ENABLE_PER_QUEUE_STAFF_PERMISSION \
and not user.is_superuser and not user.is_superuser
if limit_queues_by_user: if limit_queues_by_user:
id_list = [q.pk for q in all_queues if user.has_perm(q.permission_name)] id_list = [q.pk for q in all_queues if user.has_perm(q.permission_name)]
id_list += public_ids
return all_queues.filter(pk__in=id_list) return all_queues.filter(pk__in=id_list)
else: else:
return all_queues return all_queues
@ -104,7 +122,10 @@ def _has_access_to_queue(user, queue):
def _is_my_ticket(user, ticket): def _is_my_ticket(user, ticket):
"""Check to see if the user has permission to access """Check to see if the user has permission to access
a ticket. If not then deny access.""" a ticket. If not then deny access."""
if user.is_superuser or user.is_staff or user.id == ticket.assigned_to.id: if _has_access_to_queue(user, ticket.queue):
return True
elif user.is_superuser or user.is_staff or \
(ticket.assigned_to and user.id == ticket.assigned_to.id):
return True return True
else: else:
return False return False
@ -323,8 +344,11 @@ def view_ticket(request, ticket_id):
else: else:
users = User.objects.filter(is_active=True).order_by(User.USERNAME_FIELD) users = User.objects.filter(is_active=True).order_by(User.USERNAME_FIELD)
queues = _get_user_queues(request.user)
queue_choices = _get_queue_choices(queues)
# TODO: shouldn't this template get a form to begin with? # TODO: shouldn't this template get a form to begin with?
form = TicketForm(initial={'due_date': ticket.due_date}) form = TicketForm(initial={'due_date': ticket.due_date},
queue_choices=queue_choices)
ticketcc_string, show_subscribe = \ ticketcc_string, show_subscribe = \
return_ticketccstring_and_show_subscribe(request.user, ticket) return_ticketccstring_and_show_subscribe(request.user, ticket)
@ -1025,6 +1049,12 @@ class CreateTicketView(MustBeStaffMixin, FormView):
initial_data['queue'] = request.GET['queue'] initial_data['queue'] = request.GET['queue']
return initial_data return initial_data
def get_form_kwargs(self):
kwargs = super().get_form_kwargs()
queues = _get_user_queues(self.request.user)
kwargs["queue_choices"] = _get_queue_choices(queues)
return kwargs
def form_valid(self, form): def form_valid(self, form):
self.ticket = form.save() self.ticket = form.save()
return super().form_valid(form) return super().form_valid(form)