Browse Source

Introduce a middleware that allows for HttpResponses to be thrown from inner utility functions, to avoid boilerplate in views

Danielle McLean 6 months ago
parent
commit
7d17a92793
Signed by: Danielle McLean <dani@00dani.me> GPG Key ID: 8EB789DDF3ABD240
4 changed files with 22 additions and 9 deletions
  1. 7
    7
      entries/from_url.py
  2. 14
    0
      lemoncurry/middleware.py
  3. 1
    0
      lemoncurry/settings/base.py
  4. 0
    2
      micropub/views/delete.py

+ 7
- 7
entries/from_url.py View File

@@ -1,35 +1,35 @@
1
-from typing import Union
2 1
 from urllib.parse import urlparse
3 2
 
4 3
 from django.contrib.sites.models import Site
5 4
 from django.http import HttpResponse
6 5
 from django.urls import resolve, Resolver404
7 6
 from micropub.views import error
7
+from lemoncurry.middleware import ResponseException
8 8
 
9 9
 from .models import Entry
10 10
 
11 11
 
12
-def from_url(url: str) -> Union[Entry, HttpResponse]:
12
+def from_url(url: str) -> Entry:
13 13
     domain = Site.objects.get_current().domain
14 14
     if not url:
15
-        return error.bad_req('url parameter required')
15
+        raise ResponseException(error.bad_req('url parameter required'))
16 16
     if '//' not in url:
17 17
         url = '//' + url
18 18
     parts = urlparse(url, scheme='https')
19 19
     if parts.scheme not in ('http', 'https') or parts.netloc != domain:
20
-        return error.bad_req('url does not point to this site')
20
+        raise ResponseException(error.bad_req('url does not point to this site'))
21 21
 
22 22
     try:
23 23
         match = resolve(parts.path)
24 24
     except Resolver404:
25
-        return error.bad_req('url does not point to a valid page on this site')
25
+        raise ResponseException(error.bad_req('url does not point to a valid page on this site'))
26 26
 
27 27
     if match.view_name != 'entries:entry':
28
-        return error.bad_req('url does not point to an entry on this site')
28
+        raise ResponseException(error.bad_req('url does not point to an entry on this site'))
29 29
 
30 30
     try:
31 31
         entry = Entry.objects.get(pk=match.kwargs['id'])
32 32
     except Entry.DoesNotExist:
33
-        return error.bad_req('url does not point to an existing entry')
33
+        raise ResponseException(error.bad_req('url does not point to an existing entry'))
34 34
 
35 35
     return entry

+ 14
- 0
lemoncurry/middleware.py View File

@@ -0,0 +1,14 @@
1
+from django.http import HttpRequest, HttpResponse
2
+from django.utils.deprecation import MiddlewareMixin
3
+
4
+
5
+class ResponseException(Exception):
6
+    def __init__(self, response: HttpResponse) -> None:
7
+        self.response = response
8
+
9
+
10
+class ResponseExceptionMiddleware(MiddlewareMixin):
11
+    def process_exception(self, request: HttpRequest, exception: Exception) -> HttpResponse:
12
+        if isinstance(exception, ResponseException):
13
+            return exception.response
14
+        raise exception

+ 1
- 0
lemoncurry/settings/base.py View File

@@ -118,6 +118,7 @@ MIDDLEWARE = [
118 118
     'django.contrib.messages.middleware.MessageMiddleware',
119 119
     'django.contrib.sites.middleware.CurrentSiteMiddleware',
120 120
     'django.middleware.clickjacking.XFrameOptionsMiddleware',
121
+    'lemoncurry.middleware.ResponseExceptionMiddleware',
121 122
 ]
122 123
 
123 124
 ROOT_URLCONF = 'lemoncurry.urls'

+ 0
- 2
micropub/views/delete.py View File

@@ -17,8 +17,6 @@ def delete(request):
17 17
         return error.unsupported_type(request.content_type)
18 18
     url = normalise[request.content_type](request)
19 19
     entry = from_url(url)
20
-    if isinstance(entry, HttpResponse):
21
-        return entry
22 20
 
23 21
     if entry.author != request.token.user:
24 22
         return error.forbid('entry belongs to another user')

Loading…
Cancel
Save