summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Walsh <davidwalsh83@gmail.com>2017-07-31 23:44:31 +0200
committerdklawren <dklawren@users.noreply.github.com>2017-07-31 23:44:31 +0200
commitce080c6dcec309fa3bcfb922c834266166e57af4 (patch)
treefa07071d59f23a1cbd6152b3bb919fda18233309
parente74d21eaeb3bc4ba3a5521882815b6a6c6d45bcc (diff)
downloadbugzilla-ce080c6dcec309fa3bcfb922c834266166e57af4.tar.gz
bugzilla-ce080c6dcec309fa3bcfb922c834266166e57af4.tar.xz
Bug 1383108 - Sync security groups with Phabricator push connector
r=dkl
-rw-r--r--extensions/PhabBugz/lib/Util.pm34
-rw-r--r--extensions/PhabBugz/lib/WebService.pm3
-rw-r--r--extensions/Push/lib/Connector/Phabricator.pm126
3 files changed, 130 insertions, 33 deletions
diff --git a/extensions/PhabBugz/lib/Util.pm b/extensions/PhabBugz/lib/Util.pm
index cbbca7eab..75c523ad5 100644
--- a/extensions/PhabBugz/lib/Util.pm
+++ b/extensions/PhabBugz/lib/Util.pm
@@ -20,6 +20,7 @@ use LWP::UserAgent;
use base qw(Exporter);
our @EXPORT = qw(
+ add_comment_to_revision
create_revision_attachment
create_private_revision_policy
create_project
@@ -29,6 +30,7 @@ our @EXPORT = qw(
get_project_phid
get_revisions_by_ids
intersect
+ make_revision_private
make_revision_public
request
set_project_members
@@ -141,6 +143,23 @@ sub make_revision_public {
});
}
+sub make_revision_private {
+ my ($revision_phid) = @_;
+ return request('differential.revision.edit', {
+ transactions => [
+ {
+ type => "view",
+ value => "admin"
+ },
+ {
+ type => "edit",
+ value => "admin"
+ }
+ ],
+ objectIdentifier => $revision_phid
+ });
+}
+
sub edit_revision_policy {
my ($revision_phid, $policy_phid, $subscribers) = @_;
@@ -168,6 +187,21 @@ sub edit_revision_policy {
return request('differential.revision.edit', $data);
}
+sub add_comment_to_revision {
+ my ($revision_phid, $comment) = @_;
+
+ my $data = {
+ transactions => [
+ {
+ type => 'comment',
+ value => $comment
+ }
+ ],
+ objectIdentifier => $revision_phid
+ };
+ return request('differential.revision.edit', $data);
+}
+
sub get_project_phid {
my $project = shift;
diff --git a/extensions/PhabBugz/lib/WebService.pm b/extensions/PhabBugz/lib/WebService.pm
index 217ed18dc..11439ba70 100644
--- a/extensions/PhabBugz/lib/WebService.pm
+++ b/extensions/PhabBugz/lib/WebService.pm
@@ -17,6 +17,7 @@ use Bugzilla::Attachment;
use Bugzilla::Bug;
use Bugzilla::BugMail;
use Bugzilla::Error;
+use Bugzilla::Extension::Push::Util qw(is_public);
use Bugzilla::User;
use Bugzilla::Util qw(correct_urlbase detaint_natural);
use Bugzilla::WebService::Constants;
@@ -61,7 +62,7 @@ sub revision {
# If bug is public then remove privacy policy
my $result;
- if (!@{ $bug->groups_in }) {
+ if (is_public($bug)) {
$result = make_revision_public($revision_id);
}
# Else bug is private
diff --git a/extensions/Push/lib/Connector/Phabricator.pm b/extensions/Push/lib/Connector/Phabricator.pm
index be0ea9b58..092d63dd3 100644
--- a/extensions/Push/lib/Connector/Phabricator.pm
+++ b/extensions/Push/lib/Connector/Phabricator.pm
@@ -15,18 +15,22 @@ use base 'Bugzilla::Extension::Push::Connector::Base';
use Bugzilla::Bug;
use Bugzilla::Constants;
-use Bugzilla::Extension::PhabBugz::Util qw(intersect make_revision_public get_revisions_by_ids);
+use Bugzilla::Error;
+use Bugzilla::Extension::PhabBugz::Util qw(add_comment_to_revision
+ create_private_revision_policy edit_revision_policy get_bug_role_phids
+ get_revisions_by_ids intersect make_revision_public make_revision_private);
use Bugzilla::Extension::Push::Constants;
-use Bugzilla::Extension::Push::Util;
+use Bugzilla::Extension::Push::Util qw(is_public);
use Bugzilla::User;
use List::Util qw(any);
-use constant PHAB_CONTENT_TYPE => 'text/x-phabricator-request';
+use constant PHAB_CONTENT_TYPE => 'text/x-phabricator-request';
use constant PHAB_ATTACHMENT_PATTERN => qr/^phabricator-D(\d+)/;
sub options {
return (
- { name => 'phabricator_url',
+ {
+ name => 'phabricator_url',
label => 'Phabricator URL',
type => 'string',
default => '',
@@ -40,11 +44,11 @@ sub should_send {
return 0 unless Bugzilla->params->{phabricator_enabled};
- return 0 unless $message->routing_key =~ /^(?:attachment|bug)\.modify:.*\bbug_group\b/;
+ return 0
+ unless $message->routing_key =~
+ /^(?:attachment|bug)\.modify:.*\bbug_group\b/;
- my $data = $message->payload_decoded;
- my $bug_data = $self->_get_bug_data($data) || return 0;
- my $bug = Bugzilla::Bug->new( { id => $bug_data->{id}, cache => 1 } );
+ my $bug = $self->_get_bug_by_data( $message->payload_decoded ) || return 0;
return $bug->has_attachment_with_mimetype(PHAB_CONTENT_TYPE);
}
@@ -55,43 +59,101 @@ sub send {
my $logger = Bugzilla->push_ext->logger;
my $data = $message->payload_decoded;
- my $bug_data = $self->_get_bug_data($data) || return 0;
- my $bug = Bugzilla::Bug->new( { id => $bug_data->{id}, cache => 1 } );
+ my $bug = $self->_get_bug_by_data($data) || return PUSH_RESULT_OK;
+
+ my $is_public = is_public($bug);
+
+ my $phab_sync_groups = Bugzilla->params->{phabricator_sync_groups};
+ ThrowUserError('invalid_phabricator_sync_groups') unless $phab_sync_groups;
+
+ my $sync_group_names = [ split( '[,\s]+', $phab_sync_groups ) ];
+
+ my $bug_groups = $bug->groups_in;
+ my $bug_group_names = [ map { $_->name } @$bug_groups ];
+
+ my @set_groups = intersect( $bug_group_names, $sync_group_names );
+
+ if ( !$is_public && !@set_groups ) {
+ my $phab_error_message =
+ 'Revision is being made private due to unknown Bugzilla groups.';
+
+ my @revisions = $self->_get_attachment_revisions($bug);
+ foreach my $revision (@revisions) {
+ add_comment_to_revision( $revision->{phid}, $phab_error_message );
+ make_revision_private( $revision->{phid} );
+ }
+
+ my $num_revisions = 0 + @revisions;
+ my $bmo_error_message =
+ ( $num_revisions > 1
+ ? 'Multiple revisions were'
+ : 'One revision was' )
+ . ' made private due to unknown Bugzilla groups.';
+
+ my $user =
+ Bugzilla->set_user(
+ Bugzilla::User->new( { name => 'conduit@mozilla.bugs' } ) );
+ $bug->add_comment( $bmo_error_message, { isprivate => 0 } );
+ my $bug_changes = $bug->update();
+ $bug->send_changes($bug_changes);
- if(!is_public($bug)) {
- $logger->info('Bailing on send because the bug is not public');
return PUSH_RESULT_OK;
}
+ my $policy_phid;
+ my $subscribers;
+ if ( !$is_public ) {
+ $policy_phid = create_private_revision_policy( $bug, \@set_groups );
+ $subscribers = get_bug_role_phids($bug);
+ }
+
+ my @revisions = $self->_get_attachment_revisions($bug);
+ foreach my $revision (@revisions) {
+ my $revision_phid = $revision->{phid};
+
+ if ($is_public) {
+ make_revision_public($revision_phid);
+ }
+ else {
+ edit_revision_policy( $revision_phid, $policy_phid, $subscribers );
+ }
+ }
+
+ return PUSH_RESULT_OK;
+}
+
+sub _get_attachment_revisions() {
+ my ( $self, $bug ) = @_;
+
+ my @revisions;
+
my @attachments = grep {
- $_->isobsolete == 0 &&
- $_->contenttype eq PHAB_CONTENT_TYPE &&
- $_->attacher->login eq 'phab-bot@bmo.tld'
+ $_->isobsolete == 0
+ && $_->contenttype eq PHAB_CONTENT_TYPE
+ && $_->attacher->login ne 'phab-bot@bmo.tld'
} @{ $bug->attachments() };
- if(@attachments){
- my @rev_ids;
+ if (@attachments) {
+ my @revision_ids;
foreach my $attachment (@attachments) {
- my ($rev_id) = ($attachment->filename =~ PHAB_ATTACHMENT_PATTERN);
- next if !$rev_id;
- push(@rev_ids, int($rev_id));
+ my ($revision_id) =
+ ( $attachment->filename =~ PHAB_ATTACHMENT_PATTERN );
+ next if !$revision_id;
+ push( @revision_ids, int($revision_id) );
}
- if(@rev_ids) {
- $logger->info('Getting info for revisions: ');
- $logger->info(@rev_ids);
-
- my @rev_details = get_revisions_by_ids(\@rev_ids);
- foreach my $rev_detail (@rev_details) {
- my $rev_phid = $rev_detail->{phid};
- $logger->info('Making revision $rev_phid public:');
- $logger->info($rev_phid);
- make_revision_public($rev_phid);
- }
+ if (@revision_ids) {
+ @revisions = get_revisions_by_ids( \@revision_ids );
}
}
- return PUSH_RESULT_OK;
+ return @revisions;
+}
+
+sub _get_bug_by_data {
+ my ( $self, $data ) = @_;
+ my $bug_data = $self->_get_bug_data($data) || return 0;
+ my $bug = Bugzilla::Bug->new( { id => $bug_data->{id} } );
}
sub _get_bug_data {