Skip to content

Commit 57bb272

Browse files
Merge issue 119: return podcast method denial
2 parents 4613605 + c64637a commit 57bb272

2 files changed

Lines changed: 14 additions & 5 deletions

File tree

content/public_views.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
JsonResponse,
1717
)
1818
from django.shortcuts import render
19+
from django.views.decorators.csrf import csrf_exempt
1920
from django.views.decorators.http import require_safe
2021

2122
from courses.models.course import Course
@@ -238,6 +239,9 @@ def collection_hub(request: HttpRequest, *, collection: str) -> HttpResponse:
238239
)
239240

240241

242+
# CSRF middleware runs before method decorators. This read-only callback is exempt so
243+
# unsafe methods reach the explicit 405 response; it performs no mutation.
244+
@csrf_exempt
241245
@require_safe
242246
def podcast_hub(request: HttpRequest) -> HttpResponse:
243247
page_number = _podcast_page_number(request)

content/tests/test_podcast_catalog.py

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
from __future__ import annotations
22

33
from django.core.exceptions import ImproperlyConfigured
4-
from django.test import SimpleTestCase, TestCase
4+
from django.test import Client, SimpleTestCase, TestCase
55

66
from content.public_data import ordered_podcasts, podcast_seasons, public_projection
77
from core.seo import validated_canonical_url
@@ -285,7 +285,12 @@ def test_homepage_uses_the_same_latest_episode(self) -> None:
285285
public_projection()["podcasts"][0]["title"],
286286
)
287287

288-
def test_get_and_head_are_supported_but_post_is_not(self) -> None:
289-
self.assertEqual(self.client.get("/podcast?page=2").status_code, 200)
290-
self.assertEqual(self.client.head("/podcast?page=2").status_code, 200)
291-
self.assertEqual(self.client.post("/podcast?page=2").status_code, 405)
288+
def test_get_and_head_are_supported_but_post_is_rejected_before_csrf(self) -> None:
289+
csrf_client = Client(enforce_csrf_checks=True)
290+
291+
self.assertEqual(csrf_client.get("/podcast?page=2").status_code, 200)
292+
self.assertEqual(csrf_client.head("/podcast?page=2").status_code, 200)
293+
294+
response = csrf_client.post("/podcast?page=2")
295+
self.assertEqual(response.status_code, 405)
296+
self.assertEqual(response.headers["Allow"], "GET, HEAD")

0 commit comments

Comments
 (0)