Merged 0.2.16 bugfixes

This commit is contained in:
Garret Wassermann 2019-05-25 01:25:39 -04:00
commit 0de263280f
11 changed files with 186 additions and 62 deletions

38
.github/ISSUE_TEMPLATE/bug_report.md vendored Normal file
View File

@ -0,0 +1,38 @@
---
name: Bug report
about: Create a report to help us improve
title: ''
labels: bug
assignees: ''
---
**Describe the bug**
A clear and concise description of what the bug is.
**To Reproduce**
Steps to reproduce the behavior:
1. Go to '...'
2. Click on '....'
3. Scroll down to '....'
4. See error
**Expected behavior**
A clear and concise description of what you expected to happen.
**Screenshots**
If applicable, add screenshots to help explain your problem.
**Desktop (please complete the following information):**
- OS: [e.g. iOS]
- Browser [e.g. chrome, safari]
- Version [e.g. 22]
**Smartphone (please complete the following information):**
- Device: [e.g. iPhone6]
- OS: [e.g. iOS8.1]
- Browser [e.g. stock browser, safari]
- Version [e.g. 22]
**Additional context**
Add any other context about the problem here.

View File

@ -0,0 +1,20 @@
---
name: Feature request
about: Suggest an idea for this project
title: ''
labels: enhancement
assignees: ''
---
**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
**Describe the solution you'd like**
A clear and concise description of what you want to happen.
**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
**Additional context**
Add any other context or screenshots about the feature request here.

View File

