Skip to content

Commit eb0ad17

Browse files
committed
Extract matched rules information in scanner results used by webhooks (#24482)
1 parent 552edfc commit eb0ad17

File tree

4 files changed

+49
-2
lines changed

4 files changed

+49
-2
lines changed

src/olympia/scanners/tasks.py

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,10 @@ def call_webhooks(event_name, payload, upload=None, version=None):
122122
},
123123
)
124124

125-
scanner_result.update(results=data)
125+
scanner_result.results = data
126+
# We don't pass `update_fields` because the `save()` method
127+
# also updates other fields (e.g. has_matches, matched_rules).
128+
scanner_result.save()
126129
except Exception as exc:
127130
log.exception('Error while calling webhook "%s".', event.webhook.name)
128131
raise exc

src/olympia/scanners/tests/test_tasks.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2403,6 +2403,30 @@ def test_call_webhooks(self, _call_webhook_mock):
24032403
]
24042404
)
24052405

2406+
@mock.patch('olympia.scanners.tasks._call_webhook')
2407+
def test_call_webhooks_extracts_matched_rules(self, _call_webhook_mock):
2408+
rule = ScannerRule.objects.create(
2409+
name='some-rule',
2410+
scanner=WEBHOOK,
2411+
is_active=True,
2412+
)
2413+
webhook = ScannerWebhook.objects.create(
2414+
name='some-scanner',
2415+
url='https://example.org/webhook',
2416+
api_key='some-api-key',
2417+
is_active=True,
2418+
)
2419+
ScannerWebhookEvent.objects.create(
2420+
event=WEBHOOK_DURING_VALIDATION, webhook=webhook
2421+
)
2422+
_call_webhook_mock.return_value = {'matchedRules': [rule.name]}
2423+
2424+
call_webhooks(WEBHOOK_DURING_VALIDATION, payload={})
2425+
2426+
result = ScannerResult.objects.get(scanner=WEBHOOK)
2427+
assert result.has_matches is True
2428+
assert list(result.matched_rules.all()) == [rule]
2429+
24062430
@mock.patch('olympia.scanners.tasks._call_webhook')
24072431
def test_call_webhooks_raises(self, _call_webhook_mock):
24082432
assert len(ScannerResult.objects.all()) == 0

src/olympia/scanners/tests/test_views.py

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
)
2929
from olympia.scanners.models import (
3030
ScannerResult,
31+
ScannerRule,
3132
ScannerWebhook,
3233
ScannerWebhookEvent,
3334
)
@@ -513,6 +514,21 @@ def test_invalid_payload_empty(self):
513514

514515
assert response.status_code == 400
515516

517+
def test_success_extracts_matched_rules(self):
518+
rule = ScannerRule.objects.create(
519+
name='some-rule',
520+
scanner=WEBHOOK,
521+
is_active=True,
522+
)
523+
524+
results = {'version': '1.2.3', 'matchedRules': [rule.name]}
525+
response = self.patch(self.url, data={'results': results})
526+
527+
assert response.status_code == 204
528+
self.scanner_result.refresh_from_db()
529+
assert self.scanner_result.has_matches is True
530+
assert list(self.scanner_result.matched_rules.all()) == [rule]
531+
516532
def test_invalid_group(self):
517533
self.webhook.service_account.groupuser_set.all().delete()
518534

src/olympia/scanners/views.py

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -150,5 +150,9 @@ def patch_scanner_result(request, pk=None):
150150
# Return a 400 response if the data was invalid.
151151
serializer.is_valid(raise_exception=True)
152152

153-
scanner_result.update(results=serializer.validated_data['results'])
153+
scanner_result.results = serializer.validated_data['results']
154+
# We don't pass `update_fields` because the `save()` method
155+
# also updates other fields (e.g. has_matches, matched_rules).
156+
scanner_result.save()
157+
154158
return Response(status=status.HTTP_204_NO_CONTENT)

0 commit comments

Comments
 (0)