Submit ticket link should work for non-logged in users

This commit is contained in:
Timothy Hobbs 2018-09-07 19:05:16 +02:00
parent a12abab219
commit ffc97338c9
No known key found for this signature in database
GPG Key ID: 9CA9B3D779CEEDE7
6 changed files with 151 additions and 87 deletions

View File

@ -301,21 +301,27 @@ class TicketForm(AbstractTicketForm):
help_text=_('This e-mail address will receive copies of all public ' help_text=_('This e-mail address will receive copies of all public '
'updates to this ticket.'), 'updates to this ticket.'),
) )
assigned_to = forms.ChoiceField( assigned_to = forms.ChoiceField(
widget=forms.Select(attrs={'class': 'form-control'}), widget=forms.Select(attrs={'class': 'form-control'}) if not helpdesk_settings.HELPDESK_CREATE_TICKET_HIDE_ASSIGNED_TO else forms.HiddenInput(),
choices=(),
required=False, required=False,
label=_('Case owner'), label=_('Case owner'),
help_text=_('If you select an owner other than yourself, they\'ll be ' help_text=_('If you select an owner other than yourself, they\'ll be '
'e-mailed details of this ticket immediately.'), 'e-mailed details of this ticket immediately.'),
choices=()
) )
def __init__(self, *args, **kwargs): def __init__(self, *args, **kwargs):
""" """
Add any custom fields that are defined to the form. Add any custom fields that are defined to the form.
""" """
super(TicketForm, self).__init__(*args, **kwargs) super().__init__(*args, **kwargs)
self.fields['queue'].choices = [('', '--------')] + [(q.id, q.title) for q in Queue.objects.all()]
if helpdesk_settings.HELPDESK_STAFF_ONLY_TICKET_OWNERS:
assignable_users = User.objects.filter(is_active=True, is_staff=True).order_by(User.USERNAME_FIELD)
else:
assignable_users = User.objects.filter(is_active=True).order_by(User.USERNAME_FIELD)
self.fields['assigned_to'].choices = [('', '--------')] + [(u.id, u.get_username()) for u in assignable_users]
self._add_form_custom_fields() self._add_form_custom_fields()
def save(self, user=None): def save(self, user=None):
@ -375,8 +381,8 @@ class PublicTicketForm(AbstractTicketForm):
self.fields['priority'].widget = forms.HiddenInput() self.fields['priority'].widget = forms.HiddenInput()
if hasattr(settings, 'HELPDESK_PUBLIC_TICKET_DUE_DATE'): if hasattr(settings, 'HELPDESK_PUBLIC_TICKET_DUE_DATE'):
self.fields['due_date'].widget = forms.HiddenInput() self.fields['due_date'].widget = forms.HiddenInput()
self.fields['queue'].choices = [('', '--------')] + [
self._add_form_custom_fields(False) (q.id, q.title) for q in Queue.objects.filter(allow_public_submission=True)]
def save(self): def save(self):
""" """

View File

@ -0,0 +1,47 @@
{% extends "helpdesk/public_base.html" %}
{% load i18n bootstrap %}
{% block helpdesk_body %}
{% if helpdesk_settings.HELPDESK_SUBMIT_A_TICKET_PUBLIC %}
<div class="col-xs-6">
<div class="panel panel-default">
<div class="panel-body">
<h2 name='submit'>{% trans "Submit a Ticket" %}</h2>
<p>{% trans "Please provide as descriptive a title and description as possible." %}</p>
<form role="form" method='post' action='./#submit' enctype='multipart/form-data'>
<fieldset>
{{ form|bootstrap }}
{% comment %}
{% for field in form %}
{% if field.is_hidden %}
{{ field }}
{% else %}
<div class="form-group {% if field.errors %}has-error{% endif %}">
<label class="control-label" for='id_{{ field.name }}'>{{ field.label }}</label>{% if not field.field.required %} <span class='form_optional'>{% trans "(Optional)" %}</span>{% endif %}</dt>
<div class="input-group">{{ field }}</div>
{% if field.errors %}<div class="help-block">{{ field.errors }}</div>{% endif %}
{% if field.help_text %}<span class='fhelp-block'>{{ field.help_text }}</span>{% endif %}
</div>
{% endif %}
{% endfor %}
{% endcomment %}
<div class='buttons form-group'>
<input type='submit' class="btn btn-primary" value='{% trans "Submit Ticket" %}' />
</div>
</fieldset>
{% csrf_token %}</form>
</div>
</div>
</div>
{% endif %}
{% endblock %}

View File

