From 438e97893027828c0fbf0b3e6ca81c342adbb438 Mon Sep 17 00:00:00 2001 From: Alexandr Karpov Date: Thu, 6 Apr 2023 01:42:42 +0300 Subject: [PATCH] updated shortener slug handling --- akarpov/tools/shortener/models.py | 1 - akarpov/tools/shortener/services.py | 21 +++++++++++++++------ akarpov/tools/shortener/signals.py | 5 ++++- akarpov/tools/shortener/views.py | 4 +++- 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/akarpov/tools/shortener/models.py b/akarpov/tools/shortener/models.py index 1352a51..9c6dd99 100644 --- a/akarpov/tools/shortener/models.py +++ b/akarpov/tools/shortener/models.py @@ -10,7 +10,6 @@ class Link(TimeStampedModel): source = models.URLField(blank=False) slug = models.SlugField() - creator = models.ForeignKey( "users.User", related_name="links", null=True, on_delete=models.SET_NULL ) diff --git a/akarpov/tools/shortener/services.py b/akarpov/tools/shortener/services.py index 2f5b5f6..107e4be 100644 --- a/akarpov/tools/shortener/services.py +++ b/akarpov/tools/shortener/services.py @@ -1,21 +1,30 @@ +from secrets import compare_digest + from django.conf import settings from akarpov.tools.shortener.signals import Link from akarpov.utils.generators import get_pk_from_uuid -length = settings.SHORTENER_SLUG_LENGTH +if hasattr(settings, "SHORTENER_SLUG_LENGTH"): + length = settings.SHORTENER_SLUG_LENGTH +else: + length = 0 -def get_link_from_slug(slug: str, check_whole=False) -> Link | bool: - if settings.SHORTENER_ADD_SLUG and not check_whole: +def get_link_from_slug(slug: str, check_whole=True) -> Link | bool: + if settings.SHORTENER_ADD_SLUG and check_whole: payload = slug[length:] pk = get_pk_from_uuid(payload) try: - return Link.objects.get(pk=pk) + link = Link.objects.get(pk=pk) + if not compare_digest(link.slug, slug): + return False + return link except Link.DoesNotExist: - return get_link_from_slug(slug, check_whole=True) + return get_link_from_slug(slug, check_whole=False) pk = get_pk_from_uuid(slug) try: - return Link.objects.get(pk=pk) + link = Link.objects.get(pk=pk) + return link except Link.DoesNotExist: return False diff --git a/akarpov/tools/shortener/signals.py b/akarpov/tools/shortener/signals.py index 60dddad..9d06e30 100644 --- a/akarpov/tools/shortener/signals.py +++ b/akarpov/tools/shortener/signals.py @@ -5,7 +5,10 @@ from akarpov.tools.shortener.models import Link from akarpov.utils.generators import generate_charset, get_str_uuid -length = settings.SHORTENER_SLUG_LENGTH +if hasattr(settings, "SHORTENER_SLUG_LENGTH"): + length = settings.SHORTENER_SLUG_LENGTH +else: + length = 0 def generate_slug(pk: int) -> str: diff --git a/akarpov/tools/shortener/views.py b/akarpov/tools/shortener/views.py index 9f4dd06..a0742ee 100644 --- a/akarpov/tools/shortener/views.py +++ b/akarpov/tools/shortener/views.py @@ -1,5 +1,5 @@ from django.core.exceptions import ObjectDoesNotExist, PermissionDenied -from django.http import HttpResponseRedirect +from django.http import HttpResponseNotFound, HttpResponseRedirect from django.views.generic import CreateView, DetailView, TemplateView from akarpov.tools.shortener.forms import LinkForm @@ -48,4 +48,6 @@ class LinkRevokedView(TemplateView): def redirect_view(request, slug): # TODO: move to faster framework, like FastApi link = get_link_from_slug(slug) + if not link: + return HttpResponseNotFound("such link doesn't exist or has been revoked") return HttpResponseRedirect(link.source)