[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