summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.circleci/config.yml8
-rw-r--r--.gitignore2
-rw-r--r--.htaccess88
-rw-r--r--.perlcriticrc2
-rw-r--r--Bugzilla.pm50
-rw-r--r--Bugzilla/Attachment/PatchReader.pm15
-rw-r--r--Bugzilla/CGI.pm36
-rw-r--r--Bugzilla/Config/General.pm14
-rw-r--r--Bugzilla/Constants.pm4
-rw-r--r--Bugzilla/DaemonControl.pm26
-rw-r--r--Bugzilla/Elastic/Role/HasClient.pm2
-rw-r--r--Bugzilla/Error.pm4
-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.pm143
-rw-r--r--Bugzilla/Memcached.pm2
-rw-r--r--Bugzilla/ModPerl.pm118
-rw-r--r--Bugzilla/ModPerl/BasicAuth.pm65
-rw-r--r--Bugzilla/ModPerl/BlockIP.pm65
-rw-r--r--Bugzilla/ModPerl/StartupFix.pm51
-rw-r--r--Bugzilla/PSGI.pm42
-rw-r--r--Bugzilla/Quantum.pm119
-rw-r--r--Bugzilla/Quantum/CGI.pm161
-rw-r--r--Bugzilla/Quantum/Plugin/BasicAuth.pm40
-rw-r--r--Bugzilla/Quantum/Plugin/BlockIP.pm43
-rw-r--r--Bugzilla/Quantum/Plugin/Glue.pm101
-rw-r--r--Bugzilla/Quantum/Plugin/Hostage.pm (renamed from Bugzilla/ModPerl/Hostage.pm)53
-rw-r--r--[-rwxr-xr-x]Bugzilla/Quantum/SES.pm (renamed from ses/index.cgi)150
-rw-r--r--Bugzilla/Quantum/Static.pm30
-rw-r--r--Bugzilla/Quantum/Stdout.pm60
-rw-r--r--Bugzilla/Search.pm26
-rw-r--r--Bugzilla/Template.pm3
-rw-r--r--Bugzilla/Util.pm3
-rw-r--r--Bugzilla/WebService/Server/XMLRPC.pm6
-rw-r--r--Bugzilla/WebService/Util.pm8
-rw-r--r--Dockerfile11
-rw-r--r--Log/Log4perl/Layout/Mozilla.pm3
-rwxr-xr-xMakefile.PL22
-rw-r--r--README.rst35
-rwxr-xr-xbuglist.cgi48
-rwxr-xr-xbugzilla.pl20
-rwxr-xr-xchecksetup.pl3
-rwxr-xr-xcolchange.cgi16
-rw-r--r--conf/httpd.conf103
-rw-r--r--conf/log4perl-test.conf4
-rw-r--r--docker-compose.yml1
-rw-r--r--docs/en/rst/administering/parameters.rst6
-rw-r--r--docs/en/rst/integrating/templates.rst2
-rw-r--r--docs/en/rst/style.rst5
-rwxr-xr-xeditparams.cgi3
-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.pm140
-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/MozReview/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
-rwxr-xr-xheartbeat.cgi8
-rwxr-xr-x[-rw-r--r--]jobqueue-worker.pl0
-rw-r--r--js/instant-search.js4
-rw-r--r--mod_perl.pl204
-rw-r--r--qa/t/lib/QA/Util.pm28
-rw-r--r--qa/t/test_bug_edit.t117
-rw-r--r--qa/t/test_shutdown.t72
-rwxr-xr-xscripts/block-ip.pl10
-rwxr-xr-xscripts/eject-users-from-groups.pl2
-rwxr-xr-xscripts/entrypoint.pl32
-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
-rwxr-xr-x[-rw-r--r--]scripts/undo.pl0
-rw-r--r--t/001compile.t14
-rw-r--r--t/002goodperl.t7
-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/admin/params/editparams.html.tmpl1
-rw-r--r--template/en/default/admin/params/general.html.tmpl5
-rw-r--r--template/en/default/attachment/create.html.tmpl2
-rw-r--r--template/en/default/bug/create/user-message.html.tmpl2
-rw-r--r--template/en/default/bug/new_bug.html.tmpl6
-rw-r--r--template/en/default/global/field-descs.none.tmpl10
-rw-r--r--template/en/default/global/header.html.tmpl2
-rw-r--r--template/en/default/global/messages.html.tmpl62
-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.tmpl8
-rw-r--r--vagrant_support/apache.yml8
-rwxr-xr-xvagrant_support/hypnotoad122
-rw-r--r--vagrant_support/hypnotoad.yml27
-rw-r--r--vagrant_support/playbook.yml6
-rw-r--r--vagrant_support/update.yml5
-rwxr-xr-xvotes.cgi3
137 files changed, 1593 insertions, 1982 deletions
diff --git a/.circleci/config.yml b/.circleci/config.yml
index fe1263ee9..f64524c80 100644
--- a/.circleci/config.yml
+++ b/.circleci/config.yml
@@ -7,7 +7,7 @@ version: 2
defaults:
bmo_slim_image: &bmo_slim_image
- image: mozillabteam/bmo-slim:20180801.2
+ image: mozillabteam/bmo-slim:20180809.1
user: app
mysql_image: &mysql_image
@@ -37,12 +37,6 @@ defaults:
BMO_memcached_servers: localhost:11211
BMO_memcached_namespace: "bugzilla:"
BMO_urlbase: AUTOMATIC
- HTTPD_StartServers: 1
- HTTPD_MinSpareServers: 1
- HTTPD_MaxSpareServers: 1
- HTTPD_ServerLimit: 1
- HTTPD_MaxClients: 1
- HTTPD_MaxRequestsPerChild: 4000
mysql_env: &mysql_env
MYSQL_DATABASE: bugs
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/.perlcriticrc b/.perlcriticrc
index 0b8e4c862..d5fc03fa0 100644
--- a/.perlcriticrc
+++ b/.perlcriticrc
@@ -5,6 +5,8 @@ severity = 1
#perltidyrc = .perltidyrc
#severity = 2
+[-CodeLayout::ProhibitParensWithBuiltins]
+
[InputOutput::RequireCheckedSyscalls]
severity = 2
functions = :builtins
diff --git a/Bugzilla.pm b/Bugzilla.pm
index 44286c75b..3ba535c8e 100644
--- a/Bugzilla.pm
+++ b/Bugzilla.pm
@@ -13,7 +13,7 @@ use warnings;
use Bugzilla::Logging;
-our $VERSION = '20180820.1';
+our $VERSION = '5.16';
use Bugzilla::Auth;
use Bugzilla::Auth::Persist::Cookie;
@@ -46,6 +46,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);
@@ -114,20 +115,6 @@ sub init_page {
# 001compile.t test).
return if $^C;
- # IIS prints out warnings to the webpage, so ignore them, or log them
- # to a file if the file exists.
- if ($ENV{SERVER_SOFTWARE} && $ENV{SERVER_SOFTWARE} =~ /microsoft-iis/i) {
- $SIG{__WARN__} = sub {
- my ($msg) = @_;
- my $datadir = bz_locations()->{'datadir'};
- if (-w "$datadir/errorlog") {
- my $warning_log = new IO::File(">>$datadir/errorlog");
- print $warning_log $msg;
- $warning_log->close();
- }
- };
- }
-
my $script = basename($0);
# Because of attachment_base, attachment.cgi handles this itself.
@@ -223,6 +210,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();
@@ -235,9 +230,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;
}
@@ -262,6 +268,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();
}
@@ -838,7 +851,7 @@ sub check_rate_limit {
my $limit = join("/", @$limit);
Bugzilla->audit("[rate_limit] action=$action, ip=$ip, limit=$limit, name=$name");
if ($action eq 'block') {
- Bugzilla::ModPerl::BlockIP->block_ip($ip);
+ $Bugzilla::Quantum::CGI::C->block_ip($ip);
ThrowUserError("rate_limit");
}
}
@@ -854,6 +867,7 @@ sub markdown_parser {
# Per-process cleanup. Note that this is a plain subroutine, not a method,
# so we don't have $class available.
+*cleanup = \&_cleanup;
sub _cleanup {
return if $^C;
@@ -880,10 +894,10 @@ sub _cleanup {
sub END {
# Bugzilla.pm cannot compile in mod_perl.pl if this runs.
- _cleanup() unless $ENV{MOD_PERL};
+ _cleanup() unless BZ_PERSISTENT;
}
-init_page() if !$ENV{MOD_PERL};
+init_page() unless BZ_PERSISTENT;
1;
diff --git a/Bugzilla/Attachment/PatchReader.pm b/Bugzilla/Attachment/PatchReader.pm
index 2cfbf2c6b..8025f5b82 100644
--- a/Bugzilla/Attachment/PatchReader.pm
+++ b/Bugzilla/Attachment/PatchReader.pm
@@ -116,18 +116,9 @@ sub process_interdiff {
$ENV{'PATH'} = $lc->{diffpath};
my ($pid, $interdiff_stdout, $interdiff_stderr);
- if ($ENV{MOD_PERL}) {
- require Apache2::RequestUtil;
- require Apache2::SubProcess;
- my $request = Apache2::RequestUtil->request;
- (undef, $interdiff_stdout, $interdiff_stderr) = $request->spawn_proc_prog(
- $lc->{interdiffbin}, [$old_filename, $new_filename]
- );
- } else {
- $interdiff_stderr = gensym;
- my $pid = open3(gensym, $interdiff_stdout, $interdiff_stderr,
- $lc->{interdiffbin}, $old_filename, $new_filename);
- }
+ $interdiff_stderr = gensym;
+ $pid = open3(gensym, $interdiff_stdout, $interdiff_stderr,
+ $lc->{interdiffbin}, $old_filename, $new_filename);
binmode $interdiff_stdout;
# Check for errors
diff --git a/Bugzilla/CGI.pm b/Bugzilla/CGI.pm
index 6236b015a..2cbb02e3e 100644
--- a/Bugzilla/CGI.pm
+++ b/Bugzilla/CGI.pm
@@ -123,7 +123,7 @@ sub new {
# Under mod_perl, CGI's global variables get reset on each request,
# so we need to set them up again every time.
- $class->_init_bz_cgi_globals() if $ENV{MOD_PERL};
+ $class->_init_bz_cgi_globals();
my $self = $class->SUPER::new(@args);
@@ -141,6 +141,7 @@ sub new {
# apache collapses // to / in $ENV{PATH_INFO} but not in $self->path_info.
# url() requires the full path in ENV in order to generate the correct url.
$ENV{PATH_INFO} = $path;
+ DEBUG("redirecting because we see PATH_INFO and don't like it");
print $self->redirect($self->url(-path => 0, -query => 1));
exit;
}
@@ -151,6 +152,7 @@ sub new {
# Redirect to urlbase if we are not viewing an attachment.
if ($self->url_is_attachment_base and $script ne 'attachment.cgi') {
+ DEBUG("Redirecting to urlbase because the url is in the attachment base and not attachment.cgi");
$self->redirect_to_urlbase();
}
@@ -481,11 +483,6 @@ sub _prevent_unsafe_response {
print $self->SUPER::header(-type => 'text/html', -status => '403 Forbidden');
if ($content_type ne 'text/html') {
print "Untrusted Referer Header\n";
- if ($ENV{MOD_PERL}) {
- my $r = $self->r;
- $r->rflush;
- $r->status(200);
- }
}
exit;
}
@@ -603,8 +600,25 @@ sub header {
$headers{'-link'} .= ', <https://www.google-analytics.com>; rel="preconnect"; crossorigin';
}
}
-
- return $self->SUPER::header(%headers) || "";
+ my $headers = $self->SUPER::header(%headers) || '';
+ if ($self->server_software eq 'Bugzilla::Quantum::CGI') {
+ my $c = $Bugzilla::Quantum::CGI::C;
+ $c->res->headers->parse($headers);
+ my $status = $c->res->headers->status;
+ if ($status && $status =~ /^([0-9]+)/) {
+ $c->res->code($1);
+ }
+ elsif ($c->res->headers->location) {
+ $c->res->code(302);
+ }
+ else {
+ $c->res->code(200);
+ }
+ return '';
+ }
+ else {
+ LOGDIE("Bugzilla::CGI->header() should only be called from inside Bugzilla::Quantum::CGI!");
+ }
}
sub param {
@@ -721,6 +735,7 @@ sub redirect {
return $self->SUPER::redirect(@_);
}
+use Bugzilla::Logging;
# This helps implement Bugzilla::Search::Recent, and also shortens search
# URLs that get POSTed to buglist.cgi.
sub redirect_search_url {
@@ -769,6 +784,7 @@ sub redirect_search_url {
# are only redirected if they're under the CGI_URI_LIMIT though.
my $self_url = $self->self_url();
if ($self->request_method() ne 'POST' or length($self_url) < CGI_URI_LIMIT) {
+ DEBUG("Redirecting search url");
print $self->redirect(-url => $self_url);
exit;
}
@@ -790,10 +806,8 @@ sub redirect_to_https {
# XML-RPC clients (SOAP::Lite at least) require a 301 to redirect properly
# and do not work with 302. Our redirect really is permanent anyhow, so
# it doesn't hurt to make it a 301.
+ DEBUG("Redirecting to https");
print $self->redirect(-location => $url, -status => 301);
-
- # When using XML-RPC with mod_perl, we need the headers sent immediately.
- $self->r->rflush if $ENV{MOD_PERL};
exit;
}
diff --git a/Bugzilla/Config/General.pm b/Bugzilla/Config/General.pm
index 15688dfd3..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/',
@@ -40,12 +48,6 @@ use constant get_param_list => (
},
{
- name => 'shutdownhtml',
- type => 'l',
- default => ''
- },
-
- {
name => 'announcehtml',
type => 'l',
default => ''
diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm
index 185a30390..34e4a4cfe 100644
--- a/Bugzilla/Constants.pm
+++ b/Bugzilla/Constants.pm
@@ -194,6 +194,8 @@ use Memoize;
EMAIL_LIMIT_EXCEPTION
JOB_QUEUE_VIEW_MAX_JOBS
+
+ BZ_PERSISTENT
);
@Bugzilla::Constants::EXPORT_OK = qw(contenttypes);
@@ -696,6 +698,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/DaemonControl.pm b/Bugzilla/DaemonControl.pm
index 6ff883af0..5cb32973f 100644
--- a/Bugzilla/DaemonControl.pm
+++ b/Bugzilla/DaemonControl.pm
@@ -23,7 +23,8 @@ use IO::Async::Protocol::LineStream;
use IO::Async::Signal;
use IO::Socket;
use LWP::Simple qw(get);
-use POSIX qw(setsid WEXITSTATUS);
+use JSON::MaybeXS qw(encode_json);
+use POSIX qw(WEXITSTATUS);
use base qw(Exporter);
@@ -43,8 +44,14 @@ our %EXPORT_TAGS = (
my $BUGZILLA_DIR = bz_locations->{cgi_path};
my $JOBQUEUE_BIN = catfile( $BUGZILLA_DIR, 'jobqueue.pl' );
my $CEREAL_BIN = catfile( $BUGZILLA_DIR, 'scripts', 'cereal.pl' );
-my $HTTPD_BIN = '/usr/sbin/httpd';
-my $HTTPD_CONFIG = catfile( bz_locations->{confdir}, 'httpd.conf' );
+my $BUGZILLA_BIN = catfile( $BUGZILLA_DIR, 'bugzilla.pl' );
+my $HYPNOTOAD_BIN = catfile( $BUGZILLA_DIR, 'local', 'bin', 'hypnotoad' );
+my @PERL5LIB = ( $BUGZILLA_DIR, catdir($BUGZILLA_DIR, 'lib'), catdir($BUGZILLA_DIR, 'local', 'lib', 'perl5') );
+
+my %HTTP_BACKENDS = (
+ hypnotoad => [ $HYPNOTOAD_BIN, $BUGZILLA_BIN, '-f' ],
+ simple => [ $BUGZILLA_BIN, 'daemon' ],
+);
sub catch_signal {
my ($name, @done) = @_;
@@ -98,13 +105,12 @@ sub run_httpd {
my $exit_f = $loop->new_future;
my $httpd = IO::Async::Process->new(
code => sub {
-
- # we have to setsid() to make a new process group
- # or else apache will kill its parent.
- setsid();
- my @command = ( $HTTPD_BIN, '-DFOREGROUND', '-f' => $HTTPD_CONFIG, @args );
- exec @command
- or die "failed to exec $command[0] $!";
+ $ENV{BUGZILLA_HTTPD_ARGS} = encode_json(\@args);
+ $ENV{PERL5LIB} = join(':', @PERL5LIB);
+ my $backend = $ENV{HTTP_BACKEND} // 'hypnotoad';
+ my $command = $HTTP_BACKENDS{ $backend };
+ exec @$command
+ or die "failed to exec $command->[0] $!";
},
on_finish => on_finish($exit_f),
on_exception => on_exception( 'httpd', $exit_f ),
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.pm b/Bugzilla/Error.pm
index 9fcd16386..f932294b0 100644
--- a/Bugzilla/Error.pm
+++ b/Bugzilla/Error.pm
@@ -31,7 +31,7 @@ use Scalar::Util qw(blessed);
sub _in_eval {
my $in_eval = 0;
for (my $stack = 1; my $sub = (caller($stack))[3]; $stack++) {
- last if $sub =~ /^ModPerl/;
+ last if $sub =~ /^Bugzilla::Quantum::CGI::try/;
$in_eval = 1 if $sub =~ /^\(eval\)/;
}
return $in_eval;
@@ -196,7 +196,7 @@ sub ThrowTemplateError {
# mod_perl overrides exit to call die with this string
# we never want to display this to the user
- exit if $template_err =~ /\bModPerl::Util::exit\b/;
+ die $template_err if ref($template_err) eq 'ARRAY' && $template_err->[0] eq "EXIT\n";
state $logger = Log::Log4perl->get_logger('Bugzilla.Error.Template');
$logger->error($template_err);
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 003be22e4..cb1b1ad15 100644
--- a/Bugzilla/Install/Filesystem.pm
+++ b/Bugzilla/Install/Filesystem.pm
@@ -41,56 +41,11 @@ use English qw(-no_match_vars $OSNAME);
use base qw(Exporter);
our @EXPORT = qw(
update_filesystem
- create_htaccess
fix_all_file_permissions
fix_dir_permissions
fix_file_permissions
);
-use constant HT_DEFAULT_DENY => <<'EOT';
-# nothing in this directory is retrievable unless overridden by an .htaccess
-# in a subdirectory
-deny from all
-EOT
-
-use constant HT_GRAPHS_DIR => <<'EOT';
-# Allow access to .png and .gif files.
-<FilesMatch (\.gif|\.png)$>
- Allow from all
-</FilesMatch>
-
-# And no directory listings, either.
-Deny from all
-EOT
-
-use constant HT_WEBDOT_DIR => <<'EOT';
-# Restrict access to .dot files to the public webdot server at research.att.com
-# if research.att.com ever changes their IP, or if you use a different
-# webdot server, you'll need to edit this
-<FilesMatch \.dot$>
- Allow from 192.20.225.0/24
- Deny from all
-</FilesMatch>
-
-# Allow access to .png files created by a local copy of 'dot'
-<FilesMatch \.png\$>
- Allow from all
-</FilesMatch>
-
-# And no directory listings, either.
-Deny from all
-EOT
-
-use constant HT_ASSETS_DIR => <<'EOT';
-# Allow access to .css and js files
-<FilesMatch \.(css|js)$>
- Allow from all
-</FilesMatch>
-
-# And no directory listings, either.
-Deny from all
-EOT
-
use constant INDEX_HTML => <<'EOT';
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
@@ -112,11 +67,6 @@ use constant HTTPD_ENV => qw(
NYTPROF_DIR
);
-sub HTTPD_ENV_CONF {
- my @env = (ENV_KEYS, HTTPD_ENV);
- return join( "\n", map { "PerlPassEnv " . $_ } @env ) . "\n";
-}
-
###############
# Permissions #
###############
@@ -214,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 },
@@ -230,13 +181,13 @@ sub FILESYSTEM {
'jobqueue-worker.pl' => { perms => OWNER_EXECUTE },
'clean-bug-user-last-visit.pl' => { perms => WS_EXECUTE },
+ 'bugzilla.pl' => { perms => OWNER_EXECUTE },
'Bugzilla.pm' => { perms => CGI_READ },
"$localconfig*" => { perms => CGI_READ },
'META.*' => { perms => CGI_READ },
'MYMETA.*' => { perms => CGI_READ },
'bugzilla.dtd' => { perms => WS_SERVE },
'mod_perl.pl' => { perms => WS_SERVE },
- '.htaccess' => { perms => WS_SERVE },
'cvs-update.log' => { perms => WS_SERVE },
'scripts/sendunsentbugmail.pl' => { perms => WS_EXECUTE },
'docs/bugzilla.ent' => { perms => OWNER_WRITE },
@@ -345,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 --- #
@@ -427,65 +378,26 @@ sub FILESYSTEM {
"skins/yui3.css" => { perms => CGI_READ,
overwrite => 1,
contents => $yui3_all_css },
- "$confdir/env.conf" => { perms => CGI_READ,
- overwrite => 1,
- contents => \&HTTPD_ENV_CONF },
);
+ # 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 = (
'index.html' => { perms => WS_SERVE, contents => INDEX_HTML }
);
- # Because checksetup controls the .htaccess creation separately
- # by a localconfig variable, these go in a separate variable from
- # %create_files.
- #
- # Note that these get WS_SERVE as their permission
- # because they're *read* by the webserver, even though they're not
- # actually, themselves, served.
- my %htaccess = (
- "$attachdir/.htaccess" => { perms => WS_SERVE,
- contents => HT_DEFAULT_DENY },
- "$libdir/Bugzilla/.htaccess" => { perms => WS_SERVE,
- contents => HT_DEFAULT_DENY },
- "$extlib/.htaccess" => { perms => WS_SERVE,
- contents => HT_DEFAULT_DENY },
- "$templatedir/.htaccess" => { perms => WS_SERVE,
- contents => HT_DEFAULT_DENY },
- 'contrib/.htaccess' => { perms => WS_SERVE,
- contents => HT_DEFAULT_DENY },
- 'scripts/.htaccess' => { perms => WS_SERVE,
- contents => HT_DEFAULT_DENY },
- 't/.htaccess' => { perms => WS_SERVE,
- contents => HT_DEFAULT_DENY },
- 'xt/.htaccess' => { perms => WS_SERVE,
- contents => HT_DEFAULT_DENY },
- '.circleci/.htaccess' => { perms => WS_SERVE,
- contents => HT_DEFAULT_DENY },
- "$confdir/.htaccess" => { perms => WS_SERVE,
- contents => HT_DEFAULT_DENY },
- "$datadir/.htaccess" => { perms => WS_SERVE,
- contents => HT_DEFAULT_DENY },
- "$graphsdir/.htaccess" => { perms => WS_SERVE,
- contents => HT_GRAPHS_DIR },
- "$webdotdir/.htaccess" => { perms => WS_SERVE,
- contents => HT_WEBDOT_DIR },
- "$assetsdir/.htaccess" => { perms => WS_SERVE,
- contents => HT_ASSETS_DIR },
- );
-
Bugzilla::Hook::process('install_filesystem', {
files => \%files,
create_dirs => \%create_dirs,
non_recurse_dirs => \%non_recurse_dirs,
recurse_dirs => \%recurse_dirs,
create_files => \%create_files,
- htaccess => \%htaccess,
});
- my %all_files = (%create_files, %htaccess, %index_html, %files);
+ my %all_files = (%create_files, %index_html, %files);
my %all_dirs = (%create_dirs, %non_recurse_dirs);
return {
@@ -494,7 +406,6 @@ sub FILESYSTEM {
all_dirs => \%all_dirs,
create_files => \%create_files,
- htaccess => \%htaccess,
index_html => \%index_html,
all_files => \%all_files,
};
@@ -542,13 +453,6 @@ sub update_filesystem {
_rename_file($oldparamsfile, "$datadir/$oldparamsfile");
}
- # Remove old assets htaccess file to force recreation with correct values.
- if (-e "$assetsdir/.htaccess") {
- if (read_file("$assetsdir/.htaccess") =~ /<FilesMatch \\\.css\$>/) {
- unlink("$assetsdir/.htaccess");
- }
- }
-
_create_files(%files);
if ($params->{index_html}) {
_create_files(%{$fs->{index_html}});
@@ -564,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");
@@ -653,27 +557,6 @@ sub _convert_single_file_skins {
}
}
-sub create_htaccess {
- _create_files(%{FILESYSTEM()->{htaccess}});
-
- # Repair old .htaccess files
-
- my $webdot_dir = bz_locations()->{'webdotdir'};
- # The public webdot IP address changed.
- my $webdot = new IO::File("$webdot_dir/.htaccess", 'r')
- || die "$webdot_dir/.htaccess: $!";
- my $webdot_data;
- { local $/; $webdot_data = <$webdot>; }
- $webdot->close;
- if ($webdot_data =~ /192\.20\.225\.10/) {
- print "Repairing $webdot_dir/.htaccess...\n";
- $webdot_data =~ s/192\.20\.225\.10/192.20.225.0\/24/g;
- $webdot = new IO::File("$webdot_dir/.htaccess", 'w') || die $!;
- print $webdot $webdot_data;
- $webdot->close;
- }
-}
-
sub _rename_file {
my ($from, $to) = @_;
print install_string('file_rename', { from => $from, to => $to }), "\n";
@@ -984,16 +867,6 @@ Params: C<index_html> - Whether or not we should create
Returns: nothing
-=item C<create_htaccess()>
-
-Description: Creates all of the .htaccess files for Apache,
- in the various Bugzilla directories. Also updates
- the .htaccess files if they need updating.
-
-Params: none
-
-Returns: nothing
-
=item C<fix_all_file_permissions($output)>
Description: Sets all the file permissions on all of Bugzilla's files
diff --git a/Bugzilla/Memcached.pm b/Bugzilla/Memcached.pm
index 40755aa29..6bbef080a 100644
--- a/Bugzilla/Memcached.pm
+++ b/Bugzilla/Memcached.pm
@@ -25,6 +25,8 @@ use Sys::Syslog qw(:DEFAULT);
use constant MAX_KEY_LENGTH => 250;
use constant RATE_LIMIT_PREFIX => "rate:";
+*new = \&_new;
+
sub _new {
my $invocant = shift;
my $class = ref($invocant) || $invocant;
diff --git a/Bugzilla/ModPerl.pm b/Bugzilla/ModPerl.pm
deleted file mode 100644
index 19cd1128f..000000000
--- a/Bugzilla/ModPerl.pm
+++ /dev/null
@@ -1,118 +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::ModPerl;
-
-use 5.10.1;
-use strict;
-use warnings;
-
-use File::Find ();
-use Cwd ();
-use Carp ();
-
-# We don't need (or want) to use Bugzilla's template subclass.
-# it is easier to reason with the code without all the extra things Bugzilla::Template adds
-# (and there might be side-effects, since this code is loaded very early in the httpd startup)
-use Template ();
-
-use Bugzilla::ModPerl::BlockIP;
-use Bugzilla::ModPerl::Hostage;
-
-sub apache_config {
- my ($class, $cgi_path) = @_;
-
- Carp::croak "\$cgi_path is required" unless $cgi_path;
-
- my %htaccess;
- $cgi_path = Cwd::realpath($cgi_path);
- my $wanted = sub {
- package File::Find;
- our ($name, $dir);
-
- if ($name =~ m#/\.htaccess$#) {
- open my $fh, '<', $name or die "cannot open $name $!";
- my $contents = do {
- local $/ = undef;
- <$fh>;
- };
- close $fh;
- $htaccess{$dir} = { file => $name, contents => $contents, dir => $dir };
- }
- };
-
- File::Find::find( { wanted => $wanted, no_chdir => 1 }, $cgi_path );
- my $template = Template->new;
- my $conf;
- my %vars = (
- root_htaccess => delete $htaccess{$cgi_path},
- htaccess_files => [ map { $htaccess{$_} } sort { length $a <=> length $b } keys %htaccess ],
- cgi_path => $cgi_path,
- );
- $template->process(\*DATA, \%vars, \$conf);
- my $apache_version = Apache2::ServerUtil::get_server_version();
- if ($apache_version =~ m!Apache/(\d+)\.(\d+)\.(\d+)!) {
- my ($major, $minor, $patch) = ($1, $2, $3);
- if ($major > 2 || $major == 2 && $minor >= 4) {
- $conf =~ s{^\s+deny\s+from\s+all.*$}{Require all denied}gmi;
- $conf =~ s{^\s+allow\s+from\s+all.*$}{Require all granted}gmi;
- $conf =~ s{^\s+allow\s+from\s+(\S+).*$}{Require host $1}gmi;
- }
- }
-
- return $conf;
-}
-
-1;
-
-__DATA__
-# Make sure each httpd child receives a different random seed (bug 476622).
-# Bugzilla::RNG has one srand that needs to be called for
-# every process, and Perl has another. (Various Perl modules still use
-# the built-in rand(), even though we never use it in Bugzilla itself,
-# so we need to srand() both of them.)
-PerlChildInitHandler "sub { Bugzilla::RNG::srand(); srand(); eval { Bugzilla->dbh->ping } }"
-PerlInitHandler Bugzilla::ModPerl::Hostage
-PerlAccessHandler Bugzilla::ModPerl::BlockIP
-
-# It is important to specify ErrorDocuments outside of all directories.
-# These used to be in .htaccess, but then things like "AllowEncodedSlashes no"
-# mean that urls containing %2f are unstyled.
-ErrorDocument 401 /errors/401.html
-ErrorDocument 403 /errors/403.html
-ErrorDocument 404 /errors/404.html
-ErrorDocument 500 /errors/500.html
-
-<Directory "[% cgi_path %]">
- AddHandler perl-script .cgi
- # No need to PerlModule these because they're already defined in mod_perl.pl
- PerlResponseHandler Bugzilla::ModPerl::ResponseHandler
- PerlCleanupHandler Bugzilla::ModPerl::CleanupHandler Apache2::SizeLimit
- PerlOptions +ParseHeaders
- Options +ExecCGI +FollowSymLinks
- DirectoryIndex index.cgi index.html
- AllowOverride none
- # from [% root_htaccess.file %]
- [% root_htaccess.contents FILTER indent %]
-</Directory>
-
-# AWS SES endpoint for handling mail bounces/complaints
-<Location "/ses">
- PerlSetEnv AUTH_VAR_NAME ses_username
- PerlSetEnv AUTH_VAR_PASS ses_password
- PerlAuthenHandler Bugzilla::ModPerl::BasicAuth
- AuthName SES
- AuthType Basic
- require valid-user
-</Location>
-
-# directory rules for all the other places we have .htaccess files
-[% FOREACH htaccess IN htaccess_files %]
-# from [% htaccess.file %]
-<Directory "[% htaccess.dir %]">
- [% htaccess.contents FILTER indent %]
-</Directory>
-[% END %]
diff --git a/Bugzilla/ModPerl/BasicAuth.pm b/Bugzilla/ModPerl/BasicAuth.pm
deleted file mode 100644
index 7248a19f3..000000000
--- a/Bugzilla/ModPerl/BasicAuth.pm
+++ /dev/null
@@ -1,65 +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::ModPerl::BasicAuth;
-use 5.10.1;
-use strict;
-use warnings;
-
-# Protects a mod_perl <Location> with Basic HTTP authentication.
-#
-# Example use:
-#
-# <Location "/ses">
-# PerlAuthenHandler Bugzilla::ModPerl::BasicAuth
-# PerlSetEnv AUTH_VAR_NAME ses_username
-# PerlSetEnv AUTH_VAR_PASS ses_password
-# AuthName SES
-# AuthType Basic
-# require valid-user
-# </Location>
-#
-# AUTH_VAR_NAME and AUTH_VAR_PASS are the names of variables defined in
-# `localconfig` which hold the authentication credentials.
-
-use Apache2::Const -compile => qw(OK HTTP_UNAUTHORIZED); ## no critic (Freenode::ModPerl)
-use Bugzilla::Logging;
-use Bugzilla ();
-
-sub handler {
- my $r = shift;
- my ($status, $password) = $r->get_basic_auth_pw;
- if ($status != Apache2::Const::OK) {
- WARN("Got non-OK status: $status when trying to get password");
- return $status
- }
-
- my $auth_var_name = $ENV{AUTH_VAR_NAME};
- my $auth_var_pass = $ENV{AUTH_VAR_PASS};
- unless ($auth_var_name && $auth_var_pass) {
- ERROR('AUTH_VAR_NAME and AUTH_VAR_PASS environmental vars not set');
- $r->note_basic_auth_failure;
- return Apache2::Const::HTTP_UNAUTHORIZED;
- }
-
- my $auth_user = Bugzilla->localconfig->{$auth_var_name};
- my $auth_pass = Bugzilla->localconfig->{$auth_var_pass};
- unless ($auth_user && $auth_pass) {
- ERROR("$auth_var_name and $auth_var_pass not configured");
- $r->note_basic_auth_failure;
- return Apache2::Const::HTTP_UNAUTHORIZED;
- }
-
- unless ($r->user eq $auth_user && $password eq $auth_pass) {
- $r->note_basic_auth_failure;
- WARN('username and password do not match');
- return Apache2::Const::HTTP_UNAUTHORIZED;
- }
-
- return Apache2::Const::OK;
-}
-
-1;
diff --git a/Bugzilla/ModPerl/BlockIP.pm b/Bugzilla/ModPerl/BlockIP.pm
deleted file mode 100644
index 4e9a4be5c..000000000
--- a/Bugzilla/ModPerl/BlockIP.pm
+++ /dev/null
@@ -1,65 +0,0 @@
-package Bugzilla::ModPerl::BlockIP;
-use 5.10.1;
-use strict;
-use warnings;
-
-use Apache2::RequestRec ();
-use Apache2::Connection ();
-
-use Apache2::Const -compile => qw(OK);
-use Cache::Memcached::Fast;
-
-use constant BLOCK_TIMEOUT => 60*60;
-
-my $MEMCACHED = Bugzilla::Memcached->_new()->{memcached};
-my $STATIC_URI = qr{
- ^/
- (?: extensions/[^/]+/web
- | robots\.txt
- | __heartbeat__
- | __lbheartbeat__
- | __version__
- | images
- | skins
- | js
- | errors
- )
-}xms;
-
-sub block_ip {
- my ($class, $ip) = @_;
- $MEMCACHED->set("block_ip:$ip" => 1, BLOCK_TIMEOUT) if $MEMCACHED;
-}
-
-sub unblock_ip {
- my ($class, $ip) = @_;
- $MEMCACHED->delete("block_ip:$ip") if $MEMCACHED;
-}
-
-sub handler {
- my $r = shift;
- return Apache2::Const::OK if $r->uri =~ $STATIC_URI;
-
- my $ip = $r->headers_in->{'X-Forwarded-For'};
- if ($ip) {
- $ip = (split(/\s*,\s*/ms, $ip))[-1];
- }
- else {
- $ip = $r->connection->remote_ip;
- }
-
- if ($MEMCACHED && $MEMCACHED->get("block_ip:$ip")) {
- __PACKAGE__->block_ip($ip);
- $r->status_line("429 Too Many Requests");
- # 500 is used here because apache 2.2 doesn't understand 429.
- # the above line and the return value together mean we produce 429.
- # Any other variation doesn't work.
- $r->custom_response(500, "Too Many Requests");
- return 429;
- }
- else {
- return Apache2::Const::OK;
- }
-}
-
-1;
diff --git a/Bugzilla/ModPerl/StartupFix.pm b/Bugzilla/ModPerl/StartupFix.pm
deleted file mode 100644
index bcc467e9f..000000000
--- a/Bugzilla/ModPerl/StartupFix.pm
+++ /dev/null
@@ -1,51 +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::ModPerl::StartupFix;
-use 5.10.1;
-use strict;
-use warnings;
-
-use Filter::Util::Call;
-use Apache2::ServerUtil ();
-
-# This module is a source filter that removes every subsequent line
-# if this is the first time apache has started,
-# as reported by Apache2::ServerUtil::restart_count(), which is 1
-# on the first start.
-
-my $FIRST_STARTUP = <<'CODE';
-warn "Bugzilla::ModPerl::StartupFix: Skipping first startup using source filter\n";
-1;
-CODE
-
-sub import {
- my ($class) = @_;
- my ($ref) = {};
- filter_add( bless $ref, $class );
-}
-
-# this will be called for each line.
-# For the first line replaced, we insert $FIRST_STARTUP.
-# Every subsequent line is replaced with an empty string.
-sub filter {
- my ($self) = @_;
- my ($status);
- if ($status = filter_read() > 0) {
- if (Apache2::ServerUtil::restart_count() < 2) {
- if (!$self->{did_it}) {
- $self->{did_it} = 1;
- $_ = $FIRST_STARTUP;
- }
- else {
- $_ = "";
- }
- }
- }
- return $status;
-}
-
-1; \ No newline at end of file
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.pm b/Bugzilla/Quantum.pm
new file mode 100644
index 000000000..34d6fc45d
--- /dev/null
+++ b/Bugzilla/Quantum.pm
@@ -0,0 +1,119 @@
+# 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;
+use Mojo::Base 'Mojolicious';
+
+# Needed for its exit() overload, must happen early in execution.
+use CGI::Compile;
+
+use Bugzilla ();
+use Bugzilla::BugMail ();
+use Bugzilla::CGI ();
+use Bugzilla::Constants qw(bz_locations);
+use Bugzilla::Extension ();
+use Bugzilla::Install::Requirements ();
+use Bugzilla::Logging;
+use Bugzilla::Quantum::CGI;
+use Bugzilla::Quantum::SES;
+use Bugzilla::Quantum::Static;
+use Mojo::Loader qw( find_modules );
+use Module::Runtime qw( require_module );
+use Bugzilla::Util ();
+use Cwd qw(realpath);
+use MojoX::Log::Log4perl::Tiny;
+
+has 'static' => sub { Bugzilla::Quantum::Static->new };
+
+sub startup {
+ my ($self) = @_;
+
+ DEBUG('Starting up');
+ $self->plugin('Bugzilla::Quantum::Plugin::Glue');
+ $self->plugin('Bugzilla::Quantum::Plugin::Hostage');
+ $self->plugin('Bugzilla::Quantum::Plugin::BlockIP');
+ $self->plugin('Bugzilla::Quantum::Plugin::BasicAuth');
+
+ Bugzilla::Extension->load_all();
+ if ( $self->mode ne 'development' ) {
+ Bugzilla->preload_features();
+ DEBUG('preloading templates');
+ Bugzilla->preload_templates();
+ DEBUG('done preloading templates');
+ require_module($_) for find_modules('Bugzilla::User::Setting');
+
+ $self->hook(
+ after_static => sub {
+ my ($c) = @_;
+ $c->res->headers->cache_control('public, max-age=31536000');
+ }
+ );
+ }
+
+ my $r = $self->routes;
+ Bugzilla::Quantum::CGI->load_all($r);
+ Bugzilla::Quantum::CGI->load_one( 'bzapi_cgi', 'extensions/BzAPI/bin/rest.cgi' );
+
+ Bugzilla::WebService::Server::REST->preload;
+
+ $r->any('/')->to('CGI#index_cgi');
+ $r->any('/bug/<id:num>')->to('CGI#show_bug_cgi');
+ $r->any('/<id:num>')->to('CGI#show_bug_cgi');
+
+ $r->any('/rest')->to('CGI#rest_cgi');
+ $r->any('/rest.cgi/*PATH_INFO')->to( 'CGI#rest_cgi' => { PATH_INFO => '' } );
+ $r->any('/rest/*PATH_INFO')->to( 'CGI#rest_cgi' => { PATH_INFO => '' } );
+ $r->any('/bzapi')->to('CGI#bzapi_cgi');
+ $r->any('/bzapi/*PATH_INFO')->to('CGI#bzapi_cgi');
+ $r->any('/extensions/BzAPI/bin/rest.cgi/*PATH_INFO')->to('CGI#bzapi_cgi');
+
+ $r->get(
+ '/__lbheartbeat__' => sub {
+ my $c = shift;
+ $c->reply->file( $c->app->home->child('__lbheartbeat__') );
+ },
+ );
+
+ $r->get(
+ '/__version__' => sub {
+ my $c = shift;
+ $c->reply->file( $c->app->home->child('version.json') );
+ },
+ );
+
+ $r->get(
+ '/version.json' => sub {
+ my $c = shift;
+ $c->reply->file( $c->app->home->child('version.json') );
+ },
+ );
+
+ $r->get('/__heartbeat__')->to('CGI#heartbeat_cgi');
+ $r->get('/robots.txt')->to('CGI#robots_cgi');
+
+ $r->any('/review')->to( 'CGI#page_cgi' => { 'id' => 'splinter.html' } );
+ $r->any('/user_profile')->to( 'CGI#page_cgi' => { 'id' => 'user_profile.html' } );
+ $r->any('/userprofile')->to( 'CGI#page_cgi' => { 'id' => 'user_profile.html' } );
+ $r->any('/request_defer')->to( 'CGI#page_cgi' => { 'id' => 'request_defer.html' } );
+ $r->any('/login')->to( 'CGI#index_cgi' => { 'GoAheadAndLogIn' => '1' } );
+
+ $r->any( '/:new_bug' => [ new_bug => qr{new[-_]bug} ] )->to('CGI#new_bug_cgi');
+
+ my $ses_auth = $r->under(
+ '/ses' => sub {
+ my ($c) = @_;
+ my $lc = Bugzilla->localconfig;
+
+ return $c->basic_auth( 'SES', $lc->{ses_username}, $lc->{ses_password} );
+ }
+ );
+ $ses_auth->any('/index.cgi')->to('SES#main');
+
+ Bugzilla::Hook::process( 'app_startup', { app => $self } );
+}
+
+1;
diff --git a/Bugzilla/Quantum/CGI.pm b/Bugzilla/Quantum/CGI.pm
new file mode 100644
index 000000000..7548c0809
--- /dev/null
+++ b/Bugzilla/Quantum/CGI.pm
@@ -0,0 +1,161 @@
+# 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::CGI;
+use Mojo::Base 'Mojolicious::Controller';
+
+use CGI::Compile;
+use Try::Tiny;
+use Taint::Util qw(untaint);
+use Sys::Hostname;
+use Sub::Quote 2.005000;
+use Sub::Name;
+use Socket qw(AF_INET inet_aton);
+use File::Spec::Functions qw(catfile);
+use File::Slurper qw(read_text);
+use English qw(-no_match_vars);
+use Bugzilla::Quantum::Stdout;
+use Bugzilla::Constants qw(bz_locations);
+
+our $C;
+my %SEEN;
+
+sub load_all {
+ my ( $class, $r ) = @_;
+
+ foreach my $file ( glob '*.cgi' ) {
+ my $name = _file_to_method($file);
+ $class->load_one( $name, $file );
+ $r->any("/$file")->to("CGI#$name");
+ }
+}
+
+sub load_one {
+ my ( $class, $name, $file ) = @_;
+ my $package = __PACKAGE__ . "::$name", my $inner_name = "_$name";
+ my $content = read_text( catfile( bz_locations->{cgi_path}, $file ) );
+ $content = "package $package; $content";
+ untaint($content);
+ my %options = (
+ package => $package,
+ file => $file,
+ line => 1,
+ no_defer => 1,
+ );
+ die "Tried to load $file more than once" if $SEEN{$file}++;
+ my $inner = quote_sub $inner_name, $content, {}, \%options;
+ my $wrapper = sub {
+ my ($c) = @_;
+ my $stdin = $c->_STDIN;
+ local $C = $c;
+ local %ENV = $c->_ENV($file);
+ local $CGI::Compile::USE_REAL_EXIT = 0;
+ local $PROGRAM_NAME = $file;
+ local *STDIN; ## no critic (local)
+ open STDIN, '<', $stdin->path or die "STDIN @{[$stdin->path]}: $!" if -s $stdin->path;
+ tie *STDOUT, 'Bugzilla::Quantum::Stdout', controller => $c; ## no critic (tie)
+ try {
+ Bugzilla->init_page();
+ $inner->();
+ }
+ catch {
+ die $_ unless ref $_ eq 'ARRAY' && $_->[0] eq "EXIT\n";
+ }
+ finally {
+ my $error = shift;
+ untie *STDOUT;
+ $c->finish unless $error;
+ Bugzilla->cleanup;
+ CGI::initialize_globals();
+ };
+ };
+
+ no strict 'refs'; ## no critic (strict)
+ *{$name} = subname( $name, $wrapper );
+ return 1;
+}
+
+
+sub _ENV {
+ my ( $c, $script_name ) = @_;
+ my $tx = $c->tx;
+ my $req = $tx->req;
+ my $headers = $req->headers;
+ my $content_length = $req->content->is_multipart ? $req->body_size : $headers->content_length;
+ my %env_headers = ( HTTP_COOKIE => '', HTTP_REFERER => '' );
+
+ for my $name ( @{ $headers->names } ) {
+ my $key = uc "http_$name";
+ $key =~ s/\W/_/g;
+ $env_headers{$key} = $headers->header($name);
+ }
+
+ my $remote_user;
+ if ( my $userinfo = $req->url->to_abs->userinfo ) {
+ $remote_user = $userinfo =~ /([^:]+)/ ? $1 : '';
+ }
+ elsif ( my $authenticate = $headers->authorization ) {
+ $remote_user = $authenticate =~ /Basic\s+(.*)/ ? b64_decode $1 : '';
+ $remote_user = $remote_user =~ /([^:]+)/ ? $1 : '';
+ }
+ my $path_info = $c->stash->{'mojo.captures'}{'PATH_INFO'};
+ my %captures = %{ $c->stash->{'mojo.captures'} // {} };
+ foreach my $key ( keys %captures ) {
+ if ( $key eq 'controller' || $key eq 'action' || $key eq 'PATH_INFO' || $key =~ /^REWRITE_/ ) {
+ delete $captures{$key};
+ }
+ }
+ my $cgi_query = Mojo::Parameters->new(%captures);
+ $cgi_query->append( $req->url->query );
+ my $prefix = $c->stash->{bmo_prefix} ? '/bmo/' : '/';
+
+ return (
+ %ENV,
+ CONTENT_LENGTH => $content_length || 0,
+ CONTENT_TYPE => $headers->content_type || '',
+ GATEWAY_INTERFACE => 'CGI/1.1',
+ HTTPS => $req->is_secure ? 'on' : 'off',
+ %env_headers,
+ QUERY_STRING => $cgi_query->to_string,
+ PATH_INFO => $path_info ? "/$path_info" : '',
+ REMOTE_ADDR => $tx->original_remote_address,
+ REMOTE_HOST => $tx->original_remote_address,
+ REMOTE_PORT => $tx->remote_port,
+ REMOTE_USER => $remote_user || '',
+ REQUEST_METHOD => $req->method,
+ SCRIPT_NAME => "$prefix$script_name",
+ SERVER_NAME => hostname,
+ SERVER_PORT => $tx->local_port,
+ SERVER_PROTOCOL => $req->is_secure ? 'HTTPS' : 'HTTP', # TODO: Version is missing
+ SERVER_SOFTWARE => __PACKAGE__,
+ );
+}
+
+sub _STDIN {
+ my $c = shift;
+ my $stdin;
+
+ if ( $c->req->content->is_multipart ) {
+ $stdin = Mojo::Asset::File->new;
+ $stdin->add_chunk( $c->req->build_body );
+ }
+ else {
+ $stdin = $c->req->content->asset;
+ }
+
+ return $stdin if $stdin->isa('Mojo::Asset::File');
+ return Mojo::Asset::File->new->add_chunk( $stdin->slurp );
+}
+
+sub _file_to_method {
+ my ($name) = @_;
+ $name =~ s/\./_/s;
+ $name =~ s/\W+/_/gs;
+ return $name;
+}
+
+1;
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/BlockIP.pm b/Bugzilla/Quantum/Plugin/BlockIP.pm
new file mode 100644
index 000000000..058ecbf64
--- /dev/null
+++ b/Bugzilla/Quantum/Plugin/BlockIP.pm
@@ -0,0 +1,43 @@
+package Bugzilla::Quantum::Plugin::BlockIP;
+use 5.10.1;
+use Mojo::Base 'Mojolicious::Plugin';
+
+use Bugzilla::Memcached;
+
+use constant BLOCK_TIMEOUT => 60 * 60;
+
+my $MEMCACHED = Bugzilla::Memcached->new()->{memcached};
+
+sub register {
+ my ( $self, $app, $conf ) = @_;
+
+ $app->hook( before_routes => \&_before_routes );
+ $app->helper( block_ip => \&_block_ip );
+ $app->helper( unblock_ip => \&_unblock_ip );
+}
+
+sub _block_ip {
+ my ( $class, $ip ) = @_;
+ $MEMCACHED->set( "block_ip:$ip" => 1, BLOCK_TIMEOUT ) if $MEMCACHED;
+}
+
+sub _unblock_ip {
+ my ( $class, $ip ) = @_;
+ $MEMCACHED->delete("block_ip:$ip") if $MEMCACHED;
+}
+
+sub _before_routes {
+ my ($c) = @_;
+ return if $c->stash->{'mojo.static'};
+
+ my $ip = $c->tx->remote_address;
+ if ( $MEMCACHED && $MEMCACHED->get("block_ip:$ip") ) {
+ $c->block_ip($ip);
+ $c->res->code(429);
+ $c->res->message('Too Many Requests');
+ $c->res->body('Too Many Requests');
+ $c->finish;
+ }
+}
+
+1;
diff --git a/Bugzilla/Quantum/Plugin/Glue.pm b/Bugzilla/Quantum/Plugin/Glue.pm
new file mode 100644
index 000000000..ded4daf15
--- /dev/null
+++ b/Bugzilla/Quantum/Plugin/Glue.pm
@@ -0,0 +1,101 @@
+# 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::Glue;
+use 5.10.1;
+use Mojo::Base 'Mojolicious::Plugin';
+
+use Try::Tiny;
+use Bugzilla::Constants;
+use Bugzilla::Logging;
+use Bugzilla::RNG ();
+use JSON::MaybeXS qw(decode_json);
+
+sub register {
+ my ( $self, $app, $conf ) = @_;
+
+ my %D;
+ if ( $ENV{BUGZILLA_HTTPD_ARGS} ) {
+ my $args = decode_json( $ENV{BUGZILLA_HTTPD_ARGS} );
+ foreach my $arg (@$args) {
+ if ( $arg =~ /^-D(\w+)$/ ) {
+ $D{$1} = 1;
+ }
+ else {
+ die "Unknown httpd arg: $arg";
+ }
+ }
+ }
+
+ # hypnotoad is weird and doesn't look for MOJO_LISTEN itself.
+ $app->config(
+ hypnotoad => {
+ proxy => 1,
+ listen => [ $ENV{MOJO_LISTEN} ],
+ },
+ );
+
+ # Make sure each httpd child receives a different random seed (bug 476622).
+ # Bugzilla::RNG has one srand that needs to be called for
+ # every process, and Perl has another. (Various Perl modules still use
+ # the built-in rand(), even though we never use it in Bugzilla itself,
+ # so we need to srand() both of them.)
+ # Also, ping the dbh to force a reconnection.
+ Mojo::IOLoop->next_tick(
+ sub {
+ Bugzilla::RNG::srand();
+ srand();
+ try { Bugzilla->dbh->ping };
+ }
+ );
+
+ $app->hook(
+ before_dispatch => sub {
+ my ($c) = @_;
+ if ( $D{HTTPD_IN_SUBDIR} ) {
+ my $path = $c->req->url->path;
+ if ( $path =~ s{^/bmo}{}s ) {
+ $c->stash->{bmo_prefix} = 1;
+ $c->req->url->path($path);
+ }
+ }
+ Log::Log4perl::MDC->put( request_id => $c->req->request_id );
+ }
+ );
+
+
+ $app->secrets( [ Bugzilla->localconfig->{side_wide_secret} ] );
+
+ $app->renderer->add_handler(
+ 'bugzilla' => sub {
+ my ( $renderer, $c, $output, $options ) = @_;
+ my $vars = delete $c->stash->{vars};
+
+ # Helpers
+ my %helper;
+ foreach my $method ( grep {m/^\w+\z/} keys %{ $renderer->helpers } ) {
+ my $sub = $renderer->helpers->{$method};
+ $helper{$method} = sub { $c->$sub(@_) };
+ }
+ $vars->{helper} = \%helper;
+
+ # The controller
+ $vars->{c} = $c;
+ my $name = $options->{template};
+ unless ( $name =~ /\./ ) {
+ $name = sprintf '%s.%s.tmpl', $options->{template}, $options->{format};
+ }
+ my $template = Bugzilla->template;
+ $template->process( $name, $vars, $output )
+ or die $template->error;
+ }
+ );
+
+ $app->log( MojoX::Log::Log4perl::Tiny->new( logger => Log::Log4perl->get_logger( ref $app ) ) );
+}
+
+1;
diff --git a/Bugzilla/ModPerl/Hostage.pm b/Bugzilla/Quantum/Plugin/Hostage.pm
index a3bdfac58..418b09a0c 100644
--- a/Bugzilla/ModPerl/Hostage.pm
+++ b/Bugzilla/Quantum/Plugin/Hostage.pm
@@ -1,9 +1,6 @@
-package Bugzilla::ModPerl::Hostage;
+package Bugzilla::Quantum::Plugin::Hostage;
use 5.10.1;
-use strict;
-use warnings;
-
-use Apache2::Const qw(:common); ## no critic (Freenode::ModPerl)
+use Mojo::Base 'Mojolicious::Plugin';
sub _attachment_root {
my ($base) = @_;
@@ -24,8 +21,14 @@ sub _attachment_host_regex {
return qr/^$regex$/s;
}
-sub handler {
- my $r = shift;
+sub register {
+ my ( $self, $app, $conf ) = @_;
+
+ $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;
@@ -34,38 +37,44 @@ sub handler {
state $attachment_root = _attachment_root($attachment_base);
state $attachment_host_regex = _attachment_host_regex($attachment_base);
- my $hostname = $r->hostname;
- return OK if $hostname eq $urlbase_host;
+ my $stash = $c->stash;
+ my $req = $c->req;
+ my $url = $req->url->to_abs;
+
+ return if $stash->{'mojo.static'};
+
+ my $hostname = $url->host;
+ return if $hostname eq $urlbase_host;
- my $path = $r->uri;
- return OK if $path eq '/__lbheartbeat__';
+ my $path = $url->path;
+ return if $path eq '/__lbheartbeat__';
if ($attachment_base && $hostname eq $attachment_root) {
- $r->headers_out->set(Location => $urlbase);
- return REDIRECT;
+ $c->redirect_to($urlbase);
+ return;
}
elsif ($attachment_base && $hostname =~ $attachment_host_regex) {
if ($path =~ m{^/attachment\.cgi}s) {
- return OK;
+ return;
} else {
- my $new_uri = URI->new($r->unparsed_uri);
+ my $new_uri = $url->clone;
$new_uri->scheme($urlbase_uri->scheme);
$new_uri->host($urlbase_host);
- $r->headers_out->set(Location => $new_uri);
- return REDIRECT;
+ $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);
- $r->headers_out->set(Location => $new_uri);
- return REDIRECT;
+ $c->redirect_to($new_uri);
+ return;
}
else {
- $r->headers_out->set(Location => $urlbase);
- return REDIRECT;
+ $c->redirect_to($urlbase);
+ return;
}
}
-1; \ No newline at end of file
+1;
diff --git a/ses/index.cgi b/Bugzilla/Quantum/SES.pm
index e36956b1d..03916075d 100755..100644
--- a/ses/index.cgi
+++ b/Bugzilla/Quantum/SES.pm
@@ -1,4 +1,4 @@
-#!/usr/bin/perl
+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/.
@@ -7,12 +7,8 @@
# defined by the Mozilla Public License, v. 2.0.
use 5.10.1;
-use strict;
-use warnings;
+use Mojo::Base qw( Mojolicious::Controller );
-use lib qw(.. ../lib ../local/lib/perl5);
-
-use Bugzilla ();
use Bugzilla::Constants qw(ERROR_MODE_DIE);
use Bugzilla::Logging;
use Bugzilla::Mailer qw(MessageToMTA);
@@ -22,51 +18,62 @@ use JSON::MaybeXS qw(decode_json);
use LWP::UserAgent ();
use Try::Tiny qw(catch try);
-Bugzilla->error_mode(ERROR_MODE_DIE);
-try {
- main();
-}
-catch {
- FATAL("Fatal error: $_");
- respond( 500 => 'Internal Server Error' );
-};
+use Types::Standard qw( :all );
+use Type::Utils;
+use Type::Params qw( compile );
+
+my $Invocant = class_type { class => __PACKAGE__ };
sub main {
- my $message = decode_json_wrapper( Bugzilla->cgi->param('POSTDATA') ) // return;
- my $message_type = $ENV{HTTP_X_AMZ_SNS_MESSAGE_TYPE} // '(missing)';
+ 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' ) {
- confirm_subscription($message);
+ $self->_confirm_subscription($message);
}
elsif ( $message_type eq 'Notification' ) {
- my $notification = decode_json_wrapper( $message->{Message} ) // return;
+ my $notification = $self->_decode_json_wrapper( $message->{Message} ) // return;
unless (
# https://docs.aws.amazon.com/ses/latest/DeveloperGuide/event-publishing-retrieving-sns-contents.html
- handle_notification( $notification, 'eventType' )
+ $self->_handle_notification( $notification, 'eventType' )
# https://docs.aws.amazon.com/ses/latest/DeveloperGuide/notification-contents.html
- || handle_notification( $notification, 'notificationType' )
+ || $self->_handle_notification( $notification, 'notificationType' )
)
{
WARN('Failed to find notification type');
- respond( 400 => 'Bad Request' );
+ $self->_respond( 400 => 'Bad Request' );
}
}
else {
WARN("Unsupported message-type: $message_type");
- respond( 200 => 'OK' );
+ $self->_respond( 200 => 'OK' );
}
}
-sub confirm_subscription {
- my ($message) = @_;
+sub _confirm_subscription {
+ 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');
- respond( 400 => 'Bad Request' );
+ $self->_respond( 400 => 'Bad Request' );
return;
}
@@ -74,15 +81,24 @@ sub confirm_subscription {
my $res = $ua->get( $message->{SubscribeURL} );
if ( !$res->is_success ) {
WARN( 'Bad response from SubscribeURL: ' . $res->status_line );
- respond( 400 => 'Bad Request' );
+ $self->_respond( 400 => 'Bad Request' );
return;
}
- respond( 200 => 'OK' );
+ $self->_respond( 200 => 'OK' );
}
-sub handle_notification {
- my ( $notification, $type_field ) = @_;
+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($Invocant, $Notification, $TypeField );
+ my ( $self, $notification, $type_field ) = $check->(@_);
if ( !exists $notification->{$type_field} ) {
return 0;
@@ -90,20 +106,40 @@ sub handle_notification {
my $type = $notification->{$type_field};
if ( $type eq 'Bounce' ) {
- process_bounce($notification);
+ $self->_process_bounce($notification);
}
elsif ( $type eq 'Complaint' ) {
- process_complaint($notification);
+ $self->_process_complaint($notification);
}
else {
WARN("Unsupported notification-type: $type");
- respond( 200 => 'OK' );
+ $self->_respond( 200 => 'OK' );
}
return 1;
}
-sub process_bounce {
- my ($notification) = @_;
+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} } ) {
@@ -140,13 +176,22 @@ sub process_bounce {
}
}
- respond( 200 => 'OK' );
+ $self->_respond( 200 => 'OK' );
}
-sub process_complaint {
-
- # email notification to bugzilla admin
- my ($notification) = @_;
+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($Invocant, $ComplaintNotification);
+ my ($self, $notification) = $check->(@_);
my $template = Bugzilla->template_inner();
my $json = JSON::MaybeXS->new(
pretty => 1,
@@ -170,31 +215,24 @@ sub process_complaint {
MessageToMTA($message);
}
- respond( 200 => 'OK' );
+ $self->_respond( 200 => 'OK' );
}
-sub respond {
- my ( $code, $message ) = @_;
- print Bugzilla->cgi->header( -status => "$code $message" );
-
- # apache will generate non-200 response pages for us
- say html_quote($message) if $code == 200;
+sub _respond {
+ my ( $self, $code, $message ) = @_;
+ $self->render(text => "$message\n", status => $code);
}
-sub decode_json_wrapper {
- my ($json) = @_;
+sub _decode_json_wrapper {
+ state $check = compile($Invocant, Str);
+ my ($self, $json) = $check->(@_);
my $result;
- if ( !defined $json ) {
- WARN( 'Missing JSON from ' . remote_ip() );
- respond( 400 => 'Bad Request' );
- return undef;
- }
my $ok = try {
$result = decode_json($json);
}
catch {
- WARN( 'Malformed JSON from ' . remote_ip() );
- respond( 400 => 'Bad Request' );
+ WARN( 'Malformed JSON from ' . $self->tx->remote_address );
+ $self->_respond( 400 => 'Bad Request' );
return undef;
};
return $ok ? $result : undef;
@@ -212,3 +250,5 @@ sub ua {
}
return $ua;
}
+
+1;
diff --git a/Bugzilla/Quantum/Static.pm b/Bugzilla/Quantum/Static.pm
new file mode 100644
index 000000000..c01f062a4
--- /dev/null
+++ b/Bugzilla/Quantum/Static.pm
@@ -0,0 +1,30 @@
+# 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::Static;
+use Mojo::Base 'Mojolicious::Static';
+use Bugzilla::Constants qw(bz_locations);
+
+my $LEGACY_RE = qr{
+ ^ (?:static/v[0-9]+\.[0-9]+/) ?
+ ( (?:extensions/[^/]+/web|(?:image|graph|skin|j)s)/.+)
+ $
+}xs;
+
+sub file {
+ my ( $self, $rel ) = @_;
+
+ if ( my ($legacy_rel) = $rel =~ $LEGACY_RE ) {
+ local $self->{paths} = [ bz_locations->{cgi_path} ];
+ return $self->SUPER::file($legacy_rel);
+ }
+ else {
+ return $self->SUPER::file($rel);
+ }
+}
+
+1;
diff --git a/Bugzilla/Quantum/Stdout.pm b/Bugzilla/Quantum/Stdout.pm
new file mode 100644
index 000000000..9cf19992c
--- /dev/null
+++ b/Bugzilla/Quantum/Stdout.pm
@@ -0,0 +1,60 @@
+# 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::Stdout;
+use 5.10.1;
+use Moo;
+
+use Bugzilla::Logging;
+use Encode;
+use English qw(-no_match_vars);
+
+has 'controller' => (
+ is => 'ro',
+ required => 1,
+);
+
+has '_encoding' => (
+ is => 'rw',
+ default => '',
+);
+
+sub TIEHANDLE { ## no critic (unpack)
+ my $class = shift;
+
+ return $class->new(@_);
+}
+
+sub PRINTF { ## no critic (unpack)
+ my $self = shift;
+ $self->PRINT( sprintf @_ );
+}
+
+sub PRINT { ## no critic (unpack)
+ my $self = shift;
+ my $c = $self->controller;
+ my $bytes = join '', @_;
+ return unless $bytes;
+ if ( $self->_encoding ) {
+ $bytes = encode( $self->_encoding, $bytes );
+ }
+ $c->write($bytes . ( $OUTPUT_RECORD_SEPARATOR // '' ) );
+}
+
+sub BINMODE {
+ my ( $self, $mode ) = @_;
+ if ($mode) {
+ if ( $mode eq ':bytes' or $mode eq ':raw' ) {
+ $self->_encoding('');
+ }
+ elsif ( $mode eq ':utf8' ) {
+ $self->_encoding('utf8');
+ }
+ }
+}
+
+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 299734d64..cdeb54a50 100644
--- a/Bugzilla/Template.pm
+++ b/Bugzilla/Template.pm
@@ -12,6 +12,7 @@ use 5.10.1;
use strict;
use warnings;
+use Bugzilla::Logging;
use Bugzilla::Template::PreloadProvider;
use Bugzilla::Bug;
use Bugzilla::Constants;
@@ -994,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/Bugzilla/Util.pm b/Bugzilla/Util.pm
index a8477a62d..aa524b263 100644
--- a/Bugzilla/Util.pm
+++ b/Bugzilla/Util.pm
@@ -29,7 +29,7 @@ use base qw(Exporter);
get_text template_var disable_utf8
enable_utf8 detect_encoding email_filter
round extract_nicks);
-
+use Bugzilla::Logging;
use Bugzilla::Constants;
use Bugzilla::RNG qw(irand);
@@ -317,6 +317,7 @@ sub do_ssl_redirect_if_required {
# If we're already running under SSL, never redirect.
return if $ENV{HTTPS} && $ENV{HTTPS} eq 'on';
+ DEBUG("Redirect to HTTPS because \$ENV{HTTPS}=$ENV{HTTPS}");
Bugzilla->cgi->redirect_to_https();
}
diff --git a/Bugzilla/WebService/Server/XMLRPC.pm b/Bugzilla/WebService/Server/XMLRPC.pm
index 6bb73af01..5ad50e91c 100644
--- a/Bugzilla/WebService/Server/XMLRPC.pm
+++ b/Bugzilla/WebService/Server/XMLRPC.pm
@@ -14,11 +14,7 @@ use warnings;
use Bugzilla::Logging;
use XMLRPC::Transport::HTTP;
use Bugzilla::WebService::Server;
-if ($ENV{MOD_PERL}) {
- our @ISA = qw(XMLRPC::Transport::HTTP::Apache Bugzilla::WebService::Server);
-} else {
- our @ISA = qw(XMLRPC::Transport::HTTP::CGI Bugzilla::WebService::Server);
-}
+our @ISA = qw(XMLRPC::Transport::HTTP::CGI Bugzilla::WebService::Server);
use Bugzilla::WebService::Constants;
use Bugzilla::Error;
diff --git a/Bugzilla/WebService/Util.pm b/Bugzilla/WebService/Util.pm
index 29ff05448..d462c884a 100644
--- a/Bugzilla/WebService/Util.pm
+++ b/Bugzilla/WebService/Util.pm
@@ -23,7 +23,7 @@ use base qw(Exporter);
# We have to "require", not "use" this, because otherwise it tries to
# use features of Test::More during import().
-require Test::Taint;
+require Test::Taint if ${^TAINT};
our @EXPORT_OK = qw(
extract_flags
@@ -193,8 +193,10 @@ sub taint_data {
# Though this is a private function, it hasn't changed since 2004 and
# should be safe to use, and prevents us from having to write it ourselves
# or require another module to do it.
- Test::Taint::_deeply_traverse(\&_delete_bad_keys, \@params);
- Test::Taint::taint_deeply(\@params);
+ if (${^TAINT}) {
+ Test::Taint::_deeply_traverse(\&_delete_bad_keys, \@params);
+ Test::Taint::taint_deeply(\@params);
+ }
}
sub _delete_bad_keys {
diff --git a/Dockerfile b/Dockerfile
index 6426f1ad8..fd02f222d 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-FROM mozillabteam/bmo-slim:20180801.2
+FROM mozillabteam/bmo-slim:20180809.1
ARG CI
ARG CIRCLE_SHA1
@@ -9,12 +9,6 @@ ENV CIRCLE_BUILD_URL=${CIRCLE_BUILD_URL}
ENV CIRCLE_SHA1=${CIRCLE_SHA1}
ENV LOG4PERL_CONFIG_FILE=log4perl-json.conf
-ENV HTTPD_StartServers=8
-ENV HTTPD_MinSpareServers=5
-ENV HTTPD_MaxSpareServers=20
-ENV HTTPD_ServerLimit=256
-ENV HTTPD_MaxClients=256
-ENV HTTPD_MaxRequestsPerChild=4000
ENV PORT=8000
@@ -28,7 +22,8 @@ RUN mv /opt/bmo/local /app && \
chown -R app:app /app && \
perl -I/app -I/app/local/lib/perl5 -c -E 'use Bugzilla; BEGIN { Bugzilla->extensions }' && \
perl -c /app/scripts/entrypoint.pl && \
- setcap 'cap_net_bind_service=+ep' /usr/sbin/httpd
+ setcap 'cap_net_bind_service=+ep' /usr/sbin/httpd && \
+ setcap 'cap_net_bind_service=+ep' /usr/bin/perl
USER app
diff --git a/Log/Log4perl/Layout/Mozilla.pm b/Log/Log4perl/Layout/Mozilla.pm
index b625c54f4..4aedd9843 100644
--- a/Log/Log4perl/Layout/Mozilla.pm
+++ b/Log/Log4perl/Layout/Mozilla.pm
@@ -53,6 +53,9 @@ sub render {
my $mdc = Log::Log4perl::MDC->get_context;
my $fields = $mdc->{fields} // {};
+ if ($mdc->{request_id}) {
+ $fields->{request_id} = $mdc->{request_id}
+ }
my %out = (
EnvVersion => LOGGING_FORMAT_VERSION,
Hostname => $HOSTNAME,
diff --git a/Makefile.PL b/Makefile.PL
index 3bf6926a5..43d3930b0 100755
--- a/Makefile.PL
+++ b/Makefile.PL
@@ -47,7 +47,6 @@ my %requires = (
'Date::Format' => '2.23',
'DateTime' => '0.75',
'DateTime::TimeZone' => '2.11',
- 'Devel::NYTProf' => '6.04',
'Digest::SHA' => '5.47',
'Email::MIME' => '1.904',
'Email::Send' => '1.911',
@@ -69,6 +68,7 @@ my %requires = (
'Module::Metadata' => '1.000033',
'Module::Runtime' => '0.014',
'Mojolicious' => '7.71',
+ 'MojoX::Log::Log4perl::Tiny' => '0.01',
'Moo' => '2.002004',
'MooX::StrictConstructor' => '0.008',
'Mozilla::CA' => '20160104',
@@ -80,10 +80,12 @@ my %requires = (
'Template' => '2.24',
'Text::CSV_XS' => '1.26',
'Throwable' => '0.200013',
- 'Type::Tiny' => '1.000005',
+ 'Sub::Quote' => '2.005000',
+ 'Type::Tiny' => '1.004002',
'URI' => '1.55',
'URI::Escape::XS' => '0.14',
'version' => '0.87',
+ 'EV' => '4.0',
);
my %build_requires = ( 'ExtUtils::MakeMaker' => '7.22', );
@@ -96,7 +98,7 @@ my %test_requires = (
'Perl::Critic::Freenode' => 0,
'Capture::Tiny' => 0,
);
-my %recommends = ( Safe => '2.30' );
+my %recommends = ( Safe => '2.30',);
# Windows requires some additional modules.
if ( $OSNAME eq 'MSWin32' ) {
@@ -284,18 +286,6 @@ my %optional_features = (
}
},
},
- mod_perl => {
- description => 'mod_perl support under Apache',
- prereqs => {
- runtime => {
- requires => {
- 'mod_perl2' => '1.999022',
- 'Apache2::SizeLimit' => '0.96',
- 'Plack::Handler::Apache2' => 0,
- }
- }
- }
- },
inbound_email => {
description => 'Inbound Email',
prereqs => {
@@ -456,6 +446,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
}
@@ -467,7 +458,6 @@ sub is_bmo_feature {
^
(?: pg
| oracle
- | mod_perl
| sqlite
| auth_ldap
| auth_radius
diff --git a/README.rst b/README.rst
index 05eb1df1f..2a0fa289c 100644
--- a/README.rst
+++ b/README.rst
@@ -333,41 +333,6 @@ BMO_use_mailer_queue
Usually configured on the MTA section of the admin interface, you may change this here for testing purposes.
Should be 1 or 0. If 1, the job queue will be used. For testing, only set to 0 if the BMO_mail_delivery_method is None or Test.
-HTTPD_StartServers
- Sets the number of child server processes created on startup.
- As the number of processes is dynamically controlled depending on the load,
- there is usually little reason to adjust this parameter.
- Default: 8
-
-HTTPD_MinSpareServers
- Sets the desired minimum number of idle child server processes. An idle
- process is one which is not handling a request. If there are fewer than
- MinSpareServers idle, then the parent process creates new children at a
- maximum rate of 1 per second.
- Default: 5
-
-HTTPD_MaxSpareServers
- Sets the desired maximum number of idle child server processes. An idle
- process is one which is not handling a request. If there are more than
- MaxSpareServers idle, then the parent process will kill off the excess
- processes.
- Default: 20
-
-HTTPD_MaxClients
- Sets the maximum number of child processes that will be launched to serve requests.
- Default: 256
-
-HTTPD_ServerLimit
- Sets the maximum configured value for MaxClients for the lifetime of the
- Apache process.
- Default: 256
-
-HTTPD_MaxRequestsPerChild
- Sets the limit on the number of requests that an individual child server
- process will handle. After MaxRequestsPerChild requests, the child process
- will die. If MaxRequestsPerChild is 0, then the process will never expire.
- Default: 4000
-
USE_NYTPROF
Write `Devel::NYTProf`_ profiles out for each requests.
These will be named /app/data/nytprof.$host.$script.$n.$pid, where $host is
diff --git a/buglist.cgi b/buglist.cgi
index 4d3ad1a86..d1cde7096 100755
--- a/buglist.cgi
+++ b/buglist.cgi
@@ -41,6 +41,8 @@ my $vars = {};
my $user = Bugzilla->login();
$cgi->redirect_search_url();
+use Bugzilla::Logging;
+DEBUG("After the redirect.");
my $buffer = $cgi->query_string();
if (length($buffer) == 0) {
@@ -103,27 +105,6 @@ my $agent = ($cgi->http('X-Moz') && $cgi->http('X-Moz') =~ /\bmicrosummary\b/);
my $format = $template->get_format("list/list", scalar $cgi->param('format'),
scalar $cgi->param('ctype'));
-# Use server push to display a "Please wait..." message for the user while
-# executing their query if their browser supports it and they are viewing
-# the bug list as HTML and they have not disabled it by adding &serverpush=0
-# to the URL.
-#
-# Server push is a Netscape 3+ hack incompatible with MSIE, Lynx, and others.
-# Even Communicator 4.51 has bugs with it, especially during page reload.
-# http://www.browsercaps.org used as source of compatible browsers.
-# Safari (WebKit) does not support it, despite a UA that says otherwise (bug 188712)
-# MSIE 5+ supports it on Mac (but not on Windows) (bug 190370)
-#
-my $serverpush =
- $format->{'extension'} eq "html"
- && exists $ENV{'HTTP_USER_AGENT'}
- && $ENV{'HTTP_USER_AGENT'} =~ /Mozilla.[3-9]/
- && (($ENV{'HTTP_USER_AGENT'} !~ /[Cc]ompatible/) || ($ENV{'HTTP_USER_AGENT'} =~ /MSIE 5.*Mac_PowerPC/))
- && $ENV{'HTTP_USER_AGENT'} !~ /(?:WebKit|Trident|KHTML)/
- && !$agent
- && !defined($cgi->param('serverpush'))
- || $cgi->param('serverpush');
-
my $order = $cgi->param('order') || "";
# The params object to use for the actual query itself
@@ -744,24 +725,6 @@ $params->delete('limit') if $vars->{'default_limited'};
# Time to use server push to display an interim message to the user until
# the query completes and we can display the bug list.
-if ($serverpush) {
- print $cgi->multipart_init();
- print $cgi->multipart_start(-type => 'text/html');
-
- # Generate and return the UI (HTML page) from the appropriate template.
- $template->process("list/server-push.html.tmpl", $vars)
- || ThrowTemplateError($template->error());
-
- # Under mod_perl, flush stdout so that the page actually shows up.
- if ($ENV{MOD_PERL}) {
- require Apache2::RequestUtil;
- Apache2::RequestUtil->request->rflush();
- }
-
- # Don't do multipart_end() until we're ready to display the replacement
- # page, otherwise any errors that happen before then (like SQL errors)
- # will result in a blank page being shown to the user instead of the error.
-}
# Connect to the shadow database if this installation is using one to improve
# query performance.
@@ -1141,10 +1104,3 @@ $cgi->close_standby_message($contenttype, $disposition, $disp_prefix, $format->{
# Generate and return the UI (HTML page) from the appropriate template.
$template->process($format->{'template'}, $vars)
|| ThrowTemplateError($template->error());
-
-
-################################################################################
-# Script Conclusion
-################################################################################
-
-print $cgi->multipart_final() if $serverpush;
diff --git a/bugzilla.pl b/bugzilla.pl
new file mode 100755
index 000000000..efcea293b
--- /dev/null
+++ b/bugzilla.pl
@@ -0,0 +1,20 @@
+#!/usr/bin/perl
+use 5.10.1;
+use strict;
+use warnings;
+
+use File::Basename qw(basename dirname);
+use File::Spec::Functions qw(catdir);
+use Cwd qw(realpath);
+
+BEGIN {
+ require lib;
+ my $dir = realpath( dirname(__FILE__) );
+ lib->import( $dir, catdir( $dir, 'lib' ), catdir( $dir, qw(local lib perl5) ) );
+}
+use Mojolicious::Commands;
+
+$ENV{MOJO_LISTEN} ||= $ENV{PORT} ? "http://*:$ENV{PORT}" : "http://*:3001";
+
+# Start command line interface for application
+Mojolicious::Commands->start_app('Bugzilla::Quantum');
diff --git a/checksetup.pl b/checksetup.pl
index d3f08e024..7c9826ee3 100755
--- a/checksetup.pl
+++ b/checksetup.pl
@@ -135,7 +135,7 @@ require Bugzilla::Install::Localconfig;
import Bugzilla::Install::Localconfig qw(update_localconfig);
require Bugzilla::Install::Filesystem;
-import Bugzilla::Install::Filesystem qw(update_filesystem create_htaccess
+import Bugzilla::Install::Filesystem qw(update_filesystem
fix_all_file_permissions);
require Bugzilla::Install::DB;
require Bugzilla::DB;
@@ -201,7 +201,6 @@ unless ($switch{'no-database'}) {
###########################################################################
update_filesystem({ index_html => $lc_hash->{'index_html'} });
-create_htaccess() if $lc_hash->{'create_htaccess'};
# Remove parameters from the params file that no longer exist in Bugzilla,
# and set the defaults for new ones
diff --git a/colchange.cgi b/colchange.cgi
index d77782bec..46d25ecdf 100755
--- a/colchange.cgi
+++ b/colchange.cgi
@@ -136,26 +136,12 @@ if (defined $cgi->param('rememberedquery')) {
$params->param('columnlist', join(",", @collist));
$vars->{'redirect_url'} = "buglist.cgi?".$params->query_string();
-
# If we're running on Microsoft IIS, $cgi->redirect discards
# the Set-Cookie lines. In mod_perl, $cgi->redirect with cookies
# causes the page to be rendered as text/plain.
# Workaround is to use the old-fashioned redirection mechanism.
# See bug 214466 and bug 376044 for details.
- if ($ENV{'MOD_PERL'}
- || $ENV{'SERVER_SOFTWARE'} =~ /Microsoft-IIS/
- || $ENV{'SERVER_SOFTWARE'} =~ /Sun ONE Web/)
- {
- print $cgi->header(-type => "text/html",
- -refresh => "0; URL=$vars->{'redirect_url'}");
- }
- else {
- print $cgi->redirect($vars->{'redirect_url'});
- exit;
- }
-
- $template->process("global/message.html.tmpl", $vars)
- || ThrowTemplateError($template->error());
+ print $cgi->redirect($vars->{'redirect_url'});
exit;
}
diff --git a/conf/httpd.conf b/conf/httpd.conf
deleted file mode 100644
index 539ab4231..000000000
--- a/conf/httpd.conf
+++ /dev/null
@@ -1,103 +0,0 @@
-ServerName 127.0.0.1
-ServerTokens Prod
-ServerRoot "/etc/httpd"
-ServerAdmin root@localhost
-
-PidFile /tmp/httpd.pid
-Timeout 120
-LimitRequestLine 35000
-KeepAlive Off
-MaxKeepAliveRequests 100
-KeepAliveTimeout 15
-
-StartServers ${HTTPD_StartServers}
-MinSpareServers ${HTTPD_MinSpareServers}
-MaxSpareServers ${HTTPD_MaxSpareServers}
-ServerLimit ${HTTPD_ServerLimit}
-MaxClients ${HTTPD_MaxClients}
-MaxRequestsPerChild ${HTTPD_MaxRequestsPerChild}
-
-Listen ${PORT}
-User app
-Group app
-
-LoadModule auth_basic_module modules/mod_auth_basic.so
-LoadModule auth_digest_module modules/mod_auth_digest.so
-LoadModule authn_file_module modules/mod_authn_file.so
-LoadModule authn_alias_module modules/mod_authn_alias.so
-LoadModule authn_anon_module modules/mod_authn_anon.so
-LoadModule authn_dbm_module modules/mod_authn_dbm.so
-LoadModule authn_default_module modules/mod_authn_default.so
-LoadModule authz_host_module modules/mod_authz_host.so
-LoadModule authz_user_module modules/mod_authz_user.so
-LoadModule authz_owner_module modules/mod_authz_owner.so
-LoadModule authz_groupfile_module modules/mod_authz_groupfile.so
-LoadModule authz_default_module modules/mod_authz_default.so
-LoadModule log_config_module modules/mod_log_config.so
-LoadModule env_module modules/mod_env.so
-LoadModule mime_magic_module modules/mod_mime_magic.so
-LoadModule expires_module modules/mod_expires.so
-LoadModule deflate_module modules/mod_deflate.so
-LoadModule headers_module modules/mod_headers.so
-LoadModule setenvif_module modules/mod_setenvif.so
-LoadModule mime_module modules/mod_mime.so
-LoadModule negotiation_module modules/mod_negotiation.so
-LoadModule dir_module modules/mod_dir.so
-LoadModule alias_module modules/mod_alias.so
-LoadModule rewrite_module modules/mod_rewrite.so
-LoadModule perl_module modules/mod_perl.so
-
-UseCanonicalName Off
-<Directory />
- Options FollowSymLinks
- AllowOverride None
-</Directory>
-AccessFileName .htaccess
-<Files ~ "^\.ht">
- Order allow,deny
- Deny from all
- Satisfy All
-</Files>
-TypesConfig /etc/mime.types
-DefaultType text/plain
-MIMEMagicFile conf/magic
-HostnameLookups Off
-<IfDefine NETCAT_LOGS>
- ErrorLog "|/usr/bin/nc localhost ${LOGGING_PORT}"
- <IfDefine ACCESS_LOGS>
- TransferLog "|/usr/bin/nc localhost ${LOGGING_PORT}"
- </IfDefine>
-</IfDefine>
-<IfDefine !NETCAT_LOGS>
- ErrorLog /dev/stderr
- <IfDefine ACCESS_LOGS>
- TransferLog /dev/stdout
- </IfDefine>
-</IfDefine>
-LogLevel warn
-LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined
-LogFormat "%h %l %u %t \"%r\" %>s %b" common
-LogFormat "%{Referer}i -> %U" referer
-LogFormat "%{User-agent}i" agent
-ServerSignature Off
-AddDefaultCharset UTF-8
-
-Include /app/conf/env.conf
-
-PerlSwitches -wT
-PerlRequire /app/mod_perl.pl
-PerlSetEnv LOG4PERL_STDERR_DISABLE 1
-DirectoryIndex index.cgi
-DocumentRoot "/app"
-<IfDefine HTTPD_IN_SUBDIR>
-Alias "/bmo" "/app"
-</IfDefine>
-<IfDefine HTTPS>
- SetEnvIf X-Forwarded-Proto "https" HTTPS=on
-</IfDefine>
-<Directory "/app">
- Options -Indexes -FollowSymLinks
- AllowOverride None
- Order allow,deny
- Allow from all
-</Directory>
diff --git a/conf/log4perl-test.conf b/conf/log4perl-test.conf
index 77fc00af8..1760279db 100644
--- a/conf/log4perl-test.conf
+++ b/conf/log4perl-test.conf
@@ -4,14 +4,14 @@ log4perl.appender.Cereal.PeerAddr=127.0.0.1
log4perl.appender.Cereal.PeerPort=5880
log4perl.appender.Cereal.defer_connection=1
log4perl.appender.Cereal.layout = Log::Log4perl::Layout::PatternLayout
-log4perl.appender.Cereal.layout.ConversionPattern = %d %6p | %c | %m{chomp}%n
+log4perl.appender.Cereal.layout.ConversionPattern = %X{request_id} %d %6p | %c | %m{chomp}%n
log4perl.filter.LOG_TO_STDERR = sub { not $ENV{LOG4PERL_STDERR_DISABLE} }
log4perl.appender.Screen = Log::Log4perl::Appender::Screen
log4perl.appender.Screen.Filter = LOG_TO_STDERR
log4perl.appender.Screen.stderr = 1
log4perl.appender.Screen.layout = Log::Log4perl::Layout::PatternLayout
-log4perl.appender.Screen.layout.ConversionPattern = %d %6p | %c | %m{chomp}%n
+log4perl.appender.Screen.layout.ConversionPattern = STDERR: %X{request_id} %d %6p | %c | %m{chomp}%n
log4perl.appender.File = Log::Log4perl::Appender::File
log4perl.appender.File.layout = Log::Log4perl::Layout::Mozilla
diff --git a/docker-compose.yml b/docker-compose.yml
index 1ca6f5c90..b00c6bc03 100644
--- a/docker-compose.yml
+++ b/docker-compose.yml
@@ -19,6 +19,7 @@ services:
- LOCALCONFIG_ENV=1
- LOG4PERL_CONFIG_FILE=log4perl-docker.conf
- BUGZILLA_UNSAFE_AUTH_DELEGATION=1
+ - HTTP_BACKEND=simple
- PORT=80
- BMO_db_host=bmo-db.vm
- BMO_db_name=bugs
diff --git a/docs/en/rst/administering/parameters.rst b/docs/en/rst/administering/parameters.rst
index 338df3eb3..0492e0070 100644
--- a/docs/en/rst/administering/parameters.rst
+++ b/docs/en/rst/administering/parameters.rst
@@ -28,12 +28,6 @@ utf8
.. note:: If you turn this parameter from :paramval:`off` to :paramval:`on`,
you must re-run :file:`checksetup.pl` immediately afterward.
-shutdownhtml
- If there is any text in this field, this Bugzilla installation will
- be completely disabled and this text will appear instead of all
- Bugzilla pages for all users, including Admins. Used in the event
- of site maintenance or outage situations.
-
announcehtml
Any text in this field will be displayed at the top of every HTML
page in this Bugzilla installation. The text is not wrapped in any
diff --git a/docs/en/rst/integrating/templates.rst b/docs/en/rst/integrating/templates.rst
index b477a9553..ee2c08e92 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/docs/en/rst/style.rst b/docs/en/rst/style.rst
index aa3957b95..5058a51a3 100644
--- a/docs/en/rst/style.rst
+++ b/docs/en/rst/style.rst
@@ -65,7 +65,7 @@ Other block types:
aware of.
.. todo:: This is some documentation-related task that still needs doing.
-
+
Use both of the above block types sparingly. Consider putting the information
in the main text, omitting it, or (if long) placing it in a subsidiary file.
@@ -103,9 +103,6 @@ Inline Directives
* A command to type in the shell:
:command:`command --arguments`
-* A parameter name:
- :param:`shutdownhtml`
-
* A parameter value:
:paramval:`DB`
diff --git a/editparams.cgi b/editparams.cgi
index ac7976d99..495d53937 100755
--- a/editparams.cgi
+++ b/editparams.cgi
@@ -137,9 +137,6 @@ if ($action eq 'save' && $current_module) {
}
push(@changes, $name);
SetParam($name, $value);
- if (($name eq "shutdownhtml") && ($value ne "")) {
- $vars->{'shutdown_is_active'} = 1;
- }
if ($name eq 'duplicate_or_move_bug_status') {
Bugzilla::Status::add_missing_bug_status_transitions($value);
}
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 3b1c03eec..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
@@ -2719,4 +2742,105 @@ sub enter_bug_entrydefaultvars {
}
}
+sub app_startup {
+ my ($self, $args) = @_;
+ my $app = $args->{app};
+ my $r = $app->routes;
+
+ $r->get(
+ '/favicon.ico' => sub {
+ my $c = shift;
+ $c->reply->file(
+ $c->app->home->child('extensions/BMO/web/images/favicon.ico')
+ );
+ }
+ );
+
+ $r->any( '/:REWRITE_itrequest' => [ REWRITE_itrequest => qr{form[\.:]itrequest} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'Infrastructure & Operations', 'format' => 'itrequest' } );
+ $r->any( '/:REWRITE_mozlist' => [ REWRITE_mozlist => qr{form[\.:]mozlist} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'mozilla.org', 'format' => 'mozlist' } );
+ $r->any( '/:REWRITE_poweredby' => [ REWRITE_poweredby => qr{form[\.:]poweredby} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'mozilla.org', 'format' => 'poweredby' } );
+ $r->any( '/:REWRITE_presentation' => [ REWRITE_presentation => qr{form[\.:]presentation} ] )
+ ->to( 'cgi#enter_bug_cgi' => { 'product' => 'mozilla.org', 'format' => 'presentation' } );
+ $r->any( '/:REWRITE_trademark' => [ REWRITE_trademark => qr{form[\.:]trademark} ] )
+ ->to( 'cgi#enter_bug_cgi' => { 'product' => 'mozilla.org', 'format' => 'trademark' } );
+ $r->any( '/:REWRITE_recoverykey' => [ REWRITE_recoverykey => qr{form[\.:]recoverykey} ] )
+ ->to( 'cgi#enter_bug_cgi' => { 'product' => 'mozilla.org', 'format' => 'recoverykey' } );
+ $r->any( '/:REWRITE_legal' => [ REWRITE_legal => qr{form[\.:]legal} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'Legal', 'format' => 'legal' }, );
+ $r->any( '/:REWRITE_recruiting' => [ REWRITE_recruiting => qr{form[\.:]recruiting} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'Recruiting', 'format' => 'recruiting' } );
+ $r->any( '/:REWRITE_intern' => [ REWRITE_intern => qr{form[\.:]intern} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'Recruiting', 'format' => 'intern' } );
+ $r->any( '/:REWRITE_mozpr' => [ REWRITE_mozpr => qr{form[\.:]mozpr} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'Mozilla PR', 'format' => 'mozpr' }, );
+ $r->any( '/:REWRITE_reps_mentorship' => [ REWRITE_reps_mentorship => qr{form[\.:]reps[\.:]mentorship} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'Mozilla Reps', 'format' => 'mozreps' }, );
+ $r->any( '/:REWRITE_reps_budget' => [ REWRITE_reps_budget => qr{form[\.:]reps[\.:]budget} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'Mozilla Reps', 'format' => 'remo-budget' } );
+ $r->any( '/:REWRITE_reps_swag' => [ REWRITE_reps_swag => qr{form[\.:]reps[\.:]swag} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'Mozilla Reps', 'format' => 'remo-swag' } );
+ $r->any( '/:REWRITE_reps_it' => [ REWRITE_reps_it => qr{form[\.:]reps[\.:]it} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'Mozilla Reps', 'format' => 'remo-it' } );
+ $r->any( '/:REWRITE_reps_payment' => [ REWRITE_reps_payment => qr{form[\.:]reps[\.:]payment} ] )
+ ->to( 'CGI#page_cgi' => { 'id' => 'remo-form-payment.html' } );
+ $r->any( '/:REWRITE_csa_discourse' => [ REWRITE_csa_discourse => qr{form[\.:]csa[\.:]discourse} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'Infrastructure & Operations', 'format' => 'csa-discourse' } );
+ $r->any( '/:REWRITE_employee_incident' => [ REWRITE_employee_incident => qr{form[\.:]employee[\.\-:]incident} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'mozilla.org', 'format' => 'employee-incident' } );
+ $r->any( '/:REWRITE_brownbag' => [ REWRITE_brownbag => qr{form[\.:]brownbag} ] )
+ ->to( 'CGI#https_air_mozilla_org_requests' => {} );
+ $r->any( '/:REWRITE_finance' => [ REWRITE_finance => qr{form[\.:]finance} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'Finance', 'format' => 'finance' } );
+ $r->any(
+ '/:REWRITE_moz_project_review' => [ REWRITE_moz_project_review => qr{form[\.:]moz[\.\-:]project[\.\-:]review} ]
+ )->to( 'CGI#enter_bug_cgi' => { 'product' => 'mozilla.org', 'format' => 'moz-project-review' } );
+ $r->any( '/:REWRITE_docs' => [ REWRITE_docs => qr{form[\.:]docs?} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'Developer Documentation', 'format' => 'doc' } );
+ $r->any( '/:REWRITE_mdn' => [ REWRITE_mdn => qr{form[\.:]mdn?} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'format' => 'mdn', 'product' => 'developer.mozilla.org' } );
+ $r->any( '/:REWRITE_swag_gear' => [ REWRITE_swag_gear => qr{form[\.:](swag|gear)} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'format' => 'swag', 'product' => 'Marketing' } );
+ $r->any( '/:REWRITE_costume' => [ REWRITE_costume => qr{form[\.:]costume} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'Marketing', 'format' => 'costume' } );
+ $r->any( '/:REWRITE_ipp' => [ REWRITE_ipp => qr{form[\.:]ipp} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'Internet Public Policy', 'format' => 'ipp' } );
+ $r->any( '/:REWRITE_creative' => [ REWRITE_creative => qr{form[\.:]creative} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'format' => 'creative', 'product' => 'Marketing' } );
+ $r->any( '/:REWRITE_user_engagement' => [ REWRITE_user_engagement => qr{form[\.:]user[\.\-:]engagement} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'format' => 'user-engagement', 'product' => 'Marketing' } );
+ $r->any( '/:REWRITE_dev_engagement_event' =>
+ [ REWRITE_dev_engagement_event => qr{form[\.:]dev[\.\-:]engagement[\.\-\:]event} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'Developer Engagement', 'format' => 'dev-engagement-event' } );
+ $r->any( '/:REWRITE_mobile_compat' => [ REWRITE_mobile_compat => qr{form[\.:]mobile[\.\-:]compat} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'Tech Evangelism', 'format' => 'mobile-compat' } );
+ $r->any( '/:REWRITE_web_bounty' => [ REWRITE_web_bounty => qr{form[\.:]web[\.:]bounty} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'format' => 'web-bounty', 'product' => 'mozilla.org' } );
+ $r->any( '/:REWRITE_automative' => [ REWRITE_automative => qr{form[\.:]automative} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'Testing', 'format' => 'automative' } );
+ $r->any( '/:REWRITE_comm_newsletter' => [ REWRITE_comm_newsletter => qr{form[\.:]comm[\.:]newsletter} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'format' => 'comm-newsletter', 'product' => 'Marketing' } );
+ $r->any( '/:REWRITE_screen_share_whitelist' =>
+ [ REWRITE_screen_share_whitelist => qr{form[\.:]screen[\.:]share[\.:]whitelist} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'format' => 'screen-share-whitelist', 'product' => 'Firefox' } );
+ $r->any( '/:REWRITE_data_compliance' => [ REWRITE_data_compliance => qr{form[\.:]data[\.\-:]compliance} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'Data Compliance', 'format' => 'data-compliance' } );
+ $r->any( '/:REWRITE_fsa_budget' => [ REWRITE_fsa_budget => qr{form[\.:]fsa[\.:]budget} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'FSA', 'format' => 'fsa-budget' } );
+ $r->any( '/:REWRITE_triage_request' => [ REWRITE_triage_request => qr{form[\.:]triage[\.\-]request} ] )
+ ->to( 'CGI#page_cgi' => { 'id' => 'triage_request.html' } );
+ $r->any( '/:REWRITE_crm_CRM' => [ REWRITE_crm_CRM => qr{form[\.:](crm|CRM)} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'format' => 'crm', 'product' => 'Marketing' } );
+ $r->any( '/:REWRITE_nda' => [ REWRITE_nda => qr{form[\.:]nda} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'Legal', 'format' => 'nda' } );
+ $r->any( '/:REWRITE_name_clearance' => [ REWRITE_name_clearance => qr{form[\.:]name[\.:]clearance} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'format' => 'name-clearance', 'product' => 'Legal' } );
+ $r->any( '/:REWRITE_shield_studies' => [ REWRITE_shield_studies => qr{form[\.:]shield[\.:]studies} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'Shield', 'format' => 'shield-studies' } );
+ $r->any( '/:REWRITE_client_bounty' => [ REWRITE_client_bounty => qr{form[\.:]client[\.:]bounty} ] )
+ ->to( 'CGI#enter_bug_cgi' => { 'product' => 'Firefox', 'format' => 'client-bounty' } );
+}
+
__PACKAGE__->NAME;
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 e926c04b4..bcbea3f15 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 bb9805134..1f7cce04a 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);
@@ -188,6 +189,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 e1a9e0bc5..7ffa04922 100644
--- a/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl
+++ b/extensions/GuidedBugEntry/template/en/default/guided/guided.html.tmpl
@@ -356,7 +356,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/MozReview/disabled b/extensions/MozReview/disabled
new file mode 100644
index 000000000..e69de29bb
--- /dev/null
+++ b/extensions/MozReview/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 a7ae98744..a93533e75 100644
--- a/extensions/PhabBugz/lib/Util.pm
+++ b/extensions/PhabBugz/lib/Util.pm
@@ -102,7 +102,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/heartbeat.cgi b/heartbeat.cgi
index 3edbed371..11bb3ac30 100755
--- a/heartbeat.cgi
+++ b/heartbeat.cgi
@@ -29,7 +29,6 @@ my $ok = eval {
die "database not available" unless $database_ok;
die "memcached server(s) not available" unless $memcached_ok;
- die "mod_perl not configured?" unless $ENV{MOD_PERL};
if ($dbh->isa('Bugzilla::DB::Mysql') && Bugzilla->params->{utf8} eq 'utf8mb4') {
my $mysql_var = $dbh->selectall_hashref(q{SHOW VARIABLES LIKE 'character_set%'}, 'Variable_name');
foreach my $name (qw( character_set_client character_set_connection character_set_database )) {
@@ -46,10 +45,3 @@ FATAL("heartbeat error: $@") if !$ok && $@;
my $cgi = Bugzilla->cgi;
print $cgi->header(-type => 'text/plain', -status => $ok ? '200 OK' : '500 Internal Server Error');
print $ok ? "Bugzilla OK\n" : "Bugzilla NOT OK\n";
-
-if ($ENV{MOD_PERL}) {
- my $r = $cgi->r;
- # doing this supresses the error document, but does not change the http response code.
- $r->rflush;
- $r->status(200);
-}
diff --git a/jobqueue-worker.pl b/jobqueue-worker.pl
index b26aacdba..b26aacdba 100644..100755
--- a/jobqueue-worker.pl
+++ b/jobqueue-worker.pl
diff --git a/js/instant-search.js b/js/instant-search.js
index 6e8f104f2..183d5a3be 100644
--- a/js/instant-search.js
+++ b/js/instant-search.js
@@ -138,7 +138,7 @@ YAHOO.bugzilla.instantSearch = {
YAHOO.bugzilla.instantSearch.dataTable.showTableMessage(
'Searching...&nbsp;&nbsp;&nbsp;' +
- '<img src="extensions/GuidedBugEntry/web/images/throbber.gif"' +
+ '<img src="images/throbber.gif"' +
' width="16" height="11">',
YAHOO.widget.DataTable.CLASS_LOADING
);
@@ -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/mod_perl.pl b/mod_perl.pl
deleted file mode 100644
index 09e3bac38..000000000
--- a/mod_perl.pl
+++ /dev/null
@@ -1,204 +0,0 @@
-#!/usr/bin/perl -T
-# 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::ModPerl;
-
-use 5.10.1;
-use strict;
-use warnings;
-
-# This sets up our libpath without having to specify it in the mod_perl
-# configuration.
-use File::Basename;
-use File::Spec;
-BEGIN {
- require lib;
- my $dir = dirname(__FILE__);
- lib->import($dir, File::Spec->catdir($dir, "lib"), File::Spec->catdir($dir, qw(local lib perl5)));
-}
-
-use Bugzilla::ModPerl::StartupFix;
-use Taint::Util qw(untaint);
-
-use constant USE_NYTPROF => !! $ENV{USE_NYTPROF};
-use constant NYTPROF_DIR => do {
- my $dir = $ENV{NYTPROF_DIR};
- untaint($dir);
- $dir;
-};
-BEGIN {
- if (USE_NYTPROF) {
- $ENV{NYTPROF} = "savesrc=0:start=no:addpid=1";
- }
-}
-use if USE_NYTPROF, 'Devel::NYTProf::Apache';
-
-use Bugzilla::Constants ();
-
-# If you have an Apache2::Status handler in your Apache configuration,
-# you need to load Apache2::Status *here*, so that any later-loaded modules
-# can report information to Apache2::Status.
-#use Apache2::Status ();
-
-# We don't want to import anything into the global scope during
-# startup, so we always specify () after using any module in this
-# file.
-
-use Apache2::Log ();
-use Apache2::ServerUtil;
-use Apache2::SizeLimit;
-use ModPerl::RegistryLoader ();
-use File::Basename ();
-use File::Find ();
-use English qw(-no_match_vars $OSNAME);
-
-# This loads most of our modules.
-use Bugzilla ();
-# Loading Bugzilla.pm doesn't load this, though, and we want it preloaded.
-use Bugzilla::BugMail ();
-use Bugzilla::CGI ();
-use Bugzilla::Extension ();
-use Bugzilla::Install::Requirements ();
-use Bugzilla::Util ();
-use Bugzilla::RNG ();
-use Bugzilla::ModPerl ();
-use Mojo::Loader qw(find_modules);
-use Module::Runtime qw(require_module);
-use Bugzilla::WebService::Server::REST;
-
-# Make warnings go to the virtual host's log and not the main
-# server log.
-BEGIN { *CORE::GLOBAL::warn = \&Apache2::ServerRec::warn; }
-
-# Pre-compile the CGI.pm methods that we're going to use.
-Bugzilla::CGI->compile(qw(:cgi :push));
-
-# This means that every httpd child will die after processing a request if it
-# is taking up more than $apache_size_limit of RAM all by itself, not counting RAM it is
-# sharing with the other httpd processes.
-my $limit = Bugzilla->localconfig->{apache_size_limit};
-if ($OSNAME eq 'linux' && ! eval { require Linux::Smaps }) {
- WARN('SizeLimit requires Linux::Smaps on linux. size limit set to 800MB');
- $limit = 800_000;
-}
-Apache2::SizeLimit->set_max_unshared_size($limit);
-
-my $cgi_path = Bugzilla::Constants::bz_locations()->{'cgi_path'};
-
-# Set up the configuration for the web server
-my $server = Apache2::ServerUtil->server;
-my $conf = Bugzilla::ModPerl->apache_config($cgi_path);
-$server->add_config([ grep { length $_ } split("\n", $conf)]);
-
-# Pre-load localconfig. It might already be loaded, but we need to make sure.
-Bugzilla->localconfig;
-if ($ENV{LOCALCONFIG_ENV}) {
- delete @ENV{ (Bugzilla::Install::Localconfig::ENV_KEYS) };
-}
-
-# Pre-load all extensions
-Bugzilla::Extension->load_all();
-
-Bugzilla->preload_features();
-
-require_module($_) for find_modules('Bugzilla::User::Setting');
-
-Bugzilla::WebService::Server::REST->preload;
-
-# Force instantiation of template so Bugzilla::Template::PreloadProvider can do its magic.
-Bugzilla->preload_templates;
-
-# Have ModPerl::RegistryLoader pre-compile all CGI scripts.
-my $rl = new ModPerl::RegistryLoader();
-# If we try to do this in "new" it fails because it looks for a
-# Bugzilla/ModPerl/ResponseHandler.pm
-$rl->{package} = 'Bugzilla::ModPerl::ResponseHandler';
-my $feature_files = Bugzilla::Install::Requirements::map_files_to_features();
-
-# Prevent "use lib" from doing anything when the .cgi files are compiled.
-# This is important to prevent the current directory from getting into
-# @INC and messing things up. (See bug 630750.)
-no warnings 'redefine';
-local *lib::import = sub {};
-use warnings;
-
-foreach my $file (glob "$cgi_path/*.cgi") {
- my $base_filename = File::Basename::basename($file);
- if (my $feature = $feature_files->{$base_filename}) {
- next if !Bugzilla->feature($feature);
- }
- Bugzilla::Util::trick_taint($file);
- $rl->handler($file, $file);
-}
-
-# Some items might already be loaded into the request cache
-# best to make sure it starts out empty.
-# Because of bug 1347335 we also do this in init_page().
-Bugzilla::clear_request_cache();
-
-package Bugzilla::ModPerl::ResponseHandler;
-use strict;
-use base qw(ModPerl::Registry);
-use Bugzilla;
-use Bugzilla::Constants qw(USAGE_MODE_REST bz_locations);
-use Time::HiRes;
-use Sys::Hostname;
-
-sub handler : method {
- my $class = shift;
-
- # $0 is broken under mod_perl before 2.0.2, so we have to set it
- # here explicitly or init_page's shutdownhtml code won't work right.
- $0 = $ENV{'SCRIPT_FILENAME'};
-
- # Prevent "use lib" from modifying @INC in the case where a .cgi file
- # is being automatically recompiled by mod_perl when Apache is
- # running. (This happens if a file changes while Apache is already
- # running.)
- no warnings 'redefine';
- local *lib::import = sub {};
- use warnings;
-
- if (Bugzilla::ModPerl::USE_NYTPROF) {
- state $count = {};
- state $dir = Bugzilla::ModPerl::NYTPROF_DIR // bz_locations()->{datadir};
- state $host = (split(/\./, hostname()))[0];
- my $script = File::Basename::basename($ENV{SCRIPT_FILENAME});
- $script =~ s/\.cgi$//;
- my $file = $dir . "/nytprof.$host.$script." . ++$count->{$$};
- DB::enable_profile($file);
- }
- Bugzilla::init_page();
- my $result = $class->SUPER::handler(@_);
- if (Bugzilla::ModPerl::USE_NYTPROF) {
- DB::disable_profile();
- DB::finish_profile();
- }
-
- # When returning data from the REST api we must only return 200 or 304,
- # which tells Apache not to append its error html documents to the
- # response.
- return Bugzilla->usage_mode == USAGE_MODE_REST && $result != 304
- ? Apache2::Const::OK
- : $result;
-}
-
-
-package Bugzilla::ModPerl::CleanupHandler;
-use strict;
-use Apache2::Const -compile => qw(OK);
-
-sub handler {
- my $r = shift;
-
- Bugzilla::_cleanup();
-
- return Apache2::Const::OK;
-}
-
-1;
diff --git a/qa/t/lib/QA/Util.pm b/qa/t/lib/QA/Util.pm
index 5d041d560..bf9151fee 100644
--- a/qa/t/lib/QA/Util.pm
+++ b/qa/t/lib/QA/Util.pm
@@ -18,6 +18,7 @@ use Sys::Hostname qw(hostname);
use Socket qw(inet_ntoa);
use WWW::Selenium::Util qw(server_is_running);
use URI;
+use URI::QueryParam;
# Fixes wide character warnings
BEGIN {
@@ -50,6 +51,7 @@ use base qw(Exporter);
get_selenium
get_rpc_clients
+ check_page_load
WAIT_TIME
CHROME_MODE
@@ -396,6 +398,32 @@ sub set_parameters {
}
}
+my @ANY_KEYS = qw( t token );
+
+sub check_page_load {
+ my ($sel, $wait, $expected) = @_;
+ my $expected_uri = URI->new($expected);
+ $sel->wait_for_page_to_load_ok($wait);
+ my $uri = URI->new($sel->get_location);
+
+ foreach my $u ($expected_uri, $uri) {
+ $u->host('HOSTNAME');
+ foreach my $any_key (@ANY_KEYS) {
+ if ($u->query_param($any_key)) {
+ $u->query_param($any_key => '__ANYTHING__');
+ }
+ }
+ }
+
+ if ($expected_uri->query_param('id')) {
+ if ($expected_uri->query_param('id') eq '__BUG_ID__') {
+ $uri->query_param('id' => '__BUG_ID__');
+ }
+ }
+ my ($pkg, $file, $line) = caller;
+ is($uri, $expected_uri, "checking location on $file line $line");
+}
+
1;
__END__
diff --git a/qa/t/test_bug_edit.t b/qa/t/test_bug_edit.t
index 07a64876b..01037aa1e 100644
--- a/qa/t/test_bug_edit.t
+++ b/qa/t/test_bug_edit.t
@@ -32,10 +32,10 @@ if ($sel->is_text_present("My bugs from QA_Selenium")) {
# Just in case the test failed before completion previously, reset the CANEDIT bit.
go_to_admin($sel);
$sel->click_ok("link=Groups");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/editgroups.cgi});
$sel->title_is("Edit Groups");
$sel->click_ok("link=Master");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/editgroups.cgi?action=changeform&group=26});
$sel->title_is("Change Group: Master");
my $group_url = $sel->get_location();
$group_url =~ /group=(\d+)$/;
@@ -52,7 +52,7 @@ $sel->select_ok("bug_severity", "label=critical");
$sel->type_ok("short_desc", "Test bug editing");
$sel->type_ok("comment", "ploc");
$sel->click_ok("commit");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=__BUG_ID__});
my $bug1_id = $sel->get_value('//input[@name="id" and @type="hidden"]');
$sel->is_text_present_ok('has been added to the database', "Bug $bug1_id created");
@@ -67,28 +67,28 @@ $sel->type_ok("status_whiteboard", "[Selenium was here]");
$sel->type_ok("comment", "new comment from me :)");
$sel->select_ok("bug_status", "label=RESOLVED");
$sel->click_ok("commit");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug1_id});
$sel->is_text_present_ok("Changes submitted for bug $bug1_id");
# Now move the bug into another product, which has a mandatory group.
$sel->click_ok("link=bug $bug1_id");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug1_id});
$sel->title_like(qr/^$bug1_id /);
$sel->select_ok("product", "label=QA-Selenium-TEST");
$sel->type_ok("comment", "moving to QA-Selenium-TEST");
$sel->click_ok("commit");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/process_bug.cgi});
$sel->title_is("Verify New Product Details...");
$sel->select_ok("component", "label=QA-Selenium-TEST");
$sel->is_element_present_ok('//input[@type="checkbox" and @name="groups" and @value="QA-Selenium-TEST"]');
ok(!$sel->is_editable('//input[@type="checkbox" and @name="groups" and @value="QA-Selenium-TEST"]'), "QA-Selenium-TEST group not editable");
$sel->is_checked_ok('//input[@type="checkbox" and @name="groups" and @value="QA-Selenium-TEST"]', "QA-Selenium-TEST group is selected");
$sel->click_ok("change_product");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug1_id});
$sel->is_text_present_ok("Changes submitted for bug $bug1_id");
$sel->click_ok("link=bug $bug1_id");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug1_id});
$sel->title_like(qr/^$bug1_id /);
$sel->select_ok("bug_severity", "label=normal");
$sel->select_ok("priority", "label=High");
@@ -101,14 +101,14 @@ $sel->type_ok("comment", "Unchecking the reporter_accessible checkbox");
$sel->click_ok("reporter_accessible");
$sel->select_ok("bug_status", "label=VERIFIED");
$sel->click_ok("commit");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug1_id});
$sel->is_text_present_ok("Changes submitted for bug $bug1_id");
$sel->click_ok("link=bug $bug1_id");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug1_id});
$sel->title_like(qr/^$bug1_id /);
$sel->type_ok("comment", "I am the reporter, but I can see the bug anyway as I belong to the mandatory group");
$sel->click_ok("commit");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug1_id});
$sel->is_text_present_ok("Changes submitted for bug $bug1_id");
logout($sel);
@@ -125,16 +125,16 @@ $sel->click_ok("bz_assignee_edit_action");
$sel->type_ok("assigned_to", $config->{admin_user_login});
$sel->type_ok("comment", "I have editbugs privs. Taking!");
$sel->click_ok("commit");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug1_id});
$sel->is_text_present_ok("Changes submitted for bug $bug1_id");
$sel->click_ok("link=bug $bug1_id");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug1_id});
$sel->title_like(qr/^$bug1_id /);
$sel->click_ok("cc_edit_area_showhide");
$sel->type_ok("newcc", $config->{unprivileged_user_login});
$sel->click_ok("commit");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug1_id});
$sel->is_text_present_ok("Changes submitted for bug $bug1_id");
logout($sel);
@@ -153,7 +153,7 @@ go_to_bug($sel, $bug1_id);
$sel->click_ok("cclist_accessible");
$sel->type_ok("comment", "I am allowed to turn off cclist_accessible despite not being in the mandatory group");
$sel->click_ok("commit");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug1_id});
$sel->is_text_present_ok("Changes submitted for bug $bug1_id");
logout($sel);
@@ -162,7 +162,7 @@ logout($sel);
log_in($sel, $config, 'unprivileged');
$sel->type_ok("quicksearch_top", $bug1_id);
$sel->submit("header-search");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug1_id});
$sel->title_is("Access Denied");
$sel->is_text_present_ok("You are not authorized to access bug $bug1_id");
logout($sel);
@@ -178,7 +178,7 @@ $sel->click_ok("set_default_assignee");
$sel->uncheck_ok("set_default_assignee");
$sel->type_ok("comment", "-> Moving back to Testproduct.");
$sel->click_ok("commit");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/process_bug.cgi});
$sel->title_is("Verify New Product Details...");
$sel->select_ok("component", "label=TestComponent");
$sel->is_text_present_ok("These groups are not legal for the 'TestProduct' product or you are not allowed to restrict bugs to these groups");
@@ -189,15 +189,15 @@ $sel->is_element_present_ok('//input[@type="checkbox" and @name="groups" and @va
$sel->is_editable_ok('//input[@type="checkbox" and @name="groups" and @value="Master"]', "Master group is editable");
ok(!$sel->is_checked('//input[@type="checkbox" and @name="groups" and @value="Master"]'), "Master group not selected by default");
$sel->click_ok("change_product");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug1_id});
$sel->is_text_present_ok("Changes submitted for bug $bug1_id");
$sel->click_ok("link=bug $bug1_id");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug1_id});
$sel->title_like(qr/^$bug1_id /);
$sel->click_ok("cclist_accessible");
$sel->type_ok("comment", "I am allowed to turn off cclist_accessible despite not being in the mandatory group");
$sel->click_ok("commit");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug1_id});
$sel->is_text_present_ok("Changes submitted for bug $bug1_id");
logout($sel);
@@ -216,7 +216,7 @@ $sel->click_ok("cc_edit_area_showhide");
$sel->add_selection_ok("cc", "label=" . $config->{admin_user_login});
$sel->click_ok("removecc");
$sel->click_ok("commit");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug1_id});
$sel->is_text_present_ok("Changes submitted for bug $bug1_id");
logout($sel);
@@ -225,11 +225,11 @@ logout($sel);
log_in($sel, $config, 'admin');
edit_product($sel, "TestProduct");
$sel->click_ok("link=Edit Group Access Controls:");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/editproducts.cgi?action=editgroupcontrols&product=TestProduct});
$sel->title_is("Edit Group Controls for TestProduct");
$sel->check_ok("canedit_$master_gid");
$sel->click_ok("submit");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/editproducts.cgi});
$sel->title_is("Update group access controls for TestProduct");
# The user is in the master group, so he can comment.
@@ -237,7 +237,7 @@ $sel->title_is("Update group access controls for TestProduct");
go_to_bug($sel, $bug1_id);
$sel->type_ok("comment", "Do nothing except adding a comment...");
$sel->click_ok("commit");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug1_id});
$sel->is_text_present_ok("Changes submitted for bug $bug1_id");
logout($sel);
@@ -247,7 +247,7 @@ log_in($sel, $config, 'QA_Selenium_TEST');
go_to_bug($sel, $bug1_id);
$sel->type_ok("comment", "Just a comment too...");
$sel->click_ok("commit");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/process_bug.cgi});
$sel->title_is("Product Edit Access Denied");
$sel->is_text_present_ok("You are not permitted to edit bugs in product TestProduct.");
logout($sel);
@@ -256,10 +256,12 @@ logout($sel);
log_in($sel, $config, 'admin');
open_advanced_search_page($sel);
+screenshot_page($sel, '/app/artifacts/line259.png');
$sel->remove_all_selections_ok("product");
$sel->add_selection_ok("product", "TestProduct");
$sel->remove_all_selections_ok("bug_status");
$sel->remove_all_selections_ok("resolution");
+screenshot_page($sel, '/app/artifacts/line264.png');
$sel->is_checked_ok("emailassigned_to1");
$sel->select_ok("emailtype1", "label=is");
$sel->type_ok("email1", $config->{admin_user_login});
@@ -268,21 +270,22 @@ $sel->check_ok("emailqa_contact2");
$sel->check_ok("emailcc2");
$sel->select_ok("emailtype2", "label=is");
$sel->type_ok("email2", $config->{QA_Selenium_TEST_user_login});
+screenshot_page($sel, '/app/artifacts/line271.png');
$sel->click_ok("Search");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/buglist.cgi?emailreporter2=1&emailtype2=exact&order=Importance&list_id=15&emailtype1=exact&emailcc2=1&query_format=advanced&emailassigned_to1=1&emailqa_contact2=1&email2=QA-Selenium-TEST%40mozilla.test&email1=admin%40mozilla.test&emailassigned_to2=1&product=TestProduct});
$sel->title_is("Bug List");
-
+screenshot_page($sel, '/app/artifacts/line275.png');
$sel->is_text_present_ok("One bug found.");
$sel->type_ok("save_newqueryname", "My bugs from QA_Selenium");
$sel->click_ok("remember");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/buglist.cgi?newquery=email1%3Dadmin%2540mozilla.test%26email2%3DQA-Selenium-TEST%2540mozilla.test%26emailassigned_to1%3D1%26emailassigned_to2%3D1%26emailcc2%3D1%26emailqa_contact2%3D1%26emailreporter2%3D1%26emailtype1%3Dexact%26emailtype2%3Dexact%26list_id%3D15%26product%3DTestProduct%26query_format%3Dadvanced%26order%3Dpriority%252Cbug_severity&cmdtype=doit&remtype=asnamed&token=1531926552-dc69995d79c786af046436ec6717000b&newqueryname=My%20bugs%20from%20QA_Selenium&list_id=16});
$sel->title_is("Search created");
$sel->is_text_present_ok("OK, you have a new search named My bugs from QA_Selenium.");
$sel->click_ok("link=My bugs from QA_Selenium");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/buglist.cgi?cmdtype=runnamed&namedcmd=My%20bugs%20from%20QA_Selenium&list_id=17});
$sel->title_is("Bug List: My bugs from QA_Selenium");
$sel->click_ok("long_format");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/show_bug.cgi});
$sel->title_is("Full Text Bug Listing");
$sel->is_text_present_ok("Bug $bug1_id");
$sel->is_text_present_ok("Status: CONFIRMED");
@@ -303,25 +306,25 @@ $sel->type_ok("short_desc", "New bug from me");
# We turned on the CANEDIT bit for TestProduct.
$sel->type_ok("comment", "I can enter a new bug, but not edit it, right?");
$sel->click_ok("commit");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=__BUG_ID__});
my $bug2_id = $sel->get_value('//input[@name="id" and @type="hidden"]');
$sel->is_text_present_ok('has been added to the database', "Bug $bug2_id created");
# Clicking the "Back" button and resubmitting the form again should trigger a suspicous action error.
$sel->go_back_ok();
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/enter_bug.cgi?product=TestProduct&format=__default__});
$sel->title_is("Enter Bug: TestProduct");
$sel->click_ok("commit");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/post_bug.cgi});
$sel->title_is("Suspicious Action");
$sel->is_text_present_ok("you have no valid token for the create_bug action");
$sel->click_ok('//input[@value="Confirm Changes"]');
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/show_bug.cgi?id=15});
$sel->is_text_present_ok('has been added to the database', 'Bug created');
$sel->type_ok("comment", "New comment not allowed");
$sel->click_ok("commit");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/process_bug.cgi});
$sel->title_is("Product Edit Access Denied");
$sel->is_text_present_ok("You are not permitted to edit bugs in product TestProduct.");
logout($sel);
@@ -334,42 +337,46 @@ $sel->click_ok("bz_assignee_edit_action");
$sel->type_ok("assigned_to", $config->{admin_user_login});
$sel->type_ok("comment", "Taking!");
$sel->click_ok("commit");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug2_id});
$sel->is_text_present_ok("Changes submitted for bug $bug2_id");
# Test mass-change.
$sel->click_ok("link=My bugs from QA_Selenium");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+screenshot_page($sel, '/app/artifacts/line344.png');
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/buglist.cgi?cmdtype=runnamed&namedcmd=My%20bugs%20from%20QA_Selenium&list_id=19});
+screenshot_page($sel, '/app/artifacts/line346.png');
$sel->title_is("Bug List: My bugs from QA_Selenium");
+screenshot_page($sel, '/app/artifacts/line348.png');
$sel->is_text_present_ok("2 bugs found");
+screenshot_page($sel, '/app/artifacts/line350.png');
$sel->click_ok("link=Change Several Bugs at Once");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/buglist.cgi?email1=admin%40mozilla.test&email2=QA-Selenium-TEST%40mozilla.test&emailassigned_to1=1&emailassigned_to2=1&emailcc2=1&emailqa_contact2=1&emailreporter2=1&emailtype1=exact&emailtype2=exact&product=TestProduct&query_format=advanced&order=priority%2Cbug_severity&tweak=1&list_id=20});
$sel->title_is("Bug List");
$sel->click_ok("check_all");
$sel->type_ok("comment", 'Mass change"');
$sel->select_ok("bug_status", "label=RESOLVED");
$sel->select_ok("resolution", "label=WORKSFORME");
$sel->click_ok("commit");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/process_bug.cgi});
$sel->title_is("Bugs processed");
$sel->click_ok("link=bug $bug1_id");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug1_id});
$sel->title_like(qr/$bug1_id /);
$sel->selected_label_is("resolution", "WORKSFORME");
$sel->select_ok("resolution", "label=INVALID");
$sel->click_ok("commit");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug1_id});
$sel->is_text_present_ok("Changes submitted for bug $bug1_id");
$sel->click_ok("link=bug $bug1_id");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug1_id});
$sel->title_like(qr/$bug1_id /);
$sel->selected_label_is("resolution", "INVALID");
$sel->click_ok("link=History");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_activity.cgi?id=$bug1_id});
$sel->title_is("Changes made to bug $bug1_id");
$sel->is_text_present_ok("URL foo.cgi?action=bar");
$sel->is_text_present_ok("Severity critical blocker");
@@ -431,10 +438,10 @@ foreach my $params (["no_token_single_bug", ""], ["invalid_token_single_bug", "&
$sel->title_is("Suspicious Action");
$sel->is_text_present_ok($token ? "an invalid token" : "web browser directly");
$sel->click_ok("confirm");
- $sel->wait_for_page_to_load_ok(WAIT_TIME);
+ check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug1_id});
$sel->is_text_present_ok("Changes submitted for bug $bug1_id");
$sel->click_ok("link=bug $bug1_id");
- $sel->wait_for_page_to_load_ok(WAIT_TIME);
+ check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug1_id});
$sel->title_like(qr/^$bug1_id /);
$sel->is_text_present_ok($comment);
}
@@ -446,16 +453,16 @@ foreach my $params (["no_token_mass_change", ""], ["invalid_token_mass_change",
$sel->title_is("Suspicious Action");
$sel->is_text_present_ok("no valid token for the buglist_mass_change action");
$sel->click_ok("confirm");
- $sel->wait_for_page_to_load_ok(WAIT_TIME);
+ check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/process_bug.cgi});
$sel->title_is("Bugs processed");
foreach my $bug_id ($bug1_id, $bug2_id) {
$sel->click_ok("link=bug $bug_id");
- $sel->wait_for_page_to_load_ok(WAIT_TIME);
+ check_page_load($sel, WAIT_TIME, qq{http://HOSTNAME:8000/bmo/show_bug.cgi?id=$bug_id});
$sel->title_like(qr/^$bug_id /);
$sel->is_text_present_ok($comment);
next if $bug_id == $bug2_id;
$sel->go_back_ok();
- $sel->wait_for_page_to_load_ok(WAIT_TIME);
+ check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/process_bug.cgi});
$sel->title_is("Bugs processed");
}
}
@@ -463,26 +470,26 @@ foreach my $params (["no_token_mass_change", ""], ["invalid_token_mass_change",
# Now move these bugs out of our radar.
$sel->click_ok("link=My bugs from QA_Selenium");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/buglist.cgi?cmdtype=runnamed&namedcmd=My%20bugs%20from%20QA_Selenium&list_id=21});
$sel->title_is("Bug List: My bugs from QA_Selenium");
$sel->is_text_present_ok("2 bugs found");
$sel->click_ok("link=Change Several Bugs at Once");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/buglist.cgi?email1=admin%40mozilla.test&email2=QA-Selenium-TEST%40mozilla.test&emailassigned_to1=1&emailassigned_to2=1&emailcc2=1&emailqa_contact2=1&emailreporter2=1&emailtype1=exact&emailtype2=exact&product=TestProduct&query_format=advanced&order=priority%2Cbug_severity&tweak=1&list_id=22});
$sel->title_is("Bug List");
$sel->click_ok("check_all");
$sel->type_ok("comment", "Reassigning to the reporter");
$sel->type_ok("assigned_to", $config->{QA_Selenium_TEST_user_login});
$sel->click_ok("commit");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/process_bug.cgi});
$sel->title_is("Bugs processed");
# Now delete the saved search.
$sel->click_ok("link=My bugs from QA_Selenium");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/buglist.cgi?cmdtype=runnamed&namedcmd=My%20bugs%20from%20QA_Selenium&list_id=23});
$sel->title_is("Bug List: My bugs from QA_Selenium");
$sel->click_ok("link=Forget Search 'My bugs from QA_Selenium'");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/buglist.cgi?cmdtype=dorem&remaction=forget&namedcmd=My%20bugs%20from%20QA_Selenium&token=1531926582-f228fa8ebc2f2b3970f2a791e54534ec&list_id=24});
$sel->title_is("Search is gone");
$sel->is_text_present_ok("OK, the My bugs from QA_Selenium search is gone");
@@ -495,10 +502,10 @@ sub clear_canedit_on_testproduct {
edit_product($sel, "TestProduct");
$sel->click_ok("link=Edit Group Access Controls:");
- $sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/editproducts.cgi?action=editgroupcontrols&product=TestProduct});
$sel->title_is("Edit Group Controls for TestProduct");
$sel->uncheck_ok("canedit_$master_gid");
$sel->click_ok("submit");
- $sel->wait_for_page_to_load_ok(WAIT_TIME);
+check_page_load($sel, WAIT_TIME, q{http://HOSTNAME:8000/bmo/editproducts.cgi});
$sel->title_is("Update group access controls for TestProduct");
}
diff --git a/qa/t/test_shutdown.t b/qa/t/test_shutdown.t
deleted file mode 100644
index dc5cabd4a..000000000
--- a/qa/t/test_shutdown.t
+++ /dev/null
@@ -1,72 +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.
-
-use strict;
-use warnings;
-use lib qw(lib ../../lib ../../local/lib/perl5);
-
-use Test::More "no_plan";
-
-use QA::Util;
-
-my ($sel, $config) = get_selenium();
-
-log_in($sel, $config, 'admin');
-set_parameters($sel, { "General" => {shutdownhtml => {type => "text",
- value => "I'm down (set by test_shutdown.t)" }
- } });
-
-# None of the following pages should be accessible when Bugzilla is down.
-
-my @pages = qw(admin attachment buglist chart colchange config createaccount
- describecomponents describekeywords duplicates
- editclassifications editcomponents editfields editflagtypes
- editgroups editkeywords editmilestones editproducts editsettings
- editusers editvalues editversions editwhines editworkflow
- enter_bug index long_list page post_bug process_bug query quips
- relogin report reports request sanitycheck search_plugin
- show_activity show_bug showattachment showdependencygraph
- showdependencytree sidebar summarize_time token userprefs votes
- xml xmlrpc);
-
-foreach my $page (@pages) {
- $sel->open_ok("/$config->{bugzilla_installation}/${page}.cgi");
- $sel->title_is("Bugzilla is Down");
-}
-
-# Those have parameters passed to the page, so we put them here separately.
-
-@pages = ("query.cgi?format=report-table", "query.cgi?format=report-graph",
- "votes.cgi?action=show_user", "votes.cgi?action=show_bug");
-
-foreach my $page (@pages) {
- $sel->open_ok("/$config->{bugzilla_installation}/$page");
- $sel->title_is("Bugzilla is Down");
-}
-
-# Clear 'shutdownhtml', to re-enable Bugzilla.
-# At this point, the admin has been logged out. We cannot use log_in(),
-# nor set_parameters(), due to shutdownhtml being active.
-
-$sel->open_ok("/$config->{bugzilla_installation}/editparams.cgi");
-$sel->title_is("Log in to Bugzilla");
-$sel->type_ok("Bugzilla_login", $config->{admin_user_login}, "Enter admin login name");
-$sel->type_ok("Bugzilla_password", $config->{admin_user_passwd}, "Enter admin password");
-$sel->click_ok("log_in");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
-$sel->title_is("Configuration: General");
-$sel->type_ok("shutdownhtml", "");
-$sel->click_ok('//input[@type="submit" and @value="Save Changes"]', undef, "Save Changes");
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
-$sel->title_is("Parameters Updated");
-
-# Accessing index.cgi should work again now.
-
-$sel->click_ok('//*[@id="header-title"]//a');
-$sel->wait_for_page_to_load_ok(WAIT_TIME);
-$sel->title_is("Bugzilla Main Page");
-logout($sel);
diff --git a/scripts/block-ip.pl b/scripts/block-ip.pl
index b767a1fd5..3fa66d336 100755
--- a/scripts/block-ip.pl
+++ b/scripts/block-ip.pl
@@ -12,8 +12,8 @@ use warnings;
use lib qw(. lib local/lib/perl5);
use Bugzilla;
+use Bugzilla::Quantum;
use Bugzilla::Constants;
-use Bugzilla::ModPerl::BlockIP;
use Getopt::Long;
Bugzilla->usage_mode(USAGE_MODE_CMDLINE);
@@ -23,10 +23,12 @@ GetOptions('unblock' => \$unblock);
pod2usage("No IPs given") unless @ARGV;
+my $app = Bugzilla::Quantum->new;
+
if ($unblock) {
- Bugzilla::ModPerl::BlockIP->unblock_ip($_) for @ARGV;
+ $app->unblock_ip($_) for @ARGV;
} else {
- Bugzilla::ModPerl::BlockIP->block_ip($_) for @ARGV;
+ $app->block_ip($_) for @ARGV;
}
=head1 NAME
@@ -52,4 +54,4 @@ If passed, the IPs will be unblocked instead of blocked. Use this to remove IPs
=head1 DESCRIPTION
-This is just a simple CLI inteface to L<Bugzilla::ModPerl::BlockIP>.
+This is just a simple CLI inteface to L<Bugzilla::Quantum::Plugin::BlockIP>.
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 ce1cc795b..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 {
@@ -83,7 +78,6 @@ sub cmd_demo {
sub cmd_httpd {
check_data_dir();
wait_for_db();
- check_httpd_env();
my $httpd_exit_f = run_cereal_and_httpd();
assert_httpd()->get();
@@ -111,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();
@@ -141,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 => [
@@ -156,6 +155,7 @@ sub cmd_test_webservices {
sub cmd_test_selenium {
my $conf = require $ENV{BZ_QA_CONF_FILE};
+ $ENV{HTTP_BACKEND} = 'simple';
check_data_dir();
copy_qa_extension();
@@ -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 ],
@@ -207,8 +207,6 @@ sub cmd_test_bmo {
sub run_prove {
my (%param) = @_;
- check_httpd_env();
-
my $prove_cmd = $param{prove_cmd};
my $prove_dir = $param{prove_dir};
assert_httpd()->then(sub {
@@ -246,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;
}
@@ -268,16 +270,6 @@ sub check_env {
die 'Missing required environmental variables: ', join(', ', @missing_env), "\n";
}
}
-sub check_httpd_env {
- check_env(qw(
- HTTPD_StartServers
- HTTPD_MinSpareServers
- HTTPD_MaxSpareServers
- HTTPD_ServerLimit
- HTTPD_MaxClients
- HTTPD_MaxRequestsPerChild
- ))
-}
sub fix_path {
$ENV{PATH} = "/app/local/bin:$ENV{PATH}";
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/scripts/undo.pl b/scripts/undo.pl
index 24d6f594b..24d6f594b 100644..100755
--- a/scripts/undo.pl
+++ b/scripts/undo.pl
diff --git a/t/001compile.t b/t/001compile.t
index e81162056..3d8d82bf4 100644
--- a/t/001compile.t
+++ b/t/001compile.t
@@ -35,7 +35,7 @@ sub compile_file {
my ($file) = @_;
# Don't allow CPAN.pm to modify the global @INC, which the version
- # shipped with Perl 5.8.8 does. (It gets loaded by
+ # shipped with Perl 5.8.8 does. (It gets loaded by
# Bugzilla::Install::CPAN.)
local @INC = @INC;
@@ -43,10 +43,6 @@ sub compile_file {
skip "$file: extensions not tested", 1;
return;
}
- if ($file =~ /ModPerl/) {
- skip "$file: ModPerl stuff not tested", 1;
- return;
- }
if ($file =~ s/\.pm$//) {
$file =~ s{/}{::}g;
@@ -82,7 +78,7 @@ my $file_features = map_files_to_features();
# Test the scripts by compiling them
foreach my $file (@testitems) {
# These were already compiled, above.
- next if ($file eq 'Bugzilla.pm'
+ next if ($file eq 'Bugzilla.pm'
or $file eq 'Bugzilla/Constants.pm'
or $file eq 'Bugzilla/Install/Requirements.pm');
SKIP: {
@@ -94,10 +90,10 @@ foreach my $file (@testitems) {
skip "$file: $feature not enabled", 1;
}
- # Check that we have a DBI module to support the DB, if this
+ # Check that we have a DBI module to support the DB, if this
# is a database module (but not Schema)
if ($file =~ m{Bugzilla/DB/([^/]+)\.pm$}
- and $file ne "Bugzilla/DB/Schema.pm")
+ and $file ne "Bugzilla/DB/Schema.pm")
{
my $module = lc($1);
Bugzilla->feature($module) or skip "$file: Driver for $module not installed", 1;
@@ -105,4 +101,4 @@ foreach my $file (@testitems) {
compile_file($file);
}
-}
+}
diff --git a/t/002goodperl.t b/t/002goodperl.t
index 5f201160b..80d7cf2b9 100644
--- a/t/002goodperl.t
+++ b/t/002goodperl.t
@@ -83,6 +83,7 @@ foreach my $file (@testitems) {
my $found_use_strict = 0;
my $found_use_warnings = 0;
my $found_modern_perl = 0;
+ my $found_mojo = 0;
$file =~ s/\s.*$//; # nuke everything after the first space (#comment)
next if (!$file); # skip null entries
@@ -92,13 +93,17 @@ foreach my $file (@testitems) {
}
while (my $file_line = <FILE>) {
$found_modern_perl = 1 if $file_line =~ m/^use\s*(?:Moo|Role::Tiny)/;
+ $found_mojo = 1 if $file_line =~ m/^use\s(?:Mojo(?:licious::Lite|::Base)\b)/;
$found_use_perl = 1 if $file_line =~ m/^\s*use 5.10.1/;
$found_use_strict = 1 if $file_line =~ m/^\s*use strict/;
$found_use_warnings = 1 if $file_line =~ m/^\s*use warnings/;
- if ($found_modern_perl) {
+ if ($found_modern_perl || $found_mojo) {
$found_use_strict = 1;
$found_use_warnings = 1;
}
+ if ($found_mojo) {
+ $found_use_perl = 1;
+ }
last if ($found_use_perl && $found_use_strict && $found_use_warnings);
}
close (FILE);
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/admin/params/editparams.html.tmpl b/template/en/default/admin/params/editparams.html.tmpl
index 838bff7ef..6e8bc2257 100644
--- a/template/en/default/admin/params/editparams.html.tmpl
+++ b/template/en/default/admin/params/editparams.html.tmpl
@@ -21,7 +21,6 @@
[%# INTERFACE:
# panels: array of hashes representing the panels available.
# param_changed: array of parameters which have been changed.
- # shutdown_is_active: boolean; is true when 'shutdownhtml' has been turned on.
#%]
[% PROCESS global/variables.none.tmpl %]
diff --git a/template/en/default/admin/params/general.html.tmpl b/template/en/default/admin/params/general.html.tmpl
index f1b86e19f..05e8f09a2 100644
--- a/template/en/default/admin/params/general.html.tmpl
+++ b/template/en/default/admin/params/general.html.tmpl
@@ -48,11 +48,6 @@
_ " &quot;on&quot;, you must re-run <kbd>checksetup.pl</kbd> immediately"
_ " afterward.</p>",
- shutdownhtml =>
- "If this field is non-empty, then $terms.Bugzilla will be completely"
- _ " disabled and this text will be displayed instead of all the"
- _ " $terms.Bugzilla pages.",
-
announcehtml =>
"If this field is non-empty, then $terms.Bugzilla will"
_ " display whatever is in this field at the top of every"
diff --git a/template/en/default/attachment/create.html.tmpl b/template/en/default/attachment/create.html.tmpl
index f83a9f83a..2727a225c 100644
--- a/template/en/default/attachment/create.html.tmpl
+++ b/template/en/default/attachment/create.html.tmpl
@@ -75,7 +75,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/create/user-message.html.tmpl b/template/en/default/bug/create/user-message.html.tmpl
index fa42ace81..51e787870 100644
--- a/template/en/default/bug/create/user-message.html.tmpl
+++ b/template/en/default/bug/create/user-message.html.tmpl
@@ -30,7 +30,7 @@
[% PROCESS global/variables.none.tmpl %]
Before reporting [% terms.abug %], please read the
-<a href="https://developer.mozilla.org/docs/Mozilla/QA/Bug_writing_guidelines">
+<a href="[% terms.BugWritingGuidelinesURL %]">
[% terms.bug %] writing guidelines</a>, please look at the list of
<a href="duplicates.cgi">most frequently reported [% terms.bugs %]</a>, and please
<a href="query.cgi">search</a> for the [% terms.bug %].
diff --git a/template/en/default/bug/new_bug.html.tmpl b/template/en/default/bug/new_bug.html.tmpl
index ef5e361c0..9e0b2c1ab 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/field-descs.none.tmpl b/template/en/default/global/field-descs.none.tmpl
index 3e0a528dc..cb6240c29 100644
--- a/template/en/default/global/field-descs.none.tmpl
+++ b/template/en/default/global/field-descs.none.tmpl
@@ -162,13 +162,11 @@ if ( $stash->get("in_template_var") ) {
# database. If you want to override this for your language
# or your installation, just use a hook. %]
my $bug_fields = $stash->get("bug_fields");
- unless ( Bugzilla->params->{shutdownhtml} ) {
- foreach my $bz_field ( values %$bug_fields ) {
- $vars->{field_descs}{$bz_field->name} //= $bz_field->description;
- }
-
- $context->process("bug/field-help.none.tmpl");
+ foreach my $bz_field ( values %$bug_fields ) {
+ $vars->{field_descs}{$bz_field->name} //= $bz_field->description;
}
+
+ $context->process("bug/field-help.none.tmpl");
}
[% END %]
diff --git a/template/en/default/global/header.html.tmpl b/template/en/default/global/header.html.tmpl
index bd9ec8bcb..9db9a1404 100644
--- a/template/en/default/global/header.html.tmpl
+++ b/template/en/default/global/header.html.tmpl
@@ -97,6 +97,8 @@
[% IF Param('utf8') %]
<meta charset="UTF-8">
[% END %]
+ [% USE Bugzilla %]
+ <base href="[% urlbase FILTER html %]">
[% IF Bugzilla.cgi.should_block_referrer %]
<meta name="referrer" content="origin">
diff --git a/template/en/default/global/messages.html.tmpl b/template/en/default/global/messages.html.tmpl
index 591617f3e..278b0f161 100644
--- a/template/en/default/global/messages.html.tmpl
+++ b/template/en/default/global/messages.html.tmpl
@@ -140,7 +140,7 @@
[% ELSIF message_tag == "buglist_updated_named_query" %]
[% title = "Search updated" %]
- Your search named <code><a
+ Your search named <code><a
href="buglist.cgi?cmdtype=runnamed&amp;namedcmd=[% queryname FILTER uri %]"
>[% queryname FILTER html %]</a></code> has been updated.
@@ -298,22 +298,22 @@
[% ELSIF message_tag == "email_change_canceled_reinstated" %]
[% title = "Cancel Request to Change Email Address" %]
The request to change the email address for the
- account [%+ old_email FILTER html %] to
+ account [%+ old_email FILTER html %] to
[%+ new_email FILTER html %] has been canceled.
Your old account settings have been reinstated.
[% ELSIF message_tag == "extension_created" %]
An extension named [% name FILTER html %] has been created
- in [% path FILTER html %]. Make sure you change "YOUR NAME" and
+ in [% path FILTER html %]. Make sure you change "YOUR NAME" and
"YOUR EMAIL ADDRESS" in the code to your name and your email address.
[% ELSIF message_tag == "field_value_created" %]
[% title = "New Field Value Created" %]
- The value <em>[% value.name FILTER html %]</em> has been added as a
+ The value <em>[% value.name FILTER html %]</em> has been added as a
valid choice for the <em>[% field.description FILTER html %]</em>
(<em>[% field.name FILTER html %]</em>) field.
[% IF field.name == "bug_status" %]
- You should now visit the <a href="editworkflow.cgi">status workflow
+ You should now visit the <a href="editworkflow.cgi">status workflow
page</a> to include your new [% terms.bug %] status.
[% END %]
@@ -331,7 +331,7 @@
(<em>[% field.name FILTER html %]</em>) field has been changed:
<ul>
[% IF changes.value %]
- <li>Field value updated to
+ <li>Field value updated to
<em>[% changes.value.1 FILTER html %]</em>.
[% IF value.is_default %]
(Note that this value is the default for this field. All
@@ -340,16 +340,16 @@
</li>
[% END %]
[% IF changes.sortkey %]
- <li>Sortkey updated to
+ <li>Sortkey updated to
<em>[% changes.sortkey.1 FILTER html %]</em>.</li>
[% END %]
[% IF changes.visibility_value_id %]
[% IF value.visibility_value.defined %]
- <li>It only appears when
+ <li>It only appears when
[%+ value.field.value_field.description FILTER html %] is set to
'[%+ value.visibility_value.name FILTER html %]'.</li>
[% ELSE %]
- <li>It now always appears, no matter what
+ <li>It now always appears, no matter what
[%+ value.field.value_field.description FILTER html %] is set to.
</li>
[% END %]
@@ -535,7 +535,7 @@
Reading users...
[% ELSIF message_tag == "migrate_translating_bugs" %]
- Converting [% terms.bug %] values to be appropriate for
+ Converting [% terms.bug %] values to be appropriate for
[%+ terms.Bugzilla %]...
[% ELSIF message_tag == "migrate_user_created" %]
@@ -594,12 +594,6 @@
No changes made.
[% END %]
- [% IF shutdown_is_active == 1 %]
- <hr>
- [% terms.Bugzilla %] has now been shut down. To re-enable the system,
- clear the <em>shutdownhtml</em> field.
- [% END%]
-
[% ELSIF message_tag == "password_change_canceled" %]
[% title = "Cancel Request to Change Password" %]
Your request has been canceled.
@@ -731,7 +725,7 @@
[% ELSIF message_tag == "install_fk_invalid" %]
ERROR: There are invalid values for the [% column FILTER html %] column in the [% table FILTER html %]
- table. (These values do not exist in the [% foreign_table FILTER html %] table, in the
+ table. (These values do not exist in the [% foreign_table FILTER html %] table, in the
[%+ foreign_column FILTER html %] column.)
Before continuing with checksetup, you will need to fix these values,
@@ -789,8 +783,8 @@
to be editable by both you and the web server must be world writable, and
other files (including the localconfig file which stores your database
password) must be world readable. This means that _anyone_ who can obtain
- local access to this machine can do whatever they want to your
- [%+ terms.Bugzilla %] installation, and is probably also able to run
+ local access to this machine can do whatever they want to your
+ [%+ terms.Bugzilla %] installation, and is probably also able to run
arbitrary Perl code as the user that the web server runs as.
You really, really, really need to change this setting.
@@ -798,10 +792,10 @@
[% ELSIF message_tag == "install_webservergroup_not_in" %]
Warning: you have entered a value for the "webservergroup" parameter in
- localconfig, but you are not either a) running this script as [% constants.ROOT_USER FILTER html %];
- or b) a member of this group. This can cause permissions problems and
+ localconfig, but you are not either a) running this script as [% constants.ROOT_USER FILTER html %];
+ or b) a member of this group. This can cause permissions problems and
decreased security. If you experience problems running [% terms.Bugzilla %]
- scripts, log in as [% constants.ROOT_USER FILTER html %] and re-run this script, become a
+ scripts, log in as [% constants.ROOT_USER FILTER html %] and re-run this script, become a
member of the group, or remove the value of the "webservergroup" parameter.
[% ELSIF message_tag == "install_webservergroup_windows" %]
@@ -836,7 +830,7 @@
products you can choose from.
[% ELSIF message_tag == "remaining_time_zeroed" %]
- The [% field_descs.remaining_time FILTER html %] field has been
+ The [% field_descs.remaining_time FILTER html %] field has been
set to zero automatically as part of closing this [% terms.bug %]
or moving it from one closed state to another.
@@ -856,21 +850,21 @@
[% ELSIF message_tag == "sudo_started" %]
[% title = "Sudo session started" %]
- The sudo session has been started. For the next 6 hours, or until you
- end the session, everything you do you do as the user you are
+ The sudo session has been started. For the next 6 hours, or until you
+ end the session, everything you do you do as the user you are
impersonating ([% target FILTER html %]).
-
+
[% ELSIF message_tag == "sudo_ended" %]
[% title = "Sudo session complete" %]
- The sudo session has been ended. From this point forward, everything you
+ The sudo session has been ended. From this point forward, everything you
do you do as yourself.
[% ELSIF message_tag == "series_created" %]
[% title = "Series Created" %]
The series <em>[% series.category FILTER html %] /
- [%+ series.subcategory FILTER html %] /
+ [%+ series.subcategory FILTER html %] /
[%+ series.name FILTER html %]</em>
- has been created. Note that you may need to wait up to
+ has been created. Note that you may need to wait up to
[%+ series.frequency * 2 %] days before there will be enough data for a
chart of this series to be produced.
@@ -881,14 +875,6 @@
[%+ series.name FILTER html %]</em>
has been deleted.
- [% ELSIF message_tag == "shutdown" %]
- [% title = "$terms.Bugzilla is Down" %]
- [% Param("shutdownhtml") %]
- [% IF userid %]
- <p>For security reasons, you have been logged out automatically.
- The cookie that was remembering your login is now gone.
- [% END %]
-
[% ELSIF message_tag == "tag_updated" %]
[% title = "Tag Updated" %]
The '<a href="buglist.cgi?tag=[% tag FILTER uri %]">[% tag FILTER html %]</a>'
@@ -908,7 +894,7 @@
Some flags could not be set. Please check your changes.
[% ELSIF message_tag == "user_match_failed" %]
- You entered a username that did not match any known
+ You entered a username that did not match any known
[% terms.Bugzilla %] users, so we have instead left
the [% match_field FILTER html %] field blank.
diff --git a/template/en/default/global/variables.none.tmpl b/template/en/default/global/variables.none.tmpl
index faf1a5427..93002efa3 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 e63bf0e87..2aff68615 100644
--- a/template/en/default/index.html.tmpl
+++ b/template/en/default/index.html.tmpl
@@ -76,7 +76,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 eb989d15c..ead3ff54c 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 df2f6b349..486f3a00a 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 d0cf078e7..ed3942166 100644
--- a/template/en/default/search/search-instant.html.tmpl
+++ b/template/en/default/search/search-instant.html.tmpl
@@ -8,11 +8,15 @@
[% PROCESS global/variables.none.tmpl %]
+[% javascript_urls = [ 'js/instant-search.js' ] %]
+[% IF has_extension('GuidedBugEntry') %]
+ [% javascript_urls.import(['extensions/GuidedBugEntry/web/js/products.js']); %]
+[% END %]
+
[% 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/vagrant_support/apache.yml b/vagrant_support/apache.yml
index 5031187e3..2d65965ab 100644
--- a/vagrant_support/apache.yml
+++ b/vagrant_support/apache.yml
@@ -6,8 +6,8 @@
mode: 0644
when: LAZY == 0
-- name: enable httpd
- service: name=httpd enabled=yes
+- name: disable httpd
+ service: name=httpd enabled=no
when: LAZY == 0
- name: ensure bugzilla.log has right permissions
@@ -16,5 +16,5 @@
- name: ensure bugzilla-json.log has right permissions
file: path=/vagrant/logs/bugzilla-json.log state=touch owner=vagrant group=apache mode=0660
-- name: restart httpd
- service: name=httpd state=restarted \ No newline at end of file
+- name: stop httpd
+ service: name=httpd state=stopped
diff --git a/vagrant_support/hypnotoad b/vagrant_support/hypnotoad
new file mode 100755
index 000000000..5e8dc910e
--- /dev/null
+++ b/vagrant_support/hypnotoad
@@ -0,0 +1,122 @@
+#!/bin/bash
+#
+# bugzilla-push This starts, stops, and restarts the Bugzilla push
+# daemon, which manages syncronising bugzilla.mozilla.org and
+# third party bugzilla installs.
+#
+# chkconfig: 345 85 15
+# description: Bugzilla push daemon
+#
+### BEGIN INIT INFO
+# Provides: bugzilla-push
+# Required-Start: $local_fs $syslog MTA mysqld
+# Required-Stop: $local_fs $syslog MTA mysqld
+# Default-Start: 3 5
+# Default-Stop: 0 1 2 6
+# Short-Description: Start and stop the Bugzilla push daemon.
+# Description: The Bugzilla push daemon (bugzilla-pushd.pl)
+#
+#
+#
+### END INIT INFO
+
+NAME=`basename $0`
+
+#################
+# Configuration #
+#################
+
+# This should be the path to your Bugzilla
+BUGZILLA=/vagrant
+# Who owns the Bugzilla directory and files?
+USER=vagrant
+
+PERL5LIB="$BUGZILLA:$BUGZILLA/lib:$BUGZILLA/local/lib/perl5"
+export PERL5LIB
+export MOJO_MODE
+
+if [[ x$PORT == x ]]; then
+ PORT=80
+ export PORT
+fi
+
+# If you want to pass any options to the daemon (like -d for debugging)
+# specify it here.
+OPTIONS=""
+
+# You can also override the configuration by creating a
+# /etc/sysconfig/bugzilla-queue file so that you don't
+# have to edit this script.
+if [ -r /etc/sysconfig/$NAME ]; then
+ . /etc/sysconfig/$NAME
+fi
+
+##########
+# Script #
+##########
+
+RETVAL=0
+BIN="$BUGZILLA/local/bin/hypnotoad"
+PIDFILE="$BUGZILLA/hypnotoad.pid"
+
+# Source function library.
+. /etc/rc.d/init.d/functions
+
+usage ()
+{
+ echo "Usage: service $NAME {start|stop|status|restart|condrestart}"
+ RETVAL=1
+}
+
+
+start ()
+{
+ if [[ -f $PIDFILE ]]; then
+ checkpid "$(cat $PIDFILE)" && return 0
+ fi
+ echo -n "Starting $NAME: "
+ daemon --pidfile=$PIDFILE --user=$USER "cd $BUGZILLA && $BIN bugzilla.pl >/dev/null"
+ ret=$?
+ [ $ret -eq "0" ] && touch /var/lock/subsys/$NAME
+ echo
+ return $ret
+}
+
+stop ()
+{
+ cd $BUGZILLA && $BIN bugzilla.pl --stop
+ rm -f /var/lock/subsys/$NAME
+}
+
+restart ()
+{
+ stop
+ start
+}
+
+condrestart ()
+{
+ [ -e /var/lock/subsys/$NAME ] && restart || return 0
+}
+
+status ()
+{
+ if [[ -f $PIDFILE ]] && checkpid "$(cat $PIDFILE)"; then
+ echo hypnotoad is amazing
+ return 0
+ else
+ echo hypnotoad is not running
+ return 1
+ fi
+}
+
+case "$1" in
+ start) start; RETVAL=$? ;;
+ stop) stop; RETVAL=$? ;;
+ status) status; RETVAL=$?;;
+ restart) restart; RETVAL=$? ;;
+ condrestart) condrestart; RETVAL=$? ;;
+ *) usage ; RETVAL=2 ;;
+esac
+
+exit $RETVAL
diff --git a/vagrant_support/hypnotoad.yml b/vagrant_support/hypnotoad.yml
new file mode 100644
index 000000000..a66f9ba04
--- /dev/null
+++ b/vagrant_support/hypnotoad.yml
@@ -0,0 +1,27 @@
+- name: grant perl ability to listen to privledged ports
+ command: setcap 'cap_net_bind_service=+ep' /usr/bin/perl
+
+- name: hypnotoad daemon sysconfig
+ copy:
+ dest: /etc/sysconfig/hypnotoad
+ mode: 0644
+ content: |
+ BUGZILLA=/vagrant
+ USER=vagrant
+ MOJO_MODE=development
+
+- name: hypnotoad daemon init file
+ template:
+ dest: /etc/init.d/hypnotoad
+ src: hypnotoad
+ owner: root
+ group: root
+ mode: 0755
+
+- name: enable hypnotoad
+ service: name=hypnotoad enabled=yes
+ when: LAZY == 0
+
+- name: restart hypnotoad
+ service: name=hypnotoad state=restarted
+
diff --git a/vagrant_support/playbook.yml b/vagrant_support/playbook.yml
index c067eab05..3dd320f0b 100644
--- a/vagrant_support/playbook.yml
+++ b/vagrant_support/playbook.yml
@@ -170,9 +170,6 @@
dest: /usr/local/bin/cpanm
mode: '0755'
- - name: install more recent Apache2::SizeLimit
- cpanm: name=Apache2::SizeLimit executable=/usr/local/bin/cpanm
-
- name: 'check /opt/bmo (failure is ok)'
shell: test -d /opt/bmo && test -f /opt/bmo/local/lib/perl5/Plack.pm
register: opt_bmo
@@ -222,5 +219,8 @@
- include_tasks: apache.yml
vars:
LAZY: 0
+ - include_tasks: hypnotoad.yml
+ vars:
+ LAZY: 0
- import_tasks: devtools.yml
diff --git a/vagrant_support/update.yml b/vagrant_support/update.yml
index c53a0554e..533da5b5e 100644
--- a/vagrant_support/update.yml
+++ b/vagrant_support/update.yml
@@ -20,4 +20,7 @@
LAZY: 1
- include_tasks: apache.yml
vars:
- LAZY: 1 \ No newline at end of file
+ LAZY: 1
+ - include_tasks: hypnotoad.yml
+ vars:
+ LAZY: 1
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';