Extension page should be 404 for everyone unless publicly listed #167

Merged
Anna Sirota merged 5 commits from extension-detail-page-listed-only into main 2024-06-05 12:12:14 +02:00
3 changed files with 53 additions and 50 deletions
Showing only changes of commit af1586bc26 - Show all commits

View File

@ -28,6 +28,14 @@ urlpatterns = [
path('search/', public.SearchView.as_view(), name='search'), path('search/', public.SearchView.as_view(), name='search'),
path('tag/<slug:tag_slug>/', public.SearchView.as_view(), name='by-tag'), path('tag/<slug:tag_slug>/', public.SearchView.as_view(), name='by-tag'),
path('team/<slug:team_slug>/', public.SearchView.as_view(), name='by-team'), path('team/<slug:team_slug>/', public.SearchView.as_view(), name='by-team'),
re_path(
rf'^(?P<type_slug>{EXTENSION_SLUGS_PATH})/',
include(
[
path('<slug:slug>/', public.ExtensionDetailView.as_view(), name='detail'),
]
),
),
re_path( re_path(
rf'^(?P<type_slug>{EXTENSION_SLUGS_PATH})/$', rf'^(?P<type_slug>{EXTENSION_SLUGS_PATH})/$',
public.SearchView.as_view(), public.SearchView.as_view(),
@ -84,7 +92,6 @@ urlpatterns = [
name='version-download', name='version-download',
), ),
path('<slug:slug>/versions/', manage.VersionsView.as_view(), name='versions'), path('<slug:slug>/versions/', manage.VersionsView.as_view(), name='versions'),
path('<slug:slug>/', manage.ExtensionDetailView.as_view(), name='detail'),
], ],
), ),
), ),

View File

@ -3,7 +3,7 @@ from django.contrib.auth.mixins import LoginRequiredMixin, UserPassesTestMixin
from django.contrib.messages.views import SuccessMessageMixin from django.contrib.messages.views import SuccessMessageMixin
from django.db import transaction from django.db import transaction
from django.shortcuts import get_object_or_404, redirect, reverse from django.shortcuts import get_object_or_404, redirect, reverse
from django.views.generic import DetailView, ListView from django.views.generic import ListView
from django.views.generic.edit import CreateView, UpdateView, DeleteView, FormView from django.views.generic.edit import CreateView, UpdateView, DeleteView, FormView
@ -22,52 +22,6 @@ from extensions.forms import (
from extensions.models import Extension, Version from extensions.models import Extension, Version
from files.forms import FileForm from files.forms import FileForm
from files.models import File from files.models import File
from stats.models import ExtensionView
import ratings.models
class ExtensionDetailView(ExtensionQuerysetMixin, DetailView):
model = Extension
context_object_name = 'extension'
template_name = 'extensions/detail.html'
def get_queryset(self):
"""Allow logged in users to view unlisted add-ons in certain conditions.
* maintainers should be able to preview their yet unlisted add-ons;
* staff should be able to preview yet unlisted add-ons;
"""
return self.get_extension_queryset().prefetch_related(
'authors',
'ratings',
'ratings__user',
'versions',
'versions__file',
'versions__file__validation',
'versions__permissions',
'versions__platforms',
)
def get_object(self, queryset=None):
"""Record a page view when returning the Extension object."""
obj = super().get_object(queryset=queryset)
if obj.is_listed and (
self.request.user.is_anonymous or not obj.has_maintainer(self.request.user)
):
ExtensionView.create_from_request(self.request, object_id=obj.pk)
return obj
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if self.request.user.is_authenticated:
context['my_rating'] = ratings.models.Rating.get_for(
self.request.user.pk, self.object.pk
)
extension = context['object']
# Add the image for "og:image" meta to the context
if extension.featured_image and extension.featured_image.is_listed:
context['default_image_path'] = extension.featured_image.thumbnail_1080p_url
return context
class VersionsView(ExtensionQuerysetMixin, ListView): class VersionsView(ExtensionQuerysetMixin, ListView):

View File

@ -6,8 +6,7 @@ from django.db import connection
from django.db.models import Count, Q from django.db.models import Count, Q
from django.shortcuts import get_object_or_404, redirect from django.shortcuts import get_object_or_404, redirect
from django.utils.translation import gettext_lazy as _ from django.utils.translation import gettext_lazy as _
from django.views.generic.list import ListView from django.views.generic import DetailView, ListView
from extensions.models import Extension, Version, Tag from extensions.models import Extension, Version, Tag
from constants.base import ( from constants.base import (
@ -15,6 +14,8 @@ from constants.base import (
EXTENSION_TYPE_PLURAL, EXTENSION_TYPE_PLURAL,
EXTENSION_TYPE_CHOICES, EXTENSION_TYPE_CHOICES,
) )
from stats.models import ExtensionView
import ratings.models
from stats.models import ExtensionDownload, VersionDownload from stats.models import ExtensionDownload, VersionDownload
import teams.models import teams.models
@ -219,3 +220,44 @@ class SearchView(ListedExtensionsView):
context['total_count'] = super().get_queryset().filter(type=tag_type_id).count() context['total_count'] = super().get_queryset().filter(type=tag_type_id).count()
return context return context
class ExtensionDetailView(DetailView):
queryset = Extension.objects.listed.prefetch_related(
'authors',
'latest_version__file',
'latest_version__tags',
'preview_set',
'preview_set__file',
'ratings',
'ratings__user',
'team',
'versions',
'versions__file',
'versions__file__validation',
'versions__permissions',
'versions__platforms',
).distinct()
context_object_name = 'extension'
template_name = 'extensions/detail.html'
def get_object(self, queryset=None):
"""Record a page view when returning the Extension object."""
obj = super().get_object(queryset=queryset)
if obj.is_listed and (
self.request.user.is_anonymous or not obj.has_maintainer(self.request.user)
):
ExtensionView.create_from_request(self.request, object_id=obj.pk)
return obj
def get_context_data(self, **kwargs):
context = super().get_context_data(**kwargs)
if self.request.user.is_authenticated:
context['my_rating'] = ratings.models.Rating.get_for(
self.request.user.pk, self.object.pk
)
extension = context['object']
# Add the image for "og:image" meta to the context
if extension.featured_image and extension.featured_image.is_listed:
context['default_image_path'] = extension.featured_image.thumbnail_1080p_url
return context