@ -12,7 +12,7 @@ from django.contrib.auth.decorators import login_required
from django.contrib.auth import views as auth_views from django.contrib.auth import views as auth_views
from django.views.generic import TemplateView from django.views.generic import TemplateView
from helpdesk.decorators import helpdesk_staff_member_required from helpdesk.decorators import helpdesk_staff_member_required, protect_view
from helpdesk import settings as helpdesk_settings from helpdesk import settings as helpdesk_settings
from helpdesk.views import feeds, staff, public, kb from helpdesk.views import feeds, staff, public, kb
@ -46,10 +46,6 @@ urlpatterns = [
staff.mass_update, staff.mass_update,
name='mass_update'), name='mass_update'),
url(r'^tickets/submit/$',
staff.create_ticket,
name='submit'),
url(r'^tickets/(?P<ticket_id>[0-9]+)/$', url(r'^tickets/(?P<ticket_id>[0-9]+)/$',
staff.view_ticket, staff.view_ticket,
name='view'), name='view'),
@ -149,9 +145,13 @@ urlpatterns = [
urlpatterns += [ urlpatterns += [
url(r'^$', url(r'^$',
public.homepage, protect_view(public.Homepage.as_view()),
name='home'), name='home'),
url(r'^tickets/submit/$',
public.create_ticket,
name='submit'),
url(r'^view/$', url(r'^view/$',
public.view_ticket, public.view_ticket,
name='public_view'), name='public_view'),

View File

@ -0,0 +1,8 @@
from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from helpdesk.decorators import is_helpdesk_staff
class MustBeStaffMixin(LoginRequiredMixin, UserPassesTestMixin):
def test_func(self):
return is_helpdesk_staff(self.request.user)

View File

@ -18,55 +18,58 @@ from django.shortcuts import render
from django.utils.http import urlquote from django.utils.http import urlquote
from django.utils.translation import ugettext as _ from django.utils.translation import ugettext as _
from django.conf import settings from django.conf import settings
from django.views.generic.edit import FormView
from helpdesk import settings as helpdesk_settings from helpdesk import settings as helpdesk_settings
from helpdesk.decorators import protect_view, is_helpdesk_staff from helpdesk.decorators import protect_view, is_helpdesk_staff
import helpdesk.views.staff as 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
@protect_view def create_ticket(request, *args, **kwargs):
def homepage(request): if is_helpdesk_staff(request.user):
if not request.user.is_authenticated and helpdesk_settings.HELPDESK_REDIRECT_TO_LOGIN_BY_DEFAULT: return staff.CreateTicketView.as_view()(request, *args, **kwargs)
return HttpResponseRedirect(reverse('login'))
if is_helpdesk_staff(request.user) or \
(request.user.is_authenticated and
helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE):
try:
if request.user.usersettings_helpdesk.settings.get('login_view_ticketlist', False):
return HttpResponseRedirect(reverse('helpdesk:list'))
else:
return HttpResponseRedirect(reverse('helpdesk:dashboard'))
except UserSettings.DoesNotExist:
return HttpResponseRedirect(reverse('helpdesk:dashboard'))
if request.method == 'POST':
form = PublicTicketForm(request.POST, request.FILES)
form.fields['queue'].choices = [('', '--------')] + [
(q.id, q.title) for q in Queue.objects.filter(allow_public_submission=True)]
if form.is_valid():
if text_is_spam(form.cleaned_data['body'], request):
# This submission is spam. Let's not save it.
return render(request, template_name='helpdesk/public_spam.html')
else:
ticket = form.save()
try:
return HttpResponseRedirect('%s?ticket=%s&email=%s' % (
reverse('helpdesk:public_view'),
ticket.ticket_for_url,
urlquote(ticket.submitter_email))
)
except ValueError:
# if someone enters a non-int string for the ticket
return HttpResponseRedirect(reverse('helpdesk:home'))
else: else:
return CreateTicketView.as_view()(request, *args, **kwargs)
class CreateTicketView(FormView):
template_name = 'helpdesk/public_create_ticket.html'
form_class = PublicTicketForm
def dispatch(self, *args, **kwargs):
request = self.request
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
helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE):
try:
if request.user.usersettings_helpdesk.settings.get('login_view_ticketlist', False):
return HttpResponseRedirect(reverse('helpdesk:list'))
else:
return HttpResponseRedirect(reverse('helpdesk:dashboard'))
except UserSettings.DoesNotExist:
return HttpResponseRedirect(reverse('helpdesk:dashboard'))
return super().dispatch(*args, **kwargs)
def get_context(self):
knowledgebase_categories = KBCategory.objects.all()
return {
'helpdesk_settings': helpdesk_settings,
'kb_categories': knowledgebase_categories
}
def get_initial(self):
request = self.request
initial_data = {}
try: try:
queue = Queue.objects.get(slug=request.GET.get('queue', None)) queue = Queue.objects.get(slug=request.GET.get('queue', None))
except Queue.DoesNotExist: except Queue.DoesNotExist:
queue = None queue = None
initial_data = {}
# add pre-defined data for public ticket # add pre-defined data for public ticket
if hasattr(settings, 'HELPDESK_PUBLIC_TICKET_QUEUE'): if hasattr(settings, 'HELPDESK_PUBLIC_TICKET_QUEUE'):
@ -85,18 +88,31 @@ def homepage(request):
if request.user.is_authenticated and request.user.email: if request.user.is_authenticated and request.user.email:
initial_data['submitter_email'] = request.user.email initial_data['submitter_email'] = request.user.email
return initial_data
form = PublicTicketForm(initial=initial_data) def form_valid(self, form):
form.fields['queue'].choices = [('', '--------')] + [ request = self.request
(q.id, q.title) for q in Queue.objects.filter(allow_public_submission=True)] if text_is_spam(form.cleaned_data['body'], request):
# This submission is spam. Let's not save it.
return render(request, template_name='helpdesk/public_spam.html')
else:
ticket = form.save()
try:
return HttpResponseRedirect('%s?ticket=%s&email=%s' % (
reverse('helpdesk:public_view'),
ticket.ticket_for_url,
urlquote(ticket.submitter_email))
)
except ValueError:
# if someone enters a non-int string for the ticket
return HttpResponseRedirect(reverse('helpdesk:home'))
knowledgebase_categories = KBCategory.objects.all() def get_success_url(self):
request = self.request
return render(request, 'helpdesk/public_homepage.html', {
'form': form, class Homepage(CreateTicketView):
'helpdesk_settings': helpdesk_settings, template_name = 'helpdesk/public_homepage.html'
'kb_categories': knowledgebase_categories
})
@protect_view @protect_view

View File

@ -26,6 +26,7 @@ from django.utils.translation import ugettext as _
from django.utils.html import escape from django.utils.html import escape
from django import forms from django import forms
from django.utils import timezone from django.utils import timezone
from django.views.generic.edit import FormView
from django.utils import six from django.utils import six
@ -46,6 +47,7 @@ from helpdesk.models import (
IgnoreEmail, TicketCC, TicketDependency, IgnoreEmail, TicketCC, TicketDependency,
) )
from helpdesk import settings as helpdesk_settings from helpdesk import settings as helpdesk_settings
from helpdesk.views.permissions import MustBeStaffMixin
User = get_user_model() User = get_user_model()
@ -1019,44 +1021,29 @@ def edit_ticket(request, ticket_id):
edit_ticket = staff_member_required(edit_ticket) edit_ticket = staff_member_required(edit_ticket)
@helpdesk_staff_member_required class CreateTicketView(MustBeStaffMixin, FormView):
def create_ticket(request): template_name = 'helpdesk/create_ticket.html'
if helpdesk_settings.HELPDESK_STAFF_ONLY_TICKET_OWNERS: form_class = TicketForm
assignable_users = User.objects.filter(is_active=True, is_staff=True).order_by(User.USERNAME_FIELD)
else:
assignable_users = User.objects.filter(is_active=True).order_by(User.USERNAME_FIELD)
if request.method == 'POST': def get_initial(self):
form = TicketForm(request.POST, request.FILES)
form.fields['queue'].choices = [('', '--------')] + [
(q.id, q.title) for q in Queue.objects.all()]
form.fields['assigned_to'].choices = [('', '--------')] + [
(u.id, u.get_username()) for u in assignable_users]
if form.is_valid():
ticket = form.save(user=request.user)
if _has_access_to_queue(request.user, ticket.queue):
return HttpResponseRedirect(ticket.get_absolute_url())
else:
return HttpResponseRedirect(reverse('helpdesk:dashboard'))
else:
initial_data = {} initial_data = {}
request = self.request
if request.user.usersettings_helpdesk.settings.get('use_email_as_submitter', False) and request.user.email: if request.user.usersettings_helpdesk.settings.get('use_email_as_submitter', False) and request.user.email:
initial_data['submitter_email'] = request.user.email initial_data['submitter_email'] = request.user.email
if 'queue' in request.GET: if 'queue' in request.GET:
initial_data['queue'] = request.GET['queue'] initial_data['queue'] = request.GET['queue']
return initial_data
form = TicketForm(initial=initial_data) def form_valid(self, form):
form.fields['queue'].choices = [('', '--------')] + [ self.ticket = form.save()
(q.id, q.title) for q in Queue.objects.all()] return super().form_valid(form)
form.fields['assigned_to'].choices = [('', '--------')] + [
(u.id, u.get_username()) for u in assignable_users]
if helpdesk_settings.HELPDESK_CREATE_TICKET_HIDE_ASSIGNED_TO:
form.fields['assigned_to'].widget = forms.HiddenInput()
return render(request, 'helpdesk/create_ticket.html', {'form': form}) def get_success_url(self):
request = self.request
if _has_access_to_queue(request.user, self.ticket.queue):
create_ticket = staff_member_required(create_ticket) return self.ticket.get_absolute_url()
else:
return reverse('helpdesk:dashboard')
@helpdesk_staff_member_required @helpdesk_staff_member_required