updated shortener slug handling

This commit is contained in:
Alexander Karpov 2023-04-06 01:42:42 +03:00
parent 24250e1a37
commit 438e978930
4 changed files with 22 additions and 9 deletions

View File

@ -10,7 +10,6 @@
class Link(TimeStampedModel): class Link(TimeStampedModel):
source = models.URLField(blank=False) source = models.URLField(blank=False)
slug = models.SlugField() slug = models.SlugField()
creator = models.ForeignKey( creator = models.ForeignKey(
"users.User", related_name="links", null=True, on_delete=models.SET_NULL "users.User", related_name="links", null=True, on_delete=models.SET_NULL
) )

View File

@ -1,21 +1,30 @@
from secrets import compare_digest
from django.conf import settings from django.conf import settings
from akarpov.tools.shortener.signals import Link from akarpov.tools.shortener.signals import Link
from akarpov.utils.generators import get_pk_from_uuid 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: def get_link_from_slug(slug: str, check_whole=True) -> Link | bool:
if settings.SHORTENER_ADD_SLUG and not check_whole: if settings.SHORTENER_ADD_SLUG and check_whole:
payload = slug[length:] payload = slug[length:]
pk = get_pk_from_uuid(payload) pk = get_pk_from_uuid(payload)
try: 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: 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) pk = get_pk_from_uuid(slug)
try: try:
return Link.objects.get(pk=pk) link = Link.objects.get(pk=pk)
return link
except Link.DoesNotExist: except Link.DoesNotExist:
return False return False

View File

@ -5,7 +5,10 @@
from akarpov.tools.shortener.models import Link from akarpov.tools.shortener.models import Link
from akarpov.utils.generators import generate_charset, get_str_uuid 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: def generate_slug(pk: int) -> str:

View File

@ -1,5 +1,5 @@
from django.core.exceptions import ObjectDoesNotExist, PermissionDenied 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 django.views.generic import CreateView, DetailView, TemplateView
from akarpov.tools.shortener.forms import LinkForm from akarpov.tools.shortener.forms import LinkForm
@ -48,4 +48,6 @@ class LinkRevokedView(TemplateView):
def redirect_view(request, slug): def redirect_view(request, slug):
# TODO: move to faster framework, like FastApi # TODO: move to faster framework, like FastApi
link = get_link_from_slug(slug) link = get_link_from_slug(slug)
if not link:
return HttpResponseNotFound("such link doesn't exist or has been revoked")
return HttpResponseRedirect(link.source) return HttpResponseRedirect(link.source)