Skip to content

Commit 4cdd5e5

Browse files
committed
Bug 1244602 - rewrite the bmo --> reviewboard connector to create a bug instead of updating reviewboard
1 parent 9c75c64 commit 4cdd5e5

File tree

4 files changed

+102
-256
lines changed

4 files changed

+102
-256
lines changed

extensions/Push/lib/Connector/ReviewBoard.pm

Lines changed: 102 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -12,67 +12,88 @@ use warnings;
1212

1313
use base 'Bugzilla::Extension::Push::Connector::Base';
1414

15+
use Bugzilla::Bug;
16+
use Bugzilla::BugMail;
17+
use Bugzilla::Component;
1518
use Bugzilla::Constants;
1619
use Bugzilla::Extension::Push::Constants;
1720
use Bugzilla::Extension::Push::Util;
18-
use Bugzilla::Bug;
19-
use Bugzilla::Attachment;
20-
use Bugzilla::Extension::Push::Connector::ReviewBoard::Client;
21-
22-
use JSON 'decode_json';
23-
use DateTime;
24-
use Scalar::Util 'blessed';
21+
use Bugzilla::Group;
22+
use Bugzilla::Product;
23+
use Bugzilla::User;
24+
use Bugzilla::Util qw( trim );
2525

2626
use constant RB_CONTENT_TYPE => 'text/x-review-board-request';
27-
28-
sub client {
29-
my $self = shift;
30-
31-
$self->{client} //= Bugzilla::Extension::Push::Connector::ReviewBoard::Client->new(
32-
base_uri => $self->config->{base_uri},
33-
username => $self->config->{username},
34-
password => $self->config->{password},
35-
$self->config->{proxy} ? (proxy => $self->config->{proxy}) : (),
36-
);
37-
38-
return $self->{client};
39-
}
27+
use constant AUTOMATION_USER => 'automation@bmo.tld';
4028

4129
sub options {
4230
return (
4331
{
44-
name => 'base_uri',
45-
label => 'Base URI for ReviewBoard',
32+
name => 'product',
33+
label => 'Product to create bugs in',
4634
type => 'string',
47-
default => 'https://reviewboard.allizom.org',
35+
default => 'Developer Services',
4836
required => 1,
37+
validate => sub {
38+
Bugzilla::Product->new({ name => $_[0] })
39+
|| die "Invalid Product ($_[0])\n";
40+
},
4941
},
5042
{
51-
name => 'username',
52-
label => 'Username',
43+
name => 'component',
44+
label => 'Component to create bugs in',
5345
type => 'string',
54-
default => 'guest',
46+
default => 'MozReview',
5547
required => 1,
48+
validate => sub {
49+
my ($component, $config) = @_;
50+
my $product = Bugzilla::Product->new({ name => $config->{product} })
51+
|| die "Invalid Product (" . $config->{product} . ")\n";
52+
Bugzilla::Component->new({ product => $product, name => $component })
53+
|| die "Invalid Component ($component)\n";
54+
},
5655
},
5756
{
58-
name => 'password',
59-
label => 'Password',
60-
type => 'password',
61-
default => 'guest',
57+
name => 'version',
58+
label => "The bug's version",
59+
type => 'string',
60+
default => 'Production',
6261
required => 1,
62+
validate => sub {
63+
my ($version, $config) = @_;
64+
my $product = Bugzilla::Product->new({ name => $config->{product} })
65+
|| die "Invalid Product (" . $config->{product} . ")\n";
66+
Bugzilla::Version->new({ product => $product, name => $version })
67+
|| die "Invalid Version ($version)\n";
68+
},
6369
},
6470
{
65-
name => 'proxy',
66-
label => 'Proxy',
67-
type => 'string',
71+
name => 'group',
72+
label => 'Security group',
73+
type => 'string',
74+
default => 'mozilla-employee-confidential',
75+
required => 1,
76+
validate => sub {
77+
Bugzilla::Group->new({ name => $_[0] })
78+
|| die "Invalid Group ($_[0])\n";
79+
},
80+
},
81+
{
82+
name => 'cc',
83+
label => 'Comma separated list of users to CC',
84+
type => 'string',
85+
default => '',
86+
required => 1,
87+
validate => sub {
88+
foreach my $login (map { trim($_) } split(',', $_[0])) {
89+
Bugzilla::User->new({ name => $login })
90+
|| die "Invalid User ($login)\n";
91+
}
92+
},
6893
},
6994
);
7095
}
7196

