diff --git a/entries/from_url.py b/entries/from_url.py index 5572963..b19475f 100644 --- a/entries/from_url.py +++ b/entries/from_url.py @@ -1,35 +1,35 @@ -from typing import Union from urllib.parse import urlparse from django.contrib.sites.models import Site from django.http import HttpResponse from django.urls import resolve, Resolver404 from micropub.views import error +from lemoncurry.middleware import ResponseException from .models import Entry -def from_url(url: str) -> Union[Entry, HttpResponse]: +def from_url(url: str) -> Entry: domain = Site.objects.get_current().domain if not url: - return error.bad_req('url parameter required') + raise ResponseException(error.bad_req('url parameter required')) if '//' not in url: url = '//' + url parts = urlparse(url, scheme='https') if parts.scheme not in ('http', 'https') or parts.netloc != domain: - return error.bad_req('url does not point to this site') + raise ResponseException(error.bad_req('url does not point to this site')) try: match = resolve(parts.path) except Resolver404: - return error.bad_req('url does not point to a valid page on this site') + raise ResponseException(error.bad_req('url does not point to a valid page on this site')) if match.view_name != 'entries:entry': - return error.bad_req('url does not point to an entry on this site') + raise ResponseException(error.bad_req('url does not point to an entry on this site')) try: entry = Entry.objects.get(pk=match.kwargs['id']) except Entry.DoesNotExist: - return error.bad_req('url does not point to an existing entry') + raise ResponseException(error.bad_req('url does not point to an existing entry')) return entry diff --git a/lemoncurry/middleware.py b/lemoncurry/middleware.py new file mode 100644 index 0000000..02221bc --- /dev/null +++ b/lemoncurry/middleware.py @@ -0,0 +1,14 @@ +from django.http import HttpRequest, HttpResponse +from django.utils.deprecation import MiddlewareMixin + + +class ResponseException(Exception): + def __init__(self, response: HttpResponse) -> None: + self.response = response + + +class ResponseExceptionMiddleware(MiddlewareMixin): + def process_exception(self, request: HttpRequest, exception: Exception) -> HttpResponse: + if isinstance(exception, ResponseException): + return exception.response + raise exception diff --git a/lemoncurry/settings/base.py b/lemoncurry/settings/base.py index 38ccee7..efc25ae 100644 --- a/lemoncurry/settings/base.py +++ b/lemoncurry/settings/base.py @@ -118,6 +118,7 @@ MIDDLEWARE = [ 'django.contrib.messages.middleware.MessageMiddleware', 'django.contrib.sites.middleware.CurrentSiteMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', + 'lemoncurry.middleware.ResponseExceptionMiddleware', ] ROOT_URLCONF = 'lemoncurry.urls' diff --git a/micropub/views/delete.py b/micropub/views/delete.py index 9182c1e..4fc1f3e 100644 --- a/micropub/views/delete.py +++ b/micropub/views/delete.py @@ -17,8 +17,6 @@ def delete(request): return error.unsupported_type(request.content_type) url = normalise[request.content_type](request) entry = from_url(url) - if isinstance(entry, HttpResponse): - return entry if entry.author != request.token.user: return error.forbid('entry belongs to another user')