Prevent caching of pages requiring authentication

This commit is contained in:
Christopher C. Wells 2021-09-16 19:34:33 -07:00
parent 45cb43958d
commit 0e6a5cb08a
5 changed files with 50 additions and 45 deletions

View File

@ -1,14 +1,22 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.contrib.auth.mixins import AccessMixin, PermissionRequiredMixin from django.contrib.auth.mixins import AccessMixin, \
LoginRequiredMixin as LoginRequiredMixInBase, \
PermissionRequiredMixin as PermissionRequiredMixinBase
from django.utils.decorators import method_decorator
from django.views.decorators.cache import never_cache
class PermissionRequired403Mixin(PermissionRequiredMixin): @method_decorator(never_cache, name='dispatch')
""" class LoginRequiredMixin(LoginRequiredMixInBase):
Raise an exception instead of redirecting to login. pass
"""
raise_exception = True
@method_decorator(never_cache, name='dispatch')
class PermissionRequiredMixin(PermissionRequiredMixinBase):
login_url = '/login'
@method_decorator(never_cache, name='dispatch')
class StaffOnlyMixin(AccessMixin): class StaffOnlyMixin(AccessMixin):
""" """
Verify the current user is staff. Verify the current user is staff.

View File

@ -2,7 +2,6 @@
from django.contrib import messages from django.contrib import messages
from django.contrib.auth import update_session_auth_hash from django.contrib.auth import update_session_auth_hash
from django.contrib.auth.forms import PasswordChangeForm from django.contrib.auth.forms import PasswordChangeForm
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.auth.models import User from django.contrib.auth.models import User
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
from django.shortcuts import redirect, render from django.shortcuts import redirect, render
@ -17,7 +16,8 @@ from django.views.i18n import set_language
from django_filters.views import FilterView from django_filters.views import FilterView
from babybuddy import forms from babybuddy import forms
from babybuddy.mixins import PermissionRequired403Mixin, StaffOnlyMixin from babybuddy.mixins import LoginRequiredMixin, PermissionRequiredMixin, \
StaffOnlyMixin
from babybuddy.models import user_logged_in_callback from babybuddy.models import user_logged_in_callback
@ -56,7 +56,7 @@ class UserList(StaffOnlyMixin, BabyBuddyFilterView):
filterset_fields = ('username', 'first_name', 'last_name', 'email') filterset_fields = ('username', 'first_name', 'last_name', 'email')
class UserAdd(StaffOnlyMixin, PermissionRequired403Mixin, SuccessMessageMixin, class UserAdd(StaffOnlyMixin, PermissionRequiredMixin, SuccessMessageMixin,
CreateView): CreateView):
model = User model = User
template_name = 'babybuddy/user_form.html' template_name = 'babybuddy/user_form.html'
@ -66,7 +66,7 @@ class UserAdd(StaffOnlyMixin, PermissionRequired403Mixin, SuccessMessageMixin,
success_message = gettext_lazy('User %(username)s added!') success_message = gettext_lazy('User %(username)s added!')
class UserUpdate(StaffOnlyMixin, PermissionRequired403Mixin, class UserUpdate(StaffOnlyMixin, PermissionRequiredMixin,
SuccessMessageMixin, UpdateView): SuccessMessageMixin, UpdateView):
model = User model = User
template_name = 'babybuddy/user_form.html' template_name = 'babybuddy/user_form.html'
@ -76,7 +76,7 @@ class UserUpdate(StaffOnlyMixin, PermissionRequired403Mixin,
success_message = gettext_lazy('User %(username)s updated.') success_message = gettext_lazy('User %(username)s updated.')
class UserDelete(StaffOnlyMixin, PermissionRequired403Mixin, class UserDelete(StaffOnlyMixin, PermissionRequiredMixin,
DeleteView): DeleteView):
model = User model = User
template_name = 'babybuddy/user_confirm_delete.html' template_name = 'babybuddy/user_confirm_delete.html'

View File

@ -1,6 +1,5 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.contrib import messages from django.contrib import messages
from django.contrib.auth.mixins import LoginRequiredMixin
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
from django.forms import Form from django.forms import Form
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
@ -12,7 +11,7 @@ from django.views.generic.detail import DetailView
from django.views.generic.edit import CreateView, UpdateView, DeleteView, \ from django.views.generic.edit import CreateView, UpdateView, DeleteView, \
FormView FormView
from babybuddy.mixins import PermissionRequired403Mixin from babybuddy.mixins import LoginRequiredMixin, PermissionRequiredMixin
from babybuddy.views import BabyBuddyFilterView from babybuddy.views import BabyBuddyFilterView
from core import forms, models, timeline from core import forms, models, timeline
@ -28,7 +27,7 @@ def _prepare_timeline_context_data(context, date, child=None):
pass pass
class CoreAddView(PermissionRequired403Mixin, SuccessMessageMixin, CreateView): class CoreAddView(PermissionRequiredMixin, SuccessMessageMixin, CreateView):
def get_success_message(self, cleaned_data): def get_success_message(self, cleaned_data):
cleaned_data['model'] = self.model._meta.verbose_name.title() cleaned_data['model'] = self.model._meta.verbose_name.title()
if 'child' in cleaned_data: if 'child' in cleaned_data:
@ -56,7 +55,7 @@ class CoreAddView(PermissionRequired403Mixin, SuccessMessageMixin, CreateView):
return kwargs return kwargs
class CoreUpdateView(PermissionRequired403Mixin, SuccessMessageMixin, class CoreUpdateView(PermissionRequiredMixin, SuccessMessageMixin,
UpdateView): UpdateView):
def get_success_message(self, cleaned_data): def get_success_message(self, cleaned_data):
cleaned_data['model'] = self.model._meta.verbose_name.title() cleaned_data['model'] = self.model._meta.verbose_name.title()
@ -67,7 +66,7 @@ class CoreUpdateView(PermissionRequired403Mixin, SuccessMessageMixin,
return self.success_message % cleaned_data return self.success_message % cleaned_data
class CoreDeleteView(PermissionRequired403Mixin, DeleteView): class CoreDeleteView(PermissionRequiredMixin, DeleteView):
""" """
SuccessMessageMixin is not compatible DeleteView. SuccessMessageMixin is not compatible DeleteView.
See: https://code.djangoproject.com/ticket/21936 See: https://code.djangoproject.com/ticket/21936
@ -80,7 +79,7 @@ class CoreDeleteView(PermissionRequired403Mixin, DeleteView):
return super(CoreDeleteView, self).delete(request, *args, **kwargs) return super(CoreDeleteView, self).delete(request, *args, **kwargs)
class ChildList(PermissionRequired403Mixin, BabyBuddyFilterView): class ChildList(PermissionRequiredMixin, BabyBuddyFilterView):
model = models.Child model = models.Child
template_name = 'core/child_list.html' template_name = 'core/child_list.html'
permission_required = ('core.view_child',) permission_required = ('core.view_child',)
@ -96,7 +95,7 @@ class ChildAdd(CoreAddView):
success_message = _('%(first_name)s %(last_name)s added!') success_message = _('%(first_name)s %(last_name)s added!')
class ChildDetail(PermissionRequired403Mixin, DetailView): class ChildDetail(PermissionRequiredMixin, DetailView):
model = models.Child model = models.Child
permission_required = ('core.view_child',) permission_required = ('core.view_child',)
@ -130,7 +129,7 @@ class ChildDelete(CoreUpdateView):
return success_message % cleaned_data return success_message % cleaned_data
class DiaperChangeList(PermissionRequired403Mixin, BabyBuddyFilterView): class DiaperChangeList(PermissionRequiredMixin, BabyBuddyFilterView):
model = models.DiaperChange model = models.DiaperChange
template_name = 'core/diaperchange_list.html' template_name = 'core/diaperchange_list.html'
permission_required = ('core.view_diaperchange',) permission_required = ('core.view_diaperchange',)
@ -158,7 +157,7 @@ class DiaperChangeDelete(CoreDeleteView):
success_url = reverse_lazy('core:diaperchange-list') success_url = reverse_lazy('core:diaperchange-list')
class FeedingList(PermissionRequired403Mixin, BabyBuddyFilterView): class FeedingList(PermissionRequiredMixin, BabyBuddyFilterView):
model = models.Feeding model = models.Feeding
template_name = 'core/feeding_list.html' template_name = 'core/feeding_list.html'
permission_required = ('core.view_feeding',) permission_required = ('core.view_feeding',)
@ -186,7 +185,7 @@ class FeedingDelete(CoreDeleteView):
success_url = reverse_lazy('core:feeding-list') success_url = reverse_lazy('core:feeding-list')
class NoteList(PermissionRequired403Mixin, BabyBuddyFilterView): class NoteList(PermissionRequiredMixin, BabyBuddyFilterView):
model = models.Note model = models.Note
template_name = 'core/note_list.html' template_name = 'core/note_list.html'
permission_required = ('core.view_note',) permission_required = ('core.view_note',)
@ -214,7 +213,7 @@ class NoteDelete(CoreDeleteView):
success_url = reverse_lazy('core:note-list') success_url = reverse_lazy('core:note-list')
class SleepList(PermissionRequired403Mixin, BabyBuddyFilterView): class SleepList(PermissionRequiredMixin, BabyBuddyFilterView):
model = models.Sleep model = models.Sleep
template_name = 'core/sleep_list.html' template_name = 'core/sleep_list.html'
permission_required = ('core.view_sleep',) permission_required = ('core.view_sleep',)
@ -242,7 +241,7 @@ class SleepDelete(CoreDeleteView):
success_url = reverse_lazy('core:sleep-list') success_url = reverse_lazy('core:sleep-list')
class TemperatureList(PermissionRequired403Mixin, BabyBuddyFilterView): class TemperatureList(PermissionRequiredMixin, BabyBuddyFilterView):
model = models.Temperature model = models.Temperature
template_name = 'core/temperature_list.html' template_name = 'core/temperature_list.html'
permission_required = ('core.view_temperature',) permission_required = ('core.view_temperature',)
@ -294,7 +293,7 @@ class Timeline(LoginRequiredMixin, TemplateView):
return context return context
class TimerList(PermissionRequired403Mixin, BabyBuddyFilterView): class TimerList(PermissionRequiredMixin, BabyBuddyFilterView):
model = models.Timer model = models.Timer
template_name = 'core/timer_list.html' template_name = 'core/timer_list.html'
permission_required = ('core.view_timer',) permission_required = ('core.view_timer',)
@ -302,12 +301,12 @@ class TimerList(PermissionRequired403Mixin, BabyBuddyFilterView):
filterset_fields = ('active', 'user') filterset_fields = ('active', 'user')
class TimerDetail(PermissionRequired403Mixin, DetailView): class TimerDetail(PermissionRequiredMixin, DetailView):
model = models.Timer model = models.Timer
permission_required = ('core.view_timer',) permission_required = ('core.view_timer',)
class TimerAdd(PermissionRequired403Mixin, CreateView): class TimerAdd(PermissionRequiredMixin, CreateView):
model = models.Timer model = models.Timer
permission_required = ('core.add_timer',) permission_required = ('core.add_timer',)
form_class = forms.TimerForm form_class = forms.TimerForm
@ -337,7 +336,7 @@ class TimerUpdate(CoreUpdateView):
return reverse('core:timer-detail', kwargs={'pk': instance.pk}) return reverse('core:timer-detail', kwargs={'pk': instance.pk})
class TimerAddQuick(PermissionRequired403Mixin, RedirectView): class TimerAddQuick(PermissionRequiredMixin, RedirectView):
http_method_names = ['post'] http_method_names = ['post']
permission_required = ('core.add_timer',) permission_required = ('core.add_timer',)
@ -352,7 +351,7 @@ class TimerAddQuick(PermissionRequired403Mixin, RedirectView):
return super(TimerAddQuick, self).get(request, *args, **kwargs) return super(TimerAddQuick, self).get(request, *args, **kwargs)
class TimerRestart(PermissionRequired403Mixin, RedirectView): class TimerRestart(PermissionRequiredMixin, RedirectView):
http_method_names = ['post'] http_method_names = ['post']
permission_required = ('core.change_timer',) permission_required = ('core.change_timer',)
@ -366,7 +365,7 @@ class TimerRestart(PermissionRequired403Mixin, RedirectView):
return reverse('core:timer-detail', kwargs={'pk': kwargs['pk']}) return reverse('core:timer-detail', kwargs={'pk': kwargs['pk']})
class TimerStop(PermissionRequired403Mixin, SuccessMessageMixin, RedirectView): class TimerStop(PermissionRequiredMixin, SuccessMessageMixin, RedirectView):
http_method_names = ['post'] http_method_names = ['post']
permission_required = ('core.change_timer',) permission_required = ('core.change_timer',)
success_message = _('%(timer)s stopped.') success_message = _('%(timer)s stopped.')
@ -387,7 +386,7 @@ class TimerDelete(CoreDeleteView):
success_url = reverse_lazy('core:timer-list') success_url = reverse_lazy('core:timer-list')
class TimerDeleteInactive(PermissionRequired403Mixin, SuccessMessageMixin, class TimerDeleteInactive(PermissionRequiredMixin, SuccessMessageMixin,
FormView): FormView):
permission_required = ('core.delete_timer',) permission_required = ('core.delete_timer',)
form_class = Form form_class = Form
@ -416,7 +415,7 @@ class TimerDeleteInactive(PermissionRequired403Mixin, SuccessMessageMixin,
return models.Timer.objects.filter(active=False) return models.Timer.objects.filter(active=False)
class TummyTimeList(PermissionRequired403Mixin, BabyBuddyFilterView): class TummyTimeList(PermissionRequiredMixin, BabyBuddyFilterView):
model = models.TummyTime model = models.TummyTime
template_name = 'core/tummytime_list.html' template_name = 'core/tummytime_list.html'
permission_required = ('core.view_tummytime',) permission_required = ('core.view_tummytime',)
@ -444,7 +443,7 @@ class TummyTimeDelete(CoreDeleteView):
success_url = reverse_lazy('core:tummytime-list') success_url = reverse_lazy('core:tummytime-list')
class WeightList(PermissionRequired403Mixin, BabyBuddyFilterView): class WeightList(PermissionRequiredMixin, BabyBuddyFilterView):
model = models.Weight model = models.Weight
template_name = 'core/weight_list.html' template_name = 'core/weight_list.html'
permission_required = ('core.view_weight',) permission_required = ('core.view_weight',)

View File

@ -1,11 +1,10 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.contrib.auth.mixins import LoginRequiredMixin
from django.http import HttpResponseRedirect from django.http import HttpResponseRedirect
from django.urls import reverse from django.urls import reverse
from django.views.generic.base import TemplateView from django.views.generic.base import TemplateView
from django.views.generic.detail import DetailView from django.views.generic.detail import DetailView
from babybuddy.mixins import PermissionRequired403Mixin from babybuddy.mixins import LoginRequiredMixin, PermissionRequiredMixin
from core.models import Child from core.models import Child
@ -34,8 +33,7 @@ class Dashboard(LoginRequiredMixin, TemplateView):
return context return context
class ChildDashboard(PermissionRequired403Mixin, DetailView): class ChildDashboard(PermissionRequiredMixin, DetailView):
model = Child model = Child
permission_required = ('core.view_child',) permission_required = ('core.view_child',)
raise_exception = True
template_name = 'dashboard/child.html' template_name = 'dashboard/child.html'

View File

@ -1,13 +1,13 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
from django.views.generic.detail import DetailView from django.views.generic.detail import DetailView
from babybuddy.mixins import PermissionRequired403Mixin from babybuddy.mixins import PermissionRequiredMixin
from core import models from core import models
from . import graphs from . import graphs
class DiaperChangeAmounts(PermissionRequired403Mixin, DetailView): class DiaperChangeAmounts(PermissionRequiredMixin, DetailView):
""" """
Graph of diaper "amounts" - measurements of urine output. Graph of diaper "amounts" - measurements of urine output.
""" """
@ -25,7 +25,7 @@ class DiaperChangeAmounts(PermissionRequired403Mixin, DetailView):
return context return context
class DiaperChangeLifetimesChildReport(PermissionRequired403Mixin, DetailView): class DiaperChangeLifetimesChildReport(PermissionRequiredMixin, DetailView):
""" """
Graph of diaper "lifetimes" - time between diaper changes. Graph of diaper "lifetimes" - time between diaper changes.
""" """
@ -44,7 +44,7 @@ class DiaperChangeLifetimesChildReport(PermissionRequired403Mixin, DetailView):
return context return context
class DiaperChangeTypesChildReport(PermissionRequired403Mixin, DetailView): class DiaperChangeTypesChildReport(PermissionRequiredMixin, DetailView):
""" """
Graph of diaper changes by day and type. Graph of diaper changes by day and type.
""" """
@ -63,7 +63,7 @@ class DiaperChangeTypesChildReport(PermissionRequired403Mixin, DetailView):
return context return context
class FeedingAmountsChildReport(PermissionRequired403Mixin, DetailView): class FeedingAmountsChildReport(PermissionRequiredMixin, DetailView):
""" """
Graph of daily feeding amounts over time. Graph of daily feeding amounts over time.
""" """
@ -86,7 +86,7 @@ class FeedingAmountsChildReport(PermissionRequired403Mixin, DetailView):
return context return context
class FeedingDurationChildReport(PermissionRequired403Mixin, DetailView): class FeedingDurationChildReport(PermissionRequiredMixin, DetailView):
""" """
Graph of feeding durations over time. Graph of feeding durations over time.
""" """
@ -109,7 +109,7 @@ class FeedingDurationChildReport(PermissionRequired403Mixin, DetailView):
return context return context
class SleepPatternChildReport(PermissionRequired403Mixin, DetailView): class SleepPatternChildReport(PermissionRequiredMixin, DetailView):
""" """
Graph of sleep pattern comparing sleep to wake times by day. Graph of sleep pattern comparing sleep to wake times by day.
""" """
@ -132,7 +132,7 @@ class SleepPatternChildReport(PermissionRequired403Mixin, DetailView):
return context return context
class SleepTotalsChildReport(PermissionRequired403Mixin, DetailView): class SleepTotalsChildReport(PermissionRequiredMixin, DetailView):
""" """
Graph of total sleep by day. Graph of total sleep by day.
""" """
@ -155,7 +155,7 @@ class SleepTotalsChildReport(PermissionRequired403Mixin, DetailView):
return context return context
class WeightWeightChildReport(PermissionRequired403Mixin, DetailView): class WeightWeightChildReport(PermissionRequiredMixin, DetailView):
""" """
Graph of weight change over time. Graph of weight change over time.
""" """