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

Commit 9b7aea8

Browse files
authored
Merge pull request #449 from InfernoCoder/VOLUNTEER_URL
Added fix to disable unauthorized access by volunteers
2 parents 880a3c8 + dac9219 commit 9b7aea8

File tree

6 files changed

+175
-3
lines changed

6 files changed

+175
-3
lines changed

vms/event/views.py

+3
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
from django.shortcuts import render_to_response
1717
from django.http import Http404
1818
from volunteer.utils import vol_id_check
19+
from vms.utils import check_correct_volunteer_shift_sign_up
20+
1921

2022
class AdministratorLoginRequiredMixin(object):
2123

@@ -122,6 +124,7 @@ def get_queryset(self):
122124

123125

124126
@login_required
127+
@check_correct_volunteer_shift_sign_up
125128
@vol_id_check
126129
def list_sign_up(request, volunteer_id):
127130
if request.method == 'POST':

vms/shift/tests/test_viewVolunteerShift.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -67,7 +67,7 @@ def test_access_another_existing_volunteer_view(self):
6767
def test_access_another_nonexisting_volunteer_view(self):
6868
upcoming_shift_page = self.upcoming_shift_page
6969
upcoming_shift_page.get_page(self.live_server_url, upcoming_shift_page.view_shift_page + '65459')
70-
found = re.search('You don\'t have the necessary rights to access this page', self.driver.page_source)
70+
found = re.search('You don\'t have the required rights', self.driver.page_source)
7171
self.assertNotEqual(found, None)
7272

7373
def test_view_without_any_assigned_shift(self):

vms/shift/views.py

+21-2
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
from django.utils.decorators import method_decorator
2020
from django.core.urlresolvers import reverse_lazy
2121
from volunteer.utils import vol_id_check
22+
from vms.utils import check_correct_volunteer, check_correct_volunteer_shift
2223

2324
class AdministratorLoginRequiredMixin(object):
2425

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

44+
@method_decorator(check_correct_volunteer_shift)
45+
def dispatch(self, *args, **kwargs):
46+
return super(AddHoursView, self).dispatch(*args, **kwargs)
47+
4348
def get_context_data(self, **kwargs):
4449
context = super(AddHoursView, self).get_context_data(**kwargs)
4550
shift_id = self.kwargs['shift_id']
@@ -161,12 +166,20 @@ def cancel(request, shift_id, volunteer_id):
161166

162167
# check that either an admin or volunteer is logged in
163168
if not admin and not volunteer:
164-
return HttpResponse(status=403)
169+
return render(
170+
request,
171+
'vms/no_volunteer_rights.html',
172+
status=403
173+
)
165174

166175
# if a volunteer is logged in, verify that they are canceling their own shift
167176
if volunteer:
168177
if (int(volunteer.id) != int(volunteer_id)):
169-
return HttpResponse(status=403)
178+
return render(
179+
request,
180+
'vms/no_volunteer_rights.html',
181+
status=403
182+
)
170183

171184
if request.method == 'POST':
172185
try:
@@ -373,6 +386,10 @@ class EditHoursView(LoginRequiredMixin, FormView):
373386
template_name = 'shift/edit_hours.html'
374387
form_class = HoursForm
375388

389+
@method_decorator(check_correct_volunteer_shift)
390+
def dispatch(self, *args, **kwargs):
391+
return super(EditHoursView, self).dispatch(*args, **kwargs)
392+
376393
def get_context_data(self, **kwargs):
377394
context = super(EditHoursView, self).get_context_data(**kwargs)
378395
volunteer_id = self.kwargs['volunteer_id']
@@ -573,6 +590,7 @@ def sign_up(request, shift_id, volunteer_id):
573590
class ViewHoursView(LoginRequiredMixin, FormView, TemplateView):
574591
template_name = 'shift/hours_list.html'
575592

593+
@method_decorator(check_correct_volunteer)
576594
@method_decorator(vol_id_check)
577595
def dispatch(self, *args, **kwargs):
578596
return super(ViewHoursView, self).dispatch(*args, **kwargs)
@@ -586,6 +604,7 @@ def get_context_data(self, **kwargs):
586604

587605

588606
@login_required
607+
@check_correct_volunteer
589608
@vol_id_check
590609
def view_volunteer_shifts(request, volunteer_id):
591610
shift_list = get_unlogged_shifts_by_volunteer_id(volunteer_id)
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
{% extends "vms/base.html" %}
2+
3+
{% load i18n %}
4+
5+
{% block content %}
6+
<div class="spacer"></div>
7+
8+
{% csrf_token %}
9+
<div class="panel panel-danger">
10+
<div class="panel-heading">
11+
<h3 class="panel-title">{% trans "No Access" %}</h3>
12+
</div>
13+
<div class="panel-body">
14+
<br>
15+
{% trans "You don't have the required rights" %}
16+
<br>
17+
<br>
18+
<input type="button" class="btn btn-default" value="{% blocktrans %}Return to Previous Page{% endblocktrans %}" onClick="javascript:history.go(-1);">
19+
</div>
20+
</div>
21+
22+
{% endblock %}

