[Rt-commit] rt branch, 4.4/add-role-by-username, created. rt-4.4.2-226-g222c890d1
? sunnavy
sunnavy at bestpractical.com
Tue Apr 24 13:13:06 EDT 2018
The branch, 4.4/add-role-by-username has been created
at 222c890d1468223da70ed95e2dccf495e1b62ce4 (commit)
- Log -----------------------------------------------------------------
commit 19840dbc0d060188ffbbe8cd43f1f39d8bb9d354
Author: Jim Brandt <jbrandt at bestpractical.com>
Date: Wed Jan 10 16:40:40 2018 -0500
Accept usernames for roles on ticket create
In addition to being able to add an RT user to a role
with an email address, also accept a valid RT username via the
web UI on create.
diff --git a/lib/RT/Record/Role/Roles.pm b/lib/RT/Record/Role/Roles.pm
index 1a88793ae..ef990ef61 100644
--- a/lib/RT/Record/Role/Roles.pm
+++ b/lib/RT/Record/Role/Roles.pm
@@ -621,21 +621,10 @@ sub _ResolveRoles {
$self->loc("Couldn't load principal: [_1]", $msg);
}
} else {
- my @addresses = RT::EmailParser->ParseEmailAddress( $value );
- for my $address ( @addresses ) {
- my $user = RT::User->new( RT->SystemUser );
- my ($id, $msg) = $user->LoadOrCreateByEmail( $address );
- if ( $id ) {
- # Load it back as us, not as the system
- # user, to be completely safe.
- $user = RT::User->new( $self->CurrentUser );
- $user->Load( $id );
- push @{ $roles->{$role} }, $user->PrincipalObj;
- } else {
- push @errors,
- $self->loc("Couldn't load or create user: [_1]", $msg);
- }
- }
+ my ($users, $errors) = $self->ParseInputPrincipals( $value );
+
+ push @{ $roles->{$role} }, map { $_->PrincipalObj } @{$users};
+ push @errors, @$errors if @$errors;
}
}
}
@@ -643,6 +632,79 @@ sub _ResolveRoles {
return (@errors);
}
+=head2 ParseInputPrincipals
+
+In the RT web UI, some watcher input fields can accept RT users
+identified by email address or RT username. On the ticket Create
+and Update pages, these fields can have multiple values submitted
+as a comma-separated list. This method parses such lists and returns
+an array of user objects found or created for each parsed value.
+
+C<ParseEmailAddress> in L<RT::EmailParser> provides a similar
+function, but only handles email addresses, filtering out
+usernames. It also returns a list of L<Email::Address> objects
+rather than RT objects.
+
+Accepts: a string with usernames and email addresses
+
+Returns: arrayref of RT::User objects, arrayref of any error strings
+
+=cut
+
+sub ParseInputPrincipals {
+ my $self = shift;
+ my $input_string = shift;
+
+ # Some broken mailers send: ""Vincent, Jesse"" <jesse at fsck.com>
+ $input_string =~ s/\"\"(.*?)\"\"/\"$1\"/g;
+
+ my @list = Email::Address::List->parse(
+ $input_string,
+ skip_comments => 1,
+ skip_groups => 1,
+ );
+
+ my @principals; # Collect user or group objects
+ my @errors;
+
+ foreach my $e ( @list ) {
+ my $user = RT::User->new( RT->SystemUser );
+
+ if ($e->{'type'} eq 'mailbox') {
+ if ($e->{'not_ascii'}) {
+ RT::Logger->error($e->{'value'} ." contains non-ASCII values");
+ next;
+ }
+
+ my ($id, $msg) = $user->LoadOrCreateByEmail( $e->{'value'} );
+ if ( $id ) {
+ push @principals, $user;
+ }
+ else {
+ push @errors, $self->loc("Couldn't load or create user: [_1]", $msg);
+ RT::Logger->error("Couldn't load or create user from email address " . $e->{'value'} . ", " . $msg);
+ }
+ }
+ elsif ( $e->{'value'} =~ /^\s*(\w+)\s*$/ ) {
+ # Email::Address::List found a value that doesn't look like an email
+ my ($id, $msg) = $user->Load( $1 );
+ if ($id) {
+ push @principals, $user;
+ }
+ else {
+ push @errors, $self->loc("Couldn't load or create user: [_1]", $msg);
+ RT::Logger->error("Couldn't load or create user from username " . $e->{'value'} . ", " . $msg);
+ }
+ }
+ else {
+ push @errors, $self->loc("Couldn't load or create user: [_1]", $e->{'value'});
+ RT::Logger->warn($e->{'value'} . " is not a valid email address or username");
+ }
+ }
+
+ return (\@principals, \@errors);
+}
+
sub _CreateRoleGroup {
my $self = shift;
my $name = shift;
diff --git a/share/html/Ticket/Create.html b/share/html/Ticket/Create.html
index c8b73f4e1..81caf366b 100644
--- a/share/html/Ticket/Create.html
+++ b/share/html/Ticket/Create.html
@@ -488,6 +488,9 @@ if ( !exists $ARGS{'AddMoreAttach'} && ($ARGS{'id'}||'') eq 'new' ) {
my $value = $ARGS{ $field };
next unless defined $value && length $value;
+ # Preserve non-email username inputs
+ my @usernames = grep {!/\@/} split /,/, $value;
+
my @emails = Email::Address->parse( $value );
foreach my $email ( grep RT::EmailParser->IsRTAddress($_->address), @emails ) {
push @results, loc("[_1] is an address RT receives mail at. Adding it as a '[_2]' would create a mail loop", $email->format, loc($field =~ /^(.*?)s?$/) );
@@ -495,6 +498,11 @@ if ( !exists $ARGS{'AddMoreAttach'} && ($ARGS{'id'}||'') eq 'new' ) {
$email = undef;
}
$ARGS{ $field } = join ', ', map $_->format, grep defined, @emails;
+
+ if ( @usernames ){
+ # Restore usernames, if any
+ $ARGS{ $field } .= ', ' . join ', ', grep defined, @usernames;
+ }
}
}
commit 222c890d1468223da70ed95e2dccf495e1b62ce4
Author: sunnavy <sunnavy at bestpractical.com>
Date: Thu Apr 12 03:48:53 2018 +0800
Accept usernames for one time Cc/Bcc on ticket update
diff --git a/lib/RT/Ticket.pm b/lib/RT/Ticket.pm
index e8046c446..09832ade8 100644
--- a/lib/RT/Ticket.pm
+++ b/lib/RT/Ticket.pm
@@ -1685,10 +1685,12 @@ sub _RecordNote {
foreach my $type (qw/Cc Bcc/) {
if ( defined $args{ $type . 'MessageTo' } ) {
-
- my $addresses = join ', ', (
- map { RT::User->CanonicalizeEmailAddress( $_->address ) }
- Email::Address->parse( $args{ $type . 'MessageTo' } ) );
+ my ( $users, $errors ) = $self->ParseInputPrincipals( $args{ $type . 'MessageTo' } );
+ my $addresses = join ', ',
+ (
+ map { RT::User->CanonicalizeEmailAddress( $_ ) }
+ map { $_->EmailAddress || () } @$users
+ );
$args{'MIMEObj'}->head->replace( 'RT-Send-' . $type, Encode::encode( "UTF-8", $addresses ) );
}
}
diff --git a/share/html/Ticket/Update.html b/share/html/Ticket/Update.html
index 6e73b50a8..dcd21f323 100644
--- a/share/html/Ticket/Update.html
+++ b/share/html/Ticket/Update.html
@@ -339,6 +339,9 @@ if ( $ARGS{'SubmitTicket'} ) {
my $value = $ARGS{ $field };
next unless defined $value && length $value;
+ # Preserve non-email username inputs
+ my @usernames = grep {!/\@/} split /,/, $value;
+
my @emails = Email::Address->parse( $value );
foreach my $email ( grep RT::EmailParser->IsRTAddress($_->address), @emails ) {
push @results, loc("[_1] is an address RT receives mail at. Adding it as a '[_2]' would create a mail loop", $email->format, loc(substr($field, 6)) );
@@ -346,6 +349,11 @@ if ( $ARGS{'SubmitTicket'} ) {
$email = undef;
}
$ARGS{ $field } = join ', ', map $_->format, grep defined, @emails;
+
+ if ( @usernames ){
+ # Restore usernames, if any
+ $ARGS{ $field } .= ', ' . join ', ', grep defined, @usernames;
+ }
}
}
-----------------------------------------------------------------------
More information about the rt-commit
mailing list