Extension page should be 404 for everyone unless publicly listed #167
18
abuse/migrations/0008_alter_abusereport_reason.py
Normal file
18
abuse/migrations/0008_alter_abusereport_reason.py
Normal 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),
|
||||||
|
),
|
||||||
|
]
|
@ -55,7 +55,7 @@ class AbuseReport(CreatedModifiedMixin, TrackChangesMixin, models.Model):
|
|||||||
rating = models.ForeignKey('ratings.Rating', blank=True, null=True, on_delete=models.CASCADE)
|
rating = models.ForeignKey('ratings.Rating', blank=True, null=True, on_delete=models.CASCADE)
|
||||||
message = models.TextField(blank=True)
|
message = models.TextField(blank=True)
|
||||||
reason = models.PositiveSmallIntegerField(
|
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(
|
version = extensions.fields.VersionStringField(
|
||||||
max_length=64,
|
max_length=64,
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
<h1>{{ object.get_type_display }} Report</h1>
|
<h1>{{ object.get_type_display }} Report</h1>
|
||||||
|
|
||||||
<div class="hero-subtitle d-flex">
|
<div class="hero-subtitle d-flex">
|
||||||
|
{% if extension %}
|
||||||
<div class="ext-detail-tagline">
|
<div class="ext-detail-tagline">
|
||||||
<a href="{{ extension.get_absolute_url }}">{{ extension.name }}</a>
|
<a href="{{ extension.get_absolute_url }}">{{ extension.name }}</a>
|
||||||
</div>
|
</div>
|
||||||
@ -39,6 +40,11 @@
|
|||||||
{% trans 'by' %} {% include "extensions/components/authors.html" %}
|
{% trans 'by' %} {% include "extensions/components/authors.html" %}
|
||||||
{% endif %}
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
|
{% else %}
|
||||||
|
<div class="ext-detail-tagline">
|
||||||
|
Reported user: {{ object.name }}
|
||||||
|
</div>
|
||||||
|
{% endif %}
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
@ -93,11 +99,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="dl-row">
|
<div class="dl-row">
|
||||||
<div class="dl-col">
|
<div class="dl-col">
|
||||||
{% if object.extension %}
|
{% if extension %}
|
||||||
<dt>{{ object.extension.get_type_display }}</dt>
|
<dt>{{ extension.get_type_display }}</dt>
|
||||||
<dd>
|
<dd>
|
||||||
<a href="{{ object.extension.get_absolute_url }}">
|
<a href="{{ extension.get_absolute_url }}">
|
||||||
{{ object.extension.name }}
|
{{ extension.name }}
|
||||||
</a>
|
</a>
|
||||||
</dd>
|
</dd>
|
||||||
{% else %}
|
{% else %}
|
||||||
@ -124,9 +130,13 @@
|
|||||||
<div class="dl-col">
|
<div class="dl-col">
|
||||||
<dt>by</dt>
|
<dt>by</dt>
|
||||||
<dd>
|
<dd>
|
||||||
|
{% if object.reporter %}
|
||||||
<a href="{% url "extensions:by-author" user_id=object.reporter.pk %}">
|
<a href="{% url "extensions:by-author" user_id=object.reporter.pk %}">
|
||||||
{{ object.reporter }}
|
{{ object.reporter }}
|
||||||
</a>
|
</a>
|
||||||
|
{% else %}
|
||||||
|
unknown
|
||||||
|
{% endif %}
|
||||||
</dd>
|
</dd>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -1,7 +1,8 @@
|
|||||||
from django.test import TestCase
|
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.extensions import create_approved_version
|
||||||
from common.tests.factories.users import UserFactory
|
from common.tests.factories.users import UserFactory, create_moderator
|
||||||
|
|
||||||
POST_DATA = {
|
POST_DATA = {
|
||||||
'message': 'test message',
|
'message': 'test message',
|
||||||
@ -19,3 +20,44 @@ class ReportTest(TestCase):
|
|||||||
_ = self.client.post(url, POST_DATA)
|
_ = self.client.post(url, POST_DATA)
|
||||||
response = self.client.get(url, follow=True)
|
response = self.client.get(url, follow=True)
|
||||||
self.assertEqual(response.status_code, 200)
|
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)
|
||||||
|
@ -128,6 +128,8 @@ class ReportView(LoginRequiredMixin, DetailView):
|
|||||||
|
|
||||||
def get_object(self, *args, **kwargs):
|
def get_object(self, *args, **kwargs):
|
||||||
obj = super().get_object(*args, **kwargs)
|
obj = super().get_object(*args, **kwargs)
|
||||||
if obj.reporter.pk != self.request.user.pk and not self.request.user.is_moderator:
|
if self.request.user.is_authenticated and (
|
||||||
raise Http404()
|
obj.reporter_id == self.request.user.pk or self.request.user.is_moderator
|
||||||
|
):
|
||||||
return obj
|
return obj
|
||||||
|
raise Http404()
|
||||||
|
12
common/tests/factories/abuse.py
Normal file
12
common/tests/factories/abuse.py
Normal 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')
|
Loading…
Reference in New Issue
Block a user