summaryrefslogtreecommitdiffstats
path: root/Bugzilla/Quantum/Plugin/Glue.pm
diff options
context:
space:
mode:
Diffstat (limited to 'Bugzilla/Quantum/Plugin/Glue.pm')
-rw-r--r--Bugzilla/Quantum/Plugin/Glue.pm217
1 files changed, 140 insertions, 77 deletions
diff --git a/Bugzilla/Quantum/Plugin/Glue.pm b/Bugzilla/Quantum/Plugin/Glue.pm
index ded4daf15..f04b9c025 100644
--- a/Bugzilla/Quantum/Plugin/Glue.pm
+++ b/Bugzilla/Quantum/Plugin/Glue.pm
@@ -13,89 +13,152 @@ use Try::Tiny;
use Bugzilla::Constants;
use Bugzilla::Logging;
use Bugzilla::RNG ();
-use JSON::MaybeXS qw(decode_json);
+use Bugzilla::Util qw(with_writable_database);
+use Mojo::Util qw(secure_compare);
+use Mojo::JSON qw(decode_json);
+use Scalar::Util qw(blessed);
+use Scope::Guard;
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";
- }
- }
+ 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->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);
+ $c->stash->{cleanup_guard} = Scope::Guard->new(\&Bugzilla::cleanup);
+ Bugzilla->usage_mode(USAGE_MODE_MOJO);
+ }
+ );
+
+ $app->secrets([Bugzilla->localconfig->{side_wide_secret}]);
+
+ $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 = sprintf '%s.%s.tmpl', $options->{template}, $options->{format};
+ my $template = Bugzilla->template;
+ $template->process($name, \%params, $output) or die $template->error;
+ }
+ );
+ $app->helper(
+ 'bugzilla.login_redirect_if_required' => sub {
+ my ($c, $type) = @_;
+
+ if ($type == LOGIN_REQUIRED) {
+ $c->redirect_to('/login');
+ return undef;
+ }
+ else {
+ return Bugzilla->user;
+ }
+ }
+ );
+ $app->helper(
+ 'bugzilla.login' => sub {
+ my ($c, $type) = @_;
+ $type //= LOGIN_NORMAL;
+
+ return Bugzilla->user if Bugzilla->user->id;
+
+ $type = LOGIN_REQUIRED
+ if $c->param('GoAheadAndLogIn') || Bugzilla->params->{requirelogin};
+
+ # Allow templates to know that we're in a page that always requires
+ # login.
+ if ($type == LOGIN_REQUIRED) {
+ Bugzilla->request_cache->{page_requires_login} = 1;
+ }
+
+ my $login_cookie = $c->cookie("Bugzilla_logincookie");
+ my $user_id = $c->cookie("Bugzilla_login");
+ my $ip_addr = $c->tx->remote_address;
+
+ return $c->bugzilla->login_redirect_if_required($type)
+ unless ($login_cookie && $user_id);
+
+ my $db_cookie = Bugzilla->dbh->selectrow_array(
+ q{
+ SELECT cookie
+ FROM logincookies
+ WHERE cookie = ?
+ AND userid = ?
+ AND (restrict_ipaddr = 0 OR ipaddr = ?)
+ }, undef, ($login_cookie, $user_id, $ip_addr)
+ );
+
+ if (defined $db_cookie && secure_compare($login_cookie, $db_cookie)) {
+ my $user = Bugzilla::User->check({id => $user_id, cache => 1});
+
+ # If we logged in successfully, then update the lastused
+ # time on the login cookie
+ with_writable_database {
+ Bugzilla->dbh->do(
+ q{ UPDATE logincookies SET lastused = NOW() WHERE cookie = ? },
+ undef, $login_cookie);
+ };
+ Bugzilla->set_user($user);
+ return $user;
+ }
+ else {
+ return $c->bugzilla->login_redirect_if_required($type);
+ }
+ }
+ );
+ $app->helper(
+ 'bugzilla.error_page' => sub {
+ my ($c, $error) = @_;
+ if (blessed $error && $error->isa('Bugzilla::Error::Base')) {
+ $c->render(
+ handler => 'bugzilla',
+ template => $error->template,
+ error => $error->message,
+ %{$error->vars}
+ );
+ }
+ else {
+ $c->reply->exception($error);
+ }
+ }
+ );
- $app->log( MojoX::Log::Log4perl::Tiny->new( logger => Log::Log4perl->get_logger( ref $app ) ) );
+ $app->log(MojoX::Log::Log4perl::Tiny->new(
+ logger => Log::Log4perl->get_logger(ref $app)
+ ));
}
1;