@ -1,6 +1,10 @@
Contributing Contributing
============ ============
We're really glad you're reading this and considering contributing to
`django-helpdesk`! As an open source project, we rely on volunteers
to improve and grow the project. Welcome!
django-helpdesk is an open-source project and as such contributions from the django-helpdesk is an open-source project and as such contributions from the
community are welcomed and encouraged! community are welcomed and encouraged!
@ -10,38 +14,20 @@ repository is available at:
https://github.com/django-helpdesk/django-helpdesk https://github.com/django-helpdesk/django-helpdesk
Licensing
---------
All contributions to django-helpdesk *must* be under the BSD license documented Testing
in the LICENSE file in the top-level directory of this project. -------
By submitting a contribution to this project (in any way: via e-mail, If you don't mind testing pre-releases (don't use in production!), we appreciate
via GitHub pull requests, ticket attachments, etc), you acknowledge that your continuous feedback on the `develop` branch, which is our work toward the next
contribution is open-source and licensed under the BSD license. major release. Please file bug reports, and tag the report with the "pre-release"
tag.
If you or your organisation does not accept these license terms then we cannot This is an easy way to get involved that doesn't require programming.
accept your contribution. Please reconsider!
Ways to Contribute
------------------
We're happy to include any type of contribution! This can be: Pull Requests
-------------
* back-end python/django code development
* front-end web development (HTML/Javascript, especially jQuery)
* language translations
* writing improved documentation and demos
More details on each of theses tasks is below.
If you have any questions on contributing, please start a discussion on
the GitHub issue tracker at
https://github.com/django-helpdesk/django-helpdesk/issues
Back-end Python/Django
``````````````````````
Please fork the project on GitHub, make your changes, and submit a Please fork the project on GitHub, make your changes, and submit a
pull request back into the appropriate branch of the pull request back into the appropriate branch of the
@ -89,8 +75,35 @@ If your changes affect the Django models for `django-helpdesk`, be aware
that your commits should include database schema python scripts; see the that your commits should include database schema python scripts; see the
Database Schema Changes section below for more details. Database Schema Changes section below for more details.
Coding Conventions
------------------
Be sure all Python code follows PEP8 conventions.
Ideally, add comments and documentation whenever you touch code.
HTML and Javascript templates should be appropriately indented.
Database schema changes
-----------------------
As well as making your normal code changes to ``models.py``, please generate a
Django migration file and commit it with your code. You will want to use a
command similar to the following::
./manage.py migrate helpdesk --auto [migration_name]
Make sure that ``migration_name`` is a sensible single-string explanation of
what this migration does, such as *add_priority_options* or *add_basket_table*.
This will add a file to the ``migrations/`` folder, which must be committed to
git with your other code changes.
Tests Tests
..... -----
Currently, test coverage is very low. We're working on increasing this, and to Currently, test coverage is very low. We're working on increasing this, and to
make life easier we are using Travis CI (http://travis-ci.org/) for continuous make life easier we are using Travis CI (http://travis-ci.org/) for continuous
@ -118,23 +131,27 @@ start a discussion on the GitHub issue tracker at
https://github.com/django-helpdesk/django-helpdesk/issues https://github.com/django-helpdesk/django-helpdesk/issues
Database schema changes
.......................
As well as making your normal code changes to ``models.py``, please generate a Ways to Contribute
Django migration file and commit it with your code. You will want to use a ------------------
command similar to the following::
./manage.py migrate helpdesk --auto [migration_name] We're happy to include any type of contribution! This can be:
Make sure that ``migration_name`` is a sensible single-string explanation of * back-end python/django code development
what this migration does, such as *add_priority_options* or *add_basket_table*. * front-end web development (HTML/Javascript, especially jQuery)
* language translations
* writing improved documentation and demos
More details on each of theses tasks is below.
If you have any questions on contributing, please start a discussion on
the GitHub issue tracker at
https://github.com/django-helpdesk/django-helpdesk/issues
This will add a file to the ``migrations/`` folder, which must be committed to
git with your other code changes.
Translations Translations
```````````` ------------
Although `django-helpdesk` has originally been written for the English language, Although `django-helpdesk` has originally been written for the English language,
there are already multiple community translations, including Spanish, Polish, there are already multiple community translations, including Spanish, Polish,
@ -149,4 +166,19 @@ project:
http://www.transifex.net/projects/p/django-helpdesk/resource/core/ http://www.transifex.net/projects/p/django-helpdesk/resource/core/
Once you have translated content via Transifex, please raise an issue on the Once you have translated content via Transifex, please raise an issue on the
project Github page to let us know it's ready to import. project Github page and tag it as "translations" to let us know it's ready to
import.
Licensing
---------
All contributions to django-helpdesk *must* be under the BSD license documented
in the LICENSE file in the top-level directory of this project.
By submitting a contribution to this project (in any way: via e-mail,
via GitHub pull requests, ticket attachments, etc), you acknowledge that your
contribution is open-source and licensed under the BSD license.
If you or your organization does not accept these license terms then we cannot
accept your contribution. Please reconsider!

View File

@ -78,8 +78,8 @@ readme:
#: demo - Setup demo project using Python3. #: demo - Setup demo project using Python3.
.PHONY: demo .PHONY: demo
demo: demo:
$(PIP) install -e . $(PIP) install -e . --user
$(PIP) install -e demo $(PIP) install -e demo --user
demodesk migrate --noinput demodesk migrate --noinput
# Create superuser; user will be prompted to manually set a password # Create superuser; user will be prompted to manually set a password
# When you get a prompt, enter a password of your choosing. # When you get a prompt, enter a password of your choosing.

View File

@ -41,7 +41,7 @@ resides in the `demo/` top-level folder.
It's likely that you can start up a demo project server by running It's likely that you can start up a demo project server by running
only the command:: only the command::
sudo make rundemo make rundemo
then pointing your web browser at `localhost:8080`. then pointing your web browser at `localhost:8080`.

View File

@ -26,7 +26,7 @@ Ideally, you'd use a virtualenv instead
To use your system directory, from the top-level To use your system directory, from the top-level
django-helpdesk directory, simply run: django-helpdesk directory, simply run:
sudo make rundemo make rundemo
Once the console gives a prompt that the HTTP Once the console gives a prompt that the HTTP
server is listening, open your web browser server is listening, open your web browser

View File

@ -1,10 +1,13 @@
from functools import wraps from functools import wraps
from django.urls import reverse from django.core.exceptions import PermissionDenied
from django.http import HttpResponseRedirect, Http404 from django.http import Http404
from django.shortcuts import redirect
from django.utils.decorators import available_attrs from django.utils.decorators import available_attrs
from django.contrib.auth.decorators import user_passes_test from django.contrib.auth.decorators import user_passes_test
from helpdesk import settings as helpdesk_settings from helpdesk import settings as helpdesk_settings
@ -48,9 +51,41 @@ def protect_view(view_func):
@wraps(view_func, assigned=available_attrs(view_func)) @wraps(view_func, assigned=available_attrs(view_func))
def _wrapped_view(request, *args, **kwargs): def _wrapped_view(request, *args, **kwargs):
if not request.user.is_authenticated and helpdesk_settings.HELPDESK_REDIRECT_TO_LOGIN_BY_DEFAULT: if not request.user.is_authenticated and helpdesk_settings.HELPDESK_REDIRECT_TO_LOGIN_BY_DEFAULT:
return HttpResponseRedirect(reverse('helpdesk:login')) return redirect('helpdesk:login')
elif not request.user.is_authenticated and helpdesk_settings.HELPDESK_ANON_ACCESS_RAISES_404: elif not request.user.is_authenticated and helpdesk_settings.HELPDESK_ANON_ACCESS_RAISES_404:
raise Http404 raise Http404
return view_func(request, *args, **kwargs) return view_func(request, *args, **kwargs)
return _wrapped_view return _wrapped_view
def staff_member_required(view_func):
"""
Decorator for staff member the views checking user, redirecting
to the log-in page if necessary or returning 403
"""
@wraps(view_func, assigned=available_attrs(view_func))
def _wrapped_view(request, *args, **kwargs):
if not request.user.is_authenticated and not request.user.is_active:
return redirect('helpdesk:login')
if not helpdesk_settings.HELPDESK_ALLOW_NON_STAFF_TICKET_UPDATE and not request.user.is_staff:
raise PermissionDenied()
return view_func(request, *args, **kwargs)
return _wrapped_view
def superuser_required(view_func):
"""
Decorator for superuser member the views checking user, redirecting
to the log-in page if necessary or returning 403
"""
@wraps(view_func, assigned=available_attrs(view_func))
def _wrapped_view(request, *args, **kwargs):
if not request.user.is_authenticated and not request.user.is_active:
return redirect('helpdesk:login')
if not request.user.is_superuser:
raise PermissionDenied()
return view_func(request, *args, **kwargs)
return _wrapped_view

View File

@ -7,12 +7,18 @@ from helpdesk.models import Ticket, Queue, UserSettings
User = get_user_model() User = get_user_model()
def get_staff_user(username='helpdesk.staff', password='password'): def get_user(username='helpdesk.staff',
password='password',
is_staff=False,
is_superuser=False):
try: try:
user = User.objects.get(username=username) user = User.objects.get(username=username)
except User.DoesNotExist: except User.DoesNotExist:
user = User.objects.create_user(username=username, password=password, email='staff@example.com') user = User.objects.create_user(username=username,
user.is_staff = True password=password,
email='%s@example.com' % username)
user.is_staff = is_staff
user.is_superuser = is_superuser
user.save() user.save()
else: else:
user.set_password(password) user.set_password(password)

View File

@ -25,7 +25,7 @@ class KBDisabledTestCase(TestCase):
"""Test proper rendering of navigation.html by accessing the dashboard""" """Test proper rendering of navigation.html by accessing the dashboard"""
from django.urls import NoReverseMatch from django.urls import NoReverseMatch
self.client.login(username=get_staff_user().get_username(), password='password') self.client.login(username=get_user(is_staff=True).get_username(), password='password')
self.assertRaises(NoReverseMatch, reverse, 'helpdesk:kb_index') self.assertRaises(NoReverseMatch, reverse, 'helpdesk:kb_index')
try: try:
response = self.client.get(reverse('helpdesk:dashboard')) response = self.client.get(reverse('helpdesk:dashboard'))

View File

@ -2,7 +2,7 @@
from django.urls import reverse from django.urls import reverse
from django.test import TestCase from django.test import TestCase
from helpdesk.models import Queue from helpdesk.models import Queue
from helpdesk.tests.helpers import get_staff_user from helpdesk.tests.helpers import get_user
class TestSavingSharedQuery(TestCase): class TestSavingSharedQuery(TestCase):
@ -14,7 +14,7 @@ class TestSavingSharedQuery(TestCase):
def test_cansavequery(self): def test_cansavequery(self):
"""Can a query be saved""" """Can a query be saved"""
url = reverse('helpdesk:savequery') url = reverse('helpdesk:savequery')
self.client.login(username=get_staff_user().get_username(), self.client.login(username=get_user(is_staff=True).get_username(),
password='password') password='password')
response = self.client.post( response = self.client.post(
url, url,

View File

@ -13,7 +13,6 @@ from django.contrib.auth.decorators import user_passes_test
from django.contrib.contenttypes.models import ContentType from django.contrib.contenttypes.models import ContentType
from django.urls import reverse, reverse_lazy from django.urls import reverse, reverse_lazy
from django.core.exceptions import ValidationError, PermissionDenied from django.core.exceptions import ValidationError, PermissionDenied
from django.db import connection
from django.db.models import Q from django.db.models import Q
from django.http import HttpResponseRedirect, Http404, HttpResponse from django.http import HttpResponseRedirect, Http404, HttpResponse
from django.shortcuts import render, get_object_or_404 from django.shortcuts import render, get_object_or_404
@ -37,6 +36,7 @@ from helpdesk.forms import (
TicketForm, UserSettingsForm, EmailIgnoreForm, EditTicketForm, TicketCCForm, TicketForm, UserSettingsForm, EmailIgnoreForm, EditTicketForm, TicketCCForm,
TicketCCEmailForm, TicketCCUserForm, EditFollowUpForm, TicketDependencyForm TicketCCEmailForm, TicketCCUserForm, EditFollowUpForm, TicketDependencyForm
) )
from helpdesk.decorators import staff_member_required, superuser_required
from helpdesk.lib import ( from helpdesk.lib import (
query_to_dict, apply_query, safe_template_context, query_to_dict, apply_query, safe_template_context,
process_attachments, queue_template_context, process_attachments, queue_template_context,
@ -67,8 +67,7 @@ else:
lambda u: u.is_authenticated and u.is_active and u.is_staff) lambda u: u.is_authenticated and u.is_active and u.is_staff)
superuser_required = user_passes_test( User = get_user_model()
lambda u: u.is_authenticated and u.is_active and u.is_superuser)
def _get_queue_choices(queues): def _get_queue_choices(queues):
@ -380,9 +379,6 @@ def view_ticket(request, ticket_id):
}) })
view_ticket = staff_member_required(view_ticket)
def return_ticketccstring_and_show_subscribe(user, ticket): def return_ticketccstring_and_show_subscribe(user, ticket):
"""used in view_ticket() and followup_edit()""" """used in view_ticket() and followup_edit()"""
# create the ticketcc_string and check whether current user is already # create the ticketcc_string and check whether current user is already
@ -1609,9 +1605,6 @@ def attachment_del(request, ticket_id, attachment_id):
}) })
attachment_del = staff_member_required(attachment_del)
def calc_average_nbr_days_until_ticket_resolved(Tickets): def calc_average_nbr_days_until_ticket_resolved(Tickets):
nbr_closed_tickets = len(Tickets) nbr_closed_tickets = len(Tickets)
days_per_ticket = 0 days_per_ticket = 0