diff --git a/helpdesk/forms.py b/helpdesk/forms.py index 74002389..52fccf48 100644 --- a/helpdesk/forms.py +++ b/helpdesk/forms.py @@ -6,11 +6,10 @@ django-helpdesk - A Django powered ticket tracker for small enterprise. forms.py - Definitions of newforms-based forms for creating and maintaining tickets. """ - +import logging from django.core.exceptions import ObjectDoesNotExist from django import forms -from django.forms import widgets from django.conf import settings from django.utils.translation import ugettext_lazy as _ from django.contrib.auth import get_user_model @@ -21,6 +20,7 @@ from helpdesk.models import (Ticket, Queue, FollowUp, IgnoreEmail, TicketCC, CustomField, TicketCustomFieldValue, TicketDependency, UserSettings, KBItem) from helpdesk import settings as helpdesk_settings +logger = logging.getLogger(__name__) User = get_user_model() CUSTOMFIELD_TO_FIELD_DICT = { @@ -158,7 +158,7 @@ class AbstractTicketForm(CustomFieldMixin, forms.Form): widget=forms.Select(attrs={'class': 'form-control'}), choices=Ticket.PRIORITY_CHOICES, required=True, - initial='3', + initial=getattr(settings, 'HELPDESK_PUBLIC_TICKET_PRIORITY', '3'), label=_('Priority'), help_text=_("Please select a priority carefully. If unsure, leave it as '3'."), ) @@ -203,25 +203,32 @@ class AbstractTicketForm(CustomFieldMixin, forms.Form): self.customfield_to_field(field, instanceargs) def _get_queue(self): - # this procedure is re-defined for anon submission form + # this procedure is re-defined for public submission form return Queue.objects.get(id=int(self.cleaned_data['queue'])) def _create_ticket(self): - queue = Queue.objects.get(id=int(self.cleaned_data['queue'])) + queue = self._get_queue() kbitem = None if 'kbitem' in self.cleaned_data: kbitem = KBItem.objects.get(id=int(self.cleaned_data['kbitem'])) - ticket = Ticket(title=self.cleaned_data['title'], - submitter_email=self.cleaned_data['submitter_email'], - created=timezone.now(), - status=Ticket.OPEN_STATUS, - queue=queue, - description=self.cleaned_data['body'], - priority=self.cleaned_data['priority'], - due_date=self.cleaned_data['due_date'], - kbitem=kbitem, - ) + ticket = Ticket( + title=self.cleaned_data['title'], + submitter_email=self.cleaned_data['submitter_email'], + created=timezone.now(), + status=Ticket.OPEN_STATUS, + queue=queue, + description=self.cleaned_data['body'], + priority=self.cleaned_data.get( + 'priority', + getattr(settings, "HELPDESK_PUBLIC_TICKET_PRIORITY", "3") + ), + due_date=self.cleaned_data.get( + 'due_date', + getattr(settings, "HELPDESK_PUBLIC_TICKET_DUE_DATE", None) + ) or None, + kbitem=kbitem, + ) return ticket, queue @@ -281,7 +288,11 @@ class TicketForm(AbstractTicketForm): 'updates to this ticket.'), ) assigned_to = forms.ChoiceField( - widget=forms.Select(attrs={'class': 'form-control'}) if not helpdesk_settings.HELPDESK_CREATE_TICKET_HIDE_ASSIGNED_TO else forms.HiddenInput(), + widget=( + forms.Select(attrs={'class': 'form-control'}) + if not helpdesk_settings.HELPDESK_CREATE_TICKET_HIDE_ASSIGNED_TO + else forms.HiddenInput() + ), required=False, label=_('Case owner'), help_text=_('If you select an owner other than yourself, they\'ll be ' @@ -364,15 +375,42 @@ class PublicTicketForm(AbstractTicketForm): 'due_date': 'HELPDESK_PUBLIC_TICKET_DUE_DATE', } - for field in self.fields.keys(): - setting = field_hide_table.get(field, None) - if (setting and hasattr(settings, setting)) or field in hidden_fields: - self.fields[field].widget = forms.HiddenInput() - if field in readonly_fields: - self.fields[field].disabled = True + for field_name, field_setting_key in field_hide_table.items(): + has_settings_default_value = getattr(settings, field_setting_key, None) + if has_settings_default_value is not None: + hidden_fields += (field_name,) - self.fields['queue'].choices = [('', '--------')] + [ - (q.id, q.title) for q in Queue.objects.filter(allow_public_submission=True)] + for field in hidden_fields: + if field in self.fields: + del self.fields[field] + + public_queues = Queue.objects.filter(allow_public_submission=True) + + if len(public_queues) == 0: + logger.warning( + "There are no public queues defined - public ticket creation is impossible" + ) + + if 'queue' in self.fields: + self.fields['queue'].choices = [('', '--------')] + [ + (q.id, q.title) for q in public_queues] + + def _get_queue(self): + if getattr(settings, 'HELPDESK_PUBLIC_TICKET_QUEUE', None) is not None: + # force queue to be the pre-defined one + # (only for public submissions) + public_queue = Queue.objects.filter( + slug=settings.HELPDESK_PUBLIC_TICKET_QUEUE + ).first() + if not public_queue: + logger.fatal( + "Public queue '%s' is configured as default but can't be found", + settings.HELPDESK_PUBLIC_TICKET_QUEUE + ) + return public_queue + else: + # get the queue user entered + return Queue.objects.get(id=int(self.cleaned_data['queue'])) def save(self): """ diff --git a/helpdesk/views/public.py b/helpdesk/views/public.py index 8a2846fb..a05c9e52 100644 --- a/helpdesk/views/public.py +++ b/helpdesk/views/public.py @@ -6,9 +6,13 @@ django-helpdesk - A Django powered ticket tracker for small enterprise. views/public.py - All public facing views, eg non-staff (no authentication required) views. """ -from django.core.exceptions import ObjectDoesNotExist, PermissionDenied +import logging + +from django.core.exceptions import ( + ObjectDoesNotExist, PermissionDenied, ImproperlyConfigured, +) from django.urls import reverse -from django.http import HttpResponseRedirect, HttpResponse +from django.http import HttpResponseRedirect from django.shortcuts import render from django.utils.http import urlquote from django.utils.translation import ugettext as _ @@ -26,6 +30,8 @@ from helpdesk.forms import PublicTicketForm from helpdesk.lib import text_is_spam from helpdesk.models import CustomField, Ticket, Queue, UserSettings, KBCategory, KBItem +logger = logging.getLogger(__name__) + def create_ticket(request, *args, **kwargs): if is_helpdesk_staff(request.user): @@ -55,16 +61,22 @@ class BaseCreateTicketView(abstract_views.AbstractCreateTicketMixin, FormView): return super().dispatch(*args, **kwargs) def get_initial(self): - request = self.request initial_data = super().get_initial() # add pre-defined data for public ticket if hasattr(settings, 'HELPDESK_PUBLIC_TICKET_QUEUE'): # get the requested queue; return an error if queue not found try: - initial_data['queue'] = Queue.objects.get(slug=settings.HELPDESK_PUBLIC_TICKET_QUEUE).id - except Queue.DoesNotExist: - return HttpResponse(status=500) + initial_data['queue'] = Queue.objects.get( + slug=settings.HELPDESK_PUBLIC_TICKET_QUEUE, + allow_public_submission=True + ).id + except Queue.DoesNotExist as e: + logger.fatal( + "Public queue '%s' is configured as default but can't be found", + settings.HELPDESK_PUBLIC_TICKET_QUEUE + ) + raise ImproperlyConfigured("Wrong public queue configuration") from e if hasattr(settings, 'HELPDESK_PUBLIC_TICKET_PRIORITY'): initial_data['priority'] = settings.HELPDESK_PUBLIC_TICKET_PRIORITY if hasattr(settings, 'HELPDESK_PUBLIC_TICKET_DUE_DATE'): @@ -73,7 +85,8 @@ class BaseCreateTicketView(abstract_views.AbstractCreateTicketMixin, FormView): def get_form_kwargs(self, *args, **kwargs): kwargs = super().get_form_kwargs(*args, **kwargs) - kwargs['hidden_fields'] = self.request.GET.get('_hide_fields_', '').split(',') + if '_hide_fields_' in self.request.GET: + kwargs['hidden_fields'] = self.request.GET.get('_hide_fields_', '').split(',') kwargs['readonly_fields'] = self.request.GET.get('_readonly_fields_', '').split(',') return kwargs