diff options
Diffstat (limited to 'Bugzilla/Quantum/Plugin')
-rw-r--r-- | Bugzilla/Quantum/Plugin/BlockIP.pm | 38 | ||||
-rw-r--r-- | Bugzilla/Quantum/Plugin/Glue.pm | 234 | ||||
-rw-r--r-- | Bugzilla/Quantum/Plugin/Helpers.pm | 82 | ||||
-rw-r--r-- | Bugzilla/Quantum/Plugin/Hostage.pm | 117 |
4 files changed, 238 insertions, 233 deletions
diff --git a/Bugzilla/Quantum/Plugin/BlockIP.pm b/Bugzilla/Quantum/Plugin/BlockIP.pm index 058ecbf64..974eebff9 100644 --- a/Bugzilla/Quantum/Plugin/BlockIP.pm +++ b/Bugzilla/Quantum/Plugin/BlockIP.pm @@ -9,35 +9,35 @@ use constant BLOCK_TIMEOUT => 60 * 60; my $MEMCACHED = Bugzilla::Memcached->new()->{memcached}; sub register { - my ( $self, $app, $conf ) = @_; + my ($self, $app, $conf) = @_; - $app->hook( before_routes => \&_before_routes ); - $app->helper( block_ip => \&_block_ip ); - $app->helper( unblock_ip => \&_unblock_ip ); + $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; + 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; + 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; - } + 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 index 8f4144589..f04b9c025 100644 --- a/Bugzilla/Quantum/Plugin/Glue.pm +++ b/Bugzilla/Quantum/Plugin/Glue.pm @@ -20,141 +20,145 @@ 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"; + } + } + } + + $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->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->secrets( [ Bugzilla->localconfig->{side_wide_secret} ] ); + $app->renderer->add_handler( + 'bugzilla' => sub { + my ($renderer, $c, $output, $options) = @_; - $app->renderer->add_handler( - 'bugzilla' => sub { - my ( $renderer, $c, $output, $options ) = @_; + my %params; - 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}; + # Helpers + foreach my $method (grep {m/^\w+\z/} keys %{$renderer->helpers}) { + my $sub = $renderer->helpers->{$method}; + $params{$method} = sub { $c->$sub(@_) }; + } - $params{self} = $params{c} = $c; + # Stash values + $params{$_} = $c->stash->{$_} for grep {m/^\w+\z/} keys %{$c->stash}; - 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; + $params{self} = $params{c} = $c; - return Bugzilla->user if Bugzilla->user->id; + 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; - $type = LOGIN_REQUIRED if $c->param('GoAheadAndLogIn') || Bugzilla->params->{requirelogin}; + return Bugzilla->user if Bugzilla->user->id; - # 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; - } + $type = LOGIN_REQUIRED + if $c->param('GoAheadAndLogIn') || Bugzilla->params->{requirelogin}; - my $login_cookie = $c->cookie("Bugzilla_logincookie"); - my $user_id = $c->cookie("Bugzilla_login"); - my $ip_addr = $c->tx->remote_address; + # 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; + } - return $c->bugzilla->login_redirect_if_required($type) unless ( $login_cookie && $user_id ); + my $login_cookie = $c->cookie("Bugzilla_logincookie"); + my $user_id = $c->cookie("Bugzilla_login"); + my $ip_addr = $c->tx->remote_address; - my $db_cookie = Bugzilla->dbh->selectrow_array( - q{ + 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); - } - } - ); + }, 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; diff --git a/Bugzilla/Quantum/Plugin/Helpers.pm b/Bugzilla/Quantum/Plugin/Helpers.pm index 0aedca338..72dd96cf9 100644 --- a/Bugzilla/Quantum/Plugin/Helpers.pm +++ b/Bugzilla/Quantum/Plugin/Helpers.pm @@ -12,53 +12,55 @@ use Bugzilla::Logging; use Carp; sub register { - my ( $self, $app, $conf ) = @_; + my ($self, $app, $conf) = @_; - $app->helper( - basic_auth => sub { - my ( $c, $realm, $auth_user, $auth_pass ) = @_; - my $req = $c->req; - my ( $user, $password ) = $req->url->to_abs->userinfo =~ /^([^:]+):(.*)/; + $app->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 ($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; - } + 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; - } - ); - $app->routes->add_shortcut( - static_file => sub { - my ($r, $path, $option) = @_; - my $file = $option->{file}; - my $content_type = $option->{content_type} // 'text/plain'; - unless ($file) { - $file = $path; - $file =~ s!^/!!; - } + return 1; + } + ); + $app->routes->add_shortcut( + static_file => sub { + my ($r, $path, $option) = @_; + my $file = $option->{file}; + my $content_type = $option->{content_type} // 'text/plain'; + unless ($file) { + $file = $path; + $file =~ s!^/!!; + } - return $r->get($path => sub { - my ($c) = @_; - $c->res->headers->content_type($content_type); - $c->reply->file( $c->app->home->child($file) ); - }) + return $r->get( + $path => sub { + my ($c) = @_; + $c->res->headers->content_type($content_type); + $c->reply->file($c->app->home->child($file)); } - ); - $app->routes->add_shortcut( - page => sub { - my ($r, $path, $id) = @_; + ); + } + ); + $app->routes->add_shortcut( + page => sub { + my ($r, $path, $id) = @_; - return $r->any($path)->to('CGI#page_cgi' => { id => $id }); - } - ); + return $r->any($path)->to('CGI#page_cgi' => {id => $id}); + } + ); } 1; diff --git a/Bugzilla/Quantum/Plugin/Hostage.pm b/Bugzilla/Quantum/Plugin/Hostage.pm index cbde7b5ee..63fad2be2 100644 --- a/Bugzilla/Quantum/Plugin/Hostage.pm +++ b/Bugzilla/Quantum/Plugin/Hostage.pm @@ -4,83 +4,82 @@ use Mojo::Base 'Mojolicious::Plugin'; use Bugzilla::Logging; sub _attachment_root { - my ($base) = @_; - return undef unless $base; - return $base =~ m{^https?://(?:bug)?\%bugid\%\.([a-zA-Z\.-]+)} - ? $1 - : undef; + my ($base) = @_; + return undef unless $base; + return $base =~ m{^https?://(?:bug)?\%bugid\%\.([a-zA-Z\.-]+)} ? $1 : undef; } sub _attachment_host_regex { - my ($base) = @_; - return undef unless $base; - my $val = $base; - $val =~ s{^https?://}{}s; - $val =~ s{/$}{}s; - my $regex = quotemeta $val; - $regex =~ s/\\\%bugid\\\%/\\d+/g; - return qr/^$regex$/s; + my ($base) = @_; + return undef unless $base; + my $val = $base; + $val =~ s{^https?://}{}s; + $val =~ s{/$}{}s; + my $regex = quotemeta $val; + $regex =~ s/\\\%bugid\\\%/\\d+/g; + return qr/^$regex$/s; } sub register { - my ( $self, $app, $conf ) = @_; + my ($self, $app, $conf) = @_; - $app->hook( before_routes => \&_before_routes ); + $app->hook(before_routes => \&_before_routes); } sub _before_routes { - my ($c) = @_; - state $urlbase = Bugzilla->localconfig->{urlbase}; - state $urlbase_uri = URI->new($urlbase); - state $urlbase_host = $urlbase_uri->host; - state $urlbase_host_regex = qr/^bug(\d+)\.\Q$urlbase_host\E$/; - state $attachment_base = Bugzilla->localconfig->{attachment_base}; - state $attachment_root = _attachment_root($attachment_base); - state $attachment_host_regex = _attachment_host_regex($attachment_base); + my ($c) = @_; + state $urlbase = Bugzilla->localconfig->{urlbase}; + state $urlbase_uri = URI->new($urlbase); + state $urlbase_host = $urlbase_uri->host; + state $urlbase_host_regex = qr/^bug(\d+)\.\Q$urlbase_host\E$/; + state $attachment_base = Bugzilla->localconfig->{attachment_base}; + state $attachment_root = _attachment_root($attachment_base); + state $attachment_host_regex = _attachment_host_regex($attachment_base); - my $stash = $c->stash; - my $req = $c->req; - my $url = $req->url->to_abs; + my $stash = $c->stash; + my $req = $c->req; + my $url = $req->url->to_abs; - return if $stash->{'mojo.static'}; + return if $stash->{'mojo.static'}; - my $hostname = $url->host; - return if $hostname eq $urlbase_host; + my $hostname = $url->host; + return if $hostname eq $urlbase_host; - my $path = $url->path; - return if $path eq '/__lbheartbeat__'; + my $path = $url->path; + return if $path eq '/__lbheartbeat__'; - if ( $attachment_base && $hostname eq $attachment_root ) { - DEBUG("redirecting to $urlbase because $hostname is $attachment_root"); - $c->redirect_to($urlbase); - return; - } - elsif ( $attachment_base && $hostname =~ $attachment_host_regex ) { - if ( $path =~ m{^/attachment\.cgi}s ) { - return; - } - else { - my $new_uri = $url->clone; - $new_uri->scheme( $urlbase_uri->scheme ); - $new_uri->host($urlbase_host); - DEBUG("redirecting to $new_uri because $hostname matches attachment regex"); - $c->redirect_to($new_uri); - return; - } - } - elsif ( my ($id) = $hostname =~ $urlbase_host_regex ) { - my $new_uri = $urlbase_uri->clone; - $new_uri->path('/show_bug.cgi'); - $new_uri->query_form( id => $id ); - DEBUG("redirecting to $new_uri because $hostname includes bug id"); - $c->redirect_to($new_uri); - return; + if ($attachment_base && $hostname eq $attachment_root) { + DEBUG("redirecting to $urlbase because $hostname is $attachment_root"); + $c->redirect_to($urlbase); + return; + } + elsif ($attachment_base && $hostname =~ $attachment_host_regex) { + if ($path =~ m{^/attachment\.cgi}s) { + return; } else { - DEBUG("redirecting to $urlbase because $hostname doesn't make sense"); - $c->redirect_to($urlbase); - return; + my $new_uri = $url->clone; + $new_uri->scheme($urlbase_uri->scheme); + $new_uri->host($urlbase_host); + DEBUG( + "redirecting to $new_uri because $hostname matches attachment regex"); + $c->redirect_to($new_uri); + return; } + } + elsif (my ($id) = $hostname =~ $urlbase_host_regex) { + my $new_uri = $urlbase_uri->clone; + $new_uri->path('/show_bug.cgi'); + $new_uri->query_form(id => $id); + DEBUG("redirecting to $new_uri because $hostname includes bug id"); + $c->redirect_to($new_uri); + return; + } + else { + DEBUG("redirecting to $urlbase because $hostname doesn't make sense"); + $c->redirect_to($urlbase); + return; + } } 1; |