72-
sub stop {
73-
my ($self) = @_;
74-
}
75-
7697
sub should_send {
7798
my ($self, $message) = @_;
7899

@@ -102,86 +123,55 @@ sub send {
102123
my $payload = $message->payload_decoded();
103124
my $target = $payload->{event}->{target};
104125

105-
if (my $method = $self->can("_process_$target")) {
106-
$self->$method($payload->{$target});
126+
# load attachments
127+
my $bug_id = $target eq 'bug' ? $payload->{bug}->{id} : $payload->{attachment}->{bug}->{id};
128+
my $attach_id = $target eq 'attachment' ? $payload->{attachment}->{id} : undef;
129+
Bugzilla->set_user(Bugzilla::User->super_user);
130+
my $bug = Bugzilla::Bug->new({ id => $bug_id, cache => 1 });
131+
Bugzilla->logout;
132+
133+
# create a bug if there are any mozreview attachments
134+
my @reviews = grep { $_->contenttype eq RB_CONTENT_TYPE } @{ $bug->attachments };
135+
if (@reviews) {
136+
137+
# build comment
138+
my $comment = $target eq 'bug'
139+
? "Bug $bug_id has MozReview reviews and is no longer public."
140+
: "MozReview attachment $attach_id on Bug $bug_id is no longer public.";
141+
$comment .= "\n\n";
142+
foreach my $attachment (@reviews) {
143+
$comment .= $attachment->data . "\n";
144+
}
145+
146+
# create bug
147+
my $user = Bugzilla::User->new({ name => AUTOMATION_USER, cache => 1 });
148+
die "Invalid User: " . AUTOMATION_USER . "\n" unless $user;
149+
Bugzilla->set_user($user);
150+
my $new_bug = Bugzilla::Bug->create({
151+
short_desc => "[SECURITY] Bug $bug_id is no longer public",
152+
product => $config->{product},
153+
component => $config->{component},
154+
bug_severity => 'normal',
155+
groups => [ map { trim($_) } split(',', $config->{group}) ],
156+
op_sys => 'Unspecified',
157+
rep_platform => 'Unspecified',
158+
version => $config->{version},
159+
cc => [ map { trim($_) } split(',', $config->{cc}) ],
160+
comment => $comment,
161+
});
162+
Bugzilla::BugMail::Send($new_bug->id, { changer => Bugzilla->user });
163+
Bugzilla->logout;
164+
165+
$logger->info("Created bug " . $new_bug->id);
107166
}
108167
};
109-
if ($@) {
110-
return (PUSH_RESULT_TRANSIENT, clean_error($@));
168+
my $error = $@;
169+
Bugzilla->logout;
170+
if ($error) {
171+
return (PUSH_RESULT_TRANSIENT, clean_error($error));
111172
}
112173

113174
return PUSH_RESULT_OK;
114175
}
115176

116-
sub _process_attachment {
117-
my ($self, $payload_target) = @_;
118-
my $logger = Bugzilla->push_ext->logger;
119-
my $attachment = blessed($payload_target)
120-
? $payload_target
121-
: Bugzilla::Attachment->new({ id => $payload_target->{id}, cache => 1 });
122-
123-
if ($attachment) {
124-
my $content = $attachment->data;
125-
my $base_uri = quotemeta($self->config->{base_uri});
126-
if (my ($id) = $content =~ m|$base_uri/r/([0-9]+)|) {
127-
my $resp = $self->client->review_request->delete($id);
128-
my $content = $resp->decoded_content;
129-
my $status = $resp->code;
130-
my $result = $content && decode_json($content) ;
131-
132-
if ($status == 204) {
133-
# Success, review request deleted!
134-
$logger->debug("Deleted review request $id");
135-
}
136-
elsif ($status == 404) {
137-
# API error 100 - Does Not Exist
138-
$logger->debug("Does Not Exist: Review Request $id does not exist");
139-
}
140-
elsif ($status == 403) {
141-
# API error 101 - Permission Denied
142-
$logger->error("Permission Denied: ReviewBoard Push Connector may be misconfigured");
143-
die $result->{err}{msg};
144-
}
145-
elsif ($status == 401) {
146-
# API error 103 - Not logged in
147-
$logger->error("Not logged in: ReviewBoard Push Connector may be misconfigured");
148-
die $result->{err}{msg};
149-
}
150-
else {
151-
if ($result) {
152-
my $code = $result->{err}{code};
153-
my $msg = $result->{err}{msg};
154-
$logger->error("Unexpected API Error: ($code) $msg");
155-
die $msg;
156-
}
157-
else {
158-
$logger->error("Unexpected HTTP Response $status");
159-
die "HTTP Status: $status";
160-
}
161-
}
162-
}
163-
else {
164-
$logger->error("Cannot find link: ReviewBoard Push Connector may be misconfigured");
165-
die "Unable to find link in $content";
166-
}
167-
}
168-
else {
169-
$logger->error("Cannot find attachment with id = $payload_target->{id}");
170-
}
171-
}
172-
173-
sub _process_bug {
174-
my ($self, $payload_target) = @_;
175-
176-
Bugzilla->set_user(Bugzilla::User->super_user);
177-
my $bug = Bugzilla::Bug->new({ id => $payload_target->{id}, cache => 1 });
178-
my @attachments = @{ $bug->attachments };
179-
Bugzilla->logout;
180-
181-
foreach my $attachment (@attachments) {
182-
next if $attachment->contenttype ne RB_CONTENT_TYPE;
183-
$self->_process_attachment($attachment);
184-
}
185-
}
186-
187177
1;

extensions/Push/lib/Connector/ReviewBoard/Client.pm

Lines changed: 0 additions & 78 deletions
This file was deleted.

extensions/Push/lib/Connector/ReviewBoard/Resource.pm

Lines changed: 0 additions & 38 deletions
This file was deleted.

0 commit comments

Comments
 (0)