mirror of
https://github.com/Southampton-RSG/breccia-mapper.git
synced 2026-03-03 03:17:07 +00:00
@@ -8,6 +8,7 @@ from django.views.generic import DetailView, ListView, View
|
||||
from django.views.generic.detail import SingleObjectMixin
|
||||
|
||||
from people import models as people_models
|
||||
from people import permissions
|
||||
from . import models
|
||||
|
||||
|
||||
@@ -54,20 +55,23 @@ class ActivityDetailView(DetailView):
|
||||
return context
|
||||
|
||||
|
||||
class ActivityAttendanceView(SingleObjectMixin, View):
|
||||
class ActivityAttendanceView(permissions.UserIsLinkedPersonMixin, SingleObjectMixin, View):
|
||||
"""
|
||||
View to add or delete attendance of an activity.
|
||||
"""
|
||||
model = models.Activity
|
||||
|
||||
def get_test_person(self) -> people_models.Person:
|
||||
data = json.loads(self.request.body)
|
||||
|
||||
self.person = people_models.Person.objects.get(pk=data['pk'])
|
||||
return self.person
|
||||
|
||||
def post(self, request, *args, **kwargs):
|
||||
self.object = self.get_object()
|
||||
|
||||
if request.is_ajax():
|
||||
data = json.loads(request.body)
|
||||
|
||||
person = people_models.Person.objects.get(pk=data['pk'])
|
||||
self.object.attendance_list.add(person)
|
||||
self.object.attendance_list.add(self.person)
|
||||
|
||||
return HttpResponse(status=204)
|
||||
|
||||
@@ -77,10 +81,7 @@ class ActivityAttendanceView(SingleObjectMixin, View):
|
||||
self.object = self.get_object()
|
||||
|
||||
if request.is_ajax():
|
||||
data = json.loads(request.body)
|
||||
|
||||
person = people_models.Person.objects.get(pk=data['pk'])
|
||||
self.object.attendance_list.remove(person)
|
||||
self.object.attendance_list.remove(self.person)
|
||||
|
||||
return HttpResponse(status=204)
|
||||
|
||||
|
||||
7
breccia_mapper/templates/403.html
Normal file
7
breccia_mapper/templates/403.html
Normal file
@@ -0,0 +1,7 @@
|
||||
{% extends 'base.html' %}
|
||||
|
||||
{% block content %}
|
||||
<h2>Error 403 at {{ request.path }}</h2>
|
||||
|
||||
<p>{{ exception }}</p>
|
||||
{% endblock content %}
|
||||
33
people/permissions.py
Normal file
33
people/permissions.py
Normal file
@@ -0,0 +1,33 @@
|
||||
"""
|
||||
Permission mixins for views relating to :class:`Person`s.
|
||||
"""
|
||||
|
||||
from django.contrib.auth.mixins import UserPassesTestMixin
|
||||
|
||||
from . import models
|
||||
|
||||
|
||||
class UserIsLinkedPersonMixin(UserPassesTestMixin):
|
||||
"""
|
||||
Grant access if the user is staff or has a :class:`Person` record and
|
||||
this is the one referred to in the view.
|
||||
"""
|
||||
related_person_field = None
|
||||
permission_denied_message = 'You do not have permission to view this page.'
|
||||
|
||||
def get_test_person(self) -> models.Person:
|
||||
"""
|
||||
Get the :class:`Person` to test the user against.
|
||||
"""
|
||||
if self.related_person_field is None:
|
||||
test_person = self.get_object()
|
||||
|
||||
if not isinstance(test_person, models.Person):
|
||||
raise AttributeError('View incorrectly configured: \'related_person_field\' must be defined.')
|
||||
|
||||
return test_person
|
||||
|
||||
return getattr(self.get_object(), self.related_person_field)
|
||||
|
||||
def test_func(self) -> bool:
|
||||
return self.request.user.is_staff or self.get_test_person() == self.request.user.person
|
||||
@@ -5,7 +5,7 @@ Views for displaying or manipulating models in the 'people' app.
|
||||
from django.http import HttpResponseRedirect
|
||||
from django.views.generic import CreateView, DetailView, ListView, UpdateView
|
||||
|
||||
from . import forms, models
|
||||
from . import forms, models, permissions
|
||||
|
||||
|
||||
class PersonCreateView(CreateView):
|
||||
@@ -33,7 +33,7 @@ class PersonListView(ListView):
|
||||
template_name = 'people/person/list.html'
|
||||
|
||||
|
||||
class ProfileView(DetailView):
|
||||
class ProfileView(permissions.UserIsLinkedPersonMixin, DetailView):
|
||||
"""
|
||||
View displaying the profile of a :class:`Person` - who may be a user.
|
||||
"""
|
||||
@@ -50,10 +50,11 @@ class ProfileView(DetailView):
|
||||
return super().get_object(queryset)
|
||||
|
||||
except AttributeError:
|
||||
# pk was not provided in URL
|
||||
return self.request.user.person
|
||||
|
||||
|
||||
class PersonUpdateView(UpdateView):
|
||||
class PersonUpdateView(permissions.UserIsLinkedPersonMixin, UpdateView):
|
||||
"""
|
||||
View for updating a :class:`Person` record.
|
||||
"""
|
||||
@@ -62,15 +63,16 @@ class PersonUpdateView(UpdateView):
|
||||
form_class = forms.PersonForm
|
||||
|
||||
|
||||
class RelationshipDetailView(DetailView):
|
||||
class RelationshipDetailView(permissions.UserIsLinkedPersonMixin, DetailView):
|
||||
"""
|
||||
View displaying details of a :class:`Relationship`.
|
||||
"""
|
||||
model = models.Relationship
|
||||
template_name = 'people/relationship/detail.html'
|
||||
related_person_field = 'source'
|
||||
|
||||
|
||||
class RelationshipCreateView(CreateView):
|
||||
class RelationshipCreateView(permissions.UserIsLinkedPersonMixin, CreateView):
|
||||
"""
|
||||
View for creating a :class:`Relationship`.
|
||||
|
||||
@@ -80,6 +82,15 @@ class RelationshipCreateView(CreateView):
|
||||
template_name = 'people/relationship/create.html'
|
||||
form_class = forms.RelationshipForm
|
||||
|
||||
def get_test_person(self) -> models.Person:
|
||||
"""
|
||||
|
||||
"""
|
||||
if self.request.method == 'POST':
|
||||
return models.Person.objects.get(pk=self.request.POST.get('source'))
|
||||
|
||||
return models.Person.objects.get(pk=self.kwargs.get('person_pk'))
|
||||
|
||||
def get(self, request, *args, **kwargs):
|
||||
self.person = models.Person.objects.get(pk=self.kwargs.get('person_pk'))
|
||||
|
||||
|
||||
Reference in New Issue
Block a user