vms/vms/utils.py

+120
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
from functools import wraps
2+
from django.http import Http404
3+
from django.shortcuts import render
4+
from volunteer.models import Volunteer
5+
6+
7+
def check_correct_volunteer(func):
8+
@wraps(func)
9+
def wrapped_view(request, volunteer_id):
10+
req_volunteer = getattr(request.user, "volunteer",
11+
hasattr(request.user, "administrator"))
12+
if not req_volunteer:
13+
raise Http404
14+
elif req_volunteer is not True:
15+
try:
16+
volunteer = Volunteer.objects.get(id=volunteer_id)
17+
except Volunteer.DoesNotExist:
18+
return render(
19+
request,
20+
"vms/no_volunteer_rights.html",
21+
status=403
22+
)
23+
if volunteer.id == req_volunteer.id:
24+
return func(request, volunteer_id=volunteer_id)
25+
else:
26+
return render(
27+
request,
28+
"vms/no_volunteer_rights.html",
29+
status=403
30+
)
31+
else:
32+
return render(
33+
request,
34+
"vms/no_volunteer_rights.html",
35+
status=403
36+
)
37+
return render(
38+
request,
39+
"vms/no_volunteer_rights.html",
40+
status=403
41+
)
42+
return wrapped_view
43+
44+
45+
def check_correct_volunteer_shift(func):
46+
@wraps(func)
47+
def wrapped_view(request, shift_id, volunteer_id):
48+
req_volunteer = getattr(request.user, "volunteer",
49+
hasattr(request.user, "administrator"))
50+
if not req_volunteer:
51+
raise Http404
52+
elif req_volunteer is not True:
53+
try:
54+
volunteer = Volunteer.objects.get(id=volunteer_id)
55+
except Volunteer.DoesNotExist:
56+
return render(
57+
request,
58+
"vms/no_volunteer_rights.html",
59+
status=403
60+
)
61+
if volunteer.id == req_volunteer.id:
62+
return func(request, volunteer_id=volunteer_id)
63+
else:
64+
return render(
65+
request,
66+
"vms/no_volunteer_rights.html",
67+
status=403
68+
)
69+
else:
70+
return render(
71+
request,
72+
"vms/no_volunteer_rights.html",
73+
status=403
74+
)
75+
return render(
76+
request,
77+
"vms/no_volunteer_rights.html",
78+
status=403
79+
)
80+
return wrapped_view
81+
82+
83+
def check_correct_volunteer_shift_sign_up(func):
84+
@wraps(func)
85+
def wrapped_view(request, volunteer_id):
86+
req_volunteer = getattr(request.user, "volunteer",
87+
hasattr(request.user, "administrator"))
88+
if req_volunteer is True:
89+
return func(request, volunteer_id=volunteer_id)
90+
if not req_volunteer:
91+
raise Http404
92+
elif req_volunteer is not True:
93+
try:
94+
volunteer = Volunteer.objects.get(id=volunteer_id)
95+
except Volunteer.DoesNotExist:
96+
return render(
97+
request,
98+
"vms/no_volunteer_rights.html",
99+
status=403
100+
)
101+
if volunteer.id == req_volunteer.id:
102+
return func(request, volunteer_id=volunteer_id)
103+
else:
104+
return render(
105+
request,
106+
"vms/no_volunteer_rights.html",
107+
status=403
108+
)
109+
else:
110+
return render(
111+
request,
112+
"vms/no_volunteer_rights.html",
113+
status=403
114+
)
115+
return render(
116+
request,
117+
"vms/no_volunteer_rights.html",
118+
status=403
119+
)
120+
return wrapped_view

vms/volunteer/views.py

+8
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
from django.core.urlresolvers import reverse_lazy
2525
from django.utils.decorators import method_decorator
2626
from volunteer.utils import vol_id_check
27+
from vms.utils import check_correct_volunteer
2728

2829
@login_required
2930
def download_resume(request, volunteer_id):
@@ -61,6 +62,11 @@ def delete_resume(request, volunteer_id):
6162
'''
6263

6364
class VolunteerUpdateView(LoginRequiredMixin, UpdateView, FormView):
65+
66+
@method_decorator(check_correct_volunteer)
67+
def dispatch(self, *args, **kwargs):
68+
return super(VolunteerUpdateView, self).dispatch(*args, **kwargs)
69+
6470
form_class = VolunteerForm
6571
template_name = 'volunteer/edit.html'
6672
success_url = reverse_lazy('volunteer:profile')
@@ -110,6 +116,7 @@ def form_valid(self, form):
110116
class ProfileView(LoginRequiredMixin, DetailView):
111117
template_name = 'volunteer/profile.html'
112118

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

128135
class GenerateReportView(LoginRequiredMixin, View):
129136

137+
@method_decorator(check_correct_volunteer)
130138
@method_decorator(vol_id_check)
131139
def dispatch(self, *args, **kwargs):
132140
return super(GenerateReportView, self).dispatch(*args, **kwargs)

0 commit comments

Comments
 (0)