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
6 changed files with 113 additions and 29 deletions
Showing only changes of commit 8d8a650a96 - Show all commits

View File

@ -0,0 +1,18 @@
# Generated by Django 4.2.11 on 2024-06-05 09:52
from django.db import migrations, models
class Migration(migrations.Migration):
dependencies = [
('abuse', '0007_alter_abusereport_status'),
]
operations = [
migrations.AlterField(
model_name='abusereport',
name='reason',
field=models.PositiveSmallIntegerField(choices=[(127, 'Other'), (1, 'Damages computer and/or data'), (2, 'Creates spam or advertising'), (3, "Doesn't work, breaks Blender, or slows it down"), (4, 'Hateful, violent, or illegal content'), (5, "Pretends to be something it's not")], default=127),
),
]

View File

@ -55,7 +55,7 @@ class AbuseReport(CreatedModifiedMixin, TrackChangesMixin, models.Model):
rating = models.ForeignKey('ratings.Rating', blank=True, null=True, on_delete=models.CASCADE)
message = models.TextField(blank=True)
reason = models.PositiveSmallIntegerField(
default=REASONS[0][1], choices=REASONS.choices, blank=False, null=False
default=REASONS.OTHER, choices=REASONS.choices, blank=False, null=False
)
version = extensions.fields.VersionStringField(
max_length=64,

View File

@ -21,6 +21,7 @@
<h1>{{ object.get_type_display }} Report</h1>
<div class="hero-subtitle d-flex">
{% if extension %}
<div class="ext-detail-tagline">
<a href="{{ extension.get_absolute_url }}">{{ extension.name }}</a>
</div>
@ -39,6 +40,11 @@
{% trans 'by' %} {% include "extensions/components/authors.html" %}
{% endif %}
</div>
{% else %}
<div class="ext-detail-tagline">
Reported user: {{ object.name }}
</div>
{% endif %}
</div>
</div>
@ -93,11 +99,11 @@
</div>
<div class="dl-row">
<div class="dl-col">
{% if object.extension %}
<dt>{{ object.extension.get_type_display }}</dt>
{% if extension %}
<dt>{{ extension.get_type_display }}</dt>
<dd>
<a href="{{ object.extension.get_absolute_url }}">
{{ object.extension.name }}
<a href="{{ extension.get_absolute_url }}">
{{ extension.name }}
</a>
</dd>
{% else %}
@ -124,9 +130,13 @@
<div class="dl-col">
<dt>by</dt>
<dd>
{% if object.reporter %}
<a href="{% url "extensions:by-author" user_id=object.reporter.pk %}">
{{ object.reporter }}
</a>
{% else %}
unknown
{% endif %}
</dd>
</div>
</div>

View File

@ -1,7 +1,8 @@
from django.test import TestCase
from common.tests.factories.abuse import AbuseReportFactory
from common.tests.factories.extensions import create_approved_version
from common.tests.factories.users import UserFactory
from common.tests.factories.users import UserFactory, create_moderator
POST_DATA = {
'message': 'test message',
@ -19,3 +20,44 @@ class ReportTest(TestCase):
_ = self.client.post(url, POST_DATA)
response = self.client.get(url, follow=True)
self.assertEqual(response.status_code, 200)
def test_only_reporter_and_moderator_can_view_report_abt_user(self):
reported_user = UserFactory()
report = AbuseReportFactory(user=reported_user)
self.assertIsNone(report.extension)
report_url = report.get_absolute_url()
# Check that anonymous gets redirected (to login)
self.assertEqual(self.client.get(report_url).status_code, 302)
# Check that reported user cannot view the report
self.client.force_login(reported_user)
self.assertEqual(self.client.get(report_url).status_code, 404)
# Check that reporter and moderator can view the report
for account, role in (
(report.reporter, 'reporter'),
(create_moderator(), 'moderator'),
):
with self.subTest(role=role):
self.client.logout()
self.client.force_login(account)
self.assertEqual(self.client.get(report_url).status_code, 200)
def test_only_reporter_and_moderator_can_view_report_abt_extension(self):
report = AbuseReportFactory(user=None, extension=create_approved_version().extension)
self.assertIsNone(report.user)
report_url = report.get_absolute_url()
# Check that anonymous gets redirected (to login)
self.assertEqual(self.client.get(report_url).status_code, 302)
# Check that reporter and moderator can view the report
for account, role in (
(report.reporter, 'reporter'),
(create_moderator(), 'moderator'),
):
with self.subTest(role=role):
self.client.logout()
self.client.force_login(account)
self.assertEqual(self.client.get(report_url).status_code, 200)

View File

@ -128,6 +128,8 @@ class ReportView(LoginRequiredMixin, DetailView):
def get_object(self, *args, **kwargs):
obj = super().get_object(*args, **kwargs)
if obj.reporter.pk != self.request.user.pk and not self.request.user.is_moderator:
raise Http404()
if self.request.user.is_authenticated and (
obj.reporter_id == self.request.user.pk or self.request.user.is_moderator
):
return obj
raise Http404()

View File

@ -0,0 +1,12 @@
from factory.django import DjangoModelFactory
import factory
import abuse.models
class AbuseReportFactory(DjangoModelFactory):
class Meta:
model = abuse.models.AbuseReport
reporter = factory.SubFactory('common.tests.factories.users.UserFactory')
user = factory.SubFactory('common.tests.factories.users.UserFactory')