[Bps-public-commit] RT-Extension-MandatoryOnTransition branch, support-coreroles-and-customroles, repushed
Craig Kaiser
craig at bestpractical.com
Wed Jan 23 16:31:51 EST 2019
The branch support-coreroles-and-customroles was deleted and repushed:
was ffc1664001d998b78a508285c9644a5042d4b416
now 999d738b1eabdd6e112e9415421490864f2e3ab4
1: fa95e1a ! 1: 27e5c92 Support customroles for mandatoryontransition conditions
@@ -4,6 +4,89 @@
Use the syntax 'CustomRole.MyRole' to set mandatory conditions for
customrole values.
+
+diff --git a/html/Callbacks/RT-Extension-MandatoryOnTransition/Ticket/Update.html/AfterWorked b/html/Callbacks/RT-Extension-MandatoryOnTransition/Ticket/Update.html/AfterWorked
+--- a/html/Callbacks/RT-Extension-MandatoryOnTransition/Ticket/Update.html/AfterWorked
++++ b/html/Callbacks/RT-Extension-MandatoryOnTransition/Ticket/Update.html/AfterWorked
+@@
+ $Ticket
+ </%args>
+ <%init>
+-my ($core, $cfs) = RT::Extension::MandatoryOnTransition->RequiredFields(
++my ($core, $cfs, $roles) = RT::Extension::MandatoryOnTransition->RequiredFields(
+ Ticket => $Ticket,
+ To => $ARGS{'Status'} || $ARGS{'DefaultStatus'},
+ );
+-return unless @$cfs;
++return unless @$cfs or @$roles;
+
+ my $comp = '/Elements/EditCustomFields';
+ my %obj_args = ( Object => $Ticket );
+@@
+ %obj_args = ( TicketObj => $Ticket );
+ }
+
++my @roles;
++foreach my $role (@{$roles}) {
++ if ( $role =~ s/^CustomRole\.//i ) {
++ my $role_object = RT::CustomRole->new($session{CurrentUser});
++ my ($ret, $msg) = $role_object->Load($role);
++
++ RT::Logger->error($msg) unless $ret;
++ push @roles, $role_object if $ret;
++ }
++}
+ </%init>
+ %# 'Named' is handled by this extension in the MassageCustomFields callback
+-<& $comp,
+- %ARGS,
+- %obj_args,
+- InTable => 1,
+- Named => $cfs,
+- &>
++% if ( @$cfs ) {
++ <& $comp,
++ %ARGS,
++ %obj_args,
++ InTable => 1,
++ Named => $cfs,
++ &>
++% }
++% if ( @$roles ) {
++% my $count = 0;
++% foreach my $role (@roles) {
++<input type='hidden' name="WatcherTypeEmail<% $count %>" value=<% $role->Name %>></input>
++ <tr>
++ <td class="label"><% $role->Name %>:</td>
++ <td class="entry">
++ <& /Elements/EmailInput,
++ Name => 'RT::CustomRole-' . $role->Id,
++ Autocomplete => 1,
++ AutocompleteNobody => 1,
++ AutocompleteReturn => "Name",
++ Size => 20,
++ &>
++ </td>
++ </tr>
++% $count++;
++% }
++% }
+
+diff --git a/html/Callbacks/RT-Extension-MandatoryOnTransition/Ticket/Update.html/BeforeUpdate b/html/Callbacks/RT-Extension-MandatoryOnTransition/Ticket/Update.html/BeforeUpdate
+--- a/html/Callbacks/RT-Extension-MandatoryOnTransition/Ticket/Update.html/BeforeUpdate
++++ b/html/Callbacks/RT-Extension-MandatoryOnTransition/Ticket/Update.html/BeforeUpdate
+@@
+ $$skip_update = 1;
+ push @$results, @$errors_ref;
+ }
++
++# Allow mandatory roles to be set on update page
++foreach my $key (keys %{$ARGSRef}) {
++ if ( $key =~ /^WatcherAddressEmail(\d*)$/ && not $ARGSRef->{$key} ) {
++ $ARGSRef->{"WatcherTypeEmail$1"} = undef;
++ }
++}
+ </%init>
diff --git a/lib/RT/Extension/MandatoryOnTransition.pm b/lib/RT/Extension/MandatoryOnTransition.pm
--- a/lib/RT/Extension/MandatoryOnTransition.pm
@@ -31,11 +114,20 @@
);
@@
+ my %config = ();
+ %config = $self->Config($args{Queue});
+
+- return ([], []) unless %config;
++ return ([], [], []) unless %config;
+
+ $to ||= '';
+ $from ||= '';
+@@
my @core = grep { !/^CF\./i && $core_supported{$_} } @$required;
my @cfs = map { /^CF\.(.+)$/i; $1; }
grep { /^CF\./i } @$required;
+ my @roles = map { /^(:?[CustomRole\.]?.+)$/i; $1; }
-+ grep { /^CustomRole\./i } @$required;
++ grep { /^CustomRole\.|^AdminCc|^Cc|^Requestor|^Owner/i } @$required;
# Pull out any must_be or must_not_be rules
my %cf_must_values = ();
@@ -45,24 +137,7 @@
}
- return (\@core, \@cfs, \%cf_must_values);
+
-+ my %role_group_values;
-+ foreach my $role (@roles){
-+ if ( $config{$role} ){
-+ my $transition = $config{$role}->{'transition'};
-+ unless ( $transition ){
-+ RT->Logger->error("No transition defined in group rules for $role");
-+ next;
-+ }
-+
-+ if ( $transition eq "$from -> $to"
-+ || $transition eq "* -> $to"
-+ || $transition eq "$from -> *" ) {
-+
-+ $role_group_values{$role} = $config{$role};
-+ }
-+ }
-+ }
-+ return (\@core, \@cfs, \@roles, \%cf_must_values, \%role_group_values);
++ return (\@core, \@cfs, \@roles, \%cf_must_values);
}
=head3 CheckMandatoryFields
@@ -88,7 +163,7 @@
}
- my ($core, $cfs, $must_values) = $self->RequiredFields(
-+ my ($core, $cfs, $roles, $cf_must_values, $role_group_values) = $self->RequiredFields(
++ my ($core, $cfs, $roles, $cf_must_values) = $self->RequiredFields(
Ticket => $args{'Ticket'},
Queue => $args{'Queue'} ? $args{'Queue'}->Name : undef,
From => $args{'From'},
@@ -97,7 +172,7 @@
);
-
- return \@errors unless @$core or @$cfs;
-+ return \@errors unless @$core or @$cfs or $roles;
++ return \@errors unless @$core or @$cfs or @$roles;
my $transition = ($args{'From'} ||'') ne ($args{'To'} || '') ? 'Status' : 'Queue';
@@ -105,18 +180,33 @@
$label, $CurrentUser->loc($transition), $CurrentUser->loc($field_label{$transition}));
}
-+ if ( @$roles ) {
++ if (@$roles) {
+ foreach my $role (@$roles) {
-+ my $role_values;
-+ my $role_arg = $role;
-+ my $role_full = $role;
-+
-+ if ( not $CRs ){
-+ $RT::Logger->error("Custom Roles object required to process mandatory custom roles");
-+ return \@errors;
++ my ( $role_values, $owner_value );
++ my ( $role_arg, $role_full ) = ( $role, $role );
++
++ if ( $role =~ s/^CustomRole\.//i ) {
++ push @errors,
++ $CurrentUser->loc(
++ 'Custom Roles object required to process mandatory custom roles'
++ ) unless $CRs;
++
++ my $role_object =
++ RT::CustomRole->new( $args{Ticket}->CurrentUser );
++
++ my ( $ret, $msg ) = $role_object->Load($role);
++ push @errors,
++ $CurrentUser->loc("Failed to load customrole $role: $msg")
++ unless $ret;
++ next unless $role_object->Id;
++
++ $role_arg = 'RT::CustomRole-' . $role_object->Id;
++
++ ( $ret, $msg ) = $role_values =
++ $args{Ticket}->RoleGroup( $role_object->GroupType );
++ push @errors, $CurrentUser->loc("Could not load current user")
++ unless $ret;
+ }
-+ $role =~ qr/^CustomRole\.(.+)$/i;
-+ $role = $1;
+
+ my $role_object = RT::CustomRole->new($args{Ticket}->CurrentUser);
+
@@ -131,19 +221,36 @@
+ return \@errors unless $ret;
+
+ my @role_values;
-+ my @row_input_id = grep $role_arg eq $ARGSRef->{$_}, keys %{$ARGSRef};
-+ if ( @row_input_id ) {
-+ map {push @role_values, $ARGSRef->{"WatcherAddressEmail$_"} } grep { $_ =~ qr/WatcherTypeEmail(.+)/ } @row_input_id;
++
++ # Use this to keep track of input fields that use a count increment
++ # example: WatcherAddressEmail1 or WatcherAddressEmail2
++ my @row_input_num = grep $role_arg eq $ARGSRef->{$_},
++ keys %{$ARGSRef};
++ map { push @role_values, $ARGSRef->{$_} if $ARGSRef->{$_} }
++ grep /$role_arg/, keys %{$ARGSRef};
++
++ # Grab our arguments for current role
++ if (@row_input_num) {
++ map {
++ push @role_values, $ARGSRef->{"WatcherAddressEmail$_"}
++ if $ARGSRef->{"WatcherAddressEmail$_"}
++ }
++ map { $_ =~ /^WatcherTypeEmail(\d*)$/; $1 } @row_input_num;
+ }
-+
+ my @temp_array = $role_values->MemberEmailAddresses;
+ push @role_values, @temp_array if scalar @temp_array;
+
-+ if ( not scalar @role_values ) {
-+ push @errors, "Requires value for $role to perform action.";
-+ return \@errors;
++ if ( $args{'To'} && ( not scalar @role_values ) ) {
++ push @errors,
++ $CurrentUser->loc(
++ "[_1] is required when changing [_2] to [_3]",
++ $role,
++ $CurrentUser->loc($transition),
++ $CurrentUser->loc( $args{'To'} )
++ );
++ next;
+ }
-+ return \@errors if scalar @errors;
++ }
+ }
+
return \@errors unless @$cfs;
2: 6da4599 < --: ------- Support core roles for mandatoryontransation
3: 3bb91be < --: ------- Allow group key to be set for roles
4: aef2cc5 < --: ------- Move Owner code into the roles code block
5: 872c6d2 < --: ------- Update README
--: ------- > 2: 77e91ad Support all core role fields as mandatory on transition fields
--: ------- > 3: e516c76 Support requiring a role to be a member of a group
6: eec1d04 ! 4: 5c6ef55 Create test file for roles
@@ -1,6 +1,6 @@
Author: Craig Kaiser <craig at bestpractical.com>
- Create test file for role mandatory fields
+ Create test file for roles
diff --git a/xt/require_owner_for_resolve.t b/xt/require_owner_for_resolve.t
deleted file mode 100644
@@ -130,6 +130,30 @@
-undef $m;
-done_testing;
+diff --git a/xt/required_fields.t b/xt/required_fields.t
+--- a/xt/required_fields.t
++++ b/xt/required_fields.t
+@@
+ );
+ is( $core->[0], 'TimeWorked', 'Got TimeWorked for required core');
+
+- my $must_values;
+- ($core, $cf, $must_values) = RT::Extension::MandatoryOnTransition->RequiredFields(
++ my ($must_values, $role, $role_group_values);
++ ($core, $cf, $role, $must_values, $role_group_values) = RT::Extension::MandatoryOnTransition->RequiredFields(
+ From => "''",
+ To => 'resolved',
+ Queue => 'General',
+@@
+
+ ok( $t->id, 'Created test ticket: ' . $t->id);
+
+- my ($core, $cf, $must_values) = RT::Extension::MandatoryOnTransition->RequiredFields(
++ my ($core, $cf, $roles, $must_values, $role_group_values) = RT::Extension::MandatoryOnTransition->RequiredFields(
+ Ticket => $t,
+ To => 'resolved',
+ );
+
diff --git a/xt/roles.t b/xt/roles.t
new file mode 100644
--- /dev/null
@@ -141,10 +165,10 @@
+use RT::Extension::MandatoryOnTransition::Test tests => undef, config => <<CONFIG
+Set( %MandatoryOnTransition,
+ '*' => {
-+ '* -> resolved' => ['Owner',],
++ '* -> resolved' => ['Owner'],
+ '* -> stalled' => ['AdminCc'],
+ '* -> deleted' => ['CustomRole.vip'],
-+ 'AdminCc' => { transition => '* -> stalled', group => 'Admins' },
++ 'AdminCc' => { transition => '* -> stalled', group => ['Admins'] },
+ 'CustomRole.vip' => { transition => '* -> deleted' },
+ }
+ );
@@ -280,7 +304,7 @@
+ },
+ "Submit stalled with no $role member"
+ );
-+ $m->text_contains("$role is required when changing Status to stalled");
++ $m->text_contains("A member of group Admins is required for role: $role");
+
+ my $role_group = $t->$role;
+ ok $role_group->Id;
@@ -301,7 +325,7 @@
+ },
+ "Try to stall ticket with no Admins group created"
+ );
-+ $m->text_contains('Failed to load group: \'Admins\' Couldn\'t find row');
++ $m->text_contains("A member of group Admins is required for role: $role");
+
+ my $group = RT::Group->new(RT->SystemUser);
+ ($ret, $msg) = $group->CreateUserDefinedGroup(Name => 'Admins');
@@ -316,7 +340,7 @@
+ },
+ "Try to stall ticket with no $role but not a member of required group"
+ );
-+ $m->text_contains("User who is a member of Admins is required for role: $role");
++ $m->text_contains("A member of group Admins is required for role: $role");
+
+ ($ret, $msg) = $group->AddMember($root->PrincipalId);
+ ok $ret, $msg;
7: 1d64e75 < --: ------- Update tests to pass after adding in support for roles
8: a63da46 ! 5: 999d738 Update README and Changelog
@@ -1,6 +1,19 @@
Author: Craig Kaiser <craig at bestpractical.com>
- Update README
+ Update README and Changelog
+
+diff --git a/Changes b/Changes
+--- a/Changes
++++ b/Changes
+@@
++0.17 2019-01-23
++ - Add support for custom roles as a mandatory field
++ - Add support for all RT core roles as a mandatory field
++ - Add support for requiring group membership for roles
++
+ 0.17 2018-10-26
+ - Add support for Owner as a mandatory field
+
diff --git a/README b/README
--- a/README
@@ -17,19 +30,19 @@
you'd like to see additional fields added, please email your request to
the bug address at the bottom of this documentation.
@@
+
+ Set( %MandatoryOnTransition,
+ 'QueueName' => {
+- 'from -> to' => [ 'BasicField', 'CF.MyField', ],
++ 'from -> to' => [ 'BasicField', 'CF.MyField', 'CustomRole.MyRole' ],
+ },
+ );
+
+@@
+ The transition syntax is similar to that found in RT's Lifecycles. See
perldoc /opt/rt4/etc/RT_Config.pm.
- Requiring role values
-- You can require any core or custom role on a RT::Ticket object, further
-- more you can require a 'group' category to check that at least one value
-- for that role is a member of the required group. In the below example we
-- require that the custom role 'customer' have a user value who is a
-- member of the group 'Customers' and the owner of the ticket must be a
-- member of the group 'Helpdesk'.
--
-- Set( %MandatoryOnTransition, 'General' => { 'CustomRole.customer' => {
-- transition => 'open -> *', group => 'Customers' }, 'Owner' => {
-- transition => 'open -> *', group => 'Helpdesk' }, }, );
++ Requiring role values
+ You can require any core or custom role on a RT::Ticket object, below is
+ an example of requiring a customrole "customer" be set on transition
+ from open and the owner also be set for the ticket on transition from a
@@ -48,9 +61,10 @@
+ Set( %MandatoryOnTransition, 'General' => { 'open -> *' => ['Owner'],
+ 'Owner' => { transition => 'open -> *', group => ['SupportReps',
+ 'Admins'] } } );
-
++
Restrictions on Queue Transitions
The default behavior for MandatoryOnTransition operates on status
+ transitions, so a change from new to open or from open to resolved. It
diff --git a/lib/RT/Extension/MandatoryOnTransition.pm b/lib/RT/Extension/MandatoryOnTransition.pm
--- a/lib/RT/Extension/MandatoryOnTransition.pm
@@ -69,27 +83,34 @@
A larger set of basic fields may be supported in future releases. If you'd
@@
- =head2 Requiring role values
+ Set( %MandatoryOnTransition,
+ Helpdesk => {
+- '* -> resolved' => ['TimeWorked', 'CF.Resolution', 'CustomRole.Analyst'],
++ '* -> resolved' => ['TimeWorked', 'CF.Resolution'],
+ },
+ '*' => {
+ '* -> resolved' => ['CF.Category'],
+- 'CustomRole.Analyst' => {transition => '* -> open', group => 'Engineering'},
+ },
+ );
--You can require any core or custom role on a RT::Ticket object, further more
--you can require a 'group' category to check that at least one value for that
--role is a member of the required group. In the below example we require that
--the custom role 'customer' have a user value who is a member of the group 'Customers'
--and the owner of the ticket must be a member of the group 'Helpdesk'.
+ The transition syntax is similar to that found in RT's Lifecycles. See
+ C<perldoc /opt/rt4/etc/RT_Config.pm>.
+
++=head2 Requiring role values
++
+You can require any core or custom role on a RT::Ticket object, below is an
+example of requiring a customrole "customer" be set on transition from open
+and the owner also be set for the ticket on transition from a status of open.
-
- Set( %MandatoryOnTransition,
- 'General' => {
-- 'CustomRole.customer' => { transition => 'open -> *', group => 'Customers' },
-- 'Owner' => { transition => 'open -> *', group => 'Helpdesk' },
++
++Set( %MandatoryOnTransition,
++ 'General' => {
+ '*' => ['CustomRole.customer', 'Owner']
+ 'CustomRole.customer' => { transition => 'open -> *' },
+ 'Owner' => { transition => 'open -> *' },
- },
- );
-
++ },
++);
++
+=head2 Role Membership in a Group
+
+Roles can require the members of the role to also be a member of a group
@@ -107,4 +128,3 @@
=head2 Restrictions on Queue Transitions
The default behavior for C<MandatoryOnTransition> operates on status transitions,
-
9: e8b66d7 < --: ------- Update group message
10: 8d23680 < --: ------- Make minor change to get owner working
11: 30ce0c9 < --: ------- Support roles arg as a array
12: ffc1664 < --: ------- tmp
More information about the Bps-public-commit
mailing list