summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorByron Jones <glob@mozilla.com>2016-02-11 04:48:08 +0100
committerByron Jones <glob@mozilla.com>2016-02-11 04:48:08 +0100
commit4cdd5e501cf7e50c47cb4e25dd1cdf0aebfc3540 (patch)
tree390e1e140c849ffff3562452287a2a9f31ade6e0
parent9c75c64203c1c1c69b1c7ae2ec7092b44a05122c (diff)
downloadbugzilla-4cdd5e501cf7e50c47cb4e25dd1cdf0aebfc3540.tar.gz
bugzilla-4cdd5e501cf7e50c47cb4e25dd1cdf0aebfc3540.tar.xz
Bug 1244602 - rewrite the bmo --> reviewboard connector to create a bug instead of updating reviewboard
-rw-r--r--extensions/Push/lib/Connector/ReviewBoard.pm214
-rw-r--r--extensions/Push/lib/Connector/ReviewBoard/Client.pm78
-rw-r--r--extensions/Push/lib/Connector/ReviewBoard/Resource.pm38
-rw-r--r--extensions/Push/lib/Connector/ReviewBoard/ReviewRequest.pm28
4 files changed, 102 insertions, 256 deletions
diff --git a/extensions/Push/lib/Connector/ReviewBoard.pm b/extensions/Push/lib/Connector/ReviewBoard.pm
index b5d1a9214..97f489826 100644
--- a/extensions/Push/lib/Connector/ReviewBoard.pm
+++ b/extensions/Push/lib/Connector/ReviewBoard.pm
@@ -12,67 +12,88 @@ use warnings;
use base 'Bugzilla::Extension::Push::Connector::Base';
+use Bugzilla::Bug;
+use Bugzilla::BugMail;
+use Bugzilla::Component;
use Bugzilla::Constants;
use Bugzilla::Extension::Push::Constants;
use Bugzilla::Extension::Push::Util;
-use Bugzilla::Bug;
-use Bugzilla::Attachment;
-use Bugzilla::Extension::Push::Connector::ReviewBoard::Client;
-
-use JSON 'decode_json';
-use DateTime;
-use Scalar::Util 'blessed';
+use Bugzilla::Group;
+use Bugzilla::Product;
+use Bugzilla::User;
+use Bugzilla::Util qw( trim );
use constant RB_CONTENT_TYPE => 'text/x-review-board-request';
-
-sub client {
- my $self = shift;
-
- $self->{client} //= Bugzilla::Extension::Push::Connector::ReviewBoard::Client->new(
- base_uri => $self->config->{base_uri},
- username => $self->config->{username},
- password => $self->config->{password},
- $self->config->{proxy} ? (proxy => $self->config->{proxy}) : (),
- );
-
- return $self->{client};
-}
+use constant AUTOMATION_USER => 'automation@bmo.tld';
sub options {
return (
{
- name => 'base_uri',
- label => 'Base URI for ReviewBoard',
+ name => 'product',
+ label => 'Product to create bugs in',
type => 'string',
- default => 'https://reviewboard.allizom.org',
+ default => 'Developer Services',
required => 1,
+ validate => sub {
+ Bugzilla::Product->new({ name => $_[0] })
+ || die "Invalid Product ($_[0])\n";
+ },
},
{
- name => 'username',
- label => 'Username',
+ name => 'component',
+ label => 'Component to create bugs in',
type => 'string',
- default => 'guest',
+ default => 'MozReview',
required => 1,
+ validate => sub {
+ my ($component, $config) = @_;
+ my $product = Bugzilla::Product->new({ name => $config->{product} })
+ || die "Invalid Product (" . $config->{product} . ")\n";
+ Bugzilla::Component->new({ product => $product, name => $component })
+ || die "Invalid Component ($component)\n";
+ },
},
{
- name => 'password',
- label => 'Password',
- type => 'password',
- default => 'guest',
+ name => 'version',
+ label => "The bug's version",
+ type => 'string',
+ default => 'Production',
required => 1,
+ validate => sub {
+ my ($version, $config) = @_;
+ my $product = Bugzilla::Product->new({ name => $config->{product} })
+ || die "Invalid Product (" . $config->{product} . ")\n";
+ Bugzilla::Version->new({ product => $product, name => $version })
+ || die "Invalid Version ($version)\n";
+ },
},
{
- name => 'proxy',
- label => 'Proxy',
- type => 'string',
+ name => 'group',
+ label => 'Security group',
+ type => 'string',
+ default => 'mozilla-employee-confidential',
+ required => 1,
+ validate => sub {
+ Bugzilla::Group->new({ name => $_[0] })
+ || die "Invalid Group ($_[0])\n";
+ },
+ },
+ {
+ name => 'cc',
+ label => 'Comma separated list of users to CC',
+ type => 'string',
+ default => '',
+ required => 1,
+ validate => sub {
+ foreach my $login (map { trim($_) } split(',', $_[0])) {
+ Bugzilla::User->new({ name => $login })
+ || die "Invalid User ($login)\n";
+ }
+ },
},
);
}
-sub stop {
- my ($self) = @_;
-}
-
sub should_send {
my ($self, $message) = @_;
@@ -102,86 +123,55 @@ sub send {
my $payload = $message->payload_decoded();
my $target = $payload->{event}->{target};
- if (my $method = $self->can("_process_$target")) {
- $self->$method($payload->{$target});
+ # load attachments
+ my $bug_id = $target eq 'bug' ? $payload->{bug}->{id} : $payload->{attachment}->{bug}->{id};
+ my $attach_id = $target eq 'attachment' ? $payload->{attachment}->{id} : undef;
+ Bugzilla->set_user(Bugzilla::User->super_user);
+ my $bug = Bugzilla::Bug->new({ id => $bug_id, cache => 1 });
+ Bugzilla->logout;
+
+ # create a bug if there are any mozreview attachments
+ my @reviews = grep { $_->contenttype eq RB_CONTENT_TYPE } @{ $bug->attachments };
+ if (@reviews) {
+
+ # build comment
+ my $comment = $target eq 'bug'
+ ? "Bug $bug_id has MozReview reviews and is no longer public."
+ : "MozReview attachment $attach_id on Bug $bug_id is no longer public.";
+ $comment .= "\n\n";
+ foreach my $attachment (@reviews) {
+ $comment .= $attachment->data . "\n";
+ }
+
+ # create bug
+ my $user = Bugzilla::User->new({ name => AUTOMATION_USER, cache => 1 });
+ die "Invalid User: " . AUTOMATION_USER . "\n" unless $user;
+ Bugzilla->set_user($user);
+ my $new_bug = Bugzilla::Bug->create({
+ short_desc => "[SECURITY] Bug $bug_id is no longer public",
+ product => $config->{product},
+ component => $config->{component},
+ bug_severity => 'normal',
+ groups => [ map { trim($_) } split(',', $config->{group}) ],
+ op_sys => 'Unspecified',
+ rep_platform => 'Unspecified',
+ version => $config->{version},
+ cc => [ map { trim($_) } split(',', $config->{cc}) ],
+ comment => $comment,
+ });
+ Bugzilla::BugMail::Send($new_bug->id, { changer => Bugzilla->user });
+ Bugzilla->logout;
+
+ $logger->info("Created bug " . $new_bug->id);
}
};
- if ($@) {
- return (PUSH_RESULT_TRANSIENT, clean_error($@));
+ my $error = $@;
+ Bugzilla->logout;
+ if ($error) {
+ return (PUSH_RESULT_TRANSIENT, clean_error($error));
}
return PUSH_RESULT_OK;
}
-sub _process_attachment {
- my ($self, $payload_target) = @_;
- my $logger = Bugzilla->push_ext->logger;
- my $attachment = blessed($payload_target)
- ? $payload_target
- : Bugzilla::Attachment->new({ id => $payload_target->{id}, cache => 1 });
-
- if ($attachment) {
- my $content = $attachment->data;
- my $base_uri = quotemeta($self->config->{base_uri});
- if (my ($id) = $content =~ m|$base_uri/r/([0-9]+)|) {
- my $resp = $self->client->review_request->delete($id);
- my $content = $resp->decoded_content;
- my $status = $resp->code;
- my $result = $content && decode_json($content) ;
-
- if ($status == 204) {
- # Success, review request deleted!
- $logger->debug("Deleted review request $id");
- }
- elsif ($status == 404) {
- # API error 100 - Does Not Exist
- $logger->debug("Does Not Exist: Review Request $id does not exist");
- }
- elsif ($status == 403) {
- # API error 101 - Permission Denied
- $logger->error("Permission Denied: ReviewBoard Push Connector may be misconfigured");
- die $result->{err}{msg};
- }
- elsif ($status == 401) {
- # API error 103 - Not logged in
- $logger->error("Not logged in: ReviewBoard Push Connector may be misconfigured");
- die $result->{err}{msg};
- }
- else {
- if ($result) {
- my $code = $result->{err}{code};
- my $msg = $result->{err}{msg};
- $logger->error("Unexpected API Error: ($code) $msg");
- die $msg;
- }
- else {
- $logger->error("Unexpected HTTP Response $status");
- die "HTTP Status: $status";
- }
- }
- }
- else {
- $logger->error("Cannot find link: ReviewBoard Push Connector may be misconfigured");
- die "Unable to find link in $content";
- }
- }
- else {
- $logger->error("Cannot find attachment with id = $payload_target->{id}");
- }
-}
-
-sub _process_bug {
- my ($self, $payload_target) = @_;
-
- Bugzilla->set_user(Bugzilla::User->super_user);
- my $bug = Bugzilla::Bug->new({ id => $payload_target->{id}, cache => 1 });
- my @attachments = @{ $bug->attachments };
- Bugzilla->logout;
-
- foreach my $attachment (@attachments) {
- next if $attachment->contenttype ne RB_CONTENT_TYPE;
- $self->_process_attachment($attachment);
- }
-}
-
1;
diff --git a/extensions/Push/lib/Connector/ReviewBoard/Client.pm b/extensions/Push/lib/Connector/ReviewBoard/Client.pm
deleted file mode 100644
index 4848d820f..000000000
--- a/extensions/Push/lib/Connector/ReviewBoard/Client.pm
+++ /dev/null
@@ -1,78 +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::ReviewBoard::Client;
-
-use 5.10.1;
-use strict;
-use warnings;
-
-use Carp qw(croak);
-use LWP::UserAgent;
-use Scalar::Util qw(blessed);
-use URI;
-
-use Bugzilla::Extension::Push::Connector::ReviewBoard::ReviewRequest;
-
-BEGIN {
- unless (LWP::UserAgent->can('delete')) {
- *LWP::UserAgent::delete = sub {
- my ($self, @parameters) = @_;
- require HTTP::Request::Common;
- my @suff = $self->_process_colonic_headers(\@parameters, 1);
- return $self->request(HTTP::Request::Common::DELETE(@parameters), @suff);
- };
- }
-};
-
-sub new {
- my ($class, %params) = @_;
-
- croak "->new() is a class method" if blessed($class);
- return bless(\%params, $class);
-}
-
-sub username { $_[0]->{username} }
-sub password { $_[0]->{password} }
-sub base_uri { $_[0]->{base_uri} }
-sub realm { $_[0]->{realm} // 'Web API' }
-sub proxy { $_[0]->{proxy} }
-
-sub _netloc {
- my $self = shift;
-
- my $uri = URI->new($self->base_uri);
- return $uri->host . ':' . $uri->port;
-}
-
-sub useragent {
- my $self = shift;
-
- unless ($self->{useragent}) {
- my $ua = LWP::UserAgent->new(agent => Bugzilla->params->{urlbase});
- $ua->credentials(
- $self->_netloc,
- $self->realm,
- $self->username,
- $self->password,
- );
- $ua->proxy('https', $self->proxy) if $self->proxy;
- $ua->timeout(10);
-
- $self->{useragent} = $ua;
- }
-
- return $self->{useragent};
-}
-
-sub review_request {
- my $self = shift;
-
- return Bugzilla::Extension::Push::Connector::ReviewBoard::ReviewRequest->new(client => $self, @_);
-}
-
-1;
diff --git a/extensions/Push/lib/Connector/ReviewBoard/Resource.pm b/extensions/Push/lib/Connector/ReviewBoard/Resource.pm
deleted file mode 100644
index 3f8d434ce..000000000
--- a/extensions/Push/lib/Connector/ReviewBoard/Resource.pm
+++ /dev/null
@@ -1,38 +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::ReviewBoard::Resource;
-
-use 5.10.1;
-use strict;
-use warnings;
-
-use URI;
-use Carp qw(croak confess);
-use Scalar::Util qw(blessed);
-
-sub new {
- my ($class, %params) = @_;
-
- croak "->new() is a class method" if blessed($class);
- return bless(\%params, $class);
-}
-
-sub client { $_[0]->{client} }
-
-sub path { confess 'Unimplemented'; }
-
-sub uri {
- my ($self, @path) = @_;
-
- my $uri = URI->new($self->client->base_uri);
- $uri->path(join('/', $self->path, @path) . '/');
-
- return $uri;
-}
-
-1;
diff --git a/extensions/Push/lib/Connector/ReviewBoard/ReviewRequest.pm b/extensions/Push/lib/Connector/ReviewBoard/ReviewRequest.pm
deleted file mode 100644
index 32bebfbe8..000000000
--- a/extensions/Push/lib/Connector/ReviewBoard/ReviewRequest.pm
+++ /dev/null
@@ -1,28 +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::ReviewBoard::ReviewRequest;
-
-use 5.10.1;
-use strict;
-use warnings;
-
-use base 'Bugzilla::Extension::Push::Connector::ReviewBoard::Resource';
-
-# Reference: http://www.reviewboard.org/docs/manual/dev/webapi/2.0/resources/review-request/
-
-sub path {
- return '/api/review-requests';
-}
-
-sub delete {
- my ($self, $id) = @_;
-
- return $self->client->useragent->delete($self->uri($id));
-}
-
-1;