summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.gitignore2
-rw-r--r--.htaccess88
-rw-r--r--Bugzilla.pm27
-rw-r--r--Bugzilla/Config/General.pm8
-rw-r--r--Bugzilla/Constants.pm4
-rw-r--r--Bugzilla/Elastic/Role/HasClient.pm2
-rw-r--r--Bugzilla/Error/disabled0
-rw-r--r--Bugzilla/Group.pm29
-rw-r--r--Bugzilla/Install.pm40
-rw-r--r--Bugzilla/Install/DB.pm11
-rw-r--r--Bugzilla/Install/Filesystem.pm8
-rw-r--r--Bugzilla/PSGI.pm42
-rw-r--r--Bugzilla/Quantum/Plugin/BasicAuth.pm40
-rw-r--r--Bugzilla/Quantum/Plugin/Hostage.pm113
-rw-r--r--Bugzilla/Quantum/SES.pm414
-rw-r--r--Bugzilla/Search.pm26
-rw-r--r--Bugzilla/Template.pm2
-rwxr-xr-xMakefile.PL1
-rw-r--r--docs/en/rst/integrating/templates.rst2
-rwxr-xr-xeditusers.cgi3
-rwxr-xr-xenter_bug.cgi11
-rw-r--r--errors/401.html40
-rw-r--r--errors/403.html37
-rw-r--r--errors/404.html37
-rw-r--r--errors/500.html37
-rw-r--r--extensions/AntiSpam/lib/Config.pm2
-rw-r--r--extensions/BMO/Extension.pm39
-rwxr-xr-xextensions/BMO/bin/bug_1093952.pl2
-rwxr-xr-xextensions/BMO/bin/bug_1141452.pl2
-rwxr-xr-xextensions/BMO/bin/migrate-github-pull-requests.pl2
-rw-r--r--extensions/BMO/template/en/default/bug/create/create-mozpr.html.tmpl2
-rw-r--r--extensions/BMO/template/en/default/bug/create/create-poweredby.html.tmpl2
-rw-r--r--extensions/BMO/template/en/default/bug/create/create-web-bounty.html.tmpl2
-rw-r--r--extensions/BMO/template/en/default/bug/create/user-message.html.tmpl2
-rw-r--r--extensions/BMO/template/en/default/pages/bug-writing.html.tmpl2
-rw-r--r--extensions/BMO/template/en/default/pages/etiquette.html.tmpl2
-rw-r--r--extensions/BMO/template/en/default/pages/group_admins.html.tmpl2
-rw-r--r--extensions/BugModal/Extension.pm10
-rw-r--r--extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl2
-rw-r--r--extensions/BzAPI/Extension.pm9
-rw-r--r--extensions/ComponentWatching/Extension.pm6
-rw-r--r--extensions/ContributorEngagement/Extension.pm5
-rw-r--r--extensions/EditComments/Extension.pm4
-rw-r--r--extensions/FlagTypeComment/Extension.pm19
-rw-r--r--extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl2
-rw-r--r--extensions/MozProjectReview/disabled0
-rw-r--r--extensions/PhabBugz/disabled0
-rw-r--r--extensions/PhabBugz/lib/Util.pm2
-rw-r--r--extensions/Push/Config.pm6
-rw-r--r--extensions/Push/disabled0
-rw-r--r--extensions/Push/lib/Connector/TCL.pm353
-rw-r--r--extensions/RestrictComments/Extension.pm4
-rw-r--r--extensions/Review/Extension.pm8
-rwxr-xr-xextensions/Review/bin/migrate_mentor_from_whiteboard.pl2
-rw-r--r--extensions/Review/lib/WebService.pm2
-rw-r--r--extensions/SecureMail/Extension.pm5
-rw-r--r--extensions/TagNewUsers/Extension.pm15
-rwxr-xr-xextensions/TrackingFlags/bin/bug_825946.pl2
-rwxr-xr-xextensions/TrackingFlags/bin/bulk_flag_clear.pl2
-rw-r--r--extensions/TrackingFlags/disabled0
-rw-r--r--extensions/UserProfile/Extension.pm4
-rw-r--r--js/instant-search.js2
-rwxr-xr-xscripts/eject-users-from-groups.pl2
-rwxr-xr-xscripts/entrypoint.pl18
-rwxr-xr-xscripts/generate_bmo_data.pl6
-rwxr-xr-xscripts/move_os.pl2
-rwxr-xr-xscripts/movebugs.pl6
-rwxr-xr-xscripts/nagios_blocker_checker.pl2
-rwxr-xr-xscripts/remove_idle_group_members.pl2
-rwxr-xr-xscripts/reset_default_user.pl2
-rwxr-xr-xscripts/rewrite2mojo.pl70
-rw-r--r--t/bmo/comments.t4
-rw-r--r--t/docker.t4
-rw-r--r--template/en/default/account/prefs/account.html.tmpl2
-rw-r--r--template/en/default/attachment/create.html.tmpl2
-rw-r--r--template/en/default/bug/new_bug.html.tmpl6
-rw-r--r--template/en/default/global/variables.none.tmpl4
-rw-r--r--template/en/default/index.html.tmpl2
-rw-r--r--template/en/default/list/edit-multiple.html.tmpl1
-rw-r--r--template/en/default/list/table.html.tmpl8
-rw-r--r--template/en/default/search/search-google.html.tmpl2
-rw-r--r--template/en/default/search/search-instant.html.tmpl3
-rwxr-xr-xvotes.cgi3
83 files changed, 694 insertions, 1006 deletions
diff --git a/.gitignore b/.gitignore
index 18f2d0a17..7bf2816b9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -16,7 +16,9 @@
/data
/localconfig
/localconfig.*
+/conf/env.conf
/index.html
+/errors/
/error_reports
/.DS_Store
/template_cache
diff --git a/.htaccess b/.htaccess
deleted file mode 100644
index d9681baa6..000000000
--- a/.htaccess
+++ /dev/null
@@ -1,88 +0,0 @@
-# Don't allow people to retrieve non-cgi executable files or our private data
-<FilesMatch (\.pm|\.pl|\.tmpl|\.swf|localconfig.*|cpanfile)$>
- deny from all
-</FilesMatch>
-
-AddType image/x-icon .ico
-AddType application/font-woff .woff
-AddType application/font-woff2 .woff2
-
-Redirect permanent /queryhelp.cgi https://bugzilla.mozilla.org/query.cgi?format=advanced&help=1
-Redirect permanent /bug_status.html https://bugzilla.mozilla.org/page.cgi?id=fields.html
-Redirect permanent /bugwritinghelp.html https://bugzilla.mozilla.org/page.cgi?id=bug-writing.html
-Redirect permanent /etiquette.html https://bugzilla.mozilla.org/page.cgi?id=etiquette.html
-Redirect permanent /duplicates.html https://bugzilla.mozilla.org/duplicates.cgi
-Redirect permanent /quicksearch.html https://bugzilla.mozilla.org/page.cgi?id=quicksearch.html
-Redirect permanent /bugwritinghelp.html https://bugzilla.mozilla.org/page.cgi?id=bug-writing.html
-
-RewriteEngine On
-# This rewrite rule skips over the rest, which is good because the load balancers
-# might hit this file once a second and we want apache to not take much time.
-# Note that this file is generated by checksetup.pl
-RewriteRule ^__lbheartbeat__$ - [L]
-
-# allow cloud-services to identify the version we're running.
-# version.json is also generated by checksetup.pl
-RewriteRule ^__version__$ version.json [L]
-
-# Unlike lbheartbeat, this endpoint is called less frequently (every five minutes or so)
-# heartbeat.cgi returns 200 if the DB and memcached are both working, and 500 otherwise.
-RewriteRule ^__heartbeat__$ heartbeat.cgi [L]
-
-RewriteRule ^static/v\d{4}\d{2}\d{2}\.\d+/(.+\.(?:js|css|woff2?|png|jpe?g|gif|ico|svg))$ $1 [NC,E=IMMUTABLE:1,L]
-Header set Cache-Control "public, max-age=31536000" env=REDIRECT_IMMUTABLE
-
-RewriteRule ^robots\.txt$ robots.cgi [L]
-
-# New single page interface for filing bugs
-RewriteRule ^new[-_]bug$ new_bug.cgi [L,QSA]
-
-RewriteRule ^template_cache/ - [F,L,NC]
-RewriteRule ^template_cache.deleteme/ - [F,L,NC]
-RewriteRule ^review$ page.cgi?id=splinter.html$1 [QSA]
-RewriteRule ^user_?profile$ page.cgi?id=user_profile.html$1 [QSA]
-RewriteRule ^request_defer$ page.cgi?id=request_defer.html$1 [QSA]
-RewriteRule ^([0-9]+)$ show_bug.cgi?id=$1 [QSA]
-RewriteRule ^favicon\.ico$ extensions/BMO/web/images/favicon.ico
-RewriteRule ^form[\.:]itrequest$ enter_bug.cgi?product=Infrastructure+\%26+Operations&format=itrequest [QSA]
-RewriteRule ^form[\.:](mozlist|poweredby|presentation|trademark|recoverykey)$ enter_bug.cgi?product=mozilla.org&format=$1 [QSA]
-RewriteRule ^form[\.:]legal$ enter_bug.cgi?product=Legal&format=legal [QSA]
-RewriteRule ^form[\.:]recruiting$ enter_bug.cgi?product=Recruiting&format=recruiting [QSA]
-RewriteRule ^form[\.:]intern$ enter_bug.cgi?product=Recruiting&format=intern [QSA]
-RewriteRule ^form[\.:]mozpr$ enter_bug.cgi?product=Mozilla+PR&format=mozpr [QSA]
-RewriteRule ^form[\.:]reps[\.:]mentorship$ enter_bug.cgi?product=Mozilla+Reps&format=mozreps [QSA]
-RewriteRule ^form[\.:]reps[\.:]budget$ enter_bug.cgi?product=Mozilla+Reps&format=remo-budget [QSA]
-RewriteRule ^form[\.:]reps[\.:]swag$ enter_bug.cgi?product=Mozilla+Reps&format=remo-swag [QSA]
-RewriteRule ^form[\.:]reps[\.:]payment$ page.cgi?id=remo-form-payment.html [QSA]
-RewriteRule ^form[\.:]csa[\.:]discourse$ enter_bug.cgi?product=Infrastructure+\%26\+Operations&format=csa-discourse [QSA]
-RewriteRule ^form[\.:]employee[\.\-:]incident$ enter_bug.cgi?product=mozilla.org&format=employee-incident [QSA]
-RewriteRule ^form[\.:]brownbag$ https://air.mozilla.org/requests [QSA]
-RewriteRule ^form[\.:]finance$ enter_bug.cgi?product=Finance&format=finance [QSA]
-RewriteRule ^form[\.:]moz[\.\-:]project[\.\-:]review$ enter_bug.cgi?product=mozilla.org&format=moz-project-review [QSA]
-RewriteRule ^form[\.:]docs?$ enter_bug.cgi?product=Developer+Documentation&format=doc [QSA]
-RewriteRule ^form[\.:]mdn?$ enter_bug.cgi?product=developer.mozilla.org&format=mdn [QSA]
-RewriteRule ^form[\.:](swag|gear)$ enter_bug.cgi?product=Marketing&format=swag [QSA]
-RewriteRule ^form[\.:]costume$ enter_bug.cgi?product=Marketing&format=costume [QSA]
-RewriteRule ^form[\.:]ipp$ enter_bug.cgi?product=Internet+Public+Policy&format=ipp [QSA]
-RewriteRule ^form[\.:]creative$ enter_bug.cgi?product=Marketing&format=creative [QSA]
-RewriteRule ^form[\.:]user[\.\-:]engagement$ enter_bug.cgi?product=Marketing&format=user-engagement [QSA]
-RewriteRule ^form[\.:]dev[\.\-:]engagement[\.\-\:]event$ enter_bug.cgi?product=Developer+Engagement&format=dev-engagement-event [QSA]
-RewriteRule ^form[\.:]mobile[\.\-:]compat$ enter_bug.cgi?product=Tech+Evangelism&format=mobile-compat [QSA]
-RewriteRule ^form[\.:]web[\.:]bounty$ enter_bug.cgi?product=mozilla.org&format=web-bounty [QSA]
-RewriteRule ^form[\.:]automative$ enter_bug.cgi?product=Testing&format=automative [QSA]
-RewriteRule ^form[\.:]comm[\.:]newsletter$ enter_bug.cgi?product=Marketing&format=comm-newsletter [QSA]
-RewriteRule ^form[\.:]screen[\.:]share[\.:]whitelist$ enter_bug.cgi?product=Firefox&format=screen-share-whitelist [QSA]
-RewriteRule ^form[\.:]data[\.\-:]compliance$ enter_bug.cgi?product=Data+Compliance&format=data-compliance [QSA]
-RewriteRule ^form[\.:]fsa[\.:]budget$ enter_bug.cgi?product=FSA&format=fsa-budget [QSA]
-RewriteRule ^form[\.:]triage[\.\-]request$ page.cgi?id=triage_request.html [QSA]
-RewriteRule ^form[\.:](crm|CRM)$ enter_bug.cgi?product=Marketing&format=crm [QSA]
-RewriteRule ^form[\.:](ipc|IPC)$ https://airtable.com/shrcMqgbj1H9gXRlp [R,L]
-RewriteRule ^form[\.:]nda$ enter_bug.cgi?product=Legal&format=nda [QSA]
-RewriteRule ^form[\.:]name[\.:]clearance$ enter_bug.cgi?product=Legal&format=name-clearance [QSA]
-RewriteRule ^form[\.:]shield[\.:]studies$ enter_bug.cgi?product=Shield&format=shield-studies [QSA]
-RewriteRule ^form[\.:]client[\.:]bounty$ enter_bug.cgi?product=Firefox&format=client-bounty [QSA]
-RewriteRule ^rest - [E=HTTP_AUTHORIZATION:%{HTTP:Authorization}]
-RewriteRule ^rest/(.*)$ rest.cgi/$1 [NE]
-RewriteRule ^(?:latest|1\.2|1\.3)/(.*)$ extensions/BzAPI/bin/rest.cgi/$1 [NE]
-RewriteRule ^bzapi/(.*)$ extensions/BzAPI/bin/rest.cgi/$1 [NE]
-RewriteRule ^login$ index.cgi?GoAheadAndLogIn=1 [NE]
diff --git a/Bugzilla.pm b/Bugzilla.pm
index d8f13a3ad..1ea1e59a3 100644
--- a/Bugzilla.pm
+++ b/Bugzilla.pm
@@ -44,6 +44,7 @@ use File::Basename;
use File::Spec::Functions;
use Safe;
use JSON::XS qw(decode_json);
+use URI;
use Scope::Guard;
use parent qw(Bugzilla::CPAN);
@@ -122,6 +123,14 @@ sub template_inner {
}
sub extensions {
+ # Guard against extensions querying the extension list during initialization
+ # (through this method or has_extension).
+ # The extension list is not fully populated at that point,
+ # so the results would not be meaningful.
+ state $recursive = 0;
+ die "Recursive attempt to load/query extensions" if $recursive;
+ $recursive = 1;
+
my $cache = request_cache;
if (!$cache->{extensions}) {
my $extension_packages = Bugzilla::Extension->load_all();
@@ -134,9 +143,20 @@ sub extensions {
}
$cache->{extensions} = \@extensions;
}
+ $recursive = 0;
return $cache->{extensions};
}
+sub has_extension {
+ my ($class, $name) = @_;
+ my $cache = $class->request_cache;
+ if (!$cache->{extensions_hash}) {
+ my %extensions = map { $_->NAME => 1 } @{ Bugzilla->extensions };
+ $cache->{extensions_hash} = \%extensions;
+ }
+ return exists $cache->{extensions_hash}{$name};
+}
+
sub cgi {
return request_cache->{cgi} ||= Bugzilla::CGI->new;
}
@@ -161,6 +181,13 @@ sub localconfig {
return $_[0]->process_cache->{localconfig} ||= read_localconfig();
}
+sub urlbase {
+ my ($class) = @_;
+
+ # Since this could be modified, we have to return a new one every time.
+ return URI->new($class->localconfig->{urlbase});
+}
+
sub params {
return request_cache->{params} ||= Bugzilla::Config::read_param_file();
}
diff --git a/Bugzilla/Config/General.pm b/Bugzilla/Config/General.pm
index c870c7376..fa7cf2d08 100644
--- a/Bugzilla/Config/General.pm
+++ b/Bugzilla/Config/General.pm
@@ -25,6 +25,14 @@ use constant get_param_list => (
},
{
+ name => 'nobody_user',
+ type => 't',
+ no_reset => '1',
+ default => 'nobody@mozilla.org',
+ checker => \&check_email
+ },
+
+ {
name => 'docs_urlbase',
type => 't',
default => 'docs/%lang%/html/',
diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm
index d0b74b5e3..cd478c33e 100644
--- a/Bugzilla/Constants.pm
+++ b/Bugzilla/Constants.pm
@@ -196,6 +196,8 @@ use Memoize;
EMAIL_LIMIT_EXCEPTION
JOB_QUEUE_VIEW_MAX_JOBS
+
+ BZ_PERSISTENT
);
@Bugzilla::Constants::EXPORT_OK = qw(contenttypes);
@@ -700,6 +702,8 @@ sub _bz_locations {
};
}
+use constant BZ_PERSISTENT => $main::BUGZILLA_PERSISTENT;
+
# This makes us not re-compute all the bz_locations data every time it's
# called.
BEGIN { memoize('_bz_locations') };
diff --git a/Bugzilla/Elastic/Role/HasClient.pm b/Bugzilla/Elastic/Role/HasClient.pm
index 8e2687880..a971392e0 100644
--- a/Bugzilla/Elastic/Role/HasClient.pm
+++ b/Bugzilla/Elastic/Role/HasClient.pm
@@ -8,7 +8,6 @@ package Bugzilla::Elastic::Role::HasClient;
use 5.10.1;
use Moo::Role;
-use Search::Elasticsearch;
has 'client' => (is => 'lazy');
@@ -16,6 +15,7 @@ has 'client' => (is => 'lazy');
sub _build_client {
my ($self) = @_;
+ require Search::Elasticsearch;
return Search::Elasticsearch->new(
nodes => [ split(/\s+/, Bugzilla->params->{elasticsearch_nodes}) ],
cxn_pool => 'Sniff',
diff --git a/Bugzilla/Error/disabled b/Bugzilla/Error/disabled
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/Bugzilla/Error/disabled
diff --git a/Bugzilla/Group.pm b/Bugzilla/Group.pm
index c941482f0..7f684ea15 100644
--- a/Bugzilla/Group.pm
+++ b/Bugzilla/Group.pm
@@ -26,17 +26,24 @@ use Scalar::Util qw(blessed);
use constant IS_CONFIG => 1;
-use constant DB_COLUMNS => qw(
- groups.id
- groups.name
- groups.description
- groups.isbuggroup
- groups.userregexp
- groups.isactive
- groups.icon_url
- groups.owner_user_id
- groups.idle_member_removal
-);
+sub DB_COLUMNS {
+ my $class = shift;
+ my @columns = qw(
+ id
+ name
+ description
+ isbuggroup
+ userregexp
+ isactive
+ icon_url
+ owner_user_id
+ idle_member_removal
+ );
+ my $dbh = Bugzilla->dbh;
+ my $table = $class->DB_TABLE;
+
+ return map { "$table.$_" } grep { $dbh->bz_column_info($table, $_) } @columns;
+}
use constant DB_TABLE => 'groups';
diff --git a/Bugzilla/Install.pm b/Bugzilla/Install.pm
index 8bce9b5e7..c9935f34d 100644
--- a/Bugzilla/Install.pm
+++ b/Bugzilla/Install.pm
@@ -31,21 +31,31 @@ use Bugzilla::Util qw(get_text);
use Bugzilla::Version;
use constant STATUS_WORKFLOW => (
- [undef, 'UNCONFIRMED'],
- [undef, 'CONFIRMED'],
- [undef, 'IN_PROGRESS'],
- ['UNCONFIRMED', 'CONFIRMED'],
- ['UNCONFIRMED', 'IN_PROGRESS'],
- ['UNCONFIRMED', 'RESOLVED'],
- ['CONFIRMED', 'IN_PROGRESS'],
- ['CONFIRMED', 'RESOLVED'],
- ['IN_PROGRESS', 'CONFIRMED'],
- ['IN_PROGRESS', 'RESOLVED'],
- ['RESOLVED', 'UNCONFIRMED'],
- ['RESOLVED', 'CONFIRMED'],
- ['RESOLVED', 'VERIFIED'],
- ['VERIFIED', 'UNCONFIRMED'],
- ['VERIFIED', 'CONFIRMED'],
+ [ undef, 'UNCONFIRMED' ],
+ [ undef, 'NEW' ],
+ [ undef, 'ASSIGNED' ],
+ [ 'UNCONFIRMED', 'NEW' ],
+ [ 'UNCONFIRMED', 'ASSIGNED' ],
+ [ 'UNCONFIRMED', 'RESOLVED' ],
+ [ 'NEW', 'UNCONFIRMED' ],
+ [ 'NEW', 'ASSIGNED' ],
+ [ 'NEW', 'RESOLVED' ],
+ [ 'ASSIGNED', 'UNCONFIRMED' ],
+ [ 'ASSIGNED', 'NEW' ],
+ [ 'ASSIGNED', 'RESOLVED' ],
+ [ 'REOPENED', 'UNCONFIRMED' ],
+ [ 'REOPENED', 'NEW' ],
+ [ 'REOPENED', 'ASSIGNED' ],
+ [ 'REOPENED', 'RESOLVED' ],
+ [ 'RESOLVED', 'UNCONFIRMED' ],
+ [ 'RESOLVED', 'REOPENED' ],
+ [ 'RESOLVED', 'VERIFIED' ],
+ [ 'VERIFIED', 'UNCONFIRMED' ],
+ [ 'VERIFIED', 'REOPENED' ],
+ [ 'VERIFIED', 'RESOLVED' ],
+ [ 'CLOSED', 'UNCONFIRMED' ],
+ [ 'CLOSED', 'REOPENED' ],
+ [ 'CLOSED', 'RESOLVED' ],
);
sub SETTINGS {
diff --git a/Bugzilla/Install/DB.pm b/Bugzilla/Install/DB.pm
index 2e5ae5ff2..8b3d4b8cc 100644
--- a/Bugzilla/Install/DB.pm
+++ b/Bugzilla/Install/DB.pm
@@ -3908,7 +3908,16 @@ sub _migrate_group_owners {
my $dbh = Bugzilla->dbh;
return if $dbh->bz_column_info('groups', 'owner_user_id');
$dbh->bz_add_column('groups', 'owner_user_id', {TYPE => 'INT3'});
- my $nobody = Bugzilla::User->check('nobody@mozilla.org');
+ my $nobody = Bugzilla::User->new({ name => Bugzilla->params->{'nobody_user'}, cache => 1 });
+ unless ($nobody) {
+ $nobody = Bugzilla::User->create(
+ {
+ login_name => Bugzilla->params->{'nobody_user'},
+ realname => 'Nobody (ok to assign bugs to)',
+ cryptpassword => '*',
+ }
+ );
+ }
$dbh->do('UPDATE groups SET owner_user_id = ?', undef, $nobody->id);
}
diff --git a/Bugzilla/Install/Filesystem.pm b/Bugzilla/Install/Filesystem.pm
index 317152962..cb1b1ad15 100644
--- a/Bugzilla/Install/Filesystem.pm
+++ b/Bugzilla/Install/Filesystem.pm
@@ -164,6 +164,7 @@ sub FILESYSTEM {
# users to be able to cron them or otherwise run
# them as a secure user, like the webserver owner.
'*.cgi' => { perms => WS_EXECUTE },
+ '*.psgi' => { perms => CGI_READ },
'whineatnews.pl' => { perms => WS_EXECUTE },
'collectstats.pl' => { perms => WS_EXECUTE },
'importxml.pl' => { perms => WS_EXECUTE },
@@ -295,7 +296,7 @@ sub FILESYSTEM {
'contrib' => { files => OWNER_EXECUTE,
dirs => DIR_OWNER_WRITE, },
'scripts' => { files => OWNER_EXECUTE,
- dirs => DIR_OWNER_WRITE, },
+ dirs => DIR_WS_SERVE, },
);
# --- FILES TO CREATE --- #
@@ -379,6 +380,9 @@ sub FILESYSTEM {
contents => $yui3_all_css },
);
+ # Create static error pages.
+ $create_dirs{"errors"} = DIR_CGI_READ;
+
# Because checksetup controls the creation of index.html separately
# from all other files, it gets its very own hash.
my %index_html = (
@@ -464,7 +468,7 @@ sub update_filesystem {
# Delete old files that no longer need to exist
# 2001-04-29 jake@bugzilla.org - Remove oldemailtech
- # http://bugzilla.mozilla.org/show_bugs.cgi?id=71552
+ # http://bugzilla.mozilla.org/show_bug.cgi?id=71552
if (-d 'shadow') {
print "Removing shadow directory...\n";
rmtree("shadow");
diff --git a/Bugzilla/PSGI.pm b/Bugzilla/PSGI.pm
new file mode 100644
index 000000000..46352b319
--- /dev/null
+++ b/Bugzilla/PSGI.pm
@@ -0,0 +1,42 @@
+# 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.
+
+package Bugzilla::PSGI;
+use 5.10.1;
+use strict;
+use warnings;
+
+use base qw(Exporter);
+
+use Bugzilla::Logging;
+our @EXPORT_OK = qw(compile_cgi);
+
+sub compile_cgi {
+ my ($script) = @_;
+ require CGI::Compile;
+ require CGI::Emulate::PSGI;
+
+ my $cgi = CGI::Compile->compile($script);
+ my $app = CGI::Emulate::PSGI->handler(
+ sub {
+ Bugzilla::init_page();
+ $cgi->();
+ }
+ );
+ return sub {
+ my $env = shift;
+ if ($env->{'psgix.cleanup'}) {
+ push @{ $env->{'psgix.cleanup.handler'} }, \&Bugzilla::_cleanup;
+ }
+ my $res = $app->($env);
+ Bugzilla::_cleanup() if not $env->{'psgix.cleanup'};
+ return $res;
+ };
+}
+
+
+1; \ No newline at end of file
diff --git a/Bugzilla/Quantum/Plugin/BasicAuth.pm b/Bugzilla/Quantum/Plugin/BasicAuth.pm
new file mode 100644
index 000000000..e17273404
--- /dev/null
+++ b/Bugzilla/Quantum/Plugin/BasicAuth.pm
@@ -0,0 +1,40 @@
+# 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.
+package Bugzilla::Quantum::Plugin::BasicAuth;
+use 5.10.1;
+use Mojo::Base qw(Mojolicious::Plugin);
+
+use Bugzilla::Logging;
+use Carp;
+
+sub register {
+ my ( $self, $app, $conf ) = @_;
+
+ $app->renderer->add_helper(
+ basic_auth => sub {
+ my ( $c, $realm, $auth_user, $auth_pass ) = @_;
+ my $req = $c->req;
+ my ( $user, $password ) = $req->url->to_abs->userinfo =~ /^([^:]+):(.*)/;
+
+ unless ( $realm && $auth_user && $auth_pass ) {
+ croak 'basic_auth() called with missing parameters.';
+ }
+
+ unless ( $user eq $auth_user && $password eq $auth_pass ) {
+ WARN('username and password do not match');
+ $c->res->headers->www_authenticate("Basic realm=\"$realm\"");
+ $c->res->code(401);
+ $c->rendered;
+ return 0;
+ }
+
+ return 1;
+ }
+ );
+}
+
+1; \ No newline at end of file
diff --git a/Bugzilla/Quantum/Plugin/Hostage.pm b/Bugzilla/Quantum/Plugin/Hostage.pm
index 63fad2be2..418b09a0c 100644
--- a/Bugzilla/Quantum/Plugin/Hostage.pm
+++ b/Bugzilla/Quantum/Plugin/Hostage.pm
@@ -1,85 +1,80 @@
package Bugzilla::Quantum::Plugin::Hostage;
use 5.10.1;
use Mojo::Base 'Mojolicious::Plugin';
-use Bugzilla::Logging;
sub _attachment_root {
- my ($base) = @_;
- return undef unless $base;
- return $base =~ m{^https?://(?:bug)?\%bugid\%\.([a-zA-Z\.-]+)} ? $1 : undef;
+ my ($base) = @_;
+ return undef unless $base;
+ return $base =~ m{^https?://(?:bug)?\%bugid\%\.([a-zA-Z\.-]+)}
+ ? $1
+ : undef;
}
sub _attachment_host_regex {
- my ($base) = @_;
- return undef unless $base;
- my $val = $base;
- $val =~ s{^https?://}{}s;
- $val =~ s{/$}{}s;
- my $regex = quotemeta $val;
- $regex =~ s/\\\%bugid\\\%/\\d+/g;
- return qr/^$regex$/s;
+ my ($base) = @_;
+ return undef unless $base;
+ my $val = $base;
+ $val =~ s{^https?://}{}s;
+ $val =~ s{/$}{}s;
+ my $regex = quotemeta $val;
+ $regex =~ s/\\\%bugid\\\%/\\d+/g;
+ return qr/^$regex$/s;
}
sub register {
- my ($self, $app, $conf) = @_;
+ my ( $self, $app, $conf ) = @_;
- $app->hook(before_routes => \&_before_routes);
+ $app->hook(before_routes => \&_before_routes);
}
sub _before_routes {
- my ($c) = @_;
- state $urlbase = Bugzilla->localconfig->{urlbase};
- state $urlbase_uri = URI->new($urlbase);
- state $urlbase_host = $urlbase_uri->host;
- state $urlbase_host_regex = qr/^bug(\d+)\.\Q$urlbase_host\E$/;
- state $attachment_base = Bugzilla->localconfig->{attachment_base};
- state $attachment_root = _attachment_root($attachment_base);
- state $attachment_host_regex = _attachment_host_regex($attachment_base);
+ my ( $c ) = @_;
+ state $urlbase = Bugzilla->localconfig->{urlbase};
+ state $urlbase_uri = URI->new($urlbase);
+ state $urlbase_host = $urlbase_uri->host;
+ state $urlbase_host_regex = qr/^bug(\d+)\.\Q$urlbase_host\E$/;
+ state $attachment_base = Bugzilla->localconfig->{attachment_base};
+ state $attachment_root = _attachment_root($attachment_base);
+ state $attachment_host_regex = _attachment_host_regex($attachment_base);
- my $stash = $c->stash;
- my $req = $c->req;
- my $url = $req->url->to_abs;
+ my $stash = $c->stash;
+ my $req = $c->req;
+ my $url = $req->url->to_abs;
- return if $stash->{'mojo.static'};
+ return if $stash->{'mojo.static'};
- my $hostname = $url->host;
- return if $hostname eq $urlbase_host;
+ my $hostname = $url->host;
+ return if $hostname eq $urlbase_host;
- my $path = $url->path;
- return if $path eq '/__lbheartbeat__';
+ my $path = $url->path;
+ return if $path eq '/__lbheartbeat__';
- if ($attachment_base && $hostname eq $attachment_root) {
- DEBUG("redirecting to $urlbase because $hostname is $attachment_root");
- $c->redirect_to($urlbase);
- return;
- }
- elsif ($attachment_base && $hostname =~ $attachment_host_regex) {
- if ($path =~ m{^/attachment\.cgi}s) {
- return;
+ if ($attachment_base && $hostname eq $attachment_root) {
+ $c->redirect_to($urlbase);
+ return;
+ }
+ elsif ($attachment_base && $hostname =~ $attachment_host_regex) {
+ if ($path =~ m{^/attachment\.cgi}s) {
+ return;
+ } else {
+ my $new_uri = $url->clone;
+ $new_uri->scheme($urlbase_uri->scheme);
+ $new_uri->host($urlbase_host);
+ $c->redirect_to($new_uri);
+ return;
+ }
+ }
+ elsif (my ($id) = $hostname =~ $urlbase_host_regex) {
+ my $new_uri = $urlbase_uri->clone;
+ $new_uri->path('/show_bug.cgi');
+ $new_uri->query_form(id => $id);
+ $c->redirect_to($new_uri);
+ return;
}
else {
- my $new_uri = $url->clone;
- $new_uri->scheme($urlbase_uri->scheme);
- $new_uri->host($urlbase_host);
- DEBUG(
- "redirecting to $new_uri because $hostname matches attachment regex");
- $c->redirect_to($new_uri);
- return;
+ $c->redirect_to($urlbase);
+ return;
}
- }
- elsif (my ($id) = $hostname =~ $urlbase_host_regex) {
- my $new_uri = $urlbase_uri->clone;
- $new_uri->path('/show_bug.cgi');
- $new_uri->query_form(id => $id);
- DEBUG("redirecting to $new_uri because $hostname includes bug id");
- $c->redirect_to($new_uri);
- return;
- }
- else {
- DEBUG("redirecting to $urlbase because $hostname doesn't make sense");
- $c->redirect_to($urlbase);
- return;
- }
}
1;
diff --git a/Bugzilla/Quantum/SES.pm b/Bugzilla/Quantum/SES.pm
index 2d19de240..03916075d 100644
--- a/Bugzilla/Quantum/SES.pm
+++ b/Bugzilla/Quantum/SES.pm
@@ -1,5 +1,4 @@
package Bugzilla::Quantum::SES;
-
# 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/.
@@ -19,252 +18,237 @@ use JSON::MaybeXS qw(decode_json);
use LWP::UserAgent ();
use Try::Tiny qw(catch try);
-use Type::Library -base, -declare => qw(
- Self
- Notification NotificationType TypeField
- BounceNotification BouncedRecipients
- ComplaintNotification ComplainedRecipients
-);
-use Type::Utils -all;
-use Types::Standard -all;
-use Type::Params qw(compile);
-
-class_type Self, {class => __PACKAGE__};
-
-declare ComplainedRecipients,
- as ArrayRef [Dict [emailAddress => Str, slurpy Any]];
-declare ComplaintNotification,
- as Dict [
- complaint => Dict [
- complainedRecipients => ComplainedRecipients,
- complaintFeedbackType => Str,
- slurpy Any,
- ],
- slurpy Any,
- ];
-
-declare BouncedRecipients,
- as ArrayRef [
- Dict [
- emailAddress => Str,
- action => Optional [Str],
- diagnosticCode => Optional [Str],
- status => Optional [Str],
- slurpy Any,
- ],
- ];
-declare BounceNotification,
- as Dict [
- bounce => Dict [
- bouncedRecipients => BouncedRecipients,
- reportingMTA => Str,
- bounceSubType => Str,
- bounceType => Str,
- slurpy Any,
- ],
- slurpy Any,
- ];
-
-declare NotificationType, as Enum [qw( Bounce Complaint )];
-declare TypeField, as Enum [qw(eventType notificationType)];
-declare Notification,
- as Dict [
- eventType => Optional [NotificationType],
- notificationType => Optional [NotificationType],
- slurpy Any,
- ];
+use Types::Standard qw( :all );
+use Type::Utils;
+use Type::Params qw( compile );
+
+my $Invocant = class_type { class => __PACKAGE__ };
sub main {
- my ($self) = @_;
- try {
- $self->_main;
- }
- catch {
- FATAL("Error in SES Handler: ", $_);
- $self->_respond(400 => 'Bad Request');
- };
+ my ($self) = @_;
+ try {
+ $self->_main;
+ }
+ catch {
+ FATAL("Error in SES Handler: ", $_);
+ $self->_respond( 400 => 'Bad Request' );
+ };
}
sub _main {
- my ($self) = @_;
- Bugzilla->error_mode(ERROR_MODE_DIE);
- my $message = $self->_decode_json_wrapper($self->req->body) // return;
- my $message_type = $self->req->headers->header('X-Amz-SNS-Message-Type')
- // '(missing)';
-
- if ($message_type eq 'SubscriptionConfirmation') {
- $self->_confirm_subscription($message);
- }
-
- elsif ($message_type eq 'Notification') {
- my $notification = $self->_decode_json_wrapper($message->{Message})
- // return;
- unless (
-# https://docs.aws.amazon.com/ses/latest/DeveloperGuide/event-publishing-retrieving-sns-contents.html
- $self->_handle_notification($notification, 'eventType')
-
-# https://docs.aws.amazon.com/ses/latest/DeveloperGuide/notification-contents.html
- || $self->_handle_notification($notification, 'notificationType')
- )
- {
- WARN('Failed to find notification type');
- $self->_respond(400 => 'Bad Request');
+ my ($self) = @_;
+ Bugzilla->error_mode(ERROR_MODE_DIE);
+ my $message = $self->_decode_json_wrapper( $self->req->body ) // return;
+ my $message_type = $self->req->headers->header('X-Amz-SNS-Message-Type') // '(missing)';
+
+ if ( $message_type eq 'SubscriptionConfirmation' ) {
+ $self->_confirm_subscription($message);
+ }
+
+ elsif ( $message_type eq 'Notification' ) {
+ my $notification = $self->_decode_json_wrapper( $message->{Message} ) // return;
+ unless (
+ # https://docs.aws.amazon.com/ses/latest/DeveloperGuide/event-publishing-retrieving-sns-contents.html
+ $self->_handle_notification( $notification, 'eventType' )
+
+ # https://docs.aws.amazon.com/ses/latest/DeveloperGuide/notification-contents.html
+ || $self->_handle_notification( $notification, 'notificationType' )
+ )
+ {
+ WARN('Failed to find notification type');
+ $self->_respond( 400 => 'Bad Request' );
+ }
}
- }
- else {
- WARN("Unsupported message-type: $message_type");
- $self->_respond(200 => 'OK');
- }
+ else {
+ WARN("Unsupported message-type: $message_type");
+ $self->_respond( 200 => 'OK' );
+ }
}
sub _confirm_subscription {
- state $check = compile(Self, Dict [SubscribeURL => Str, slurpy Any]);
- my ($self, $message) = $check->(@_);
-
- my $subscribe_url = $message->{SubscribeURL};
- if (!$subscribe_url) {
- WARN('Bad SubscriptionConfirmation request: missing SubscribeURL');
- $self->_respond(400 => 'Bad Request');
- return;
- }
-
- my $ua = ua();
- my $res = $ua->get($message->{SubscribeURL});
- if (!$res->is_success) {
- WARN('Bad response from SubscribeURL: ' . $res->status_line);
- $self->_respond(400 => 'Bad Request');
- return;
- }
-
- $self->_respond(200 => 'OK');
+ state $check = compile($Invocant, Dict[SubscribeURL => Str, slurpy Any]);
+ my ($self, $message) = $check->(@_);
+
+ my $subscribe_url = $message->{SubscribeURL};
+ if ( !$subscribe_url ) {
+ WARN('Bad SubscriptionConfirmation request: missing SubscribeURL');
+ $self->_respond( 400 => 'Bad Request' );
+ return;
+ }
+
+ my $ua = ua();
+ my $res = $ua->get( $message->{SubscribeURL} );
+ if ( !$res->is_success ) {
+ WARN( 'Bad response from SubscribeURL: ' . $res->status_line );
+ $self->_respond( 400 => 'Bad Request' );
+ return;
+ }
+
+ $self->_respond( 200 => 'OK' );
}
+my $NotificationType = Enum [qw( Bounce Complaint )];
+my $TypeField = Enum [qw(eventType notificationType)];
+my $Notification = Dict [
+ eventType => Optional [$NotificationType],
+ notificationType => Optional [$NotificationType],
+ slurpy Any,
+];
+
sub _handle_notification {
- state $check = compile(Self, Notification, TypeField);
- my ($self, $notification, $type_field) = $check->(@_);
-
- if (!exists $notification->{$type_field}) {
- return 0;
- }
- my $type = $notification->{$type_field};
-
- if ($type eq 'Bounce') {
- $self->_process_bounce($notification);
- }
- elsif ($type eq 'Complaint') {
- $self->_process_complaint($notification);
- }
- else {
- WARN("Unsupported notification-type: $type");
- $self->_respond(200 => 'OK');
- }
- return 1;
-}
+ state $check = compile($Invocant, $Notification, $TypeField );
+ my ( $self, $notification, $type_field ) = $check->(@_);
-sub _process_bounce {
- state $check = compile(Self, BounceNotification);
- my ($self, $notification) = $check->(@_);
-
- # disable each account that is bouncing
- foreach my $recipient (@{$notification->{bounce}->{bouncedRecipients}}) {
- my $address = $recipient->{emailAddress};
- my $reason = sprintf '(%s) %s', $recipient->{action} // 'error',
- $recipient->{diagnosticCode} // 'unknown';
-
- my $user = Bugzilla::User->new({name => $address, cache => 1});
- if ($user) {
-
- # never auto-disable admin accounts
- if ($user->in_group('admin')) {
- Bugzilla->audit("ignoring bounce for admin <$address>: $reason");
- }
-
- else {
- my $template = Bugzilla->template_inner();
- my $vars = {
- mta => $notification->{bounce}->{reportingMTA} // 'unknown',
- reason => $reason,
- };
- my $disable_text;
- $template->process('admin/users/bounce-disabled.txt.tmpl',
- $vars, \$disable_text)
- || die $template->error();
-
- $user->set_disabledtext($disable_text);
- $user->set_disable_mail(1);
- $user->update();
- Bugzilla->audit(
- "bounce for <$address> disabled userid-" . $user->id . ": $reason");
- }
+ if ( !exists $notification->{$type_field} ) {
+ return 0;
}
+ my $type = $notification->{$type_field};
+ if ( $type eq 'Bounce' ) {
+ $self->_process_bounce($notification);
+ }
+ elsif ( $type eq 'Complaint' ) {
+ $self->_process_complaint($notification);
+ }
else {
- Bugzilla->audit("bounce for <$address> has no user: $reason");
+ WARN("Unsupported notification-type: $type");
+ $self->_respond( 200 => 'OK' );
+ }
+ return 1;
+}
+
+my $BouncedRecipients = ArrayRef[
+ Dict[
+ emailAddress => Str,
+ action => Str,
+ diagnosticCode => Str,
+ slurpy Any,
+ ],
+];
+my $BounceNotification = Dict [
+ bounce => Dict [
+ bouncedRecipients => $BouncedRecipients,
+ reportingMTA => Str,
+ bounceSubType => Str,
+ bounceType => Str,
+ slurpy Any,
+ ],
+ slurpy Any,
+];
+
+sub _process_bounce {
+ state $check = compile($Invocant, $BounceNotification);
+ my ($self, $notification) = $check->(@_);
+
+ # disable each account that is bouncing
+ foreach my $recipient ( @{ $notification->{bounce}->{bouncedRecipients} } ) {
+ my $address = $recipient->{emailAddress};
+ my $reason = sprintf '(%s) %s', $recipient->{action} // 'error', $recipient->{diagnosticCode} // 'unknown';
+
+ my $user = Bugzilla::User->new( { name => $address, cache => 1 } );
+ if ($user) {
+
+ # never auto-disable admin accounts
+ if ( $user->in_group('admin') ) {
+ Bugzilla->audit("ignoring bounce for admin <$address>: $reason");
+ }
+
+ else {
+ my $template = Bugzilla->template_inner();
+ my $vars = {
+ mta => $notification->{bounce}->{reportingMTA} // 'unknown',
+ reason => $reason,
+ };
+ my $disable_text;
+ $template->process( 'admin/users/bounce-disabled.txt.tmpl', $vars, \$disable_text )
+ || die $template->error();
+
+ $user->set_disabledtext($disable_text);
+ $user->set_disable_mail(1);
+ $user->update();
+ Bugzilla->audit( "bounce for <$address> disabled userid-" . $user->id . ": $reason" );
+ }
+ }
+
+ else {
+ Bugzilla->audit("bounce for <$address> has no user: $reason");
+ }
}
- }
- $self->_respond(200 => 'OK');
+ $self->_respond( 200 => 'OK' );
}
+my $ComplainedRecipients = ArrayRef[Dict[ emailAddress => Str, slurpy Any ]];
+my $ComplaintNotification = Dict[
+ complaint => Dict [
+ complainedRecipients => $ComplainedRecipients,
+ complaintFeedbackType => Str,
+ slurpy Any,
+ ],
+ slurpy Any,
+];
+
sub _process_complaint {
- state $check = compile(Self, ComplaintNotification);
- my ($self, $notification) = $check->(@_);
- my $template = Bugzilla->template_inner();
- my $json = JSON::MaybeXS->new(pretty => 1, utf8 => 1, canonical => 1,);
-
- foreach my $recipient (@{$notification->{complaint}->{complainedRecipients}})
- {
- my $reason = $notification->{complaint}->{complaintFeedbackType}
- // 'unknown';
- my $address = $recipient->{emailAddress};
- Bugzilla->audit("complaint for <$address> for '$reason'");
- my $vars = {
- email => $address,
- user => Bugzilla::User->new({name => $address, cache => 1}),
- reason => $reason,
- notification => $json->encode($notification),
- };
- my $message;
- $template->process('email/ses-complaint.txt.tmpl', $vars, \$message)
- || die $template->error();
- MessageToMTA($message);
- }
+ state $check = compile($Invocant, $ComplaintNotification);
+ my ($self, $notification) = $check->(@_);
+ my $template = Bugzilla->template_inner();
+ my $json = JSON::MaybeXS->new(
+ pretty => 1,
+ utf8 => 1,
+ canonical => 1,
+ );
+
+ foreach my $recipient ( @{ $notification->{complaint}->{complainedRecipients} } ) {
+ my $reason = $notification->{complaint}->{complaintFeedbackType} // 'unknown';
+ my $address = $recipient->{emailAddress};
+ Bugzilla->audit("complaint for <$address> for '$reason'");
+ my $vars = {
+ email => $address,
+ user => Bugzilla::User->new( { name => $address, cache => 1 } ),
+ reason => $reason,
+ notification => $json->encode($notification),
+ };
+ my $message;
+ $template->process( 'email/ses-complaint.txt.tmpl', $vars, \$message )
+ || die $template->error();
+ MessageToMTA($message);
+ }
- $self->_respond(200 => 'OK');
+ $self->_respond( 200 => 'OK' );
}
sub _respond {
- my ($self, $code, $message) = @_;
- $self->render(text => "$message\n", status => $code);
+ my ( $self, $code, $message ) = @_;
+ $self->render(text => "$message\n", status => $code);
}
sub _decode_json_wrapper {
- state $check = compile(Self, Str);
- my ($self, $json) = $check->(@_);
- my $result;
- my $ok = try {
- $result = decode_json($json);
- }
- catch {
- WARN('Malformed JSON from ' . $self->tx->remote_address);
- $self->_respond(400 => 'Bad Request');
- return undef;
- };
- return $ok ? $result : undef;
+ state $check = compile($Invocant, Str);
+ my ($self, $json) = $check->(@_);
+ my $result;
+ my $ok = try {
+ $result = decode_json($json);
+ }
+ catch {
+ WARN( 'Malformed JSON from ' . $self->tx->remote_address );
+ $self->_respond( 400 => 'Bad Request' );
+ return undef;
+ };
+ return $ok ? $result : undef;
}
sub ua {
- my $ua = LWP::UserAgent->new();
- $ua->timeout(10);
- $ua->protocols_allowed(['http', 'https']);
- if (my $proxy_url = Bugzilla->params->{'proxy_url'}) {
- $ua->proxy(['http', 'https'], $proxy_url);
- }
- else {
- $ua->env_proxy;
- }
- return $ua;
+ my $ua = LWP::UserAgent->new();
+ $ua->timeout(10);
+ $ua->protocols_allowed( [ 'http', 'https' ] );
+ if ( my $proxy_url = Bugzilla->params->{'proxy_url'} ) {
+ $ua->proxy( [ 'http', 'https' ], $proxy_url );
+ }
+ else {
+ $ua->env_proxy;
+ }
+ return $ua;
}
1;
diff --git a/Bugzilla/Search.pm b/Bugzilla/Search.pm
index f419955dc..e15c60f7f 100644
--- a/Bugzilla/Search.pm
+++ b/Bugzilla/Search.pm
@@ -802,18 +802,20 @@ sub data {
# BMO - to avoid massive amounts of joins, if we're selecting a lot of
# tracking flags, replace them with placeholders. the values will be
# retrieved later and injected into the result.
- my %tf_map = map { $_ => 1 } Bugzilla::Extension::TrackingFlags::Flag->get_all_names();
- my @tf_selected = grep { exists $tf_map{$_} } @orig_fields;
- # mysql has a limit of 61 joins, and we want to avoid massive amounts of joins
- # 30 ensures we won't hit the limit, nor generate too many joins
- if (scalar @tf_selected > 30) {
- foreach my $column (@tf_selected) {
- $self->COLUMNS->{$column}->{name} = "'---'";
+ if (Bugzilla->has_extension('TrackingFlags')) {
+ my %tf_map = map { $_ => 1 } Bugzilla::Extension::TrackingFlags::Flag->get_all_names();
+ my @tf_selected = grep { exists $tf_map{$_} } @orig_fields;
+ # mysql has a limit of 61 joins, and we want to avoid massive amounts of joins
+ # 30 ensures we won't hit the limit, nor generate too many joins
+ if (scalar @tf_selected > 30) {
+ foreach my $column (@tf_selected) {
+ $self->COLUMNS->{$column}->{name} = "'---'";
+ }
+ $self->{tracking_flags} = \@tf_selected;
+ }
+ else {
+ $self->{tracking_flags} = [];
}
- $self->{tracking_flags} = \@tf_selected;
- }
- else {
- $self->{tracking_flags} = [];
}
my $start_time = [gettimeofday()];
@@ -863,7 +865,7 @@ sub data {
$self->{data} = [map { $data{$_} } @$bug_ids];
# BMO - get tracking flags values, and insert into result
- if (@{ $self->{tracking_flags} }) {
+ if (Bugzilla->has_extension('TrackingFlags') && @{ $self->{tracking_flags} }) {
# read values
my $values;
$sql = "
diff --git a/Bugzilla/Template.pm b/Bugzilla/Template.pm
index c337b5af8..36435d637 100644
--- a/Bugzilla/Template.pm
+++ b/Bugzilla/Template.pm
@@ -995,6 +995,8 @@ sub create {
'feature_enabled' => sub { return Bugzilla->feature(@_); },
+ 'has_extension' => sub { return Bugzilla->has_extension(@_); },
+
# field_descs can be somewhat slow to generate, so we generate
# it only once per-language no matter how many times
# $template->process() is called.
diff --git a/Makefile.PL b/Makefile.PL
index 27a9e989e..f3772adf4 100755
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -411,6 +411,7 @@ META.json: Makefile.PL
\tmake distmeta 2>&1 /dev/null; mv */META.json .
META.yml: Makefile.PL
+1: hit EOF seeking end of quote/pattern starting at line 1 ending in /
\tmake distmeta 2>&1 /dev/null; mv */META.yml .
MAKE
}
diff --git a/docs/en/rst/integrating/templates.rst b/docs/en/rst/integrating/templates.rst
index e631b7364..e563d8179 100644
--- a/docs/en/rst/integrating/templates.rst
+++ b/docs/en/rst/integrating/templates.rst
@@ -262,7 +262,7 @@ customizing for your installation.
It needs a couple of lines of boilerplate at the top like this::
[% USE Bugzilla %]
- [% cgi = Bugzilla.cgi %
+ [% cgi = Bugzilla.cgi %]
Then, this template can reference the form fields you have created using
the syntax ``[% cgi.param("field_name") %]``. When a bug report is
diff --git a/editusers.cgi b/editusers.cgi
index d2ad3a82f..beb9b3a4c 100755
--- a/editusers.cgi
+++ b/editusers.cgi
@@ -32,8 +32,7 @@ my $dbh = Bugzilla->dbh;
my $userid = $user->id;
my $editusers = $user->in_group('editusers');
my $disableusers = $user->in_group('disableusers');
-
-local our $vars = {};
+local our $vars = {};
# Reject access if there is no sense in continuing.
$editusers
diff --git a/enter_bug.cgi b/enter_bug.cgi
index 33cdf8535..5b8a97dba 100755
--- a/enter_bug.cgi
+++ b/enter_bug.cgi
@@ -37,6 +37,8 @@ use Bugzilla::Field;
use Bugzilla::Status;
use Bugzilla::UserAgent;
+use List::Util qw(any);
+
my $user = Bugzilla->login(LOGIN_REQUIRED);
my $cloned_bug;
@@ -299,8 +301,13 @@ else {
$default{'bug_severity'} = formvalue('bug_severity', Bugzilla->params->{'defaultseverity'});
# BMO - use per-product default hw/os
- $default{'rep_platform'} = formvalue('rep_platform', $product->default_platform // detect_platform());
- $default{'op_sys'} = formvalue('op_sys', $product->default_op_sys // detect_op_sys());
+ if (any { $_->NAME eq 'BMO' } @{ Bugzilla->extensions }) {
+ $default{'rep_platform'} = formvalue('rep_platform', $product->default_platform // detect_platform());
+ $default{'op_sys'} = formvalue('op_sys', $product->default_op_sys // detect_op_sys());
+ } else {
+ $default{'rep_platform'} = formvalue('rep_platform', detect_platform());
+ $default{'op_sys'} = formvalue('op_sys', detect_op_sys());
+ }
$vars->{'rep_platform'} = detect_platform();
$vars->{'rep_op_sys'} = detect_op_sys();
diff --git a/errors/401.html b/errors/401.html
deleted file mode 100644
index 8242b549f..000000000
--- a/errors/401.html
+++ /dev/null
@@ -1,40 +0,0 @@
-<!DOCTYPE HTML>
-<html>
- <head>
- <title>Access Denied</title>
- <style>
- body {
- margin: 1em 2em;
- background-color: #455372;
- color: #ddd;
- font-family: sans-serif;
- }
- h1, h3 {
- color: #fff;
- }
- a {
- color: #fff;
- text-decoration: none;
- }
- #buggie {
- float: left;
- }
- #content {
- margin-left: 100px;
- padding-top: 20px;
- }
- </style>
- </head>
- <body>
- <img src="/images/buggie.png" id="buggie" alt="buggie" width="78" height="215">
- <div id="content">
- <h1>Authentication Required</h1>
- <p>This server could not verify that you are authorized to access
- that url. you either supplied the wrong credentials (e.g., bad
- password), or your browser doesn't understand how to supply the
- credentials required.</p>
- <h3>Error 401</h3>
- <p><a href="/">bugzilla.mozilla.org</a></p>
- </div>
- </body>
-</html>
diff --git a/errors/403.html b/errors/403.html
deleted file mode 100644
index e2faf8522..000000000
--- a/errors/403.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE HTML>
-<html>
- <head>
- <title>Access Denied</title>
- <style>
- body {
- margin: 1em 2em;
- background-color: #455372;
- color: #ddd;
- font-family: sans-serif;
- }
- h1, h3 {
- color: #fff;
- }
- a {
- color: #fff;
- text-decoration: none;
- }
- #buggie {
- float: left;
- }
- #content {
- margin-left: 100px;
- padding-top: 20px;
- }
- </style>
- </head>
- <body>
- <img src="/images/buggie.png" id="buggie" alt="buggie" width="78" height="215">
- <div id="content">
- <h1>Access Denied</h1>
- <p>Access to the requested resource has been denied.</p>
- <h3>Error 403</h3>
- <p><a href="/">bugzilla.mozilla.org</a></p>
- </div>
- </body>
-</html>
diff --git a/errors/404.html b/errors/404.html
deleted file mode 100644
index 3b476471c..000000000
--- a/errors/404.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE HTML>
-<html>
- <head>
- <title>Object Not Found</title>
- <style>
- body {
- margin: 1em 2em;
- background-color: #455372;
- color: #ddd;
- font-family: sans-serif;
- }
- h1, h3 {
- color: #fff;
- }
- a {
- color: #fff;
- text-decoration: none;
- }
- #buggie {
- float: left;
- }
- #content {
- margin-left: 100px;
- padding-top: 20px;
- }
- </style>
- </head>
- <body>
- <img src="/images/buggie.png" id="buggie" alt="buggie" width="78" height="215">
- <div id="content">
- <h1>Object Not Found</h1>
- <p>The requested URL was not found on this server.</p>
- <h3>Error 404</h3>
- <p><a href="/">bugzilla.mozilla.org</a></p>
- </div>
- </body>
-</html>
diff --git a/errors/500.html b/errors/500.html
deleted file mode 100644
index e0657001d..000000000
--- a/errors/500.html
+++ /dev/null
@@ -1,37 +0,0 @@
-<!DOCTYPE HTML>
-<html>
- <head>
- <title>Internal Server Error</title>
- <style>
- body {
- margin: 1em 2em;
- background-color: #455372;
- color: #ddd;
- font-family: sans-serif;
- }
- h1, h3 {
- color: #fff;
- }
- a {
- color: #fff;
- text-decoration: none;
- }
- #buggie {
- float: left;
- }
- #content {
- margin-left: 100px;
- padding-top: 20px;
- }
- </style>
- </head>
- <body>
- <img src="/images/buggie.png" id="buggie" alt="buggie" width="78" height="215">
- <div id="content">
- <h1>Internal Server Error</h1>
- <p>The server encountered an internal error and was unable to complete your request.</p>
- <h3>Error 500</h3>
- <p><a href="/">bugzilla.mozilla.org</a></p>
- </div>
- </body>
-</html>
diff --git a/extensions/AntiSpam/lib/Config.pm b/extensions/AntiSpam/lib/Config.pm
index e35a7f001..278baea8f 100644
--- a/extensions/AntiSpam/lib/Config.pm
+++ b/extensions/AntiSpam/lib/Config.pm
@@ -55,7 +55,7 @@ sub get_param_list {
"This account has been automatically disabled as a result of " .
"a high number of comments tagged as abusive.<br>\n<br>\n" .
"All interactions on Bugzilla should follow our " .
- "<a href=\"https://bugzilla.mozilla.org/page.cgi?id=etiquette.html\">" .
+ "<a href=\"" . Bugzilla->localconfig->{'urlbase'} . "page.cgi?id=etiquette.html\">" .
"etiquette guidelines</a>.<br>\n<br>\n" .
"Please contact the address at the end of this message if you " .
"believe this to be an error, or if you would like your account " .
diff --git a/extensions/BMO/Extension.pm b/extensions/BMO/Extension.pm
index 6c4ad2ef2..7499f0d1c 100644
--- a/extensions/BMO/Extension.pm
+++ b/extensions/BMO/Extension.pm
@@ -46,6 +46,7 @@ use Bugzilla::User;
use Bugzilla::UserAgent qw(detect_platform detect_op_sys);
use Bugzilla::User::Setting;
use Bugzilla::Util;
+use Bugzilla::PSGI qw(compile_cgi);
use Date::Parse;
use DateTime;
@@ -878,7 +879,7 @@ sub object_end_of_create {
# Add default searches to new user's footer
my $dbh = Bugzilla->dbh;
- my $sharer = Bugzilla::User->new({ name => 'nobody@mozilla.org' })
+ my $sharer = Bugzilla::User->new({ name => Bugzilla->params->{'nobody_user'} })
or return;
my $group = Bugzilla::Group->new({ name => 'everyone' })
or return;
@@ -919,7 +920,7 @@ sub _bug_reporters_hw_os {
sub _bug_is_unassigned {
my ($self) = @_;
my $assignee = $self->assigned_to->login;
- return $assignee eq 'nobody@mozilla.org' || $assignee =~ /\.bugs$/;
+ return $assignee eq Bugzilla->params->{'nobody_user'} || $assignee =~ /\.bugs$/;
}
sub _bug_has_current_patch {
@@ -1100,7 +1101,7 @@ sub object_start_of_update {
# and the assignee isn't a real person
return unless
- $new_bug->assigned_to->login eq 'nobody@mozilla.org'
+ $new_bug->assigned_to->login eq Bugzilla->params->{'nobody_user'}
|| $new_bug->assigned_to->login =~ /\.bugs$/;
# and the user can set the status to NEW
@@ -1527,15 +1528,15 @@ sub install_update_db {
"www.mozilla.org" => 'websites-security',
);
# 1. Set all to core-security by default
- my $core_sec_group = Bugzilla::Group->new({ name => 'core-security' });
+ my $core_sec_group = Bugzilla::Group->new({ name => Bugzilla->params->{insidergroup} });
$dbh->do("UPDATE products SET security_group_id = ?", undef, $core_sec_group->id);
# 2. Update the ones that have explicit security groups
foreach my $prod_name (keys %product_sec_groups) {
my $group_name = $product_sec_groups{$prod_name};
- next if $group_name eq 'core-security'; # already done
+ next if $group_name eq Bugzilla->params->{insidergroup}; # already done
my $group = Bugzilla::Group->new({ name => $group_name, cache => 1 });
if (!$group) {
- warn "Security group $group_name not found. Using core-security instead.\n";
+ warn "Security group $group_name not found. Using insider group instead.\n";
next;
}
$dbh->do("UPDATE products SET security_group_id = ? WHERE name = ?", undef, $group->id, $prod_name);
@@ -1595,7 +1596,7 @@ sub field_end_of_create {
my $name = $field->name;
if (Bugzilla->usage_mode == USAGE_MODE_CMDLINE) {
- Bugzilla->set_user(Bugzilla::User->check({ name => 'nobody@mozilla.org' }));
+ Bugzilla->set_user(Bugzilla::User->check({ name => Bugzilla->params->{'nobody_user'} }));
print "Creating IT permission grant bug for new field '$name'...";
}
@@ -1666,6 +1667,28 @@ sub webservice {
$dispatch->{BMO} = "Bugzilla::Extension::BMO::WebService";
}
+sub psgi_builder {
+ my ($self, $args) = @_;
+ my $mount = $args->{mount};
+
+ my $ses_index = Plack::Builder::builder(sub {
+ my $auth_user = Bugzilla->localconfig->{ses_username};
+ my $auth_pass = Bugzilla->localconfig->{ses_password};
+ Plack::Builder::enable("Auth::Basic", authenticator => sub {
+ my ($username, $password, $env) = @_;
+ return ( $auth_user
+ && $auth_pass
+ && $username
+ && $password
+ && $username eq $auth_user
+ && $password eq $auth_pass );
+ });
+ compile_cgi("ses/index.cgi");
+ });
+
+ $mount->{'ses/index.cgi'} = $ses_index;
+}
+
our $search_content_matches;
BEGIN {
$search_content_matches = \&Bugzilla::Search::_content_matches;
@@ -1951,7 +1974,7 @@ sub _post_employee_incident_bug {
my ($investigate_bug, $ssh_key_bug);
my $old_user = Bugzilla->user;
eval {
- Bugzilla->set_user(Bugzilla::User->new({ name => 'nobody@mozilla.org' }));
+ Bugzilla->set_user(Bugzilla::User->new({ name => Bugzilla->params->{'nobody_user'} }));
my $new_user = Bugzilla->user;
# HACK: User needs to be in the editbugs and primary bug's group to allow
diff --git a/extensions/BMO/bin/bug_1093952.pl b/extensions/BMO/bin/bug_1093952.pl
index 735c6a37a..fd891f4ae 100755
--- a/extensions/BMO/bin/bug_1093952.pl
+++ b/extensions/BMO/bin/bug_1093952.pl
@@ -52,7 +52,7 @@ printf "About to fix %s bugs\n", scalar(@$bugs);
print "Press <Ctrl-C> to stop or <Enter> to continue...\n";
getc();
-my $nobody = Bugzilla::User->check({ name => 'nobody@mozilla.org' });
+my $nobody = Bugzilla::User->check({ name => Bugzilla->params->{'nobody_user'} });
my $field = Bugzilla::Field->check({ name => 'status_whiteboard' });
my $when = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)');
diff --git a/extensions/BMO/bin/bug_1141452.pl b/extensions/BMO/bin/bug_1141452.pl
index 869593802..155c4704c 100755
--- a/extensions/BMO/bin/bug_1141452.pl
+++ b/extensions/BMO/bin/bug_1141452.pl
@@ -50,7 +50,7 @@ printf "About to fix %s bugs\n", scalar(@$flags);
print "Press <Ctrl-C> to stop or <Enter> to continue...\n";
getc();
-my $nobody = Bugzilla::User->check({ name => 'nobody@mozilla.org' });
+my $nobody = Bugzilla::User->check({ name => Bugzilla->params->{'nobody_user'} });
my $when = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)');
$dbh->bz_start_transaction();
diff --git a/extensions/BMO/bin/migrate-github-pull-requests.pl b/extensions/BMO/bin/migrate-github-pull-requests.pl
index 53c1727b5..c39778a4a 100755
--- a/extensions/BMO/bin/migrate-github-pull-requests.pl
+++ b/extensions/BMO/bin/migrate-github-pull-requests.pl
@@ -23,7 +23,7 @@ use Bugzilla::User;
use Bugzilla::Util qw(trim);
my $dbh = Bugzilla->dbh;
-my $nobody = Bugzilla::User->check({ name => 'nobody@mozilla.org' });
+my $nobody = Bugzilla::User->check({ name => Bugzilla->params->{'nobody_user'} });
my $field = Bugzilla::Field->check({ name => 'attachments.mimetype' });
# grab list of suitable attachments
diff --git a/extensions/BMO/template/en/default/bug/create/create-mozpr.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-mozpr.html.tmpl
index 697542ead..0bd1c94d7 100644
--- a/extensions/BMO/template/en/default/bug/create/create-mozpr.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/create-mozpr.html.tmpl
@@ -297,7 +297,7 @@ function validate_form() {
<input type="hidden" name="version" value="unspecified">
<input type="hidden" name="bug_severity" value="normal">
<input type="hidden" name="group" value="pr-private">
-<input type="hidden" name="assigned_to" id="assigned_to" value="nobody@mozilla.org">
+<input type="hidden" name="assigned_to" id="assigned_to" value="[% Param('nobody_user') FILTER html %]">
<input type="hidden" name="token" value="[% token FILTER html %]">
<div class="head">
diff --git a/extensions/BMO/template/en/default/bug/create/create-poweredby.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-poweredby.html.tmpl
index d6243c73b..9c0c4780d 100644
--- a/extensions/BMO/template/en/default/bug/create/create-poweredby.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/create-poweredby.html.tmpl
@@ -43,7 +43,7 @@ please provide some information about your application or product.</p>
<input type="hidden" name="priority" value="--">
<input type="hidden" name="op_sys" value="Other">
<input type="hidden" name="version" value="unspecified">
- <input type="hidden" name="assigned_to" value="nobody@mozilla.org">
+ <input type="hidden" name="assigned_to" value="[% Param('nobody_user') FILTER html %]">
<input type="hidden" name="cc" value="liz@mozilla.com">
<input type="hidden" name="groups" value="marketing-private">
<input type="hidden" name="token" value="[% token FILTER html %]">
diff --git a/extensions/BMO/template/en/default/bug/create/create-web-bounty.html.tmpl b/extensions/BMO/template/en/default/bug/create/create-web-bounty.html.tmpl
index 92517cb80..803f2a746 100644
--- a/extensions/BMO/template/en/default/bug/create/create-web-bounty.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/create-web-bounty.html.tmpl
@@ -88,7 +88,7 @@ function validateAndSubmit() {
<input type="hidden" name="token" value="[% token FILTER html %]">
<div class="head_desc">
- <a href="https://developer.mozilla.org/docs/Mozilla/QA/Bug_writing_guidelines">
+ <a href="[% terms.BugWritingGuidelinesURL %]">
[% terms.Bug %] writing guidelines</a>
</div>
diff --git a/extensions/BMO/template/en/default/bug/create/user-message.html.tmpl b/extensions/BMO/template/en/default/bug/create/user-message.html.tmpl
index 6ecd0bc75..d3c7412bf 100644
--- a/extensions/BMO/template/en/default/bug/create/user-message.html.tmpl
+++ b/extensions/BMO/template/en/default/bug/create/user-message.html.tmpl
@@ -17,7 +17,7 @@
[% END +%]
[% UNLESS no_bug_guidelines %]
Before reporting a [% terms.bug %], make sure you've read our
- <a href="https://developer.mozilla.org/docs/Mozilla/QA/Bug_writing_guidelines">
+ <a href="[% terms.BugWritingGuidelinesURL %]">
[% terms.bug %] writing guidelines</a> and double checked that your [% terms.bug %] hasn't already
been reported. Consult our list of <a href="https://bugzilla.mozilla.org/duplicates.cgi">
most frequently reported [% terms.bugs %]</a> and <a href="https://bugzilla.mozilla.org/query.cgi">
diff --git a/extensions/BMO/template/en/default/pages/bug-writing.html.tmpl b/extensions/BMO/template/en/default/pages/bug-writing.html.tmpl
index e1c67605f..dc253ee03 100644
--- a/extensions/BMO/template/en/default/pages/bug-writing.html.tmpl
+++ b/extensions/BMO/template/en/default/pages/bug-writing.html.tmpl
@@ -7,5 +7,5 @@
#%]
[% PROCESS global/redirect.html.tmpl
- url = "https://developer.mozilla.org/docs/Mozilla/QA/Bug_writing_guidelines"
+ url = terms.BugWritingGuidelinesURL
%]
diff --git a/extensions/BMO/template/en/default/pages/etiquette.html.tmpl b/extensions/BMO/template/en/default/pages/etiquette.html.tmpl
index 45dd5bd65..fe7d2cd3d 100644
--- a/extensions/BMO/template/en/default/pages/etiquette.html.tmpl
+++ b/extensions/BMO/template/en/default/pages/etiquette.html.tmpl
@@ -173,7 +173,7 @@
<h2>See Also</h2>
<p>
- <a href="https://developer.mozilla.org/docs/Mozilla/QA/Bug_writing_guidelines">The [% terms.Bug %] Writing Guidelines</a>.
+ <a href="[% terms.BugWritingGuidelinesURL %]">The [% terms.Bug %] Writing Guidelines</a>.
</p>
[% INCLUDE global/footer.html.tmpl %]
diff --git a/extensions/BMO/template/en/default/pages/group_admins.html.tmpl b/extensions/BMO/template/en/default/pages/group_admins.html.tmpl
index cfa3bd3ea..838a1e84a 100644
--- a/extensions/BMO/template/en/default/pages/group_admins.html.tmpl
+++ b/extensions/BMO/template/en/default/pages/group_admins.html.tmpl
@@ -39,7 +39,7 @@
[% group.name FILTER html %]</span>
</td>
<td nowrap>
- [% IF group.owner.login == 'nobody@mozilla.org' %]
+ [% IF group.owner.login == Param('nobody_user') %]
&ndash;
[% ELSE %]
[% INCLUDE global/user.html.tmpl who = group.owner %]
diff --git a/extensions/BugModal/Extension.pm b/extensions/BugModal/Extension.pm
index 1291fca21..ef9c93a37 100644
--- a/extensions/BugModal/Extension.pm
+++ b/extensions/BugModal/Extension.pm
@@ -188,10 +188,12 @@ sub template_before_process {
return if exists $bug->{error};
# trigger loading of tracking flags
- Bugzilla::Extension::TrackingFlags->template_before_process({
- file => 'bug/edit.html.tmpl',
- vars => $vars,
- });
+ if (Bugzilla->has_extension('TrackingFlags')) {
+ Bugzilla::Extension::TrackingFlags->template_before_process({
+ file => 'bug/edit.html.tmpl',
+ vars => $vars,
+ });
+ }
if (any { $bug->product eq $_ } READABLE_BUG_STATUS_PRODUCTS) {
my @flags = map { { name => $_->name, status => $_->status } } @{$bug->flags};
diff --git a/extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl b/extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl
index 099e06c5e..f4cc83c6e 100644
--- a/extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl
+++ b/extensions/BugModal/template/en/default/bug_modal/edit.html.tmpl
@@ -19,7 +19,7 @@
# these are used in a few places
is_cced = bug.cc.contains(user.login);
- unassigned = (bug.assigned_to.login == "nobody@mozilla.org")
+ unassigned = (bug.assigned_to.login == Param('nobody_user'))
|| (bug.assigned_to.login.search('\.bugs$'));
# custom fields that have custom rendering, or should not be rendered
diff --git a/extensions/BzAPI/Extension.pm b/extensions/BzAPI/Extension.pm
index d812a01c4..ac9502fcb 100644
--- a/extensions/BzAPI/Extension.pm
+++ b/extensions/BzAPI/Extension.pm
@@ -15,6 +15,7 @@ use base qw(Bugzilla::Extension);
use Bugzilla::Extension::BzAPI::Constants;
use Bugzilla::Extension::BzAPI::Util qw(fix_credentials filter_wants_nocache);
+use Bugzilla::PSGI qw(compile_cgi);
use Bugzilla::Error;
use Bugzilla::Util qw(trick_taint datetime_from);
@@ -189,6 +190,14 @@ sub webservice_status_code_map {
$status_code_map->{51} = STATUS_BAD_REQUEST;
}
+sub psgi_builder {
+ my ($self, $args) = @_;
+ my $mount = $args->{mount};
+
+ $mount->{'bzapi'} = compile_cgi('extensions/BzAPI/bin/rest.cgi');
+}
+
+
#####################
# Utility Functions #
#####################
diff --git a/extensions/ComponentWatching/Extension.pm b/extensions/ComponentWatching/Extension.pm
index 25155f90b..fdeedff98 100644
--- a/extensions/ComponentWatching/Extension.pm
+++ b/extensions/ComponentWatching/Extension.pm
@@ -23,7 +23,7 @@ use Bugzilla::Util qw(detaint_natural trim trick_taint);
our $VERSION = '2';
use constant REQUIRE_WATCH_USER => 1;
-use constant DEFAULT_ASSIGNEE => 'nobody@mozilla.org';
+use constant DEFAULT_ASSIGNEE => Bugzilla->params->{'nobody_user'};
use constant REL_COMPONENT_WATCHER => 15;
@@ -158,7 +158,9 @@ sub object_columns {
my $columns = $args->{columns};
return unless $class->isa('Bugzilla::Component');
- push(@$columns, 'watch_user');
+ if (Bugzilla->dbh->bz_column_info($class->DB_TABLE, 'watch_user')) {
+ push @$columns, 'watch_user';
+ }
}
sub object_update_columns {
diff --git a/extensions/ContributorEngagement/Extension.pm b/extensions/ContributorEngagement/Extension.pm
index 949517ecf..35eba24ab 100644
--- a/extensions/ContributorEngagement/Extension.pm
+++ b/extensions/ContributorEngagement/Extension.pm
@@ -70,7 +70,10 @@ sub object_columns {
my ($self, $args) = @_;
my ($class, $columns) = @$args{qw(class columns)};
if ($class->isa('Bugzilla::User')) {
- push(@$columns, 'first_patch_reviewed_id');
+ my $dbh = Bugzilla->dbh;
+ if ($dbh->bz_column_info($class->DB_TABLE, 'first_patch_reviewed_id')) {
+ push @$columns, 'first_patch_reviewed_id';
+ }
}
}
diff --git a/extensions/EditComments/Extension.pm b/extensions/EditComments/Extension.pm
index ab19ab6e7..e2ace3f23 100644
--- a/extensions/EditComments/Extension.pm
+++ b/extensions/EditComments/Extension.pm
@@ -191,7 +191,9 @@ sub object_columns {
my ($self, $args) = @_;
my ($class, $columns) = @$args{qw(class columns)};
if ($class->isa('Bugzilla::Comment')) {
- push(@$columns, 'edit_count');
+ if (Bugzilla->dbh->bz_column_info($class->DB_TABLE, 'edit_count')) {
+ push @$columns, 'edit_count';
+ }
}
}
diff --git a/extensions/FlagTypeComment/Extension.pm b/extensions/FlagTypeComment/Extension.pm
index 3ec506176..e7b34113d 100644
--- a/extensions/FlagTypeComment/Extension.pm
+++ b/extensions/FlagTypeComment/Extension.pm
@@ -127,13 +127,18 @@ sub _set_ftc_states {
'active_or_has_flags' => $bug->id,
});
- my $types = join(',', map { $_->id } @$flag_types);
- my $states = "'" . join("','", FLAGTYPE_COMMENT_STATES) . "'";
- $db_result = $dbh->selectall_arrayref(
- "SELECT type_id AS flagtype, on_status AS state, comment AS text
- FROM flagtype_comments
- WHERE type_id IN ($types) AND on_status IN ($states)",
- { Slice => {} });
+ if (@$flag_types) {
+ my $types = join(',', map { $_->id } @$flag_types);
+ my $states = "'" . join("','", FLAGTYPE_COMMENT_STATES) . "'";
+ $db_result = $dbh->selectall_arrayref(
+ "SELECT type_id AS flagtype, on_status AS state, comment AS text
+ FROM flagtype_comments
+ WHERE type_id IN ($types) AND on_status IN ($states)",
+ { Slice => {} });
+ }
+ else {
+ $db_result = [];
+ }
}
foreach my $row (@$db_result) {
diff --git a/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl b/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl
index 7e34e9920..07d814839 100644
--- a/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl
+++ b/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl
@@ -355,7 +355,7 @@ Product: <b><span id="dupes_product_name">?</span></b>:
<ul>
<li>Please fill out this form clearly, precisely and in as much detail as you can manage.</li>
<li>Please report only a single problem at a time.</li>
-<li><a href="https://developer.mozilla.org/docs/Mozilla/QA/Bug_writing_guidelines" target="_blank" rel="noopener noreferrer">These guidelines</a>
+<li><a href="[% terms.BugWritingGuidelinesURL %]" target="_blank" rel="noopener noreferrer">These guidelines</a>
explain how to write effective [% terms.bug %] reports.</li>
</ul>
diff --git a/extensions/MozProjectReview/disabled b/extensions/MozProjectReview/disabled
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/extensions/MozProjectReview/disabled
diff --git a/extensions/PhabBugz/disabled b/extensions/PhabBugz/disabled
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/extensions/PhabBugz/disabled
diff --git a/extensions/PhabBugz/lib/Util.pm b/extensions/PhabBugz/lib/Util.pm
index 67b29f27c..32f860413 100644
--- a/extensions/PhabBugz/lib/Util.pm
+++ b/extensions/PhabBugz/lib/Util.pm
@@ -101,7 +101,7 @@ sub get_bug_role_phids {
my @bug_users = ( $bug->reporter );
push(@bug_users, $bug->assigned_to)
- if $bug->assigned_to->email !~ /^nobody\@mozilla\.org$/;
+ if $bug->assigned_to->email != Bugzilla->params->{'nobody_user'};
push(@bug_users, $bug->qa_contact) if $bug->qa_contact;
push(@bug_users, @{ $bug->cc_users }) if @{ $bug->cc_users };
diff --git a/extensions/Push/Config.pm b/extensions/Push/Config.pm
index 860e31a23..59b78d5a2 100644
--- a/extensions/Push/Config.pm
+++ b/extensions/Push/Config.pm
@@ -42,12 +42,6 @@ use constant REQUIRED_MODULES => [
];
use constant OPTIONAL_MODULES => [
- # connectors need the ability to extend this
- {
- package => 'Net-SFTP',
- module => 'Net::SFTP',
- version => '0'
- },
{
package => 'XML-Simple',
module => 'XML::Simple',
diff --git a/extensions/Push/disabled b/extensions/Push/disabled
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/extensions/Push/disabled
diff --git a/extensions/Push/lib/Connector/TCL.pm b/extensions/Push/lib/Connector/TCL.pm
deleted file mode 100644
index f5b430e47..000000000
--- a/extensions/Push/lib/Connector/TCL.pm
+++ /dev/null
@@ -1,353 +0,0 @@
-# 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.
-
-package Bugzilla::Extension::Push::Connector::TCL;
-
-use 5.10.1;
-use strict;
-use warnings;
-
-use base 'Bugzilla::Extension::Push::Connector::Base';
-
-use Bugzilla::Constants;
-use Bugzilla::Extension::Push::Constants;
-use Bugzilla::Extension::Push::Serialise;
-use Bugzilla::Extension::Push::Util;
-use Bugzilla::User;
-use Bugzilla::Attachment;
-
-use Digest::MD5 qw(md5_hex);
-use Encode qw(encode_utf8);
-
-sub options {
- return (
- {
- name => 'tcl_user',
- label => 'Bugzilla TCL User',
- type => 'string',
- default => 'tcl@bugzilla.tld',
- required => 1,
- validate => sub {
- Bugzilla::User->new({ name => $_[0] })
- || die "Invalid Bugzilla user ($_[0])\n";
- },
- },
- {
- name => 'sftp_host',
- label => 'SFTP Host',
- type => 'string',
- default => '',
- required => 1,
- },
- {
- name => 'sftp_port',
- label => 'SFTP Port',
- type => 'string',
- default => '22',
- required => 1,
- validate => sub {
- $_[0] =~ /\D/ && die "SFTP Port must be an integer\n";
- },
- },
- {
- name => 'sftp_user',
- label => 'SFTP Username',
- type => 'string',
- default => '',
- required => 1,
- },
- {
- name => 'sftp_pass',
- label => 'SFTP Password',
- type => 'password',
- default => '',
- required => 1,
- },
- {
- name => 'sftp_remote_path',
- label => 'SFTP Remote Path',
- type => 'string',
- default => '',
- required => 0,
- },
- );
-}
-
-my $_instance;
-
-sub init {
- my ($self) = @_;
- $_instance = $self;
-}
-
-sub load_config {
- my ($self) = @_;
- $self->SUPER::load_config(@_);
-}
-
-sub should_send {
- my ($self, $message) = @_;
-
- my $data = $message->payload_decoded;
- my $bug_data = $self->_get_bug_data($data)
- || return 0;
-
- # sanity check user
- $self->{tcl_user} ||= Bugzilla::User->new({ name => $self->config->{tcl_user} });
- if (!$self->{tcl_user} || !$self->{tcl_user}->is_enabled) {
- return 0;
- }
-
- # only send bugs created by the tcl user
- unless ($bug_data->{reporter}->{id} == $self->{tcl_user}->id) {
- return 0;
- }
-
- # don't push changes made by the tcl user
- if ($data->{event}->{user}->{id} == $self->{tcl_user}->id) {
- return 0;
- }
-
- # send comments
- if ($data->{event}->{routing_key} eq 'comment.create') {
- return 0 if $data->{comment}->{is_private};
- return 1;
- }
-
- # send status and resolution updates
- foreach my $change (@{ $data->{event}->{changes} }) {
- return 1 if $change->{field} eq 'bug_status'
- || $change->{field} eq 'resolution'
- || $change->{field} eq 'cf_blocking_b2g';
- }
-
- # send attachments
- if ($data->{event}->{routing_key} =~ /^attachment\./) {
- return 0 if $data->{attachment}->{is_private};
- return 1;
- }
-
- # and nothing else
- return 0;
-}
-
-sub send {
- my ($self, $message) = @_;
- my $logger = Bugzilla->push_ext->logger;
- my $config = $self->config;
-
- require XML::Simple;
- require Net::SFTP;
-
- $self->{tcl_user} ||= Bugzilla::User->new({ name => $self->config->{tcl_user} });
- if (!$self->{tcl_user}) {
- return (PUSH_RESULT_TRANSIENT, "Invalid bugzilla-user (" . $self->config->{tcl_user} . ")");
- }
-
- # load the bug
- my $data = $message->payload_decoded;
- my $bug_data = $self->_get_bug_data($data);
-
- # build payload
- my $attachment;
- my %xml = (
- Mozilla_ID => $bug_data->{id},
- When => $data->{event}->{time},
- Who => $data->{event}->{user}->{login},
- Status => $bug_data->{status}->{name},
- Resolution => $bug_data->{resolution},
- Blocking_B2G => $bug_data->{cf_blocking_b2g},
- );
- if ($data->{event}->{routing_key} eq 'comment.create') {
- $xml{Comment} = $data->{comment}->{body};
- } elsif ($data->{event}->{routing_key} =~ /^attachment\.(\w+)/) {
- my $is_update = $1 eq 'modify';
- if (!$is_update) {
- $attachment = Bugzilla::Attachment->new($data->{attachment}->{id});
- }
- $xml{Attach} = {
- Attach_ID => $data->{attachment}->{id},
- Filename => $data->{attachment}->{file_name},
- Description => $data->{attachment}->{description},
- ContentType => $data->{attachment}->{content_type},
- IsPatch => $data->{attachment}->{is_patch} ? 'true' : 'false',
- IsObsolete => $data->{attachment}->{is_obsolete} ? 'true' : 'false',
- IsUpdate => $is_update ? 'true' : 'false',
- };
- }
-
- # convert to xml
- my $xml = XML::Simple::XMLout(
- \%xml,
- NoAttr => 1,
- RootName => 'sync',
- XMLDecl => 1,
- );
- $xml = encode_utf8($xml);
-
- # generate md5
- my $md5 = md5_hex($xml);
-
- # build filename
- my ($sec, $min, $hour, $day, $mon, $year) = localtime(time);
- my $change_set = $data->{event}->{change_set};
- $change_set =~ s/\.//g;
- my $filename = sprintf(
- '%04s%02d%02d%02d%02d%02d%s',
- $year + 1900,
- $mon + 1,
- $day,
- $hour,
- $min,
- $sec,
- $change_set,
- );
-
- # create temp files;
- my $temp_dir = File::Temp::Directory->new();
- my $local_dir = $temp_dir->dirname;
- _write_file("$local_dir/$filename.sync", $xml);
- _write_file("$local_dir/$filename.sync.check", $md5);
- _write_file("$local_dir/$filename.done", '');
- if ($attachment) {
- _write_file("$local_dir/$filename.sync.attach", $attachment->data);
- }
-
- my $remote_dir = $self->config->{sftp_remote_path} eq ''
- ? ''
- : $self->config->{sftp_remote_path} . '/';
-
- # send files via sftp
- $logger->debug("Connecting to " . $self->config->{sftp_host} . ":" . $self->config->{sftp_port});
- my $sftp = Net::SFTP->new(
- $self->config->{sftp_host},
- ssh_args => {
- port => $self->config->{sftp_port},
- },
- user => $self->config->{sftp_user},
- password => $self->config->{sftp_pass},
- );
-
- $logger->debug("Uploading $local_dir/$filename.sync");
- $sftp->put("$local_dir/$filename.sync", "$remote_dir$filename.sync")
- or return (PUSH_RESULT_ERROR, "Failed to upload $local_dir/$filename.sync");
-
- $logger->debug("Uploading $local_dir/$filename.sync.check");
- $sftp->put("$local_dir/$filename.sync.check", "$remote_dir$filename.sync.check")
- or return (PUSH_RESULT_ERROR, "Failed to upload $local_dir/$filename.sync.check");
-
- if ($attachment) {
- $logger->debug("Uploading $local_dir/$filename.sync.attach");
- $sftp->put("$local_dir/$filename.sync.attach", "$remote_dir$filename.sync.attach")
- or return (PUSH_RESULT_ERROR, "Failed to upload $local_dir/$filename.sync.attach");
- }
-
- $logger->debug("Uploading $local_dir/$filename.done");
- $sftp->put("$local_dir/$filename.done", "$remote_dir$filename.done")
- or return (PUSH_RESULT_ERROR, "Failed to upload $local_dir/$filename.done");
-
- # success
- return (PUSH_RESULT_OK, "uploaded $filename.sync");
-}
-
-sub _get_bug_data {
- my ($self, $data) = @_;
- my $target = $data->{event}->{target};
- if ($target eq 'bug') {
- return $data->{bug};
- } elsif (exists $data->{$target}->{bug}) {
- return $data->{$target}->{bug};
- } else {
- return;
- }
-}
-
-sub _write_file {
- my ($filename, $content) = @_;
- open(my $fh, ">", $filename) or die "Failed to write to $filename: $!\n";
- binmode($fh);
- print $fh $content;
- close($fh) or die "Failed to write to $filename: $!\n";
-}
-
-1;
-
-# File::Temp->newdir() requires a newer version of File::Temp than we have on
-# production, so here's a small inline package which performs the same task.
-
-package File::Temp::Directory;
-
-use strict;
-use warnings;
-
-use File::Temp;
-use File::Path qw(rmtree);
-use File::Spec;
-
-my @chars;
-
-sub new {
- my ($class) = @_;
- my $self = {};
- bless($self, $class);
-
- @chars = qw/ A B C D E F G H I J K L M N O P Q R S T U V W X Y Z
- a b c d e f g h i j k l m n o p q r s t u v w x y z
- 0 1 2 3 4 5 6 7 8 9 _
- /;
-
- $self->{TEMPLATE} = File::Spec->catdir(File::Spec->tmpdir, 'X' x 10);
- $self->{DIRNAME} = $self->_mktemp();
- return $self;
-}
-
-sub _mktemp {
- my ($self) = @_;
- my $path = $self->_random_name();
- while(1) {
- if (mkdir($path, 0700)) {
- # in case of odd umask
- chmod(0700, $path);
- return $path;
- } else {
- # abort with error if the reason for failure was anything except eexist
- die "Could not create directory $path: $!\n" unless ($!{EEXIST});
- # loop round for another try
- }
- $path = $self->_random_name();
- }
-
- return $path;
-}
-
-sub _random_name {
- my ($self) = @_;
- my $path = $self->{TEMPLATE};
- $path =~ s/X/$chars[int(rand(@chars))]/ge;
- return $path;
-}
-
-sub dirname {
- my ($self) = @_;
- return $self->{DIRNAME};
-}
-
-sub DESTROY {
- my ($self) = @_;
- local($., $@, $!, $^E, $?);
- if (-d $self->{DIRNAME}) {
- # Some versions of rmtree will abort if you attempt to remove the
- # directory you are sitting in. We protect that and turn it into a
- # warning. We do this because this occurs during object destruction and
- # so can not be caught by the user.
- eval { rmtree($self->{DIRNAME}, 0, 0); };
- warn $@ if ($@ && $^W);
- }
-}
-
-1;
-
diff --git a/extensions/RestrictComments/Extension.pm b/extensions/RestrictComments/Extension.pm
index 213a1c44a..e93540d5a 100644
--- a/extensions/RestrictComments/Extension.pm
+++ b/extensions/RestrictComments/Extension.pm
@@ -68,7 +68,9 @@ sub object_columns {
my ($self, $args) = @_;
my ($class, $columns) = @$args{qw(class columns)};
if ($class->isa('Bugzilla::Bug')) {
- push(@$columns, 'restrict_comments');
+ if (Bugzilla->dbh->bz_column_info($class->DB_TABLE, 'restrict_comments')) {
+ push @$columns, 'restrict_comments';
+ }
}
}
diff --git a/extensions/Review/Extension.pm b/extensions/Review/Extension.pm
index 406c29c7c..a918a5ca5 100644
--- a/extensions/Review/Extension.pm
+++ b/extensions/Review/Extension.pm
@@ -286,10 +286,14 @@ sub object_columns {
my ($self, $args) = @_;
my ($class, $columns) = @$args{qw(class columns)};
if ($class->isa('Bugzilla::Product')) {
- push @$columns, 'reviewer_required';
+ my $dbh = Bugzilla->dbh;
+ my @new_columns = qw(reviewer_required);
+ push @$columns, grep { $dbh->bz_column_info($class->DB_TABLE, $_) } @new_columns;
}
elsif ($class->isa('Bugzilla::User')) {
- push @$columns, qw(review_request_count feedback_request_count needinfo_request_count);
+ my $dbh = Bugzilla->dbh;
+ my @new_columns = qw(review_request_count feedback_request_count needinfo_request_count);
+ push @$columns, grep { $dbh->bz_column_info($class->DB_TABLE, $_) } @new_columns;
}
}
diff --git a/extensions/Review/bin/migrate_mentor_from_whiteboard.pl b/extensions/Review/bin/migrate_mentor_from_whiteboard.pl
index c6b69006f..debf173a7 100755
--- a/extensions/Review/bin/migrate_mentor_from_whiteboard.pl
+++ b/extensions/Review/bin/migrate_mentor_from_whiteboard.pl
@@ -36,7 +36,7 @@ EOF
<>;
# we need to be logged in to do user searching and update bugs
-my $nobody = Bugzilla::User->check({ name => 'nobody@mozilla.org' });
+my $nobody = Bugzilla::User->check({ name => Bugzilla->params->{'nobody_user'} });
$nobody->{groups} = [ Bugzilla::Group->get_all ];
Bugzilla->set_user($nobody);
diff --git a/extensions/Review/lib/WebService.pm b/extensions/Review/lib/WebService.pm
index 3f6816916..0c54d725a 100644
--- a/extensions/Review/lib/WebService.pm
+++ b/extensions/Review/lib/WebService.pm
@@ -51,7 +51,7 @@ sub suggestions {
# we always need to be authentiated to perform user matching
my $user = Bugzilla->user;
if (!$user->id) {
- Bugzilla->set_user(Bugzilla::User->check({ name => 'nobody@mozilla.org' }));
+ Bugzilla->set_user(Bugzilla::User->check({ name => Bugzilla->params->{'nobody_user'} }));
push @reviewers, @{ $bug->mentors };
Bugzilla->set_user($user);
} else {
diff --git a/extensions/SecureMail/Extension.pm b/extensions/SecureMail/Extension.pm
index 508b1f5e8..2b5e1bdd6 100644
--- a/extensions/SecureMail/Extension.pm
+++ b/extensions/SecureMail/Extension.pm
@@ -104,7 +104,10 @@ sub object_columns {
my $columns = $args->{'columns'};
if ($class->isa('Bugzilla::Group')) {
- push(@$columns, 'secure_mail');
+ my $dbh = Bugzilla->dbh;
+ if ($dbh->bz_column_info($class->DB_TABLE, 'secure_mail')) {
+ push @$columns, 'secure_mail';
+ }
}
}
diff --git a/extensions/TagNewUsers/Extension.pm b/extensions/TagNewUsers/Extension.pm
index b94873979..1810f204f 100644
--- a/extensions/TagNewUsers/Extension.pm
+++ b/extensions/TagNewUsers/Extension.pm
@@ -123,7 +123,9 @@ sub object_columns {
my ($self, $args) = @_;
my ($class, $columns) = @$args{qw(class columns)};
if ($class->isa('Bugzilla::User')) {
- push(@$columns, qw(comment_count creation_ts first_patch_bug_id));
+ my $dbh = Bugzilla->dbh;
+ my @new_columns = qw(comment_count creation_ts first_patch_bug_id);
+ push @$columns, grep { $dbh->bz_column_info($class->DB_TABLE, $_) } @new_columns;
}
}
@@ -131,9 +133,14 @@ sub object_before_create {
my ($self, $args) = @_;
my ($class, $params) = @$args{qw(class params)};
if ($class->isa('Bugzilla::User')) {
- my ($timestamp) = Bugzilla->dbh->selectrow_array("SELECT NOW()");
- $params->{comment_count} = 0;
- $params->{creation_ts} = $timestamp;
+ my $dbh = Bugzilla->dbh;
+ my ($timestamp) = $dbh->selectrow_array("SELECT NOW()");
+ if ($dbh->bz_column_info($class->DB_TABLE, 'comment_count')) {
+ $params->{comment_count} = 0;
+ }
+ if ($dbh->bz_column_info($class->DB_TABLE, 'creation_ts')) {
+ $params->{creation_ts} = $timestamp;
+ }
} elsif ($class->isa('Bugzilla::Attachment')) {
if ($params->{ispatch} && !Bugzilla->user->first_patch_bug_id) {
Bugzilla->user->first_patch_bug_id($params->{bug}->id);
diff --git a/extensions/TrackingFlags/bin/bug_825946.pl b/extensions/TrackingFlags/bin/bug_825946.pl
index 3f380b7ac..896dc5448 100755
--- a/extensions/TrackingFlags/bin/bug_825946.pl
+++ b/extensions/TrackingFlags/bin/bug_825946.pl
@@ -24,7 +24,7 @@ use Bugzilla::Bug qw(LogActivityEntry);
Bugzilla->usage_mode(USAGE_MODE_CMDLINE);
my $dbh = Bugzilla->dbh;
-my $user = Bugzilla::User->check({name => 'nobody@mozilla.org'});
+my $user = Bugzilla::User->check({name => Bugzilla->params->{'nobody_user'}});
my $tf_vis = $dbh->selectall_arrayref(<<SQL);
SELECT
diff --git a/extensions/TrackingFlags/bin/bulk_flag_clear.pl b/extensions/TrackingFlags/bin/bulk_flag_clear.pl
index 1745018d5..305fbf883 100755
--- a/extensions/TrackingFlags/bin/bulk_flag_clear.pl
+++ b/extensions/TrackingFlags/bin/bulk_flag_clear.pl
@@ -110,7 +110,7 @@ if (!$config->{update_db}) {
# update bugs
-my $nobody = Bugzilla::User->check({ name => 'nobody@mozilla.org' });
+my $nobody = Bugzilla::User->check({ name => Bugzilla->params->{'nobody_user'} });
# put our nobody user into all groups to avoid permissions issues
$nobody->{groups} = [Bugzilla::Group->get_all];
Bugzilla->set_user($nobody);
diff --git a/extensions/TrackingFlags/disabled b/extensions/TrackingFlags/disabled
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/extensions/TrackingFlags/disabled
diff --git a/extensions/UserProfile/Extension.pm b/extensions/UserProfile/Extension.pm
index 079f7a948..9171b942d 100644
--- a/extensions/UserProfile/Extension.pm
+++ b/extensions/UserProfile/Extension.pm
@@ -385,7 +385,9 @@ sub object_columns {
my ($self, $args) = @_;
my ($class, $columns) = @$args{qw(class columns)};
if ($class->isa('Bugzilla::User')) {
- push(@$columns, qw(last_activity_ts last_statistics_ts));
+ my $dbh = Bugzilla->dbh;
+ my @new_columns = qw(last_activity_ts last_statistics_ts);
+ push @$columns, grep { $dbh->bz_column_info($class->DB_TABLE, $_) } @new_columns;
}
}
diff --git a/js/instant-search.js b/js/instant-search.js
index 6ce3516a7..93c0ef599 100644
--- a/js/instant-search.js
+++ b/js/instant-search.js
@@ -191,7 +191,7 @@ YAHOO.bugzilla.instantSearch = {
var result = [];
var name = Dom.get('product').value;
result.push(name);
- if (products[name] && products[name].related) {
+ if (typeof products !== 'undefined' && products[name] && products[name].related) {
for (var i = 0, n = products[name].related.length; i < n; i++) {
result.push(products[name].related[i]);
}
diff --git a/scripts/eject-users-from-groups.pl b/scripts/eject-users-from-groups.pl
index 52e2bbbf3..4b27be83d 100755
--- a/scripts/eject-users-from-groups.pl
+++ b/scripts/eject-users-from-groups.pl
@@ -23,7 +23,7 @@ Bugzilla->usage_mode(USAGE_MODE_CMDLINE);
my $dbh = Bugzilla->dbh;
my @remove_group_names;
-my $nobody_name = 'nobody@mozilla.org';
+my $nobody_name = Bugzilla->params->{'nobody_user'};
my $admin_name = 'automation@bmo.tld';
GetOptions(
diff --git a/scripts/entrypoint.pl b/scripts/entrypoint.pl
index 21d9aebb1..f5c52f6a6 100755
--- a/scripts/entrypoint.pl
+++ b/scripts/entrypoint.pl
@@ -57,11 +57,6 @@ check_env(qw(
BMO_urlbase
));
-if ( $ENV{BMO_urlbase} eq 'AUTOMATIC' ) {
- $ENV{BMO_urlbase} = sprintf 'http://%s:%d/%s', hostname(), $ENV{PORT}, $ENV{BZ_QA_LEGACY_MODE} ? 'bmo/' : '';
- $ENV{BZ_BASE_URL} = sprintf 'http://%s:%d', hostname(), $ENV{PORT};
-}
-
$func->($opts->());
sub cmd_demo {
@@ -110,6 +105,11 @@ sub cmd_dev_httpd {
exit $httpd_exit_f->get;
}
+sub cmd_checksetup_gen_files {
+ my (@args) = @_;
+ run( 'perl', 'checksetup.pl', '--no-database', @args);
+}
+
sub cmd_checksetup {
check_data_dir();
wait_for_db();
@@ -140,7 +140,7 @@ sub cmd_test_webservices {
check_data_dir();
copy_qa_extension();
assert_database()->get;
- my $httpd_exit_f = run_cereal_and_httpd('-DHTTPD_IN_SUBDIR', '-DACCESS_LOGS');
+ my $httpd_exit_f = run_cereal_and_httpd('-DHTTPD_IN_SUBDIR');
my $prove_exit_f = run_prove(
httpd_url => $conf->{browser_url},
prove_cmd => [
@@ -195,7 +195,7 @@ sub cmd_test_bmo {
$ENV{BZ_TEST_NEWBIE2} = 'newbie2@mozilla.example';
$ENV{BZ_TEST_NEWBIE2_PASS} = 'captain.space.pants.time.lord';
- my $httpd_exit_f = run_cereal_and_httpd('-DACCESS_LOGS');
+ my $httpd_exit_f = run_cereal_and_httpd();
my $prove_exit_f = run_prove(
httpd_url => $ENV{BZ_BASE_URL},
prove_cmd => [ 'prove', '-I/app', '-I/app/local/lib/perl5', @prove_args ],
@@ -244,6 +244,10 @@ sub copy_qa_extension {
dircopy('/app/qa/extensions/QA', '/app/extensions/QA');
}
+sub cmd_wait_for_db {
+ wait_for_db();
+}
+
sub wait_for_db {
assert_database()->get;
}
diff --git a/scripts/generate_bmo_data.pl b/scripts/generate_bmo_data.pl
index 6356762c8..8a9f72d17 100755
--- a/scripts/generate_bmo_data.pl
+++ b/scripts/generate_bmo_data.pl
@@ -158,7 +158,7 @@ $group->update();
my @users = (
{
- login => 'nobody@mozilla.org',
+ login => Bugzilla->params->{'nobody_user'},
realname => 'Nobody; OK to take it and work on it',
password => '*'
},
@@ -267,7 +267,7 @@ my @products = (
name => 'General',
description => 'For bugs in Firefox which do not fit into ' .
'other more specific Firefox components',
- initialowner => 'nobody@mozilla.org',
+ initialowner => Bugzilla->params->{'nobody_user'},
initialqaowner => '',
initial_cc => [],
watch_user => 'general@firefox.bugs'
@@ -287,7 +287,7 @@ my @products = (
name => 'General',
description => 'This is the component for issues specific to bugzilla.mozilla.org '
. 'that do not belong in other components.',
- initialowner => 'nobody@mozilla.org',
+ initialowner => Bugzilla->params->{'nobody_user'},
initialqaowner => '',
initial_cc => [],
watch_user => 'general@bugzilla.bugs'
diff --git a/scripts/move_os.pl b/scripts/move_os.pl
index 546b47c7e..963188261 100755
--- a/scripts/move_os.pl
+++ b/scripts/move_os.pl
@@ -40,7 +40,7 @@ my $dbh = Bugzilla->dbh;
my $timestamp = $dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)');
my $bug_ids = $dbh->selectcol_arrayref(q{SELECT bug_id FROM bugs WHERE bugs.op_sys = ?}, undef, $from_os);
my $field = Bugzilla::Field->check({ name => 'op_sys', cache => 1 });
-my $nobody = Bugzilla::User->check({ name => 'nobody@mozilla.org', cache => 1 });
+my $nobody = Bugzilla::User->check({ name => Bugzilla->params->{'nobody_user'}, cache => 1 });
my $bug_count = @$bug_ids;
if ($bug_count == 0) {
diff --git a/scripts/movebugs.pl b/scripts/movebugs.pl
index 2c643cdfb..55a43d943 100755
--- a/scripts/movebugs.pl
+++ b/scripts/movebugs.pl
@@ -73,10 +73,12 @@ my $component_field_id = $dbh->selectrow_array(
$component_field_id
or die "Can't find field ID for 'component' field\n";
+my $nobody = Bugzilla->params->{'nobody_user'};
my $user_id = $dbh->selectrow_array(
- "SELECT userid FROM profiles WHERE login_name='nobody\@mozilla.org'");
+ "SELECT userid FROM profiles WHERE login_name=?",
+ undef, $nobody);
$user_id
- or die "Can't find user ID for 'nobody\@mozilla.org'\n";
+ or die "Can't find user ID for '$nobody'\n";
$dbh->bz_start_transaction();
diff --git a/scripts/nagios_blocker_checker.pl b/scripts/nagios_blocker_checker.pl
index a02a1602a..01a7b7348 100755
--- a/scripts/nagios_blocker_checker.pl
+++ b/scripts/nagios_blocker_checker.pl
@@ -28,7 +28,7 @@ my $config = {
assignee => '',
product => '',
component => '',
- unassigned => 'nobody@mozilla.org',
+ unassigned => Bugzilla->params->{'nobody_user'},
# severities
severity => 'major,critical,blocker',
# time in hours to wait before paging/warning
diff --git a/scripts/remove_idle_group_members.pl b/scripts/remove_idle_group_members.pl
index 74e8658ff..e4ef88bc1 100755
--- a/scripts/remove_idle_group_members.pl
+++ b/scripts/remove_idle_group_members.pl
@@ -78,7 +78,7 @@ foreach my $group_id (keys %remove_data) {
$dbh->bz_commit_transaction();
# nobody@mozilla.org cannot recieve email
- next if $group->owner->login eq 'nobody@mozilla.org';
+ next if $group->owner->login eq Bugzilla->params->{'nobody_user'};
_send_email($group, \@users_removed);
}
diff --git a/scripts/reset_default_user.pl b/scripts/reset_default_user.pl
index d0d2534f2..942afda17 100755
--- a/scripts/reset_default_user.pl
+++ b/scripts/reset_default_user.pl
@@ -52,7 +52,7 @@ if (!$product || $help
}
# We will need these for entering into bugs_activity
-my $who = Bugzilla::User->new({ name => 'nobody@mozilla.org' });
+my $who = Bugzilla::User->new({ name => Bugzilla->params->{'nobody_user'} });
my $field = Bugzilla::Field->new({ name => $field_name });
trick_taint($product);
diff --git a/scripts/rewrite2mojo.pl b/scripts/rewrite2mojo.pl
new file mode 100755
index 000000000..bae6d514b
--- /dev/null
+++ b/scripts/rewrite2mojo.pl
@@ -0,0 +1,70 @@
+#!/usr/bin/perl
+# 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.
+
+use 5.10.1;
+use strict;
+use warnings;
+use Mojo::Parameters;
+use Data::Dumper;
+
+while (<>) {
+ my ($cmd, @args) = split /\s+/, $_;
+ next unless $cmd;
+ if (lc($cmd) eq "\LRewriteRule") {
+ my ($regex, $target, $flags) = @args;
+ $flags //= '';
+ next if $flags =~ /E=HTTP/;
+ next if $target eq '-';
+ my $action = 'rewrite_query';
+ if ($flags =~ /R/) {
+ next;
+ }
+ my ($script, $query) = $target =~ /^([^?]+)(?:\?(.+))?$/;
+ my $name = _file_to_method($script);
+ $regex =~ s/^\^//;
+ $regex =~ s/\$$//;
+ my $regex_name = _regex_to_name($regex);
+ my $param_hash = Mojo::Parameters->new($query)->to_hash;
+ my $param_str = Data::Dumper->new([$param_hash])->Terse(1)->Indent(0)->Dump;
+ say "\$r->any('/:$regex_name' => [$regex_name => qr{$regex}])->to(";
+ say " 'CGI#$name' => $param_str";
+ say ");";
+
+ }
+ # elsif (lc($cmd) eq "\LRedirect") {
+ # my ($type, $path, $url) = @args;
+ # if ($type eq 'permanent') {
+ # say "if (\$path =~ m{^\Q$path\E}s) {";
+ # say " redirect(\$c, q{$url});";
+ # say " return;";
+ # say "}";
+ # }
+ # else {
+ # warn "I don't understand Redirect $type\n";
+ # }
+ # }
+}
+
+sub _file_to_method {
+ my ($name) = @_;
+ $name =~ s/\./_/s;
+ $name =~ s/\W+/_/gs;
+ return $name;
+}
+
+sub _regex_to_name {
+ my ($name) = @_;
+ $name =~ s/\./_/s;
+ $name =~ s/\W+/_/gs;
+ $name =~ s/_+/_/g;
+ $name =~ s/^_//s;
+ $name =~ s/_$//s;
+ return $name;
+}
+
+
diff --git a/t/bmo/comments.t b/t/bmo/comments.t
index 4b0bb8177..00002040c 100644
--- a/t/bmo/comments.t
+++ b/t/bmo/comments.t
@@ -35,7 +35,7 @@ my $bug_1 = Bugzilla::Bug->create(
keywords => [],
cc => [],
comment => 'This is a brand new bug',
- assigned_to => 'nobody@mozilla.org',
+ assigned_to => Bugzilla->params->{'nobody_user'},
}
);
ok($bug_1->id, "got a new bug");
@@ -55,7 +55,7 @@ my $bug_2 = Bugzilla::Bug->create(
keywords => [],
cc => [],
comment => "This is related to ${urlbase}show_bug.cgi?id=$bug_1_id",
- assigned_to => 'nobody@mozilla.org',
+ assigned_to => Bugzilla->params->{'nobody_user'},
}
);
diff --git a/t/docker.t b/t/docker.t
index 3c8cd055b..c1f85088c 100644
--- a/t/docker.t
+++ b/t/docker.t
@@ -28,7 +28,7 @@ while (my $line = readline $dockerfile_fh) {
close $dockerfile_fh;
my ($image, $version) = split(/:/ms, $base, 2);
-is($image, 'mozillabteam/bmo-slim', "base image is mozillabteam/bmo-slim");
+is($image, 'bugzilla/harmony-slim', "base image is bugzilla/harmony-slim");
like($version, qr/\d{4}\d{2}\d{2}\.\d+/ms, "version is YYYYMMDD.x");
my $regex = qr{
@@ -49,4 +49,4 @@ while (my $line = readline $ci_config_fh) {
}
close $ci_config_fh;
-done_testing; \ No newline at end of file
+done_testing;
diff --git a/template/en/default/account/prefs/account.html.tmpl b/template/en/default/account/prefs/account.html.tmpl
index 1e7bc25db..61ce80011 100644
--- a/template/en/default/account/prefs/account.html.tmpl
+++ b/template/en/default/account/prefs/account.html.tmpl
@@ -138,7 +138,7 @@
<td></td>
<td>
<p>
- Your contributions on bugzilla.mozilla.org will still be visible;
+ Your contributions on [% terms.Bugzilla %] will still be visible;
however, your email address and name will be removed in most locations.
We are not able to remove your details that are part of comment text.
</p>
diff --git a/template/en/default/attachment/create.html.tmpl b/template/en/default/attachment/create.html.tmpl
index 5e996041c..95336ed8e 100644
--- a/template/en/default/attachment/create.html.tmpl
+++ b/template/en/default/attachment/create.html.tmpl
@@ -74,7 +74,7 @@
<td>
<em>If you want to assign this [% terms.bug %] to yourself,
check the box below.</em><br>
- [% IF bug.assigned_to.login == "nobody@mozilla.org" || bug.assigned_to.login.search('.bugs$') %]
+ [% IF bug.assigned_to.login == Param('nobody_user') || bug.assigned_to.login.search('.bugs$') %]
[% take_if_patch = 1 %]
[% END %]
<input type="checkbox" id="takebug" name="takebug" value="1" [% IF take_if_patch %] data-take-if-patch="1" [% END %]>
diff --git a/template/en/default/bug/new_bug.html.tmpl b/template/en/default/bug/new_bug.html.tmpl
index b642be3c7..80a603944 100644
--- a/template/en/default/bug/new_bug.html.tmpl
+++ b/template/en/default/bug/new_bug.html.tmpl
@@ -27,10 +27,10 @@
<h2>Create New [% terms.Bug %]</h2>
<p>
Before reporting a [% terms.bug %], make sure you've read our
- <a href="https://developer.mozilla.org/docs/Mozilla/QA/Bug_writing_guidelines">
+ <a href="[% terms.BugWritingGuidelinesURL %]">
[% terms.bug %] writing guidelines</a> and double checked that your [% terms.bug %] hasn't already
- been reported. Consult our list of <a href="https://bugzilla.mozilla.org/duplicates.cgi">
- most frequently reported [% terms.bugs %]</a> and <a href="https://bugzilla.mozilla.org/query.cgi">
+ been reported. Consult our list of <a href="duplicates.cgi">
+ most frequently reported [% terms.bugs %]</a> and <a href="query.cgi">
search through descriptions</a> of previously reported [% terms.bugs %].
</p>
</div>
diff --git a/template/en/default/global/variables.none.tmpl b/template/en/default/global/variables.none.tmpl
index 5ebf695c0..c57dac890 100644
--- a/template/en/default/global/variables.none.tmpl
+++ b/template/en/default/global/variables.none.tmpl
@@ -37,7 +37,9 @@
"bugs" => "bugs",
"Bugs" => "Bugs",
"zeroSearchResults" => "Zarro Boogs found",
- "Bugzilla" => "Bugzilla"
+ "Bugzilla" => "Bugzilla",
+
+ "BugWritingGuidelinesURL" => "https://developer.mozilla.org/docs/Mozilla/QA/Bug_writing_guidelines",
}
%]
diff --git a/template/en/default/index.html.tmpl b/template/en/default/index.html.tmpl
index d6a4f2105..6dbdabc0c 100644
--- a/template/en/default/index.html.tmpl
+++ b/template/en/default/index.html.tmpl
@@ -105,7 +105,7 @@
<a href="page.cgi?id=etiquette.html">[%- terms.Bugzilla %] Etiquette</a>
</li>
<li>
- | <a href="https://developer.mozilla.org/docs/Mozilla/QA/Bug_writing_guidelines">[%- terms.Bug %] Writing Guidelines</a>
+ | <a href="[% terms.BugWritingGuidelinesURL %]">[%- terms.Bug %] Writing Guidelines</a>
</li>
[% Hook.process('additional_links') %]
</ul>
diff --git a/template/en/default/list/edit-multiple.html.tmpl b/template/en/default/list/edit-multiple.html.tmpl
index ada635b09..ae1dade52 100644
--- a/template/en/default/list/edit-multiple.html.tmpl
+++ b/template/en/default/list/edit-multiple.html.tmpl
@@ -437,7 +437,6 @@
[% FOREACH r = resolutions %]
[% NEXT IF !r %]
[% NEXT IF r == "DUPLICATE" || r == "MOVED" %]
- [% NEXT IF r == "EXPIRED" AND user.login != "gerv@mozilla.org" %]
<option value="[% r FILTER html %]">[% display_value("resolution", r) FILTER html %]</option>
[% END %]
</select>
diff --git a/template/en/default/list/table.html.tmpl b/template/en/default/list/table.html.tmpl
index 2453c3774..66ce442b9 100644
--- a/template/en/default/list/table.html.tmpl
+++ b/template/en/default/list/table.html.tmpl
@@ -90,7 +90,9 @@
<th class="sorttable_nosort">&nbsp;</th>
[% END %]
<th colspan="[% splitheader ? 2 : 1 %]" class="first-child
- sorted_[% lsearch(order_columns, 'bug_id') FILTER html %]">
+ [% order_columns.defined
+ ? 'sorted_' _ lsearch(order_columns, 'bug_id')
+ : '' FILTER html %]">
<a href="buglist.cgi?
[% urlquerypart FILTER html %]&amp;order=
[% PROCESS new_order id='bug_id' %]
@@ -136,7 +138,9 @@
[% BLOCK columnheader %]
<th colspan="[% splitheader ? 2 : 1 %]"
class="sortable_column_[% key FILTER html %]
- sorted_[% lsearch(order_columns, id) FILTER html %]">
+ [% order_columns.defined
+ ? 'sorted_' _ lsearch(order_columns, id)
+ : '' FILTER html %]">
<a href="buglist.cgi?[% urlquerypart FILTER html %]&amp;order=
[% PROCESS new_order %]
[%-#%]&amp;query_based_on=
diff --git a/template/en/default/search/search-google.html.tmpl b/template/en/default/search/search-google.html.tmpl
index 7fdc1daaa..1b07320ce 100644
--- a/template/en/default/search/search-google.html.tmpl
+++ b/template/en/default/search/search-google.html.tmpl
@@ -32,7 +32,7 @@
<p>
<form method="get" action="https://www.google.com/search" data-no-csrf>
-<input type="hidden" name="sitesearch" value="bugzilla.mozilla.org">
+<input type="hidden" name="sitesearch" value="[% urlbase.match('^([^:]*://)?(.*?)/?$').1 %]">
<nobr>
<input type="text" name="q" size="60" maxlength="255" value="">
<input type="submit" value="Search">
diff --git a/template/en/default/search/search-instant.html.tmpl b/template/en/default/search/search-instant.html.tmpl
index e7d87084f..95d40a5eb 100644
--- a/template/en/default/search/search-instant.html.tmpl
+++ b/template/en/default/search/search-instant.html.tmpl
@@ -11,8 +11,7 @@
[% PROCESS global/header.html.tmpl
title = "Instant Search"
generate_api_token = 1
- javascript_urls = [ 'extensions/GuidedBugEntry/web/js/products.js',
- 'js/instant-search.js', ]
+ javascript_urls = javascript_urls
%]
[% UNLESS default.exists('product') && default.product.size %]
diff --git a/votes.cgi b/votes.cgi
index d9dba1541..7c1fff67a 100755
--- a/votes.cgi
+++ b/votes.cgi
@@ -30,8 +30,7 @@ use lib qw(. lib local/lib/perl5);
use Bugzilla;
use Bugzilla::Error;
-my $is_enabled = grep { $_->NAME eq 'Voting' } @{ Bugzilla->extensions };
-$is_enabled || ThrowCodeError('extension_disabled', { name => 'Voting' });
+Bugzilla->has_extension('Voting') || ThrowCodeError('extension_disabled', { name => 'Voting' });
my $cgi = Bugzilla->cgi;
my $action = $cgi->param('action') || 'show_user';