Skip to content
This repository was archived by the owner on Jan 26, 2021. It is now read-only.

Added fix to disable unauthorized access by volunteers #449

Merged
merged 1 commit into from
Mar 7, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions vms/event/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
from django.shortcuts import render_to_response
from django.http import Http404
from volunteer.utils import vol_id_check
from vms.utils import check_correct_volunteer_shift_sign_up


class AdministratorLoginRequiredMixin(object):

Expand Down Expand Up @@ -122,6 +124,7 @@ def get_queryset(self):


@login_required
@check_correct_volunteer_shift_sign_up
@vol_id_check
def list_sign_up(request, volunteer_id):
if request.method == 'POST':
Expand Down
2 changes: 1 addition & 1 deletion vms/shift/tests/test_viewVolunteerShift.py
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ def test_access_another_existing_volunteer_view(self):
def test_access_another_nonexisting_volunteer_view(self):
upcoming_shift_page = self.upcoming_shift_page
upcoming_shift_page.get_page(self.live_server_url, upcoming_shift_page.view_shift_page + '65459')
found = re.search('You don\'t have the necessary rights to access this page', self.driver.page_source)
found = re.search('You don\'t have the required rights', self.driver.page_source)
self.assertNotEqual(found, None)

def test_view_without_any_assigned_shift(self):
Expand Down
23 changes: 21 additions & 2 deletions vms/shift/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
from django.utils.decorators import method_decorator
from django.core.urlresolvers import reverse_lazy
from volunteer.utils import vol_id_check
from vms.utils import check_correct_volunteer, check_correct_volunteer_shift

class AdministratorLoginRequiredMixin(object):

Expand All @@ -40,6 +41,10 @@ class AddHoursView(LoginRequiredMixin, FormView):
template_name = 'shift/add_hours.html'
form_class = HoursForm

@method_decorator(check_correct_volunteer_shift)
def dispatch(self, *args, **kwargs):
return super(AddHoursView, self).dispatch(*args, **kwargs)

def get_context_data(self, **kwargs):
context = super(AddHoursView, self).get_context_data(**kwargs)
shift_id = self.kwargs['shift_id']
Expand Down Expand Up @@ -161,12 +166,20 @@ def cancel(request, shift_id, volunteer_id):

# check that either an admin or volunteer is logged in
if not admin and not volunteer:
return HttpResponse(status=403)
return render(
request,
'vms/no_volunteer_rights.html',
status=403
)

# if a volunteer is logged in, verify that they are canceling their own shift
if volunteer:
if (int(volunteer.id) != int(volunteer_id)):
return HttpResponse(status=403)
return render(
request,
'vms/no_volunteer_rights.html',
status=403
)

if request.method == 'POST':
try:
Expand Down Expand Up @@ -373,6 +386,10 @@ class EditHoursView(LoginRequiredMixin, FormView):
template_name = 'shift/edit_hours.html'
form_class = HoursForm

@method_decorator(check_correct_volunteer_shift)
def dispatch(self, *args, **kwargs):
return super(EditHoursView, self).dispatch(*args, **kwargs)

def get_context_data(self, **kwargs):
context = super(EditHoursView, self).get_context_data(**kwargs)
volunteer_id = self.kwargs['volunteer_id']
Expand Down Expand Up @@ -573,6 +590,7 @@ def sign_up(request, shift_id, volunteer_id):
class ViewHoursView(LoginRequiredMixin, FormView, TemplateView):
template_name = 'shift/hours_list.html'

@method_decorator(check_correct_volunteer)
@method_decorator(vol_id_check)
def dispatch(self, *args, **kwargs):
return super(ViewHoursView, self).dispatch(*args, **kwargs)
Expand All @@ -586,6 +604,7 @@ def get_context_data(self, **kwargs):


@login_required
@check_correct_volunteer
@vol_id_check
def view_volunteer_shifts(request, volunteer_id):
shift_list = get_unlogged_shifts_by_volunteer_id(volunteer_id)
Expand Down
22 changes: 22 additions & 0 deletions vms/vms/templates/vms/no_volunteer_rights.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{% extends "vms/base.html" %}

{% load i18n %}

{% block content %}
<div class="spacer"></div>

{% csrf_token %}
<div class="panel panel-danger">
<div class="panel-heading">
<h3 class="panel-title">{% trans "No Access" %}</h3>
</div>
<div class="panel-body">
<br>
{% trans "You don't have the required rights" %}
<br>
<br>
<input type="button" class="btn btn-default" value="{% blocktrans %}Return to Previous Page{% endblocktrans %}" onClick="javascript:history.go(-1);">
</div>
</div>

