]> git.ipfire.org Git - thirdparty/bugzilla.git/commitdiff
Bug 1244602 - rewrite the bmo --> reviewboard connector to create a bug instead of...
authorByron Jones <glob@mozilla.com>
Thu, 11 Feb 2016 03:48:08 +0000 (11:48 +0800)
committerByron Jones <glob@mozilla.com>
Thu, 11 Feb 2016 03:48:08 +0000 (11:48 +0800)
extensions/Push/lib/Connector/ReviewBoard.pm
extensions/Push/lib/Connector/ReviewBoard/Client.pm [deleted file]
extensions/Push/lib/Connector/ReviewBoard/Resource.pm [deleted file]
extensions/Push/lib/Connector/ReviewBoard/ReviewRequest.pm [deleted file]

index b5d1a9214f57231baa302754876c5c6c8f69de93..97f489826d59a8d4da7d6aa8395e41d48a45b089 100644 (file)
@@ -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 (file)
index 4848d82..0000000
+++ /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 (file)
index 3f8d434..0000000
+++ /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 (file)
index 32bebfb..0000000
+++ /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;