Merge custom staff filter, PR #239

This commit is contained in:
Garret Wassermann 2017-10-30 03:17:40 -04:00
commit 3a1bd76e75
10 changed files with 333 additions and 29 deletions

View File

@ -108,8 +108,12 @@ These options only change display of items on public-facing pages, not staff pag
Options that change ticket updates Options that change ticket updates
---------------------------------- ----------------------------------
- **HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE** Allow non-staff users to interact with tickets? This will also change how 'staff_member_required' - **HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE** Allow non-staff users to interact with tickets?
in staff.py will be defined. Set to True to allow any authenticated user to manage tickets.
You can also apply a custom authorisation logic for identifying helpdesk staff members, by setting this to a callable.
In that case, the value should be a function accepting the active user as a parameter and returning True if the user is considered helpdesk staff, e.g.
lambda u: u.is_authenticated() and u.is_active and u.groups.filter(name='helpdesk_staff').exists()))
**Default:** ``HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE = False`` **Default:** ``HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE = False``

View File

@ -3,9 +3,21 @@ from functools import wraps
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.http import HttpResponseRedirect, Http404 from django.http import HttpResponseRedirect, Http404
from django.utils.decorators import available_attrs from django.utils.decorators import available_attrs
from django.contrib.auth.decorators import user_passes_test
from helpdesk import settings as helpdesk_settings from helpdesk import settings as helpdesk_settings
if callable(helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE):
# apply a custom user validation condition
is_helpdesk_staff = helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE
elif helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE:
# treat 'normal' users like 'staff'
is_helpdesk_staff = lambda u: u.is_authenticated() and u.is_active
else:
is_helpdesk_staff = lambda u: u.is_authenticated() and u.is_active and u.is_staff
helpdesk_staff_member_required = user_passes_test(is_helpdesk_staff)
helpdesk_superuser_required = user_passes_test(lambda u: u.is_authenticated() and u.is_active and u.is_superuser)
def protect_view(view_func): def protect_view(view_func):
""" """
@ -21,3 +33,4 @@ def protect_view(view_func):
return view_func(request, *args, **kwargs) return view_func(request, *args, **kwargs)
return _wrapped_view return _wrapped_view

View File