{% endblock %}
120 changes: 120 additions & 0 deletions vms/vms/utils.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,120 @@
from functools import wraps
from django.http import Http404
from django.shortcuts import render
from volunteer.models import Volunteer


def check_correct_volunteer(func):
@wraps(func)
def wrapped_view(request, volunteer_id):
req_volunteer = getattr(request.user, "volunteer",
hasattr(request.user, "administrator"))
if not req_volunteer:
raise Http404
elif req_volunteer is not True:
try:
volunteer = Volunteer.objects.get(id=volunteer_id)
except Volunteer.DoesNotExist:
return render(
request,
"vms/no_volunteer_rights.html",
status=403
)
if volunteer.id == req_volunteer.id:
return func(request, volunteer_id=volunteer_id)
else:
return render(
request,
"vms/no_volunteer_rights.html",
status=403
)
else:
return render(
request,
"vms/no_volunteer_rights.html",
status=403
)
return render(
request,
"vms/no_volunteer_rights.html",
status=403
)
return wrapped_view


def check_correct_volunteer_shift(func):
@wraps(func)
def wrapped_view(request, shift_id, volunteer_id):
req_volunteer = getattr(request.user, "volunteer",
hasattr(request.user, "administrator"))
if not req_volunteer:
raise Http404
elif req_volunteer is not True:
try:
volunteer = Volunteer.objects.get(id=volunteer_id)
except Volunteer.DoesNotExist:
return render(
request,
"vms/no_volunteer_rights.html",
status=403
)
if volunteer.id == req_volunteer.id:
return func(request, volunteer_id=volunteer_id)
else:
return render(
request,
"vms/no_volunteer_rights.html",
status=403
)
else:
return render(
request,
"vms/no_volunteer_rights.html",
status=403
)
return render(
request,
"vms/no_volunteer_rights.html",
status=403
)
return wrapped_view


def check_correct_volunteer_shift_sign_up(func):
@wraps(func)
def wrapped_view(request, volunteer_id):
req_volunteer = getattr(request.user, "volunteer",
hasattr(request.user, "administrator"))
if req_volunteer is True:
return func(request, volunteer_id=volunteer_id)
if not req_volunteer:
raise Http404
elif req_volunteer is not True:
try:
volunteer = Volunteer.objects.get(id=volunteer_id)
except Volunteer.DoesNotExist:
return render(
request,
"vms/no_volunteer_rights.html",
status=403
)
if volunteer.id == req_volunteer.id:
return func(request, volunteer_id=volunteer_id)
else:
return render(
request,
"vms/no_volunteer_rights.html",
status=403
)
else:
return render(
request,
"vms/no_volunteer_rights.html",
status=403
)
return render(
request,
"vms/no_volunteer_rights.html",
status=403
)
return wrapped_view
8 changes: 8 additions & 0 deletions vms/volunteer/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
from django.core.urlresolvers import reverse_lazy
from django.utils.decorators import method_decorator
from volunteer.utils import vol_id_check
from vms.utils import check_correct_volunteer

@login_required
def download_resume(request, volunteer_id):
Expand Down Expand Up @@ -61,6 +62,11 @@ def delete_resume(request, volunteer_id):
'''

class VolunteerUpdateView(LoginRequiredMixin, UpdateView, FormView):

@method_decorator(check_correct_volunteer)
def dispatch(self, *args, **kwargs):
return super(VolunteerUpdateView, self).dispatch(*args, **kwargs)

form_class = VolunteerForm
template_name = 'volunteer/edit.html'
success_url = reverse_lazy('volunteer:profile')
Expand Down Expand Up @@ -110,6 +116,7 @@ def form_valid(self, form):
class ProfileView(LoginRequiredMixin, DetailView):
template_name = 'volunteer/profile.html'

@method_decorator(check_correct_volunteer)
@method_decorator(vol_id_check)
def dispatch(self, *args, **kwargs):
return super(ProfileView, self).dispatch(*args, **kwargs)
Expand All @@ -127,6 +134,7 @@ def get_object(self, queryset=None):

class GenerateReportView(LoginRequiredMixin, View):

@method_decorator(check_correct_volunteer)
@method_decorator(vol_id_check)
def dispatch(self, *args, **kwargs):
return super(GenerateReportView, self).dispatch(*args, **kwargs)
Expand Down