From d4dd9d2e3e15497cbcb565a05b0c3a0a4a8ab542 Mon Sep 17 00:00:00 2001 From: dklawren Date: Fri, 20 Apr 2018 16:01:16 -0400 Subject: Bug 1453124 - extensions/PhabBugz/bin/update_project_members.pl should be combined with the normal feed daemon --- extensions/PhabBugz/bin/update_project_members.pl | 99 ------------------- extensions/PhabBugz/lib/Constants.pm | 6 +- extensions/PhabBugz/lib/Feed.pm | 114 +++++++++++++++++++++- extensions/PhabBugz/lib/Project.pm | 2 +- 4 files changed, 115 insertions(+), 106 deletions(-) delete mode 100755 extensions/PhabBugz/bin/update_project_members.pl (limited to 'extensions/PhabBugz') diff --git a/extensions/PhabBugz/bin/update_project_members.pl b/extensions/PhabBugz/bin/update_project_members.pl deleted file mode 100755 index fe62170a6..000000000 --- a/extensions/PhabBugz/bin/update_project_members.pl +++ /dev/null @@ -1,99 +0,0 @@ -#!/usr/bin/perl - -# 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. - -use 5.10.1; -use strict; -use warnings; - -use lib qw(. lib local/lib/perl5); - -use Bugzilla; -BEGIN { Bugzilla->extensions() } - -use Bugzilla::Constants; -use Bugzilla::Error; -use Bugzilla::Group; - -use Bugzilla::Extension::PhabBugz::Project; -use Bugzilla::Extension::PhabBugz::Util qw( - get_phab_bmo_ids -); - -Bugzilla->usage_mode(USAGE_MODE_CMDLINE); - -my ($phab_uri, $phab_sync_groups); - -if (!Bugzilla->params->{phabricator_enabled}) { - exit; -} - -# Sanity checks -unless ($phab_uri = Bugzilla->params->{phabricator_base_uri}) { - ThrowUserError('invalid_phabricator_uri'); -} - -unless ($phab_sync_groups = Bugzilla->params->{phabricator_sync_groups}) { - ThrowUserError('invalid_phabricator_sync_groups'); -} - -# Loop through each group and perform the following: -# -# 1. Load flattened list of group members -# 2. Check to see if Phab project exists for 'bmo-' -# 3. Create if does not exist with locked down policy. -# 4. Set project members to exact list -# 5. Profit - -my $sync_groups = Bugzilla::Group->match({ name => [ split('[,\s]+', $phab_sync_groups) ] }); - -foreach my $group (@$sync_groups) { - # Create group project if one does not yet exist - my $phab_project_name = 'bmo-' . $group->name; - my $project = Bugzilla::Extension::PhabBugz::Project->new_from_query({ - name => $phab_project_name - }); - if (!$project) { - my $secure_revision = Bugzilla::Extension::PhabBugz::Project->new_from_query({ - name => 'secure-revision' - }); - $project = Bugzilla::Extension::PhabBugz::Project->create({ - name => $phab_project_name, - description => 'BMO Security Group for ' . $group->name, - view_policy => $secure_revision->phid, - edit_policy => $secure_revision->phid, - join_policy => $secure_revision->phid - }); - } - - if (my @group_members = get_group_members($group)) { - $project->set_members(\@group_members); - $project->update(); - } -} - -sub get_group_members { - my ($group) = @_; - my $group_obj = ref $group ? $group : Bugzilla::Group->check({ name => $group }); - my $members_all = $group_obj->members_complete(); - my %users; - foreach my $name (keys %$members_all) { - foreach my $user (@{ $members_all->{$name} }) { - $users{$user->id} = $user; - } - } - - # Look up the phab ids for these users - my $phab_users = get_phab_bmo_ids({ ids => [ keys %users ] }); - foreach my $phab_user (@{ $phab_users }) { - $users{$phab_user->{id}}->{phab_phid} = $phab_user->{phid}; - } - - # We only need users who have accounts in phabricator - return grep { $_->phab_phid } values %users; -} \ No newline at end of file diff --git a/extensions/PhabBugz/lib/Constants.pm b/extensions/PhabBugz/lib/Constants.pm index 2fd8613a0..1692f8fb9 100644 --- a/extensions/PhabBugz/lib/Constants.pm +++ b/extensions/PhabBugz/lib/Constants.pm @@ -18,12 +18,14 @@ our @EXPORT = qw( PHAB_CONTENT_TYPE PHAB_FEED_POLL_SECONDS PHAB_USER_POLL_SECONDS + PHAB_GROUP_POLL_SECONDS ); use constant PHAB_ATTACHMENT_PATTERN => qr/^phabricator-D(\d+)/; use constant PHAB_AUTOMATION_USER => 'phab-bot@bmo.tld'; use constant PHAB_CONTENT_TYPE => 'text/x-phabricator-request'; -use constant PHAB_FEED_POLL_SECONDS => 5; -use constant PHAB_USER_POLL_SECONDS => 60; +use constant PHAB_FEED_POLL_SECONDS => $ENV{PHAB_FEED_POLL} // 5; +use constant PHAB_USER_POLL_SECONDS => $ENV{PHAB_USER_POLL} // 60; +use constant PHAB_GROUP_POLL_SECONDS => $ENV{PHAB_GROUP_POLL} // 300; 1; diff --git a/extensions/PhabBugz/lib/Feed.pm b/extensions/PhabBugz/lib/Feed.pm index 1907b86d7..275d71976 100644 --- a/extensions/PhabBugz/lib/Feed.pm +++ b/extensions/PhabBugz/lib/Feed.pm @@ -48,7 +48,7 @@ sub start { first_interval => 0, interval => PHAB_FEED_POLL_SECONDS, reschedule => 'drift', - on_tick => sub { + on_tick => sub { try{ $self->feed_query(); } @@ -64,7 +64,7 @@ sub start { first_interval => 0, interval => PHAB_USER_POLL_SECONDS, reschedule => 'drift', - on_tick => sub { + on_tick => sub { try{ $self->user_query(); } @@ -75,11 +75,29 @@ sub start { }, ); + # Update project membership in Phabricator based on Bugzilla groups + my $group_timer = IO::Async::Timer::Periodic->new( + first_interval => 0, + interval => PHAB_GROUP_POLL_SECONDS, + reschedule => 'drift', + on_tick => sub { + try{ + $self->group_query(); + } + catch { + FATAL($_); + }; + Bugzilla->_cleanup(); + }, + ); + my $loop = IO::Async::Loop->new; $loop->add($feed_timer); $loop->add($user_timer); + $loop->add($group_timer); $feed_timer->start; $user_timer->start; + $group_timer->start; $loop->run; } @@ -90,7 +108,7 @@ sub feed_query { # Ensure Phabricator syncing is enabled if (!Bugzilla->params->{phabricator_enabled}) { - INFO("PHABRICATOR SYNC DISABLED"); + WARN("PHABRICATOR SYNC DISABLED"); return; } @@ -150,7 +168,7 @@ sub user_query { # Ensure Phabricator syncing is enabled if (!Bugzilla->params->{phabricator_enabled}) { - INFO("PHABRICATOR SYNC DISABLED"); + WARN("PHABRICATOR SYNC DISABLED"); return; } @@ -183,6 +201,72 @@ sub user_query { } } +sub group_query { + my ($self) = @_; + + # Ensure Phabricator syncing is enabled + if ( !Bugzilla->params->{phabricator_enabled} ) { + WARN("PHABRICATOR SYNC DISABLED"); + return; + } + + my $phab_sync_groups = Bugzilla->params->{phabricator_sync_groups}; + if ( !$phab_sync_groups ) { + WARN('A comma delimited list of security groups was not provided.'); + return; + } + + # PROCESS SECURITY GROUPS + + INFO("GROUPS: Updating group memberships"); + + # Loop through each group and perform the following: + # + # 1. Load flattened list of group members + # 2. Check to see if Phab project exists for 'bmo-' + # 3. Create if does not exist with locked down policy. + # 4. Set project members to exact list + # 5. Profit + + my $sync_groups = Bugzilla::Group->match( + { name => [ split( '[,\s]+', $phab_sync_groups ) ] } ); + + foreach my $group (@$sync_groups) { + + # Create group project if one does not yet exist + my $phab_project_name = 'bmo-' . $group->name; + my $project = Bugzilla::Extension::PhabBugz::Project->new_from_query( + { + name => $phab_project_name + } + ); + if ( !$project ) { + INFO("Project $project not found. Creating."); + my $secure_revision = + Bugzilla::Extension::PhabBugz::Project->new_from_query( + { + name => 'secure-revision' + } + ); + $project = Bugzilla::Extension::PhabBugz::Project->create( + { + name => $phab_project_name, + description => 'BMO Security Group for ' . $group->name, + view_policy => $secure_revision->phid, + edit_policy => $secure_revision->phid, + join_policy => $secure_revision->phid + } + ); + } + + if ( my @group_members = get_group_members($group) ) { + INFO("Setting group members for " . $project->name); + $project->set_members( \@group_members ); + $project->update(); + } + } +} + sub process_revision_change { my ($self, $revision_phid, $story_text) = @_; @@ -567,4 +651,26 @@ sub save_last_id { undef, $type_full, $last_id ); } +sub get_group_members { + my ($group) = @_; + my $group_obj = + ref $group ? $group : Bugzilla::Group->check( { name => $group, cache => 1 } ); + my $members_all = $group_obj->members_complete(); + my %users; + foreach my $name ( keys %$members_all ) { + foreach my $user ( @{ $members_all->{$name} } ) { + $users{ $user->id } = $user; + } + } + + # Look up the phab ids for these users + my $phab_users = get_phab_bmo_ids( { ids => [ keys %users ] } ); + foreach my $phab_user ( @{$phab_users} ) { + $users{ $phab_user->{id} }->{phab_phid} = $phab_user->{phid}; + } + + # We only need users who have accounts in phabricator + return grep { $_->phab_phid } values %users; +} + 1; diff --git a/extensions/PhabBugz/lib/Project.pm b/extensions/PhabBugz/lib/Project.pm index 0fb9ecaa5..cbf1bdcaf 100644 --- a/extensions/PhabBugz/lib/Project.pm +++ b/extensions/PhabBugz/lib/Project.pm @@ -168,7 +168,7 @@ sub create { my $result = request( 'project.edit', $data ); return $class->new_from_query( - { phids => $result->{result}{object}{phid} } ); + { phids => [ $result->{result}{object}{phid} ] } ); } sub update { -- cgit v1.2.3-24-g4f1b