Skip to content

Commit

Permalink
Resync all SecurityAdvisory entities to set syncTime fields. (dar…
Browse files Browse the repository at this point in the history
  • Loading branch information
szakarias authored Nov 2, 2023
1 parent 0dd6352 commit 955ff69
Show file tree
Hide file tree
Showing 4 changed files with 20 additions and 10 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Important changes to data models, configuration, and migrations between each
AppEngine version, listed here to ease deployment and troubleshooting.

## Next Release (replace with git tag when deployed)
* Resyncing all `SecurityAdvisory` entities to get `syncTime` fields backfilled.

## `20231102t094900-all`
* Bumped runtimeVersion to `2023.11.02`.
Expand Down
11 changes: 7 additions & 4 deletions app/lib/service/security_advisories/backend.dart
Original file line number Diff line number Diff line change
Expand Up @@ -61,14 +61,15 @@ class SecurityAdvisoryBackend {
return errors.isEmpty;
}

/// Overwrites existing advisory with the same id, if [osv] is newer.
/// Overwrites existing advisory with the same id, if [osv] is newer or
/// unconditionally if [resync] is set.
///
/// If id is already listed as `alias` for another advisory, no action will be
/// taken to resolve this. Instead both advisories will be stored and served.
/// It's assumed that security advisory database owners take care to keep the
/// security advisories sound, and that inconsistencies are intentional.
Future<SecurityAdvisory?> ingestSecurityAdvisory(
OSV osv, DateTime syncTime) async {
Future<SecurityAdvisory?> ingestSecurityAdvisory(OSV osv, DateTime syncTime,
{bool resync = false}) async {
return await withRetryTransaction(_db, (tx) async {
DateTime modified;
try {
Expand All @@ -80,7 +81,9 @@ class SecurityAdvisoryBackend {

final oldAdvisory = await lookupById(osv.id);

if (oldAdvisory != null && oldAdvisory.modified!.isAtOrAfter(modified)) {
if (!resync &&
oldAdvisory != null &&
oldAdvisory.modified!.isAtOrAfter(modified)) {
return oldAdvisory;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ Future<(Map<String, OSV>, List<String>)> loadAdvisoriesFromDir(
return (osvs, failedFiles);
}

Future<void> updateAdvisories(Map<String, OSV> osvs) async {
Future<void> updateAdvisories(Map<String, OSV> osvs,
{bool resync = false}) async {
final syncTime = clock.now();

final oldAdvisories = await securityAdvisoryBackend.listAdvisories();
Expand All @@ -69,18 +70,20 @@ Future<void> updateAdvisories(Map<String, OSV> osvs) async {
}

for (final osv in osvs.values) {
await securityAdvisoryBackend.ingestSecurityAdvisory(osv, syncTime);
await securityAdvisoryBackend.ingestSecurityAdvisory(osv, syncTime,
resync: resync);
}
}

/// Synchronizes the security advisory backend with security advisories from
/// osv.dev.
Future<void> syncSecurityAdvisories() async {
/// osv.dev, overwriting existing advisories with the same id, if the fetched
/// advisories are newer or overwriting unconditionally if [resync] is set.
Future<void> syncSecurityAdvisories({bool resync = false}) async {
final tempDir = await Directory.systemTemp.createTemp();
try {
await fetchAdvisories(tempDir);
final (osvs, failedFiles) = await loadAdvisoriesFromDir(tempDir);
await updateAdvisories(osvs);
await updateAdvisories(osvs, resync: resync);

if (failedFiles.isNotEmpty) {
throw Exception(
Expand Down
5 changes: 4 additions & 1 deletion app/lib/tool/backfill/backfill_new_fields.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
// BSD-style license that can be found in the LICENSE file.

import 'package:logging/logging.dart';
import 'package:pub_dev/service/security_advisories/sync_security_advisories.dart';

final _logger = Logger('backfill_new_fields');

Expand All @@ -12,5 +13,7 @@ final _logger = Logger('backfill_new_fields');
/// CHANGELOG.md must be updated with the new fields, and the next
/// release could remove the backfill from here.
Future<void> backfillNewFields() async {
_logger.info('Nothing to do.');
_logger.info('Resyncing all security advisories...');
// This will backfill the `syncTime` field on the `SecurityAdvisory` entity.
await syncSecurityAdvisories(resync: true);
}

0 comments on commit 955ff69

Please sign in to comment.