]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 1501966 - Warn when there are outdated products or components in the teams list
authorIsrael Madueme <purelogiq@gmail.com>
Mon, 29 Oct 2018 18:29:10 +0000 (14:29 -0400)
committerDylan William Hardison <dylan@hardison.net>
Mon, 29 Oct 2018 18:29:10 +0000 (14:29 -0400)
Bugzilla/Report/SecurityRisk.pm
scripts/secbugsreport.pl
template/en/default/reports/email/security-risk.html.tmpl

index 0c4c1ef2cfc306eb0cd7783c81080ef61f801eed..cb2bf8cdfef87b5954bd6238d17a5a578a2eb68c 100644 (file)
@@ -76,6 +76,10 @@ has 'sec_keywords' => (is => 'ro', required => 1, isa => ArrayRef [Str],);
 
 has 'products' => (is => 'lazy', isa => ArrayRef [Str],);
 
+has 'missing_products' => (is => 'lazy', isa => ArrayRef [Str],);
+
+has 'missing_components' => (is => 'lazy', isa => ArrayRef [Str],);
+
 has 'initial_bug_ids' => (is => 'lazy', isa => ArrayRef [Int],);
 
 has 'initial_bugs' => (
@@ -146,6 +150,65 @@ sub _build_products {
   return \@products;
 }
 
+sub _build_missing_products {
+  my ($self) = @_;
+  my $dbh = Bugzilla->dbh;
+  my @products = map { $dbh->quote($_) } @{$self->products};
+  my $query = qq{
+        SELECT
+            name
+        FROM
+            products
+         WHERE
+            @{[$dbh->sql_in('products.name', \@products)]}
+    };
+  my $found_products = Bugzilla->dbh->selectcol_arrayref($query);
+  return (diff_arrays($self->products, $found_products))[0];
+}
+
+sub _build_missing_components {
+  my ($self) = @_;
+  my $dbh = Bugzilla->dbh;
+  my $products           = join ', ', map { $dbh->quote($_) } @{$self->products};
+  my @named_components   = ();
+  my @missing_components = ();
+  foreach my $team (values %{$self->teams}) {
+    foreach my $product (keys %$team) {
+      if (exists $team->{$product}->{named_components}) {
+        foreach my $component (@{$team->{$product}->{named_components}}) {
+          push @named_components, [$product, $component];
+        }
+      }
+    }
+  }
+
+  my @components = map { $dbh->quote($_->[1]) } @named_components;
+  my $query = qq{
+      SELECT
+          product.name,
+          component.name
+      FROM
+          components AS component
+          JOIN products AS product ON component.product_id = product.id
+      WHERE
+          @{[$dbh->sql_in('component.name', \@components)]}
+  };
+  my $found_components = Bugzilla->dbh->selectall_arrayref($query);
+
+  foreach my $named_component (@named_components) {
+    my $found = 0;
+    foreach my $found_component (@$found_components) {
+      if (lc $named_component->[0] eq lc $found_component->[0] && lc $named_component->[1] eq lc $found_component->[1])
+      {
+        $found = 1;
+        last;
+      }
+    }
+    push @missing_components, "$named_component->[0]::$named_component->[1]" if !$found;
+  }
+  return \@missing_components;
+}
+
 sub _build_initial_bug_ids {
 
 # TODO: Handle changes in product (e.g. gravyarding) by searching the events table
index e57989857a3d5886aff86f03e61af28c3c7f0683..03a3db667a68a1f416c13e3554cc2e03903aaa4c 100644 (file)
@@ -48,19 +48,21 @@ my $report       = Bugzilla::Report::SecurityRisk->new(
 );
 
 my $bugs_by_team = $report->results->[-1]->{bugs_by_team};
-my @sorted_team_names = sort { ## no critic qw(BuiltinFunctions::ProhibitReverseSortBlock
-  @{$bugs_by_team->{$b}->{open}} <=> @{$bugs_by_team->{$a}->{open}} ## no critic qw(Freenode::DollarAB)
+my @sorted_team_names = sort {    ## no critic qw(BuiltinFunctions::ProhibitReverseSortBlock
+  @{$bugs_by_team->{$b}->{open}} <=> @{$bugs_by_team->{$a}->{open}}    ## no critic qw(Freenode::DollarAB)
     || $a cmp $b
 } keys %$teams;
 
 my $vars = {
-  urlbase         => Bugzilla->localconfig->{urlbase},
-  report_week     => $report_week,
-  teams           => \@sorted_team_names,
-  sec_keywords    => $sec_keywords,
-  results         => $report->results,
-  deltas          => $report->deltas,
-  build_bugs_link => \&build_bugs_link,
+  urlbase            => Bugzilla->localconfig->{urlbase},
+  report_week        => $report_week,
+  teams              => \@sorted_team_names,
+  sec_keywords       => $sec_keywords,
+  results            => $report->results,
+  deltas             => $report->deltas,
+  missing_products   => $report->missing_products,
+  missing_components => $report->missing_components,
+  build_bugs_link    => \&build_bugs_link,
 };
 
 $template->process('reports/email/security-risk.html.tmpl', $vars, \$html) or ThrowTemplateError($template->error());
index e284a71904a6b2c66553076b3b2a45d671ffe44d..564a0537d37b5b56e8bd1ed37ade80cc5db51874 100644 (file)
@@ -24,7 +24,7 @@
         Open<br>[% results.reverse.0.date FILTER time('%m/%d') %]
     </th>
     <th style="padding: 0px 15px 10px 0px; text-align: right;">Closed<br />Last Week</th>
-    <th style="padding: 0px 15px 10px 0px; text-align: right;">Added<br />Last Week</th>
+    <th style="padding: 0px 15px 10px 0px; text-align: right; border-right: 1px solid grey;">Added<br />Last Week</th>
     [% FOREACH result IN results.reverse %]
       [% NEXT IF loop.count < 2 %]
       [% LAST IF loop.count > 4 %]
         [% NEXT IF loop.count < 2 %]
         [% LAST IF loop.count > 4 %]
         <td style="padding: 0px 15px 10px [% IF loop.count == 2 %] 10px [% ELSE %] 0px [% END %]; text-align: right;  [% IF loop.count == 1 %] border-right: 1px solid grey; [% END %]">
-          [% IF result.bugs_by_sec_keyword.$keyword.open %]
+          [% IF result.bugs_by_sec_keyword.$keyword.open.size %]
             <a style="text-decoration: none;" href="[% build_bugs_link(result.bugs_by_sec_keyword.$keyword.open) FILTER html %]">
               [% result.bugs_by_sec_keyword.$keyword.open.size FILTER html %]
             </a>
@@ -166,5 +166,25 @@ this report treats marking a [% terms.bug %] as 'stalled' the same as closing it
 
 <p>Attached to this email are some graphs with stats for the past 12 months.</p>
 
+[% IF missing_products.size %]
+  <p>The following products requested on this report are no longer active in BMO:&nbsp;
+  [% FOREACH missing_product IN missing_products %]
+    [% missing_product FILTER html %][% ", " FILTER html IF not loop.last %]
+  [% END %]
+  <p>
+[% END %]
+
+[% IF missing_components.size %]
+  <p>The following components requested on this report are no longer active in BMO:&nbsp;
+  [% FOREACH missing_component IN missing_components %]
+    [% missing_component FILTER html %][% ", " FILTER html IF not loop.last %]
+  [% END %]
+  </p>
+[% END %]
+
+[% IF missing_products.size || missing_components.size %]
+  <p>Please file a [% terms.bug %] in bugzilla.mozilla.org::Administration to update the team list.</p>
+[% END %]
+
 </body>
 </html>