Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 2 additions & 3 deletions src/olympia/addons/management/commands/process_addons.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
from datetime import datetime

from django.db.models import Exists, F, OuterRef, Q

from olympia import amo
Expand All @@ -20,6 +18,7 @@
_ADDON_PLUGIN,
_ADDON_THEME,
_ADDON_WEBAPP,
COSE_DATE_CUTOFF,
)
from olympia.devhub.tasks import get_preview_sizes, recreate_previews
from olympia.lib.crypto.tasks import bump_and_resign_addons
Expand Down Expand Up @@ -82,7 +81,7 @@ def get_recalc_needed_filters():
# created before the 5th of April
Q(
status=amo.STATUS_APPROVED,
_current_version__created__lt=datetime(2019, 4, 5),
_current_version__created__lt=COSE_DATE_CUTOFF,
disabled_by_user=False,
type__in=(
amo.ADDON_EXTENSION,
Expand Down
3 changes: 3 additions & 0 deletions src/olympia/constants/base.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import re
from collections import namedtuple
from datetime import date

from django.utils.translation import gettext_lazy as _

Expand Down Expand Up @@ -433,3 +434,5 @@
SURVEY_LINK = {
DEV_EXP_SURVEY_ALCHEMER_ID: 'https://survey.alchemer.com/s3/7953020/MV3-Developer-Sentiment-2024'
}

COSE_DATE_CUTOFF = date(2019, 4, 5)
2 changes: 2 additions & 0 deletions src/olympia/scanners/admin.py
Original file line number Diff line number Diff line change
Expand Up @@ -804,6 +804,7 @@ class ScannerQueryRuleAdmin(AbstractScannerRuleAdminMixin, AMOModelAdmin):
'run_on_specific_channel',
'run_on_current_version_only',
'exclude_promoted_addons',
'created_after',
'created',
'state_with_actions',
'completion_rate',
Expand All @@ -819,6 +820,7 @@ class ScannerQueryRuleAdmin(AbstractScannerRuleAdminMixin, AMOModelAdmin):
'run_on_specific_channel',
'run_on_current_version_only',
'exclude_promoted_addons',
'created_after',
'state_with_actions',
'name',
'pretty_name',
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Generated by Django 5.2.16 on 2026-08-06 16:30

import datetime
import django.db.models.deletion
from django.db import migrations, models


class Migration(migrations.Migration):

dependencies = [
('abuse', '0070_alter_cinderpolicy_expose_in_reviewer_tools_and_more'),
('scanners', '0085_delete_enable_scanner_webhooks_waffle_switch'),
]

operations = [
migrations.AddField(
model_name='scannerqueryrule',
name='created_after',
field=models.DateField(blank=True, db_default=None, default=datetime.date(2019, 4, 5), null=True),
),
migrations.AlterField(
model_name='scannerqueryrule',
name='run_on_specific_channel',
field=models.PositiveSmallIntegerField(blank=True, choices=[(None, ''), (1, 'Unlisted'), (2, 'Listed'), (3, 'Enterprise')], default=None, help_text='Run this rule on versions in the specific channel only.', null=True),
),
migrations.AlterField(
model_name='scannerrule',
name='policy',
field=models.ForeignKey(blank=True, help_text='Policy used to automatically derive an action from when the rule hit.', limit_choices_to={'expose_in_reviewer_tools__in': [1, 2]}, null=True, on_delete=django.db.models.deletion.SET_NULL, to='abuse.cinderpolicy'),
),
]
5 changes: 4 additions & 1 deletion src/olympia/scanners/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@
from olympia.access.models import Group, GroupUser
from olympia.amo.models import ModelBase
from olympia.constants.abuse import POLICY_EXPOSURE
from olympia.constants.base import ADDON_EXTENSION
from olympia.constants.base import ADDON_EXTENSION, COSE_DATE_CUTOFF
from olympia.constants.scanners import (
ABORTED,
ABORTING,
Expand Down Expand Up @@ -650,6 +650,9 @@ class ScannerQueryRule(AbstractScannerRule):
help_text='Run this rule on versions in the specific channel only.',
choices=[(None, '')] + list(amo.CHANNEL_CHOICES.items()),
)
created_after = models.DateField(
db_default=None, default=COSE_DATE_CUTOFF, null=True, blank=True
)
celery_group_result_id = models.UUIDField(default=None, null=True)
task_count = models.PositiveIntegerField(default=0)
completed = models.DateTimeField(default=None, null=True, blank=True)
Expand Down
2 changes: 2 additions & 0 deletions src/olympia/scanners/tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -664,6 +664,8 @@ def run_scanner_query_rule(query_rule_pk):
qs = qs.filter(channel=rule.run_on_specific_channel)
if rule.run_on_current_version_only:
qs = qs.filter(pk=F('addon___current_version'))
if rule.created_after:
qs = qs.filter(created__gte=rule.created_after)
if rule.exclude_promoted_addons:
qs = qs.exclude(addon__promotedaddon__isnull=False)
qs = qs.values_list('id', flat=True).order_by('-pk')
Expand Down
33 changes: 33 additions & 0 deletions src/olympia/scanners/tests/test_tasks.py
Original file line number Diff line number Diff line change
Expand Up @@ -2126,6 +2126,39 @@ def test_run_on_specific_channel(self):
# just make sure the id was set to something.
assert self.rule.celery_group_result_id is not None

def test_run_created_after(self):
# Pretend we went through the admin, run after a specific date
some_time_ago = self.days_ago(42)
self.rule.update(state=SCHEDULED, created_after=some_time_ago)

# Make existing version old: it shouldn't be found.
self.version.update(created=self.days_ago(1200))

# Add a couple versions that should be found.
expected_versions = [
version_factory(
file_kw={'filename': 'webextension.xpi'},
addon=self.version.addon,
),
addon_factory(
version_kw={'created': some_time_ago},
file_kw={'filename': 'webextension.xpi'},
).current_version,
]

# Run the task.
run_scanner_query_rule.delay(self.rule.pk)

# Only the newer versions should have been found.
assert ScannerQueryResult.objects.count() == 2

assert sorted(
ScannerQueryResult.objects.values_list('version_id', flat=True)
) == sorted(v.pk for v in expected_versions)
self.rule.reload()
assert self.rule.state == COMPLETED
assert self.rule.task_count == 1

def test_run_not_new(self):
self.rule.update(state=RUNNING) # Not SCHEDULED.
run_scanner_query_rule.delay(self.rule.pk)
Expand Down
Loading