dont report abuse reports for unlisted versions to cinder (#22625)
* dont report abuse reports for unlisted versions to cinder * fix test * is_reportable -> is_individually_actionable * change logic to include listed only, rather than exclude unlisted
This commit is contained in:
Родитель
0ea334d43e
Коммит
7d2f18d896
|
@ -20,7 +20,7 @@ from olympia.constants.abuse import (
|
||||||
)
|
)
|
||||||
from olympia.ratings.models import Rating
|
from olympia.ratings.models import Rating
|
||||||
from olympia.users.models import UserProfile
|
from olympia.users.models import UserProfile
|
||||||
from olympia.versions.models import VersionReviewerFlags
|
from olympia.versions.models import Version, VersionReviewerFlags
|
||||||
|
|
||||||
from .cinder import (
|
from .cinder import (
|
||||||
CinderAddon,
|
CinderAddon,
|
||||||
|
@ -456,7 +456,7 @@ class AbuseReport(ModelBase):
|
||||||
)
|
)
|
||||||
# Those reasons will be reported to Cinder.
|
# Those reasons will be reported to Cinder.
|
||||||
REASONS.add_subset(
|
REASONS.add_subset(
|
||||||
'REPORTABLE_REASONS',
|
'INDIVIDUALLY_ACTIONABLE_REASONS',
|
||||||
('HATEFUL_VIOLENT_DECEPTIVE', 'ILLEGAL', 'POLICY_VIOLATION', 'SOMETHING_ELSE'),
|
('HATEFUL_VIOLENT_DECEPTIVE', 'ILLEGAL', 'POLICY_VIOLATION', 'SOMETHING_ELSE'),
|
||||||
)
|
)
|
||||||
# Abuse in these locations are handled by reviewers
|
# Abuse in these locations are handled by reviewers
|
||||||
|
@ -779,6 +779,27 @@ class AbuseReport(ModelBase):
|
||||||
else:
|
else:
|
||||||
return self.addon
|
return self.addon
|
||||||
|
|
||||||
|
@property
|
||||||
|
def is_individually_actionable(self):
|
||||||
|
"""Is this abuse report reportable under DSA, so should be sent to Cinder"""
|
||||||
|
return bool(
|
||||||
|
self.reason in AbuseReport.REASONS.INDIVIDUALLY_ACTIONABLE_REASONS
|
||||||
|
and (
|
||||||
|
not self.guid
|
||||||
|
or (
|
||||||
|
Addon.unfiltered.filter(guid=self.guid).exists()
|
||||||
|
and (
|
||||||
|
not self.addon_version
|
||||||
|
or Version.unfiltered.filter(
|
||||||
|
addon__guid=self.guid,
|
||||||
|
version=self.addon_version,
|
||||||
|
channel=amo.CHANNEL_LISTED,
|
||||||
|
).exists()
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def is_handled_by_reviewers(self):
|
def is_handled_by_reviewers(self):
|
||||||
return (
|
return (
|
||||||
|
|
|
@ -155,7 +155,7 @@ class BaseAbuseReportSerializer(AMOModelSerializer):
|
||||||
instance = super().create(validated_data)
|
instance = super().create(validated_data)
|
||||||
if (
|
if (
|
||||||
waffle.switch_is_active('dsa-job-technical-processing')
|
waffle.switch_is_active('dsa-job-technical-processing')
|
||||||
and validated_data.get('reason') in AbuseReport.REASONS.REPORTABLE_REASONS
|
and instance.is_individually_actionable
|
||||||
):
|
):
|
||||||
# call task to fire off cinder report
|
# call task to fire off cinder report
|
||||||
report_to_cinder.delay(instance.id)
|
report_to_cinder.delay(instance.id)
|
||||||
|
|
|
@ -31,7 +31,7 @@ from olympia.constants.abuse import (
|
||||||
)
|
)
|
||||||
from olympia.ratings.models import Rating
|
from olympia.ratings.models import Rating
|
||||||
from olympia.reviewers.models import NeedsHumanReview
|
from olympia.reviewers.models import NeedsHumanReview
|
||||||
from olympia.versions.models import VersionReviewerFlags
|
from olympia.versions.models import Version, VersionReviewerFlags
|
||||||
|
|
||||||
from ..cinder import (
|
from ..cinder import (
|
||||||
CinderAddon,
|
CinderAddon,
|
||||||
|
@ -66,7 +66,7 @@ from ..utils import (
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
class TestAbuse(TestCase):
|
class TestAbuseReport(TestCase):
|
||||||
fixtures = ['base/addon_3615', 'base/user_999']
|
fixtures = ['base/addon_3615', 'base/user_999']
|
||||||
|
|
||||||
def test_choices(self):
|
def test_choices(self):
|
||||||
|
@ -482,6 +482,52 @@ class TestAbuse(TestCase):
|
||||||
report.update(rating=None, collection=collection)
|
report.update(rating=None, collection=collection)
|
||||||
assert report.target == collection
|
assert report.target == collection
|
||||||
|
|
||||||
|
def test_is_individually_actionable(self):
|
||||||
|
report = AbuseReport.objects.create(
|
||||||
|
guid='@lol', reason=AbuseReport.REASONS.HATEFUL_VIOLENT_DECEPTIVE
|
||||||
|
)
|
||||||
|
assert report.is_individually_actionable is False
|
||||||
|
addon = addon_factory(guid='@lol')
|
||||||
|
user = user_factory()
|
||||||
|
for target in (
|
||||||
|
{'guid': addon.guid},
|
||||||
|
{'user': user},
|
||||||
|
{'rating': Rating.objects.create(user=user, addon=addon, rating=5)},
|
||||||
|
{'collection': collection_factory()},
|
||||||
|
):
|
||||||
|
report.update(
|
||||||
|
reason=AbuseReport.REASONS.FEEDBACK_SPAM,
|
||||||
|
**{
|
||||||
|
'guid': None,
|
||||||
|
'user': None,
|
||||||
|
'rating': None,
|
||||||
|
'collection': None,
|
||||||
|
**target,
|
||||||
|
},
|
||||||
|
)
|
||||||
|
assert report.is_individually_actionable is False
|
||||||
|
report.update(reason=AbuseReport.REASONS.HATEFUL_VIOLENT_DECEPTIVE)
|
||||||
|
assert report.is_individually_actionable is True
|
||||||
|
|
||||||
|
report.update(
|
||||||
|
guid=addon.guid,
|
||||||
|
user=None,
|
||||||
|
rating=None,
|
||||||
|
collection=None,
|
||||||
|
addon_version=addon.current_version.version,
|
||||||
|
)
|
||||||
|
assert report.is_individually_actionable is True
|
||||||
|
|
||||||
|
self.make_addon_unlisted(addon)
|
||||||
|
assert report.is_individually_actionable is False
|
||||||
|
|
||||||
|
self.make_addon_listed(addon)
|
||||||
|
Version.objects.get(version=report.addon_version).delete()
|
||||||
|
assert report.is_individually_actionable is True
|
||||||
|
|
||||||
|
Version.unfiltered.get(version=report.addon_version).delete(hard=True)
|
||||||
|
assert report.is_individually_actionable is False
|
||||||
|
|
||||||
def test_is_handled_by_reviewers(self):
|
def test_is_handled_by_reviewers(self):
|
||||||
addon = addon_factory()
|
addon = addon_factory()
|
||||||
abuse_report = AbuseReport.objects.create(
|
abuse_report = AbuseReport.objects.create(
|
||||||
|
|
|
@ -539,11 +539,11 @@ class AddonAbuseViewSetTestBase:
|
||||||
assert response.status_code == 400
|
assert response.status_code == 400
|
||||||
assert json.loads(response.content) == {'addon_install_method': 'Invalid value'}
|
assert json.loads(response.content) == {'addon_install_method': 'Invalid value'}
|
||||||
|
|
||||||
def _setup_reportable_reason(self, reason):
|
def _setup_reportable_reason(self, reason, *, addon=None, extra_data=None):
|
||||||
addon = addon_factory(guid='@badman')
|
addon = addon or addon_factory(guid='@badman')
|
||||||
response = self.client.post(
|
response = self.client.post(
|
||||||
self.url,
|
self.url,
|
||||||
data={'addon': addon.guid, 'reason': reason},
|
data={'addon': addon.guid, 'reason': reason, **(extra_data or {})},
|
||||||
REMOTE_ADDR='123.45.67.89',
|
REMOTE_ADDR='123.45.67.89',
|
||||||
HTTP_X_FORWARDED_FOR=f'123.45.67.89, {get_random_ip()}',
|
HTTP_X_FORWARDED_FOR=f'123.45.67.89, {get_random_ip()}',
|
||||||
)
|
)
|
||||||
|
@ -555,6 +555,30 @@ class AddonAbuseViewSetTestBase:
|
||||||
self._setup_reportable_reason('hateful_violent_deceptive')
|
self._setup_reportable_reason('hateful_violent_deceptive')
|
||||||
task_mock.assert_called()
|
task_mock.assert_called()
|
||||||
|
|
||||||
|
@mock.patch('olympia.abuse.tasks.report_to_cinder.delay')
|
||||||
|
@override_switch('dsa-job-technical-processing', active=True)
|
||||||
|
def test_reportable_reason_does_call_if_version_listed(self, task_mock):
|
||||||
|
addon = addon_factory(guid='@badman')
|
||||||
|
self._setup_reportable_reason(
|
||||||
|
'hateful_violent_deceptive',
|
||||||
|
addon=addon,
|
||||||
|
extra_data={'addon_version': addon.current_version.version},
|
||||||
|
)
|
||||||
|
task_mock.assert_called()
|
||||||
|
|
||||||
|
@mock.patch('olympia.abuse.tasks.report_to_cinder.delay')
|
||||||
|
@override_switch('dsa-job-technical-processing', active=True)
|
||||||
|
def test_reportable_reason_does_not_call_if_version_unlisted(self, task_mock):
|
||||||
|
addon = addon_factory(guid='@badman')
|
||||||
|
version = addon.current_version
|
||||||
|
self.make_addon_unlisted(addon)
|
||||||
|
self._setup_reportable_reason(
|
||||||
|
'hateful_violent_deceptive',
|
||||||
|
addon=addon,
|
||||||
|
extra_data={'addon_version': version.version},
|
||||||
|
)
|
||||||
|
task_mock.assert_not_called()
|
||||||
|
|
||||||
@mock.patch('olympia.abuse.tasks.report_to_cinder.delay')
|
@mock.patch('olympia.abuse.tasks.report_to_cinder.delay')
|
||||||
@override_switch('dsa-job-technical-processing', active=False)
|
@override_switch('dsa-job-technical-processing', active=False)
|
||||||
def test_reportable_reason_does_not_call_cinder_with_waffle_off(self, task_mock):
|
def test_reportable_reason_does_not_call_cinder_with_waffle_off(self, task_mock):
|
||||||
|
|
Загрузка…
Ссылка в новой задаче