# 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 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"; } } } $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 ) ) ); } 1;