Recalculate risk score for already confirmed add-ons regularly. (#11950)

* Recalculate risk score for already confirmed add-ons regularly.

Fixes #11790

* Update task to be run on Sunday, 3pm

* Cleanup, don't take deleted reports into account
This commit is contained in:
Christopher Grebs 2019-07-30 20:05:53 +02:00 коммит произвёл GitHub
Родитель b4c3a9393f
Коммит 1e0351c37c
Не найден ключ, соответствующий данной подписи
Идентификатор ключа GPG: 4AEE18F83AFDEB23
3 изменённых файлов: 167 добавлений и 2 удалений

Просмотреть файл

@ -40,6 +40,8 @@ HOME=/tmp
# Once per week
1 9 * * 1 %(django)s review_reports
0 15 * * 6 %(django)s process_addons --task=constantly_recalculate_post_review_weight
# Do not put crons below this line

Просмотреть файл

@ -1,7 +1,7 @@
from datetime import datetime
from django.core.management.base import BaseCommand, CommandError
from django.db.models import Q
from django.db.models import Q, F
from celery import chord, group
@ -18,6 +18,7 @@ from olympia.addons.tasks import (
recreate_theme_previews,
repack_themes_for_69,
)
from olympia.abuse.models import AbuseReport
from olympia.amo.utils import chunked
from olympia.devhub.tasks import get_preview_sizes, recreate_previews
from olympia.lib.crypto.tasks import sign_addons
@ -32,6 +33,30 @@ firefox_56_star = version_int('56.*')
current_autoapprovalsummary = '_current_version__autoapprovalsummary__'
def get_recalc_needed_filters():
summary_modified = F('_current_version__autoapprovalsummary__modified')
# We don't take deleted reports into account
valid_abuse_report_states = (
AbuseReport.STATES.UNTRIAGED, AbuseReport.STATES.VALID,
AbuseReport.STATES.SUSPICIOUS)
return [
# Only recalculate add-ons that received recent abuse reports
# possibly through their authors.
Q(
abuse_reports__state__in=valid_abuse_report_states,
abuse_reports__created__gte=summary_modified
) |
Q(
authors__abuse_reports__state__in=valid_abuse_report_states,
authors__abuse_reports__created__gte=summary_modified
) |
# And check ratings that have a rating of 3 or less
Q(_current_version__ratings__created__gte=summary_modified,
_current_version__ratings__rating__lte=3)
]
tasks = {
'find_inconsistencies_between_es_and_db': {
'method': find_inconsistencies_between_es_and_db, 'qs': []},
@ -42,6 +67,12 @@ tasks = {
Q(**{current_autoapprovalsummary + 'verdict': amo.AUTO_APPROVED}) &
~Q(**{current_autoapprovalsummary + 'confirmed': True})
]},
'constantly_recalculate_post_review_weight': {
# This re-calculates the whole post-review weight which can be costly
# so take that into account. We may want to optimize that later
# in case we notice things are slower than needed - cgrebs 20190730
'method': recalculate_post_review_weight,
'qs': get_recalc_needed_filters()},
'resign_addons_for_cose': {
'method': sign_addons,
'qs': [

Просмотреть файл

@ -1,5 +1,5 @@
from contextlib import contextmanager
from datetime import datetime
from datetime import datetime, timedelta
from django.core import mail
from django.core.management import call_command
@ -15,6 +15,7 @@ from olympia.activity.models import ActivityLog
from olympia.addons.management.commands import process_addons
from olympia.addons.models import (
Addon, AddonApprovalsCounter, MigratedLWT, ReusedGUID, GUID_REUSE_FORMAT)
from olympia.abuse.models import AbuseReport
from olympia.amo.tests import (
TestCase, addon_factory, user_factory, version_factory)
from olympia.files.models import FileValidation, WebextPermission
@ -227,6 +228,137 @@ class RecalculateWeightTestCase(TestCase):
assert summary.weight == 10
class ConstantlyRecalculateWeightTestCase(TestCase):
def test_affects_correct_addons(self):
# *not considered* - Non auto-approved add-on
addon_factory()
# *not considered* - Non auto-approved add-on that has an
# AutoApprovalSummary entry
AutoApprovalSummary.objects.create(
version=addon_factory().current_version,
verdict=amo.NOT_AUTO_APPROVED)
# *not considered* -Add-on with the current version not auto-approved
extra_addon = addon_factory()
AutoApprovalSummary.objects.create(
version=extra_addon.current_version, verdict=amo.AUTO_APPROVED)
extra_addon.current_version.update(created=self.days_ago(1))
version_factory(addon=extra_addon)
# *not considered* - current version is auto-approved but doesn't
# have recent abuse reports or low ratings
auto_approved_addon = addon_factory()
AutoApprovalSummary.objects.create(
version=auto_approved_addon.current_version,
verdict=amo.AUTO_APPROVED)
# *considered* - current version is auto-approved and
# has a recent rating with rating <= 3
auto_approved_addon1 = addon_factory()
summary = AutoApprovalSummary.objects.create(
version=auto_approved_addon1.current_version,
verdict=amo.AUTO_APPROVED)
Rating.objects.create(
created=summary.modified + timedelta(days=3),
addon=auto_approved_addon1,
version=auto_approved_addon1.current_version,
rating=2, body='Apocalypse', user=user_factory()),
# *not considered* - current version is auto-approved but
# has a recent rating with rating > 3
auto_approved_addon2 = addon_factory()
summary = AutoApprovalSummary.objects.create(
version=auto_approved_addon2.current_version,
verdict=amo.AUTO_APPROVED)
Rating.objects.create(
created=summary.modified + timedelta(days=3),
addon=auto_approved_addon2,
version=auto_approved_addon2.current_version,
rating=4, body='Apocalypse', user=user_factory()),
# *not considered* - current version is auto-approved but
# has a recent rating with rating > 3
auto_approved_addon3 = addon_factory()
summary = AutoApprovalSummary.objects.create(
version=auto_approved_addon3.current_version,
verdict=amo.AUTO_APPROVED)
Rating.objects.create(
created=summary.modified + timedelta(days=3),
addon=auto_approved_addon3,
version=auto_approved_addon3.current_version,
rating=4, body='Apocalypse', user=user_factory()),
# *not considered* - current version is auto-approved but
# has a low rating that isn't recent enough
auto_approved_addon4 = addon_factory()
summary = AutoApprovalSummary.objects.create(
version=auto_approved_addon4.current_version,
verdict=amo.AUTO_APPROVED)
Rating.objects.create(
created=summary.modified - timedelta(days=3),
addon=auto_approved_addon4,
version=auto_approved_addon4.current_version,
rating=1, body='Apocalypse', user=user_factory()),
# *considered* - current version is auto-approved and
# has a recent abuse report
auto_approved_addon5 = addon_factory()
summary = AutoApprovalSummary.objects.create(
version=auto_approved_addon5.current_version,
verdict=amo.AUTO_APPROVED)
AbuseReport.objects.create(
addon=auto_approved_addon5,
created=summary.modified + timedelta(days=3))
# *not considered* - current version is auto-approved but
# has an abuse report that isn't recent enough
auto_approved_addon6 = addon_factory()
summary = AutoApprovalSummary.objects.create(
version=auto_approved_addon6.current_version,
verdict=amo.AUTO_APPROVED)
AbuseReport.objects.create(
addon=auto_approved_addon6,
created=summary.modified - timedelta(days=3))
# *considered* - current version is auto-approved and
# has an abuse report through it's author that is recent enough
author = user_factory()
auto_approved_addon7 = addon_factory(users=[author])
summary = AutoApprovalSummary.objects.create(
version=auto_approved_addon7.current_version,
verdict=amo.AUTO_APPROVED)
AbuseReport.objects.create(
user=author,
created=summary.modified + timedelta(days=3))
# *not considered* - current version is auto-approved and
# has an abuse report through it's author that is recent enough
# BUT the abuse report is deleted.
author = user_factory()
auto_approved_addon8 = addon_factory(users=[author])
summary = AutoApprovalSummary.objects.create(
version=auto_approved_addon8.current_version,
verdict=amo.AUTO_APPROVED)
AbuseReport.objects.create(
user=author,
state=AbuseReport.STATES.DELETED,
created=summary.modified + timedelta(days=3))
with count_subtask_calls(
process_addons.recalculate_post_review_weight) as calls:
call_command(
'process_addons',
task='constantly_recalculate_post_review_weight')
assert len(calls) == 1
assert calls[0]['kwargs']['args'] == [[
auto_approved_addon1.pk,
auto_approved_addon5.pk,
auto_approved_addon7.pk,
]]
class TestExtractWebextensionsToGitStorage(TestCase):
@mock.patch('olympia.addons.tasks.index_addons.delay', autospec=True)
@mock.patch(