diff --git a/babybuddy/templates/babybuddy/nav-dropdown.html b/babybuddy/templates/babybuddy/nav-dropdown.html index 84fa0853..985199a1 100644 --- a/babybuddy/templates/babybuddy/nav-dropdown.html +++ b/babybuddy/templates/babybuddy/nav-dropdown.html @@ -269,7 +269,12 @@ {% trans "Settings" %} {% trans "Password" %} - {% trans "Logout" %} +
+ {% csrf_token %} + +
{% trans "API Browser" %} {% if request.user.is_staff %} diff --git a/babybuddy/tests/tests_views.py b/babybuddy/tests/tests_views.py index 8bd0976b..a19a66db 100644 --- a/babybuddy/tests/tests_views.py +++ b/babybuddy/tests/tests_views.py @@ -70,3 +70,7 @@ class ViewsTestCase(TestCase): def test_welcome(self): page = self.c.get('/welcome/') self.assertEqual(page.status_code, 200) + + def test_logout_get_fails(self): + page = self.c.get('/logout/') + self.assertEqual(page.status_code, 405) diff --git a/babybuddy/urls.py b/babybuddy/urls.py index d1f25072..57deb141 100644 --- a/babybuddy/urls.py +++ b/babybuddy/urls.py @@ -9,7 +9,7 @@ from . import views app_patterns = [ path('login/', auth_views.LoginView.as_view(), name='login'), - path('logout/', auth_views.LogoutView.as_view(), name='logout'), + path('logout/', views.LogoutView.as_view(), name='logout'), path( 'password_reset/', auth_views.PasswordResetView.as_view(), diff --git a/babybuddy/views.py b/babybuddy/views.py index c9e41be1..ec7bf7c0 100644 --- a/babybuddy/views.py +++ b/babybuddy/views.py @@ -3,12 +3,17 @@ from django.contrib import messages from django.contrib.auth import update_session_auth_hash from django.contrib.auth.forms import PasswordChangeForm from django.contrib.auth.models import User +from django.contrib.auth.views import LogoutView as LogoutViewBase from django.contrib.messages.views import SuccessMessageMixin from django.shortcuts import redirect, render from django.urls import reverse, reverse_lazy from django.utils import translation +from django.utils.decorators import method_decorator from django.utils.text import format_lazy from django.utils.translation import gettext as _, gettext_lazy +from django.views.decorators.cache import never_cache +from django.views.decorators.csrf import csrf_protect +from django.views.decorators.http import require_POST from django.views.generic import View from django.views.generic.base import TemplateView, RedirectView from django.views.generic.edit import CreateView, UpdateView, DeleteView @@ -48,6 +53,13 @@ class BabyBuddyFilterView(FilterView): return context +@method_decorator(csrf_protect, name='dispatch') +@method_decorator(never_cache, name='dispatch') +@method_decorator(require_POST, name='dispatch') +class LogoutView(LogoutViewBase): + pass + + class UserList(StaffOnlyMixin, BabyBuddyFilterView): model = User template_name = 'babybuddy/user_list.html'