From: Israel Madueme Date: Wed, 11 Dec 2019 22:16:49 +0000 (-0500) Subject: Bug 1597800 - Send a sec bug report for moderate and low levels X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=6289dda0399bf91f736a8c5b35d830dcefca7eff;p=thirdparty%2Fbugzilla.git Bug 1597800 - Send a sec bug report for moderate and low levels This augments the existing secbugsreport.pl script to also send a report on sec moderate and sec low bugs in a separate email according to the sec teams requests. Will run in the same script so no need for an extra cron job. --- diff --git a/scripts/secbugsreport.pl b/scripts/secbugsreport.pl index 29276c774..fbe840f7e 100644 --- a/scripts/secbugsreport.pl +++ b/scripts/secbugsreport.pl @@ -44,8 +44,10 @@ exit 0 && Int->check($minutes) && Int->check($seconds); -my $html; -my $template = Bugzilla->template(); +my $html_crit_high; +my $html_moderate_low; +my $template_crit_high = Bugzilla->template(); +my $template_moderate_low = Bugzilla->template(); my $end_date = DateTime->new( year => $year, month => $month, @@ -57,49 +59,87 @@ my $end_date = DateTime->new( ); $end_date->set_time_zone('UTC'); -my $start_date = $end_date->clone()->subtract(months => 12); -my $report_week = $end_date->ymd('-'); -my $teams = decode_json(Bugzilla->params->{report_secbugs_teams}); -my $sec_keywords = ['sec-critical', 'sec-high']; -my $report = Bugzilla::Report::SecurityRisk->new( +my $start_date = $end_date->clone()->subtract(months => 12); +my $start_date_no_graphs = $end_date->clone()->subtract(months => 2); +my $report_week = $end_date->ymd('-'); +my $teams = decode_json(Bugzilla->params->{report_secbugs_teams}); + +# Sec Critical and Sec High report +my $sec_keywords_crit_high = ['sec-critical', 'sec-high']; +my $report_crit_high = Bugzilla::Report::SecurityRisk->new( start_date => $start_date, end_date => $end_date, teams => $teams, - sec_keywords => $sec_keywords, + sec_keywords => $sec_keywords_crit_high, very_old_days => 45 ); - -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) - || $a cmp $b -} keys %$teams; - -my $vars = { +my $sorted_teams_crit_high = sorted_team_names_by_open_bugs($report_crit_high); +my $vars_crit_high = { 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, - very_old_days => $report->very_old_days, + teams => $sorted_teams_crit_high, + sec_keywords => $sec_keywords_crit_high, + results => $report_crit_high->results, + deltas => $report_crit_high->deltas, + missing_products => $report_crit_high->missing_products, + missing_components => $report_crit_high->missing_components, + very_old_days => $report_crit_high->very_old_days, build_bugs_link => \&build_bugs_link, }; - -$template->process('reports/email/security-risk.html.tmpl', $vars, \$html) - or ThrowTemplateError($template->error()); - -# For now, only send HTML email. -my @parts = ( +$template_crit_high->process( + 'reports/email/security-risk.html.tmpl', + $vars_crit_high, + \$html_crit_high +) or ThrowTemplateError($template_crit_high->error()); + +# Sec Moderate and Sec Low report +# These have to be done separately since they do not want the by +# teams results combined. This template is specific is to this request, +# for a generic template use security-risk.html.tmpl as above. +my $report_moderate = Bugzilla::Report::SecurityRisk->new( + start_date => $start_date_no_graphs, + end_date => $end_date, + teams => $teams, + sec_keywords => ['sec-moderate'], + very_old_days => 45 +); +my $report_low = Bugzilla::Report::SecurityRisk->new( + start_date => $start_date_no_graphs, + end_date => $end_date, + teams => $teams, + sec_keywords => ['sec-low'], + very_old_days => 45 +); +my $sorted_teams_moderate = sorted_team_names_by_open_bugs($report_moderate); +my $sorted_teams_low = sorted_team_names_by_open_bugs($report_low); +my $vars_moderate_low = { + urlbase => Bugzilla->localconfig->urlbase, + report_week => $report_week, + sec_keywords => ['sec-moderate', 'sec-low'], + teams_moderate => $sorted_teams_moderate, + results_moderate => $report_moderate->results, + deltas_moderate => $report_moderate->deltas, + teams_low => $sorted_teams_low, + results_low => $report_low->results, + deltas_low => $report_low->deltas, + very_old_days => $report_low->very_old_days, + build_bugs_link => \&build_bugs_link, +}; +$template_moderate_low->process( + 'reports/email/security-risk-moderate-low.html.tmpl', + $vars_moderate_low, + \$html_moderate_low +) or ThrowTemplateError($template_moderate_low->error()); + +# Crit + High Report. For now, only send HTML email. +my @parts_crit_high = ( Email::MIME->create( attributes => { content_type => 'text/html', charset => 'UTF-8', encoding => 'quoted-printable', }, - body_str => $html, + body_str => $html_crit_high, ), map { Email::MIME->create( @@ -112,25 +152,50 @@ my @parts = ( name => "$_.png", encoding => 'base64', }, - body => $report->graphs->{$_}->slurp, + body => $report_crit_high->graphs->{$_}->slurp, ) - } sort { $a cmp $b } keys %{$report->graphs} + } sort { $a cmp $b } keys %{$report_crit_high->graphs} ); -my $email = Email::MIME->create( +my $email_crit_high = Email::MIME->create( header_str => [ From => Bugzilla->params->{'mailfrom'}, To => Bugzilla->params->{report_secbugs_emails}, Subject => "Security Bugs Report for $report_week", 'X-Bugzilla-Type' => 'admin', ], - parts => [@parts], + parts => [@parts_crit_high], ); -MessageToMTA($email); +MessageToMTA($email_crit_high); + +# Moderate + Low Report. For now, only send HTML email. +my @parts_moderate_low = ( + Email::MIME->create( + attributes => { + content_type => 'text/html', + charset => 'UTF-8', + encoding => 'quoted-printable', + }, + body_str => $html_moderate_low, + ) +); + +my $email_moderate_low = Email::MIME->create( + header_str => [ + From => Bugzilla->params->{'mailfrom'}, + To => Bugzilla->params->{report_secbugs_emails}, + Subject => "Security Bugs Report (moderate & low) for $report_week", + 'X-Bugzilla-Type' => 'admin', + ], + parts => [@parts_moderate_low], +); + +MessageToMTA($email_moderate_low); my $report_dump_file = path(bz_locations->{datadir}, "$year-$month-$day.dump"); -$report_dump_file->spurt(Dumper($report)); +$report_dump_file->spurt(Dumper($report_crit_high)); +# Don't dump moderate low sub build_bugs_link { my ($arr, $product) = @_; @@ -139,3 +204,13 @@ sub build_bugs_link { $uri->query_param(product => $product) if $product; return $uri->as_string; } + +sub sorted_team_names_by_open_bugs { + my ($report) = @_; + 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) + || $a cmp $b + } keys %$teams; + return \@sorted_team_names; +} diff --git a/template/en/default/reports/email/security-risk-moderate-low.html.tmpl b/template/en/default/reports/email/security-risk-moderate-low.html.tmpl new file mode 100644 index 000000000..d93df3292 --- /dev/null +++ b/template/en/default/reports/email/security-risk-moderate-low.html.tmpl @@ -0,0 +1,249 @@ +[%# This Source Code Form is subject to the terms of the Mozilla Public + # License, v. 2.0. If a copy of the MPL was not distributed with this + # file, You can obtain one at http://mozilla.org/MPL/2.0/. + # + # This Source Code Form is "Incompatible With Secondary Licenses", as + # defined by the Mozilla Public License, v. 2.0. + #%] + +[% PROCESS global/variables.none.tmpl %] + + + + + Security [% terms.Bugs %] Report for the week of [% report_week FILTER html %] + + + + +

Sec-Moderate by Team

+ + + + + + + [% FOREACH result IN results_moderate.reverse %] + [% NEXT IF loop.count < 2 %] + [% LAST IF loop.count > 4 %] + + [% END %] + + [% FOREACH team IN teams_moderate %] + + + + + + [% FOREACH result IN results_moderate.reverse %] + [% NEXT IF loop.count < 2 %] + [% LAST IF loop.count > 4 %] + + [% END %] + + [% END %] +
Team + Open
[% results_moderate.reverse.0.date.strftime('%m/%d') FILTER html %] +
Closed
Last Week
Added
Last Week
+ Open
[% result.date.strftime('%m/%d') FILTER html %] +
[% team FILTER html %] + [% IF results_moderate.reverse.0.bugs_by_team.$team.open.size %] + + [% results_moderate.reverse.0.bugs_by_team.$team.open.size FILTER html %] + + [% ELSE %] + 0 + [% END %] + + [% IF deltas_moderate.by_team.$team.closed.size %] + + -[% deltas_moderate.by_team.$team.closed.size FILTER html %] + + [% ELSE %] + 0 + [% END %] + + [% IF deltas_moderate.by_team.$team.added.size %] + + +[% deltas_moderate.by_team.$team.added.size FILTER html %] + + [% ELSE %] + 0 + [% END %] + + [% IF result.bugs_by_team.$team.open.size %] + + [% result.bugs_by_team.$team.open.size FILTER html %] + + [% ELSE %] + 0 + [% END %] +
+
+ +

Sec-Low by Team

+ + + + + + + [% FOREACH result IN results_low.reverse %] + [% NEXT IF loop.count < 2 %] + [% LAST IF loop.count > 4 %] + + [% END %] + + [% FOREACH team IN teams_low %] + + + + + + [% FOREACH result IN results_low.reverse %] + [% NEXT IF loop.count < 2 %] + [% LAST IF loop.count > 4 %] + + [% END %] + + [% END %] +
Team + Open
[% results_low.reverse.0.date.strftime('%m/%d') FILTER html %] +
Closed
Last Week
Added
Last Week
+ Open
[% result.date.strftime('%m/%d') FILTER html %] +
[% team FILTER html %] + [% IF results_low.reverse.0.bugs_by_team.$team.open.size %] + + [% results_low.reverse.0.bugs_by_team.$team.open.size FILTER html %] + + [% ELSE %] + 0 + [% END %] + + [% IF deltas_low.by_team.$team.closed.size %] + + -[% deltas_low.by_team.$team.closed.size FILTER html %] + + [% ELSE %] + 0 + [% END %] + + [% IF deltas_low.by_team.$team.added.size %] + + +[% deltas_low.by_team.$team.added.size FILTER html %] + + [% ELSE %] + 0 + [% END %] + + [% IF result.bugs_by_team.$team.open.size %] + + [% result.bugs_by_team.$team.open.size FILTER html %] + + [% ELSE %] + 0 + [% END %] +
+
+ +

[% terms.Bugs %] By Severity

+ + + + + + + + [% FOREACH result IN results_moderate.reverse %] + [% NEXT IF loop.count < 2 %] + [% LAST IF loop.count > 4 %] + + [% END %] + + [% FOREACH keyword IN sec_keywords %] + [% IF keyword == 'sec-moderate' %] + [% results = results_moderate %] + [% ELSIF keyword == 'sec-low' %] + [% results = results_low %] + [% END %] + + + + + + + [% FOREACH result IN results.reverse %] + [% NEXT IF loop.count < 2 %] + [% LAST IF loop.count > 4 %] + + [% END %] + + [% END %] +
Category + Open
[% results_moderate.reverse.0.date.strftime('%m/%d') FILTER html %] +
Closed
Last Week
Added
Last Week
+ Older than
[% very_old_days FILTER html %] Days
+
+ Open
[% result.date.strftime('%m/%d') FILTER html %] +
[% keyword FILTER html %] + [% IF results.reverse.0.bugs_by_sec_keyword.$keyword.open.size %] + + [% results.reverse.0.bugs_by_sec_keyword.$keyword.open.size FILTER html %] + + [% ELSE %] + 0 + [% END %] + + [% IF deltas.by_sec_keyword.$keyword.closed.size %] + + -[% deltas.by_sec_keyword.$keyword.closed.size FILTER html %] + + [% ELSE %] + 0 + [% END %] + + [% IF deltas.by_sec_keyword.$keyword.added.size %] + + +[% deltas.by_sec_keyword.$keyword.added.size FILTER html %] + + [% ELSE %] + 0 + [% END %] + + [% IF results.reverse.0.bugs_by_sec_keyword.$keyword.very_old_bugs.size %] + + [% results.reverse.0.bugs_by_sec_keyword.$keyword.very_old_bugs.size FILTER html %] + + [% ELSE %] + 0 + [% END %] + + [% IF result.bugs_by_sec_keyword.$keyword.open.size %] + + [% result.bugs_by_sec_keyword.$keyword.open.size FILTER html %] + + [% ELSE %] + 0 + [% END %] +
+ +

+To narrow down open [% terms.bugs %] click on the link and at the bottom of the search results use the +'Edit Search' functionality to filter by component and so on. This will filter only the open [% terms.bugs %] +counted in the report (as long as you do not modify the '[% terms.Bugs %] numbered' section of the search). +Keep in mind that you will only be able to see [% terms.bugs %] that you are allowed to see. Also keep in mind that +this report treats marking a [% terms.bug %] as 'stalled' the same as closing it. +

+ +

This report was generated from the live Bugzilla instance. In rare cases, historical statistics may vary from prior reports if [% terms.bugs %] were reclassified after those reports were generated.

+ + +