@ -312,6 +312,7 @@ def process_attachments(followup, attached_files):
attachments = [] attachments = []
for attached in attached_files: for attached in attached_files:
if attached.size: if attached.size:
filename = smart_text(attached.name) filename = smart_text(attached.name)
att = Attachment( att = Attachment(

View File

@ -2,8 +2,9 @@
Default settings for django-helpdesk. Default settings for django-helpdesk.
""" """
import warnings
from django.conf import settings from django.conf import settings
from django.core.exceptions import ImproperlyConfigured
try: try:
@ -85,12 +86,12 @@ HELPDESK_SUBMIT_A_TICKET_PUBLIC = getattr(settings, 'HELPDESK_SUBMIT_A_TICKET_PU
# options for update_ticket views # # options for update_ticket views #
################################### ###################################
''' options for update_ticket views '''
# allow non-staff users to interact with tickets? # allow non-staff users to interact with tickets?
# this will also change how 'staff_member_required' # can be True/False or a callable accepting the active user and returning True if they must be considered helpdesk staff
# in staff.py will be defined. HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE = getattr(settings, 'HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE', False)
HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE = getattr(settings, if not (HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE in (True, False) or callable(HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE)):
'HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE', warnings.warn("HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE should be set to either True/False or a callable.", RuntimeWarning)
False)
# show edit buttons in ticket follow ups. # show edit buttons in ticket follow ups.
HELPDESK_SHOW_EDIT_BUTTON_FOLLOW_UP = getattr(settings, HELPDESK_SHOW_EDIT_BUTTON_FOLLOW_UP = getattr(settings,

View File

@ -1,4 +1,4 @@
{% load i18n %} {% load i18n helpdesk_staff %}
<!-- Navigation --> <!-- Navigation -->
<nav class="navbar navbar-default navbar-fixed-top" role="navigation" style="margin-bottom: 0"> <nav class="navbar navbar-default navbar-fixed-top" role="navigation" style="margin-bottom: 0">
@ -14,7 +14,7 @@
<!-- /.navbar-header --> <!-- /.navbar-header -->
<div class="collapse navbar-collapse" id="helpdesk-nav-collapse"> <div class="collapse navbar-collapse" id="helpdesk-nav-collapse">
{% if helpdesk_settings.HELPDESK_NAVIGATION_ENABLED and user.is_authenticated or user.is_staff %} {% if helpdesk_settings.HELPDESK_NAVIGATION_ENABLED and user.is_authenticated or user|is_helpdesk_staff %}
<ul class="nav navbar-top-links navbar-right"> <ul class="nav navbar-top-links navbar-right">
<li> <li>
<a href='{% url 'helpdesk:dashboard' %}'><i class="fa fa-dashboard fa-fw"></i> <span class="nav-text">{% trans "Dashboard" %}</span></a> <a href='{% url 'helpdesk:dashboard' %}'><i class="fa fa-dashboard fa-fw"></i> <span class="nav-text">{% trans "Dashboard" %}</span></a>
@ -28,6 +28,7 @@
<li> <li>
<a href='{% url 'helpdesk:report_index' %}'><i class="fa fa-bar-chart-o fa-fw"></i> <span class="nav-text"> {% trans "Stats" %}</span></a> <a href='{% url 'helpdesk:report_index' %}'><i class="fa fa-bar-chart-o fa-fw"></i> <span class="nav-text"> {% trans "Stats" %}</span></a>
</li> </li>
{% if helpdesk_settings.HELPDESK_KB_ENABLED %} {% if helpdesk_settings.HELPDESK_KB_ENABLED %}
<li> <li>
<a href='{% url 'helpdesk:kb_index' %}'><i class="fa fa-database fa-fw"></i> <span class="nav-text">{% trans "Knowledgebase" %}</span></a> <a href='{% url 'helpdesk:kb_index' %}'><i class="fa fa-database fa-fw"></i> <span class="nav-text">{% trans "Knowledgebase" %}</span></a>

View File

@ -0,0 +1,22 @@
"""
django-helpdesk - A Django powered ticket tracker for small enterprise.
templatetags/helpdesk_staff.py - The is_helpdesk_staff template filter returns True if the user qualifies as Helpdesk staff.
"""
import logging
from django.template import Library
from django.db.models import Q
from helpdesk.decorators import is_helpdesk_staff
logger = logging.getLogger(__name__)
register = Library()
@register.filter(name='is_helpdesk_staff')
def helpdesk_staff(user):
try:
return is_helpdesk_staff(user)
except Exception, e:
logger.exception("'helpdesk_staff' template tag (django-helpdesk) crashed")

View File

@ -4,6 +4,8 @@ from django.contrib.auth import get_user_model
User = get_user_model() User = get_user_model()
from helpdesk.models import Ticket, Queue
def get_staff_user(username='helpdesk.staff', password='password'): def get_staff_user(username='helpdesk.staff', password='password'):
try: try:
@ -37,4 +39,37 @@ def reload_urlconf(urlconf=None):
clear_url_caches() clear_url_caches()
def update_user_settings(user, **kwargs):
usersettings = user.usersettings
settings = usersettings.settings
settings.update(kwargs)
usersettings.settings = settings
usersettings.save()
def delete_user_settings(user, *args):
usersettings = user.usersettings
settings = usersettings.settings
for setting in args:
if setting in settings:
del settings[setting]
usersettings.settings = settings
usersettings.save()
def create_ticket(**kwargs):
q = kwargs.get('queue', None)
if q is None:
try:
q = Queue.objects.all()[0]
except IndexError:
q = Queue.objects.create(title='Test Q', slug='test', )
data = {
'title': "I wish to register a complaint",
'queue': q,
}
data.update(kwargs)
return Ticket.objects.create(**data)
HELPDESK_URLCONF = 'helpdesk.urls' HELPDESK_URLCONF = 'helpdesk.urls'

View File

@ -1,22 +1,21 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import sys
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
from django.test import TestCase from django.test import TestCase
from helpdesk.tests.helpers import get_staff_user, reload_urlconf
class TestKBDisabled(TestCase):
def setUp(self):
from helpdesk import settings from helpdesk import settings
from helpdesk.tests.helpers import (get_staff_user, reload_urlconf, User, update_user_settings, delete_user_settings,
create_ticket)
class KBDisabledTestCase(TestCase):
def setUp(self):
self.HELPDESK_KB_ENABLED = settings.HELPDESK_KB_ENABLED self.HELPDESK_KB_ENABLED = settings.HELPDESK_KB_ENABLED
if self.HELPDESK_KB_ENABLED: if self.HELPDESK_KB_ENABLED:
settings.HELPDESK_KB_ENABLED = False settings.HELPDESK_KB_ENABLED = False
reload_urlconf() reload_urlconf()
def tearDown(self): def tearDown(self):
from helpdesk import settings
if self.HELPDESK_KB_ENABLED: if self.HELPDESK_KB_ENABLED:
settings.HELPDESK_KB_ENABLED = True settings.HELPDESK_KB_ENABLED = True
reload_urlconf() reload_urlconf()
@ -36,3 +35,193 @@ class TestKBDisabled(TestCase):
raise raise
else: else:
self.assertEqual(response.status_code, 200) self.assertEqual(response.status_code, 200)
class StaffUserTestCaseMixin(object):
HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE = False
def setUp(self):
self.original_setting = settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE
settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE = self.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE
self.reload_views()
def tearDown(self):
settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE = self.original_setting
self.reload_views()
def reload_views(self):
try:
reload(sys.modules['helpdesk.decorators'])
reload(sys.modules['helpdesk.views.staff'])
reload_urlconf()
except KeyError:
pass
def test_anonymous_user(self):
"""Access to the dashboard always requires a login"""
response = self.client.get(reverse('helpdesk_dashboard'), follow=True)
self.assertTemplateUsed(response, 'helpdesk/registration/login.html')
class NonStaffUsersAllowedTestCase(StaffUserTestCaseMixin, TestCase):
HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE = True
def test_non_staff_allowed(self):
"""If HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE is True,
authenticated, non-staff users should be able to access
the dashboard.
"""
from helpdesk.decorators import is_helpdesk_staff
user = User.objects.create_user(username='henry.wensleydale', password='gouda', email='wensleydale@example.com')
self.assertTrue(is_helpdesk_staff(user))
self.client.login(username=user.username, password='gouda')
response = self.client.get(reverse('helpdesk_dashboard'), follow=True)
self.assertTemplateUsed(response, 'helpdesk/dashboard.html')
class StaffUsersOnlyTestCase(StaffUserTestCaseMixin, TestCase):
# Use default values
HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE = False
def test_non_staff(self):
"""Non-staff users are correctly identified"""
from helpdesk.decorators import is_helpdesk_staff
user = User.objects.create_user(username='henry.wensleydale', password='gouda', email='wensleydale@example.com')
self.assertFalse(is_helpdesk_staff(user))
def test_staff_only(self):
"""If HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE is False,
only staff users should be able to access the dashboard.
"""
from helpdesk.decorators import is_helpdesk_staff
user = get_staff_user()
self.assertTrue(is_helpdesk_staff(user))
self.client.login(username=user.username, password='password')
response = self.client.get(reverse('helpdesk_dashboard'), follow=True)
self.assertTemplateUsed(response, 'helpdesk/dashboard.html')
class CustomStaffUserTestCase(StaffUserTestCaseMixin, TestCase):
@staticmethod
def custom_staff_filter(user):
"""Arbitrary user validation function"""
return user.is_authenticated() and user.is_active and user.username.lower().endswith('wensleydale')
HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE = custom_staff_filter
def test_custom_staff_pass(self):
"""If HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE is callable,
a custom access rule is applied.
"""
from helpdesk.decorators import is_helpdesk_staff
user = User.objects.create_user(username='henry.wensleydale', password='gouda', email='wensleydale@example.com')
self.assertTrue(is_helpdesk_staff(user))
self.client.login(username=user.username, password='gouda')
response = self.client.get(reverse('helpdesk_dashboard'), follow=True)
self.assertTemplateUsed(response, 'helpdesk/dashboard.html')
def test_custom_staff_fail(self):
from helpdesk.decorators import is_helpdesk_staff
user = User.objects.create_user(username='terry.milton', password='frog', email='milton@example.com')
self.assertFalse(is_helpdesk_staff(user))
self.client.login(username=user.username, password='frog')
response = self.client.get(reverse('helpdesk_dashboard'), follow=True)
self.assertTemplateUsed(response, 'helpdesk/registration/login.html')
class HomePageAnonymousUserTestCase(TestCase):
def setUp(self):
self.redirect_to_login = settings.HELPDESK_REDIRECT_TO_LOGIN_BY_DEFAULT
def tearDown(self):
settings.HELPDESK_REDIRECT_TO_LOGIN_BY_DEFAULT = self.redirect_to_login
def test_homepage(self):
settings.HELPDESK_REDIRECT_TO_LOGIN_BY_DEFAULT = True
response = self.client.get(reverse('helpdesk_home'))
self.assertTemplateUsed('helpdesk/public_homepage.html')
def test_redirect_to_login(self):
"""Unauthenticated users are redirected to the login page if HELPDESK_REDIRECT_TO_LOGIN_BY_DEFAULT is True"""
settings.HELPDESK_REDIRECT_TO_LOGIN_BY_DEFAULT = True
response = self.client.get(reverse('helpdesk_home'))
self.assertRedirects(response, reverse('login'))
class HomePageTestCase(TestCase):
def setUp(self):
self.original_setting = settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE
settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE = False
try:
reload(sys.modules['helpdesk.views.public'])
except KeyError:
pass
def tearDown(self):
settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE = self.original_setting
reload(sys.modules['helpdesk.views.public'])
def assertUserRedirectedToView(self, user, view_name):
self.client.login(username=user.username, password='password')
response = self.client.get(reverse('helpdesk_home'))
self.assertRedirects(response, reverse(view_name))
self.client.logout()
def test_redirect_to_dashboard(self):
"""Authenticated users are redirected to the dashboard"""
user = get_staff_user()
# login_view_ticketlist is False...
update_user_settings(user, login_view_ticketlist=False)
self.assertUserRedirectedToView(user, 'helpdesk_dashboard')
# ... or missing
delete_user_settings(user, 'login_view_ticketlist')
self.assertUserRedirectedToView(user, 'helpdesk_dashboard')
def test_no_user_settings_redirect_to_dashboard(self):
"""Authenticated users are redirected to the dashboard if user settings are missing"""
from helpdesk.models import UserSettings
user = get_staff_user()
UserSettings.objects.filter(user=user).delete()
self.assertUserRedirectedToView(user, 'helpdesk_dashboard')
def test_redirect_to_ticket_list(self):
"""Authenticated users are redirected to the ticket list based on their user settings"""
user = get_staff_user()
update_user_settings(user, login_view_ticketlist=True)
self.assertUserRedirectedToView(user, 'helpdesk_list')
class ReturnToTicketTestCase(TestCase):
def test_staff_user(self):
from helpdesk.views.staff import return_to_ticket
user = get_staff_user()
ticket = create_ticket()
response = return_to_ticket(user, settings, ticket)
self.assertEqual(response['location'], ticket.get_absolute_url())
def test_non_staff_user(self):
from helpdesk.views.staff import return_to_ticket
user = User.objects.create_user(username='henry.wensleydale', password='gouda', email='wensleydale@example.com')
ticket = create_ticket()
response = return_to_ticket(user, settings, ticket)
self.assertEqual(response['location'], ticket.ticket_url)

View File

@ -14,7 +14,7 @@ from django.utils.http import urlquote
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from helpdesk import settings as helpdesk_settings from helpdesk import settings as helpdesk_settings
from helpdesk.decorators import protect_view from helpdesk.decorators import protect_view, is_helpdesk_staff
from helpdesk.forms import PublicTicketForm from helpdesk.forms import PublicTicketForm
from helpdesk.lib import text_is_spam from helpdesk.lib import text_is_spam
from helpdesk.models import Ticket, Queue, UserSettings, KBCategory from helpdesk.models import Ticket, Queue, UserSettings, KBCategory
@ -22,7 +22,10 @@ from helpdesk.models import Ticket, Queue, UserSettings, KBCategory
@protect_view @protect_view
def homepage(request): def homepage(request):
if request.user.is_staff or \ if not request.user.is_authenticated() and helpdesk_settings.HELPDESK_REDIRECT_TO_LOGIN_BY_DEFAULT:
return HttpResponseRedirect(reverse('login'))
if is_helpdesk_staff(request.user) or \
(request.user.is_authenticated() and (request.user.is_authenticated() and
helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE): helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE):
try: try:
@ -85,7 +88,7 @@ def view_ticket(request):
except ObjectDoesNotExist: except ObjectDoesNotExist:
error_message = _('Invalid ticket ID or e-mail address. Please try again.') error_message = _('Invalid ticket ID or e-mail address. Please try again.')
else: else:
if request.user.is_staff: if is_helpdesk_staff(request.user):
redirect_url = reverse('helpdesk:view', args=[ticket_id]) redirect_url = reverse('helpdesk:view', args=[ticket_id])
if 'close' in request.GET: if 'close' in request.GET:
redirect_url += '?close' redirect_url += '?close'

View File

@ -42,7 +42,6 @@ from helpdesk import settings as helpdesk_settings
User = get_user_model() User = get_user_model()
if helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE: if helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE:
# treat 'normal' users like 'staff' # treat 'normal' users like 'staff'
staff_member_required = user_passes_test( staff_member_required = user_passes_test(
@ -86,6 +85,7 @@ def _has_access_to_queue(user, queue):
return user.has_perm(queue.permission_name) return user.has_perm(queue.permission_name)
@helpdesk_staff_member_required
def dashboard(request): def dashboard(request):
""" """
A quick summary overview for users: A list of their own tickets, a table A quick summary overview for users: A list of their own tickets, a table
@ -166,7 +166,7 @@ def dashboard(request):
}) })
dashboard = staff_member_required(dashboard) dashboard = staff_member_required(dashboard)
@helpdesk_staff_member_required
def delete_ticket(request, ticket_id): def delete_ticket(request, ticket_id):
ticket = get_object_or_404(Ticket, id=ticket_id) ticket = get_object_or_404(Ticket, id=ticket_id)
if not _has_access_to_queue(request.user, ticket.queue): if not _has_access_to_queue(request.user, ticket.queue):
@ -178,10 +178,17 @@ def delete_ticket(request, ticket_id):
}) })
else: else:
ticket.delete() ticket.delete()
<<<<<<< HEAD
return HttpResponseRedirect(reverse('helpdesk:home')) return HttpResponseRedirect(reverse('helpdesk:home'))
delete_ticket = staff_member_required(delete_ticket) delete_ticket = staff_member_required(delete_ticket)
=======
return HttpResponseRedirect(reverse('helpdesk_home'))
@helpdesk_staff_member_required
>>>>>>> brente/custom-staff-filter
def followup_edit(request, ticket_id, followup_id): def followup_edit(request, ticket_id, followup_id):
"""Edit followup options with an ability to change the ticket.""" """Edit followup options with an ability to change the ticket."""
followup = get_object_or_404(FollowUp, id=followup_id) followup = get_object_or_404(FollowUp, id=followup_id)
@ -232,6 +239,7 @@ def followup_edit(request, ticket_id, followup_id):
followup_edit = staff_member_required(followup_edit) followup_edit = staff_member_required(followup_edit)
@helpdesk_staff_member_required
def followup_delete(request, ticket_id, followup_id): def followup_delete(request, ticket_id, followup_id):
"""followup delete for superuser""" """followup delete for superuser"""
@ -245,6 +253,7 @@ def followup_delete(request, ticket_id, followup_id):
followup_delete = staff_member_required(followup_delete) followup_delete = staff_member_required(followup_delete)
@helpdesk_staff_member_required
def view_ticket(request, ticket_id): def view_ticket(request, ticket_id):
ticket = get_object_or_404(Ticket, id=ticket_id) ticket = get_object_or_404(Ticket, id=ticket_id)
if not _has_access_to_queue(request.user, ticket.queue): if not _has_access_to_queue(request.user, ticket.queue):
@ -363,7 +372,7 @@ def update_ticket(request, ticket_id, public=False):
if not (public or ( if not (public or (
request.user.is_authenticated() and request.user.is_authenticated() and
request.user.is_active and ( request.user.is_active and (
request.user.is_staff or is_helpdesk_staff(request.user) or
helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE))): helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE))):
return HttpResponseRedirect('%s?next=%s' % return HttpResponseRedirect('%s?next=%s' %
(reverse('helpdesk:login'), request.path)) (reverse('helpdesk:login'), request.path))
@ -421,7 +430,7 @@ def update_ticket(request, ticket_id, public=False):
f = FollowUp(ticket=ticket, date=timezone.now(), comment=comment) f = FollowUp(ticket=ticket, date=timezone.now(), comment=comment)
if request.user.is_staff or helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE: if is_helpdesk_staff(request.user):
f.user = request.user f.user = request.user
f.public = public f.public = public
@ -462,6 +471,8 @@ def update_ticket(request, ticket_id, public=False):
f.save() f.save()
files = []
if request.FILES:
files = process_attachments(f, request.FILES.getlist('attachment')) files = process_attachments(f, request.FILES.getlist('attachment'))
if title and title != ticket.title: if title and title != ticket.title:
@ -586,6 +597,7 @@ def update_ticket(request, ticket_id, public=False):
(not reassigned and (not reassigned and
ticket.assigned_to.usersettings_helpdesk.settings.get( ticket.assigned_to.usersettings_helpdesk.settings.get(
'email_on_ticket_change', False)): 'email_on_ticket_change', False)):
send_templated_mail( send_templated_mail(
template_staff, template_staff,
context, context,
@ -627,14 +639,19 @@ def update_ticket(request, ticket_id, public=False):
def return_to_ticket(user, helpdesk_settings, ticket): def return_to_ticket(user, helpdesk_settings, ticket):
<<<<<<< HEAD
"""Helper function for update_ticket""" """Helper function for update_ticket"""
=======
""" Helper function for update_ticket """
>>>>>>> brente/custom-staff-filter
if user.is_staff or helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE: if is_helpdesk_staff(user):
return HttpResponseRedirect(ticket.get_absolute_url()) return HttpResponseRedirect(ticket.get_absolute_url())
else: else:
return HttpResponseRedirect(ticket.ticket_url) return HttpResponseRedirect(ticket.ticket_url)
@helpdesk_staff_member_required
def mass_update(request): def mass_update(request):
tickets = request.POST.getlist('ticket_id') tickets = request.POST.getlist('ticket_id')
action = request.POST.get('action', None) action = request.POST.get('action', None)
@ -751,6 +768,7 @@ def mass_update(request):
mass_update = staff_member_required(mass_update) mass_update = staff_member_required(mass_update)
@helpdesk_staff_member_required
def ticket_list(request): def ticket_list(request):
context = {} context = {}
@ -934,6 +952,7 @@ def ticket_list(request):
ticket_list = staff_member_required(ticket_list) ticket_list = staff_member_required(ticket_list)
@helpdesk_staff_member_required
def edit_ticket(request, ticket_id): def edit_ticket(request, ticket_id):
ticket = get_object_or_404(Ticket, id=ticket_id) ticket = get_object_or_404(Ticket, id=ticket_id)
if not _has_access_to_queue(request.user, ticket.queue): if not _has_access_to_queue(request.user, ticket.queue):
@ -951,6 +970,7 @@ def edit_ticket(request, ticket_id):
edit_ticket = staff_member_required(edit_ticket) edit_ticket = staff_member_required(edit_ticket)
@helpdesk_staff_member_required
def create_ticket(request): def create_ticket(request):
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)
@ -988,6 +1008,7 @@ def create_ticket(request):
create_ticket = staff_member_required(create_ticket) create_ticket = staff_member_required(create_ticket)
@helpdesk_staff_member_required
def raw_details(request, type): def raw_details(request, type):
# TODO: This currently only supports spewing out 'PreSetReply' objects, # TODO: This currently only supports spewing out 'PreSetReply' objects,
# in the future it needs to be expanded to include other items. All it # in the future it needs to be expanded to include other items. All it
@ -1004,9 +1025,9 @@ def raw_details(request, type):
raise Http404 raise Http404
raise Http404 raise Http404
raw_details = staff_member_required(raw_details)
@helpdesk_staff_member_required
def hold_ticket(request, ticket_id, unhold=False): def hold_ticket(request, ticket_id, unhold=False):
ticket = get_object_or_404(Ticket, id=ticket_id) ticket = get_object_or_404(Ticket, id=ticket_id)
if not _has_access_to_queue(request.user, ticket.queue): if not _has_access_to_queue(request.user, ticket.queue):
@ -1031,19 +1052,20 @@ def hold_ticket(request, ticket_id, unhold=False):
ticket.save() ticket.save()
return HttpResponseRedirect(ticket.get_absolute_url()) return HttpResponseRedirect(ticket.get_absolute_url())
hold_ticket = staff_member_required(hold_ticket)
@helpdesk_staff_member_required
def unhold_ticket(request, ticket_id): def unhold_ticket(request, ticket_id):
return hold_ticket(request, ticket_id, unhold=True) return hold_ticket(request, ticket_id, unhold=True)
unhold_ticket = staff_member_required(unhold_ticket)
@helpdesk_staff_member_required
def rss_list(request): def rss_list(request):
return render(request, 'helpdesk/rss_list.html', {'queues': Queue.objects.all()}) return render(request, 'helpdesk/rss_list.html', {'queues': Queue.objects.all()})
rss_list = staff_member_required(rss_list) rss_list = staff_member_required(rss_list)
@helpdesk_staff_member_required
def report_index(request): def report_index(request):
number_tickets = Ticket.objects.all().count() number_tickets = Ticket.objects.all().count()
saved_query = request.GET.get('saved_query', None) saved_query = request.GET.get('saved_query', None)
@ -1092,6 +1114,7 @@ def report_index(request):
report_index = staff_member_required(report_index) report_index = staff_member_required(report_index)
@helpdesk_staff_member_required
def run_report(request, report): def run_report(request, report):
if Ticket.objects.all().count() == 0 or report not in ( if Ticket.objects.all().count() == 0 or report not in (
'queuemonth', 'usermonth', 'queuestatus', 'queuepriority', 'userstatus', 'queuemonth', 'usermonth', 'queuestatus', 'queuepriority', 'userstatus',
@ -1292,6 +1315,7 @@ def run_report(request, report):
run_report = staff_member_required(run_report) run_report = staff_member_required(run_report)
@helpdesk_staff_member_required
def save_query(request): def save_query(request):
title = request.POST.get('title', None) title = request.POST.get('title', None)
shared = request.POST.get('shared', False) shared = request.POST.get('shared', False)
@ -1309,6 +1333,7 @@ def save_query(request):
save_query = staff_member_required(save_query) save_query = staff_member_required(save_query)
@helpdesk_staff_member_required
def delete_saved_query(request, id): def delete_saved_query(request, id):
query = get_object_or_404(SavedSearch, id=id, user=request.user) query = get_object_or_404(SavedSearch, id=id, user=request.user)
@ -1320,6 +1345,7 @@ def delete_saved_query(request, id):
delete_saved_query = staff_member_required(delete_saved_query) delete_saved_query = staff_member_required(delete_saved_query)
@helpdesk_staff_member_required
def user_settings(request): def user_settings(request):
s = request.user.usersettings_helpdesk s = request.user.usersettings_helpdesk
if request.POST: if request.POST:
@ -1334,6 +1360,7 @@ def user_settings(request):
user_settings = staff_member_required(user_settings) user_settings = staff_member_required(user_settings)
@helpdesk_superuser_required
def email_ignore(request): def email_ignore(request):
return render(request, 'helpdesk/email_ignore_list.html', { return render(request, 'helpdesk/email_ignore_list.html', {
'ignore_list': IgnoreEmail.objects.all(), 'ignore_list': IgnoreEmail.objects.all(),
@ -1341,6 +1368,7 @@ def email_ignore(request):
email_ignore = superuser_required(email_ignore) email_ignore = superuser_required(email_ignore)
@helpdesk_superuser_required
def email_ignore_add(request): def email_ignore_add(request):
if request.method == 'POST': if request.method == 'POST':
form = EmailIgnoreForm(request.POST) form = EmailIgnoreForm(request.POST)
@ -1354,6 +1382,7 @@ def email_ignore_add(request):
email_ignore_add = superuser_required(email_ignore_add) email_ignore_add = superuser_required(email_ignore_add)
@helpdesk_superuser_required
def email_ignore_del(request, id): def email_ignore_del(request, id):
ignore = get_object_or_404(IgnoreEmail, id=id) ignore = get_object_or_404(IgnoreEmail, id=id)
if request.method == 'POST': if request.method == 'POST':
@ -1364,6 +1393,7 @@ def email_ignore_del(request, id):
email_ignore_del = superuser_required(email_ignore_del) email_ignore_del = superuser_required(email_ignore_del)
@helpdesk_staff_member_required
def ticket_cc(request, ticket_id): def ticket_cc(request, ticket_id):
ticket = get_object_or_404(Ticket, id=ticket_id) ticket = get_object_or_404(Ticket, id=ticket_id)
if not _has_access_to_queue(request.user, ticket.queue): if not _has_access_to_queue(request.user, ticket.queue):
@ -1377,6 +1407,7 @@ def ticket_cc(request, ticket_id):
ticket_cc = staff_member_required(ticket_cc) ticket_cc = staff_member_required(ticket_cc)
@helpdesk_staff_member_required
def ticket_cc_add(request, ticket_id): def ticket_cc_add(request, ticket_id):
ticket = get_object_or_404(Ticket, id=ticket_id) ticket = get_object_or_404(Ticket, id=ticket_id)
if not _has_access_to_queue(request.user, ticket.queue): if not _has_access_to_queue(request.user, ticket.queue):
@ -1401,6 +1432,7 @@ def ticket_cc_add(request, ticket_id):
ticket_cc_add = staff_member_required(ticket_cc_add) ticket_cc_add = staff_member_required(ticket_cc_add)
@helpdesk_staff_member_required
def ticket_cc_del(request, ticket_id, cc_id): def ticket_cc_del(request, ticket_id, cc_id):
cc = get_object_or_404(TicketCC, ticket__id=ticket_id, id=cc_id) cc = get_object_or_404(TicketCC, ticket__id=ticket_id, id=cc_id)
@ -1412,6 +1444,7 @@ def ticket_cc_del(request, ticket_id, cc_id):
ticket_cc_del = staff_member_required(ticket_cc_del) ticket_cc_del = staff_member_required(ticket_cc_del)
@helpdesk_staff_member_required
def ticket_dependency_add(request, ticket_id): def ticket_dependency_add(request, ticket_id):
ticket = get_object_or_404(Ticket, id=ticket_id) ticket = get_object_or_404(Ticket, id=ticket_id)
if not _has_access_to_queue(request.user, ticket.queue): if not _has_access_to_queue(request.user, ticket.queue):
@ -1433,6 +1466,7 @@ def ticket_dependency_add(request, ticket_id):
ticket_dependency_add = staff_member_required(ticket_dependency_add) ticket_dependency_add = staff_member_required(ticket_dependency_add)
@helpdesk_staff_member_required
def ticket_dependency_del(request, ticket_id, dependency_id): def ticket_dependency_del(request, ticket_id, dependency_id):
dependency = get_object_or_404(TicketDependency, ticket__id=ticket_id, id=dependency_id) dependency = get_object_or_404(TicketDependency, ticket__id=ticket_id, id=dependency_id)
if request.method == 'POST': if request.method == 'POST':
@ -1442,6 +1476,7 @@ def ticket_dependency_del(request, ticket_id, dependency_id):
ticket_dependency_del = staff_member_required(ticket_dependency_del) ticket_dependency_del = staff_member_required(ticket_dependency_del)
@helpdesk_staff_member_required
def attachment_del(request, ticket_id, attachment_id): def attachment_del(request, ticket_id, attachment_id):
ticket = get_object_or_404(Ticket, id=ticket_id) ticket = get_object_or_404(Ticket, id=ticket_id)
if not _has_access_to_queue(request.user, ticket.queue): if not _has_access_to_queue(request.user, ticket.queue):