summaryrefslogtreecommitdiffstats
path: root/Bugzilla
diff options
context:
space:
mode:
Diffstat (limited to 'Bugzilla')
-rw-r--r--Bugzilla/CGI.pm57
-rw-r--r--Bugzilla/CGI/ContentSecurityPolicyAttr.pm71
-rw-r--r--Bugzilla/Constants.pm4
-rw-r--r--Bugzilla/Install/Filesystem.pm3
-rw-r--r--Bugzilla/ModPerl.pm4
-rw-r--r--Bugzilla/Quantum.pm25
-rw-r--r--Bugzilla/Quantum/CGI.pm (renamed from Bugzilla/CGI/Mojo.pm)32
-rw-r--r--Bugzilla/Quantum/Legacy.pm47
-rw-r--r--Bugzilla/Quantum/Plugin/Glue.pm61
-rw-r--r--Bugzilla/Quantum/Template.pm40
-rw-r--r--Bugzilla/Util.pm2
11 files changed, 277 insertions, 69 deletions
diff --git a/Bugzilla/CGI.pm b/Bugzilla/CGI.pm
index 03805ad1e..bfd2a72f6 100644
--- a/Bugzilla/CGI.pm
+++ b/Bugzilla/CGI.pm
@@ -24,6 +24,10 @@ use Bugzilla::Search::Recent;
use File::Basename;
use URI;
+use Role::Tiny::With;
+
+with 'Bugzilla::CGI::ContentSecurityPolicyAttr';
+
BEGIN {
if (ON_WINDOWS) {
# Help CGI find the correct temp directory as the default list
@@ -33,35 +37,6 @@ BEGIN {
*AUTOLOAD = \&CGI::AUTOLOAD;
}
-sub DEFAULT_CSP {
- my %policy = (
- default_src => [ 'self' ],
- script_src => [ 'self', 'nonce', 'unsafe-inline', 'https://www.google-analytics.com' ],
- frame_src => [ 'none', ],
- worker_src => [ 'none', ],
- img_src => [ 'self', 'https://secure.gravatar.com', 'https://www.google-analytics.com' ],
- style_src => [ 'self', 'unsafe-inline' ],
- object_src => [ 'none' ],
- connect_src => [
- 'self',
- # This is from extensions/OrangeFactor/web/js/orange_factor.js
- 'https://treeherder.mozilla.org/api/failurecount/',
- ],
- form_action => [
- 'self',
- # used in template/en/default/search/search-google.html.tmpl
- 'https://www.google.com/search'
- ],
- frame_ancestors => [ 'none' ],
- report_only => 1,
- );
- if (Bugzilla->params->{github_client_id} && !Bugzilla->user->id) {
- push @{$policy{form_action}}, 'https://github.com/login/oauth/authorize', 'https://github.com/login';
- }
-
- return %policy;
-}
-
# Because show_bug code lives in many different .cgi files,
# we needed a centralized place to define the policy.
# normally the policy would just live in one .cgi file.
@@ -193,30 +168,16 @@ sub target_uri {
}
}
-sub content_security_policy {
- my ($self, %add_params) = @_;
- if (%add_params || !$self->{Bugzilla_csp}) {
- my %params = DEFAULT_CSP;
- delete $params{report_only} if %add_params && !$add_params{report_only};
- foreach my $key (keys %add_params) {
- if (defined $add_params{$key}) {
- $params{$key} = $add_params{$key};
- }
- else {
- delete $params{$key};
- }
- }
- $self->{Bugzilla_csp} = Bugzilla::CGI::ContentSecurityPolicy->new(%params);
- }
+sub set_csp_object {
+ my ( $self, $object ) = @_;
- return $self->{Bugzilla_csp};
+ $self->{Bugzilla_csp} = $object;
}
-sub csp_nonce {
+sub csp_object {
my ($self) = @_;
- my $csp = $self->content_security_policy;
- return $csp->has_nonce ? $csp->nonce : '';
+ return $self->{Bugzilla_csp};
}
# We want this sorted plus the ability to exclude certain params
diff --git a/Bugzilla/CGI/ContentSecurityPolicyAttr.pm b/Bugzilla/CGI/ContentSecurityPolicyAttr.pm
new file mode 100644
index 000000000..c94b3815c
--- /dev/null
+++ b/Bugzilla/CGI/ContentSecurityPolicyAttr.pm
@@ -0,0 +1,71 @@
+# 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::CGI::ContentSecurityPolicyAttr;
+use 5.10.1;
+use strict;
+use warnings;
+use Role::Tiny;
+
+requires 'csp_object', 'set_csp_object';
+
+sub DEFAULT_CSP {
+ my %policy = (
+ default_src => [ 'self' ],
+ script_src => [ 'self', 'nonce', 'unsafe-inline', 'https://www.google-analytics.com' ],
+ frame_src => [ 'none', ],
+ worker_src => [ 'none', ],
+ img_src => [ 'self', 'https://secure.gravatar.com', 'https://www.google-analytics.com' ],
+ style_src => [ 'self', 'unsafe-inline' ],
+ object_src => [ 'none' ],
+ connect_src => [
+ 'self',
+ # This is from extensions/OrangeFactor/web/js/orange_factor.js
+ 'https://treeherder.mozilla.org/api/failurecount/',
+ ],
+ form_action => [
+ 'self',
+ # used in template/en/default/search/search-google.html.tmpl
+ 'https://www.google.com/search'
+ ],
+ frame_ancestors => [ 'none' ],
+ report_only => 1,
+ );
+ if (Bugzilla->params->{github_client_id} && !Bugzilla->user->id) {
+ push @{$policy{form_action}}, 'https://github.com/login/oauth/authorize', 'https://github.com/login';
+ }
+
+ return %policy;
+}
+
+sub content_security_policy {
+ my ($self, %add_params) = @_;
+ if (%add_params || !$self->csp_object) {
+ my %params = DEFAULT_CSP;
+ delete $params{report_only} if %add_params && !$add_params{report_only};
+ foreach my $key (keys %add_params) {
+ if (defined $add_params{$key}) {
+ $params{$key} = $add_params{$key};
+ }
+ else {
+ delete $params{$key};
+ }
+ }
+ $self->set_csp_object( Bugzilla::CGI::ContentSecurityPolicy->new(%params) );
+ }
+
+ return $self->csp_object;
+}
+
+sub csp_nonce {
+ my ($self) = @_;
+
+ my $csp = $self->content_security_policy;
+ return $csp->has_nonce ? $csp->nonce : '';
+}
+
+1;
diff --git a/Bugzilla/Constants.pm b/Bugzilla/Constants.pm
index 8ef776f96..127f1bd58 100644
--- a/Bugzilla/Constants.pm
+++ b/Bugzilla/Constants.pm
@@ -130,7 +130,7 @@ use Memoize;
USAGE_MODE_JSON
USAGE_MODE_TEST
USAGE_MODE_REST
- USAGE_MODE_MOJO
+ USAGE_MODE_QUANTUM
ERROR_MODE_WEBPAGE
ERROR_MODE_DIE
@@ -488,7 +488,7 @@ use constant USAGE_MODE_EMAIL => 3;
use constant USAGE_MODE_JSON => 4;
use constant USAGE_MODE_TEST => 5;
use constant USAGE_MODE_REST => 6;
-use constant USAGE_MODE_MOJO => 7;
+use constant USAGE_MODE_QUANTUM => 7;
# Error modes. Default set by Bugzilla->usage_mode (so ERROR_MODE_WEBPAGE
# usually). Use with Bugzilla->error_mode.
diff --git a/Bugzilla/Install/Filesystem.pm b/Bugzilla/Install/Filesystem.pm
index 739ea9a0a..b5d8bae08 100644
--- a/Bugzilla/Install/Filesystem.pm
+++ b/Bugzilla/Install/Filesystem.pm
@@ -240,6 +240,7 @@ sub FILESYSTEM {
'.htaccess' => { perms => WS_SERVE },
'cvs-update.log' => { perms => WS_SERVE },
'scripts/sendunsentbugmail.pl' => { perms => WS_EXECUTE },
+ 'scripts/bugzilla_quantum' => { perms => CGI_READ },
'docs/bugzilla.ent' => { perms => OWNER_WRITE },
'docs/makedocs.pl' => { perms => OWNER_EXECUTE },
'docs/style.css' => { perms => WS_SERVE },
@@ -346,7 +347,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 --- #
diff --git a/Bugzilla/ModPerl.pm b/Bugzilla/ModPerl.pm
index 6f7ed22e9..b4ba36934 100644
--- a/Bugzilla/ModPerl.pm
+++ b/Bugzilla/ModPerl.pm
@@ -109,11 +109,11 @@ ErrorDocument 500 /errors/500.html
require valid-user
</Location>
-<Location /new>
+<Location /quantum>
SetHandler perl-script
PerlResponseHandler Plack::Handler::Apache2
PerlSetEnv MOJO_HOME [% cgi_path %]
- PerlSetVar psgi_app [% cgi_path %]/new.psgi
+ PerlSetVar psgi_app [% cgi_path %]/scripts/bugzilla_quantum
</Location>
# directory rules for all the other places we have .htaccess files
diff --git a/Bugzilla/Quantum.pm b/Bugzilla/Quantum.pm
new file mode 100644
index 000000000..7da68e0ed
--- /dev/null
+++ b/Bugzilla/Quantum.pm
@@ -0,0 +1,25 @@
+# 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';
+
+use Bugzilla::Constants;
+use Bugzilla::Quantum::CGI;
+use Try::Tiny;
+
+sub startup {
+ my ($self) = @_;
+
+ $self->plugin('Bugzilla::Quantum::Plugin::Glue');
+ my $r = $self->routes;
+
+ $r->any( '/' )->to('legacy#index_cgi');
+ $r->any( '/show_bug.cgi' )->to('legacy#show_bug');
+}
+
+1; \ No newline at end of file
diff --git a/Bugzilla/CGI/Mojo.pm b/Bugzilla/Quantum/CGI.pm
index 2d4f40d3e..5afa19b18 100644
--- a/Bugzilla/CGI/Mojo.pm
+++ b/Bugzilla/Quantum/CGI.pm
@@ -5,7 +5,7 @@
# This Source Code Form is "Incompatible With Secondary Licenses", as
# defined by the Mozilla Public License, v. 2.0.
-package Bugzilla::CGI::Mojo;
+package Bugzilla::Quantum::CGI;
use 5.10.1;
use Moo;
@@ -14,22 +14,12 @@ has 'controller' => (
handles => [qw(param cookie)],
);
-has 'content_security_policy' => (
- is => 'lazy',
+has 'csp_object' => (
+ is => 'ro',
+ writer => 'set_csp_object',
);
-sub _build_content_security_policy {
- my ($self) = @_;
- my $csp = $self->controller->stash->{content_security_policy} // { Bugzilla::CGI::DEFAULT_CSP() };
- return Bugzilla::CGI::ContentSecurityPolicy->new( $csp );
-}
-
-sub csp_nonce {
- my ($self) = @_;
-
- my $csp = $self->content_security_policy;
- return $csp->has_nonce ? $csp->nonce : '';
-}
+with 'Bugzilla::CGI::ContentSecurityPolicyAttr';
sub script_name {
my ($self) = @_;
@@ -42,6 +32,18 @@ sub http {
return $self->controller->req->headers->header($header);
}
+sub header {
+ my ($self, @args) = @_;
+ my $c = $self->controller;
+ return '' if @args == 0;
+
+ if (@args == 1) {
+ $c->res->headers->content_type($args[0]);
+ }
+
+ return '';
+}
+
sub redirect {
my ($self, $location) = @_;
diff --git a/Bugzilla/Quantum/Legacy.pm b/Bugzilla/Quantum/Legacy.pm
new file mode 100644
index 000000000..73e877af3
--- /dev/null
+++ b/Bugzilla/Quantum/Legacy.pm
@@ -0,0 +1,47 @@
+# 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::Legacy;
+use Mojo::Base 'Mojolicious::Controller';
+use File::Spec::Functions qw(catfile);
+use Bugzilla::Constants qw(bz_locations);
+use Taint::Util qw(untaint);
+use Sub::Name qw(subname);
+use autodie;
+
+_load_cgi(index_cgi => 'index.cgi');
+_load_cgi(show_bug => 'show_bug.cgi');
+
+sub _load_cgi {
+ my ($name, $file) = @_;
+ my $content;
+ {
+ local $/ = undef;
+ open my $fh, '<', catfile(bz_locations->{cgi_path}, $file);
+ $content = <$fh>;
+ untaint($content);
+ close $fh;
+ }
+ my $pkg = __PACKAGE__ . '::' . $name;
+ my @lines = (
+ qq{package $pkg;},
+ qq{#line 1 "$file"},
+ "sub { my (\$self) = \@_; $content };"
+ );
+ my $code = join "\n", @lines;
+ my $sub = _eval($code);
+ {
+ no strict 'refs'; ## no critic (strict)
+ *{ $name } = subname($name, $sub);
+ }
+}
+
+sub _eval { ## no critic (unpack)
+ return eval $_[0]; ## no critic (eval)
+}
+
+1; \ No newline at end of file
diff --git a/Bugzilla/Quantum/Plugin/Glue.pm b/Bugzilla/Quantum/Plugin/Glue.pm
new file mode 100644
index 000000000..d689f598a
--- /dev/null
+++ b/Bugzilla/Quantum/Plugin/Glue.pm
@@ -0,0 +1,61 @@
+# 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 Mojo::Base 'Mojolicious::Plugin';
+
+use Try::Tiny;
+use Bugzilla::Constants;
+use Bugzilla::Quantum::CGI;
+use Bugzilla::Quantum::Template;
+
+sub register {
+ my ( $self, $app, $conf ) = @_;
+
+ my $template = Bugzilla::Template->create;
+ $template->{_is_main} = 1;
+
+ $app->renderer->add_handler(
+ 'bugzilla' => sub {
+ my ( $renderer, $c, $output, $options ) = @_;
+ my %params;
+
+ # Helpers
+ foreach my $method ( grep {m/^\w+\z/} keys %{ $renderer->helpers } ) {
+ my $sub = $renderer->helpers->{$method};
+ $params{$method} = sub { $c->$sub(@_) };
+ }
+
+ # Stash values
+ $params{$_} = $c->stash->{$_} for grep {m/^\w+\z/} keys %{ $c->stash };
+ $params{self} = $params{c} = $c;
+ my $name = $options->{template};
+ unless ($name =~ /\./) {
+ $name = sprintf '%s.%s.tmpl', $options->{template}, $options->{format};
+ }
+ $template->process( $name, \%params, $output )
+ or die $template->error;
+ }
+ );
+
+ $app->hook(
+ around_dispatch => sub {
+ my ($next, $c) = @_;
+ try {
+ local %{ Bugzilla->request_cache } = ();
+ Bugzilla->usage_mode(USAGE_MODE_QUANTUM);
+ Bugzilla->cgi( Bugzilla::Quantum::CGI->new(controller => $c) );
+ Bugzilla->template( Bugzilla::Quantum::Template->new( controller => $c, template => $template ) );
+ $next->();
+ } catch {
+ die $_ unless /\bModPerl::Util::exit\b/;
+ };
+ }
+ );
+}
+
+1; \ No newline at end of file
diff --git a/Bugzilla/Quantum/Template.pm b/Bugzilla/Quantum/Template.pm
new file mode 100644
index 000000000..ebae0cf9f
--- /dev/null
+++ b/Bugzilla/Quantum/Template.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::Template;
+use 5.10.1;
+use Moo;
+
+has 'controller' => (
+ is => 'ro',
+ required => 1,
+);
+
+has 'template' => (
+ is => 'ro',
+ required => 1,
+ handles => ['error', 'get_format'],
+);
+
+sub process {
+ my ($self, $file, $vars, $output) = @_;
+
+ if (@_ < 4) {
+ my $stash = $self->controller->stash;
+ $stash->{$_} = $vars->{$_} for keys %$vars;
+ $self->controller->render(template => $file, handler => 'bugzilla');
+ return 1;
+ }
+ elsif (@_ == 4) {
+ return $self->template->process($file, $vars, $output);
+ }
+ else {
+ die __PACKAGE__ . '->process() called with too many arguments';
+ }
+}
+
+1; \ No newline at end of file
diff --git a/Bugzilla/Util.pm b/Bugzilla/Util.pm
index 206c0aa3f..8e60944b0 100644
--- a/Bugzilla/Util.pm
+++ b/Bugzilla/Util.pm
@@ -321,7 +321,7 @@ sub do_ssl_redirect_if_required {
# Returns the real remote address of the client,
sub remote_ip {
- if (Bugzilla->usage_mode == USAGE_MODE_MOJO) {
+ if (Bugzilla->usage_mode == USAGE_MODE_QUANTUM) {
return Bugzilla->cgi->controller->tx->remote_address;
}
else {