summaryrefslogtreecommitdiffstats
path: root/extensions/Push/lib
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 /extensions/Push/lib
parente74d21eaeb3bc4ba3a5521882815b6a6c6d45bcc (diff)
downloadbugzilla-ce080c6dcec309fa3bcfb922c834266166e57af4.tar.gz
bugzilla-ce080c6dcec309fa3bcfb922c834266166e57af4.tar.xz
Bug 1383108 - Sync security groups with Phabricator push connector
r=dkl
Diffstat (limited to 'extensions/Push/lib')
-rw-r--r--extensions/Push/lib/Connector/Phabricator.pm126
1 files changed, 94 insertions, 32 deletions
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 {