[Rt-commit] rt branch, 4.4/add-role-by-username, created. rt-4.4.2-65-g52b582582
Jim Brandt
jbrandt at bestpractical.com
Wed Jan 10 16:45:37 EST 2018
The branch, 4.4/add-role-by-username has been created
at 52b582582a4973fd144bbd857ee8632c35db0d1b (commit)
- Log -----------------------------------------------------------------
commit 52b582582a4973fd144bbd857ee8632c35db0d1b
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 a1d49104e..7d4e1212f 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 e1b347d7a..2c954644a 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;
+ }
}
}
-----------------------------------------------------------------------
More information about the rt-commit
mailing list