add new fields to AbuseReport model to support DSA/Feedback flow (#21260)
* add new fields to AbuseReport model to support DSA/Feedback flow * drop extra line that makes black sad in CI * create CinderReport model * change abuse report fk to 1to1 field
This commit is contained in:
Родитель
33765b0ee4
Коммит
15edba7187
|
@ -0,0 +1,52 @@
|
||||||
|
# Generated by Django 4.2.5 on 2023-10-03 08:54
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
('abuse', '0008_alter_abusereport_report_entry_point'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='abusereport',
|
||||||
|
name='reporter_email',
|
||||||
|
field=models.CharField(default=None, max_length=255, null=True),
|
||||||
|
),
|
||||||
|
migrations.AddField(
|
||||||
|
model_name='abusereport',
|
||||||
|
name='reporter_name',
|
||||||
|
field=models.CharField(default=None, max_length=255, null=True),
|
||||||
|
),
|
||||||
|
migrations.AlterField(
|
||||||
|
model_name='abusereport',
|
||||||
|
name='reason',
|
||||||
|
field=models.PositiveSmallIntegerField(
|
||||||
|
blank=True,
|
||||||
|
choices=[
|
||||||
|
(None, 'None'),
|
||||||
|
(1, 'Damages computer and/or data'),
|
||||||
|
(2, 'Creates spam or advertising'),
|
||||||
|
(
|
||||||
|
3,
|
||||||
|
'Changes search / homepage / new tab page without informing user',
|
||||||
|
),
|
||||||
|
(5, 'Doesn’t work, breaks websites, or slows Firefox down'),
|
||||||
|
(6, 'Hateful, violent, or illegal content'),
|
||||||
|
(7, 'Pretends to be something it’s not'),
|
||||||
|
(9, "Wasn't wanted / impossible to get rid of"),
|
||||||
|
(11, 'DSA: Contains hate speech'),
|
||||||
|
(12, 'DSA: Contains child sexual abuse material'),
|
||||||
|
(
|
||||||
|
20,
|
||||||
|
'Feedback: Doesn’t work, breaks websites, or slows Firefox down',
|
||||||
|
),
|
||||||
|
(21, "Feedback: Wasn't wanted or can't be uninstalled"),
|
||||||
|
(127, 'Other'),
|
||||||
|
],
|
||||||
|
default=None,
|
||||||
|
null=True,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
]
|
|
@ -0,0 +1,63 @@
|
||||||
|
# Generated by Django 4.2.5 on 2023-10-03 20:33
|
||||||
|
|
||||||
|
from django.db import migrations, models
|
||||||
|
import django.db.models.deletion
|
||||||
|
import django.utils.timezone
|
||||||
|
import olympia.amo.models
|
||||||
|
|
||||||
|
|
||||||
|
class Migration(migrations.Migration):
|
||||||
|
dependencies = [
|
||||||
|
('abuse', '0009_abusereport_reporter_email_name_reasons'),
|
||||||
|
]
|
||||||
|
|
||||||
|
operations = [
|
||||||
|
migrations.CreateModel(
|
||||||
|
name='CinderReport',
|
||||||
|
fields=[
|
||||||
|
(
|
||||||
|
'created',
|
||||||
|
models.DateTimeField(
|
||||||
|
blank=True, default=django.utils.timezone.now, editable=False
|
||||||
|
),
|
||||||
|
),
|
||||||
|
('modified', models.DateTimeField(auto_now=True)),
|
||||||
|
('job_id', models.CharField(max_length=36)),
|
||||||
|
(
|
||||||
|
'abuse_report',
|
||||||
|
models.OneToOneField(
|
||||||
|
on_delete=django.db.models.deletion.CASCADE,
|
||||||
|
primary_key=True,
|
||||||
|
serialize=False,
|
||||||
|
to='abuse.abusereport',
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'decision_action',
|
||||||
|
models.PositiveSmallIntegerField(
|
||||||
|
choices=[
|
||||||
|
(0, 'No decision'),
|
||||||
|
(1, 'User ban'),
|
||||||
|
(2, 'Add-on disable'),
|
||||||
|
(3, 'Escalate add-on to reviewers'),
|
||||||
|
(4, 'Escalate add-on to reviewers'),
|
||||||
|
(5, 'Rating delete'),
|
||||||
|
(6, 'Collection delete'),
|
||||||
|
(7, 'Approved (no action)'),
|
||||||
|
],
|
||||||
|
default=0,
|
||||||
|
),
|
||||||
|
),
|
||||||
|
(
|
||||||
|
'decision_id',
|
||||||
|
models.CharField(default=None, max_length=36, null=True),
|
||||||
|
),
|
||||||
|
],
|
||||||
|
options={
|
||||||
|
'get_latest_by': 'created',
|
||||||
|
'abstract': False,
|
||||||
|
'base_manager_name': 'objects',
|
||||||
|
},
|
||||||
|
bases=(olympia.amo.models.SaveUpdateMixin, models.Model),
|
||||||
|
),
|
||||||
|
]
|
|
@ -4,7 +4,7 @@ from extended_choices import Choices
|
||||||
|
|
||||||
from olympia import amo
|
from olympia import amo
|
||||||
from olympia.amo.models import BaseQuerySet, ManagerBase, ModelBase
|
from olympia.amo.models import BaseQuerySet, ManagerBase, ModelBase
|
||||||
from olympia.api.utils import APIChoicesWithNone
|
from olympia.api.utils import APIChoices, APIChoicesWithNone
|
||||||
from olympia.users.models import UserProfile
|
from olympia.users.models import UserProfile
|
||||||
|
|
||||||
|
|
||||||
|
@ -58,6 +58,7 @@ class AbuseReport(ModelBase):
|
||||||
('PRIVILEGED', 12, 'Privileged'),
|
('PRIVILEGED', 12, 'Privileged'),
|
||||||
)
|
)
|
||||||
REASONS = APIChoicesWithNone(
|
REASONS = APIChoicesWithNone(
|
||||||
|
# Reporting reasons used in Firefox
|
||||||
('DAMAGE', 1, 'Damages computer and/or data'),
|
('DAMAGE', 1, 'Damages computer and/or data'),
|
||||||
('SPAM', 2, 'Creates spam or advertising'),
|
('SPAM', 2, 'Creates spam or advertising'),
|
||||||
(
|
(
|
||||||
|
@ -74,6 +75,16 @@ class AbuseReport(ModelBase):
|
||||||
# previous one. We avoid re-using the value.
|
# previous one. We avoid re-using the value.
|
||||||
('UNWANTED', 9, "Wasn't wanted / impossible to get rid of"),
|
('UNWANTED', 9, "Wasn't wanted / impossible to get rid of"),
|
||||||
# `10` was previously "Other". We avoid re-using the value.
|
# `10` was previously "Other". We avoid re-using the value.
|
||||||
|
# Reporting reasons used in AMO Feedback flow - DSA categories
|
||||||
|
('HATE_SPEECH', 11, 'DSA: Contains hate speech'),
|
||||||
|
('CSAM', 12, 'DSA: Contains child sexual abuse material'),
|
||||||
|
# Reporting reasons used in AMO Feedback flow - Feedback (non-DSA) categories
|
||||||
|
(
|
||||||
|
'DOES_NOT_WORK',
|
||||||
|
20,
|
||||||
|
'Feedback: Doesn’t work, breaks websites, or slows Firefox down',
|
||||||
|
),
|
||||||
|
('NOT_WANTED', 21, "Feedback: Wasn't wanted or can't be uninstalled"),
|
||||||
('OTHER', 127, 'Other'),
|
('OTHER', 127, 'Other'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -150,7 +161,7 @@ class AbuseReport(ModelBase):
|
||||||
('DELETED', 4, 'Deleted'),
|
('DELETED', 4, 'Deleted'),
|
||||||
)
|
)
|
||||||
|
|
||||||
# NULL if the reporter is anonymous.
|
# NULL if the reporter was not authenticated.
|
||||||
reporter = models.ForeignKey(
|
reporter = models.ForeignKey(
|
||||||
UserProfile,
|
UserProfile,
|
||||||
null=True,
|
null=True,
|
||||||
|
@ -158,6 +169,9 @@ class AbuseReport(ModelBase):
|
||||||
related_name='abuse_reported',
|
related_name='abuse_reported',
|
||||||
on_delete=models.SET_NULL,
|
on_delete=models.SET_NULL,
|
||||||
)
|
)
|
||||||
|
# name and/or email can be provided instead for unauthenticated reporters
|
||||||
|
reporter_email = models.CharField(max_length=255, default=None, null=True)
|
||||||
|
reporter_name = models.CharField(max_length=255, default=None, null=True)
|
||||||
country_code = models.CharField(max_length=2, default=None, null=True)
|
country_code = models.CharField(max_length=2, default=None, null=True)
|
||||||
# An abuse report can be for an addon or a user.
|
# An abuse report can be for an addon or a user.
|
||||||
# If user is set then guid should be null.
|
# If user is set then guid should be null.
|
||||||
|
@ -279,3 +293,25 @@ class AbuseReport(ModelBase):
|
||||||
def __str__(self):
|
def __str__(self):
|
||||||
name = self.guid if self.guid else self.user
|
name = self.guid if self.guid else self.user
|
||||||
return f'Abuse Report for {self.type} {name}'
|
return f'Abuse Report for {self.type} {name}'
|
||||||
|
|
||||||
|
|
||||||
|
class CinderReport(ModelBase):
|
||||||
|
DECISION_ACTIONS = APIChoices(
|
||||||
|
('NO_DECISION', 0, 'No decision'),
|
||||||
|
('AMO_BAN_USER', 1, 'User ban'),
|
||||||
|
('AMO_DISABLE_ADDON', 2, 'Add-on disable'),
|
||||||
|
('AMO_ESCALATE_ADDON', 3, 'Escalate add-on to reviewers'),
|
||||||
|
('AMO_ESCALATE_USER', 4, 'Escalate add-on to reviewers'),
|
||||||
|
('AMO_DELETE_RATING', 5, 'Rating delete'),
|
||||||
|
('AMO_DELETE_COLLECTION', 6, 'Collection delete'),
|
||||||
|
('AMO_APPROVE', 7, 'Approved (no action)'),
|
||||||
|
)
|
||||||
|
|
||||||
|
job_id = models.CharField(max_length=36)
|
||||||
|
abuse_report = models.OneToOneField(
|
||||||
|
AbuseReport, on_delete=models.CASCADE, primary_key=True
|
||||||
|
)
|
||||||
|
decision_action = models.PositiveSmallIntegerField(
|
||||||
|
default=DECISION_ACTIONS.NO_DECISION, choices=DECISION_ACTIONS.choices
|
||||||
|
)
|
||||||
|
decision_id = models.CharField(max_length=36, default=None, null=True)
|
||||||
|
|
|
@ -46,6 +46,10 @@ class TestAbuse(TestCase):
|
||||||
(6, 'Hateful, violent, or illegal content'),
|
(6, 'Hateful, violent, or illegal content'),
|
||||||
(7, 'Pretends to be something it’s not'),
|
(7, 'Pretends to be something it’s not'),
|
||||||
(9, "Wasn't wanted / impossible to get rid of"),
|
(9, "Wasn't wanted / impossible to get rid of"),
|
||||||
|
(11, 'DSA: Contains hate speech'),
|
||||||
|
(12, 'DSA: Contains child sexual abuse material'),
|
||||||
|
(20, 'Feedback: Doesn’t work, breaks websites, or slows Firefox down'),
|
||||||
|
(21, "Feedback: Wasn't wanted or can't be uninstalled"),
|
||||||
(127, 'Other'),
|
(127, 'Other'),
|
||||||
)
|
)
|
||||||
assert AbuseReport.REASONS.api_choices == (
|
assert AbuseReport.REASONS.api_choices == (
|
||||||
|
@ -57,6 +61,10 @@ class TestAbuse(TestCase):
|
||||||
(6, 'policy'),
|
(6, 'policy'),
|
||||||
(7, 'deceptive'),
|
(7, 'deceptive'),
|
||||||
(9, 'unwanted'),
|
(9, 'unwanted'),
|
||||||
|
(11, 'hate_speech'),
|
||||||
|
(12, 'csam'),
|
||||||
|
(20, 'does_not_work'),
|
||||||
|
(21, 'not_wanted'),
|
||||||
(127, 'other'),
|
(127, 'other'),
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
Загрузка…
Ссылка в новой задаче