From 7b864281523a0bf15ecea235f463c27bb77dec53 Mon Sep 17 00:00:00 2001 From: Dan Fandrich Date: Mon, 15 Apr 2024 23:26:06 -0700 Subject: Get the last modified date of advisories from SVN The modification date helps track if an advisory was changed after initial publication. This is especially important for OSV users who need the modification date in the vulns.json index to determine whether an existing advisory was updated so they can download the update. Also, keep "ref" (pointing to bug number) in all advisories, not just the TODO ones. --- NEWS | 1 + lib/MGA/Advisories.pm | 30 +++++++++++++++++++++++++++++- tmpl/advisory.html | 1 + tmpl/advisory.json | 1 + tmpl/vulns.json | 3 ++- 5 files changed, 34 insertions(+), 2 deletions(-) diff --git a/NEWS b/NEWS index 488caef..228d6e2 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,7 @@ Version 0.X - try to fix publish-all +- include a last modified date in advisories Version 0.29 diff --git a/lib/MGA/Advisories.pm b/lib/MGA/Advisories.pm index 1b86049..2506c3c 100644 --- a/lib/MGA/Advisories.pm +++ b/lib/MGA/Advisories.pm @@ -5,6 +5,7 @@ use strict; use YAML qw(LoadFile DumpFile Load); use Template; use DateTime; +use DateTime::Format::ISO8601; use Email::Sender::Simple qw(try_to_sendmail); use Email::Simple; use Email::Simple::Creator; @@ -13,6 +14,8 @@ use LWP::UserAgent; use Parallel::ForkManager; use File::Basename; use XMLRPC::Lite; +use XML::XPath; +use XML::XPath::XMLParser; use Term::ReadKey; #use Data::Dump qw(dd); @@ -169,6 +172,9 @@ sub login_bz { sub get_advisories_from_dir { + # Retrieve last modified dates from SVN + my $modified = get_modified(); + my %advisories; foreach my $advfile (glob "$config->{advisories_dir}/*.adv") { my $adv; @@ -180,9 +186,9 @@ sub get_advisories_from_dir { print $@; next; } + $adv->{ref} = basename($advfile, ".adv"); if (!$adv->{ID}) { next unless $config->{mode} eq 'qa'; - $adv->{ref} = basename($advfile, ".adv"); $adv->{ID} = next_id('TODO', keys %advisories); $adv->{no_save_status} = 1; } @@ -192,6 +198,11 @@ sub get_advisories_from_dir { $advisories{$adv->{ID}} = $adv; my $statusfile = status_file($adv->{ID}); $adv->{status} = -f $statusfile ? LoadFile($statusfile) : {}; + my $fn = $adv->{ref} = basename($advfile); + if (exists $modified->{$fn}) { + # Pull the modified date into the advisory + $adv->{status}{modified} = $modified->{$fn}; + } } return \%advisories; } @@ -619,6 +630,23 @@ sub process_template { } } +# Get the last modified date for each advisory file from SVN +sub get_modified { + my $xml = `svn status -v --xml`; + my $xp = XML::XPath->new(xml => $xml); + my $nodeset = $xp->find('/status/target/entry'); + my %modified; + foreach my $node ($nodeset->get_nodelist) { + my $path = $node->findvalue('@path')->value(); + my $datez = $node->findvalue('wc-status/commit/date')->value(); + if ($path and $datez) { + my $timestamp = DateTime::Format::ISO8601->parse_datetime($datez); + $modified{$path} = $timestamp->epoch; + } + } + return \%modified; +} + # Max 10 processes for processing templates my $pm = Parallel::ForkManager->new(10); $pm->run_on_finish(\¶llel_finish); diff --git a/tmpl/advisory.html b/tmpl/advisory.html index a5cbb52..dda79a4 100644 --- a/tmpl/advisory.html +++ b/tmpl/advisory.html @@ -15,6 +15,7 @@

[% adv.subject %]

Publication date: [% date.format(adv.status.published, format => '%d %b %Y', gmt => 1) %]
+ Modification date: [% date.format(adv.status.modified, format => '%d %b %Y', gmt => 1) %]
Type: [% adv.type %]
Affected Mageia releases : [% SET sep = '' %] diff --git a/tmpl/advisory.json b/tmpl/advisory.json index 475012f..ab46f2b 100644 --- a/tmpl/advisory.json +++ b/tmpl/advisory.json @@ -11,6 +11,7 @@ print JSON::encode_json($stash->get($stash->get('var'))); "schema_version": "1.6.2", "id": [% jsonvar('advisory') %], "published": "[% date.format(adv.status.published, format => '%Y-%m-%dT%H:%M:%SZ', gmt => 1) %]", + "modified": "[% date.format(adv.status.modified, format => '%Y-%m-%dT%H:%M:%SZ', gmt => 1) %]", "summary": [% jsonvar('adv.subject') %], "details": [% jsonvar('adv.description') %], [% IF adv.CVE && adv.CVE.list.size != 0 -%] diff --git a/tmpl/vulns.json b/tmpl/vulns.json index aadcd05..790f88a 100644 --- a/tmpl/vulns.json +++ b/tmpl/vulns.json @@ -1,9 +1,10 @@ +[%- USE date -%] [ [%- FOR adv IN advdb.sorted -%] [% USE advid = String(basename.ID(adv)) -%] [% IF advid.search('^MGASA-') -%] [%- "," IF gotone %] -{"id": "[% basename.ID(adv) %]"} +{"id": "[% basename.ID(adv) %]","modified": "[% date.format(advdb.advisories.$adv.status.modified, format => '%Y-%m-%dT%H:%M:%SZ', gmt => 1) %]"} [%- SET gotone = 1 %] [%- END %] [%- END %] -- cgit v1.2.1