Skip Menu |

This queue is for tickets about the RT-Authen-ExternalAuth CPAN distribution.

Report information
The Basics
Id: 67080
Status: resolved
Priority: 0/
Queue: RT-Authen-ExternalAuth

People
Owner: Nobody in particular
Requestors: terencemo [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: (no value)
Broken in: 0.08
Fixed in: (no value)



Subject: Fails to auto-create users if auto-created on ticket submission
This happens when RT already has users auto-created by email. e.g, a user foo@testdomain.com is auto-created when added as a Cc. Later, with the RT::Authen::ExtenalAuth plugin enabled with auto-create set, the user foo tries to login with the username foo. RT finds a user foo in LDAP and checks whether the user exists in RT's database. This check returns *false* because RT doesn't treat the earlier user record in the Users table as the same user, since that user's username is the same as the email address (foo@testdomain.com). So RT tries to create a new user in the RT database with username foo and email foo@testdomain.com. But since the earlier record already exists in RT's Users table with the same email address, it fails since the unique email constraint is violated.
I got around this using the attached patch. Instead of directly loading the user, I have a GetEmail method that fetches the email of the user from LDAP and uses this to load the current user.
Subject: ExternalAuth-0.08.patch
diff -Nbaur lib.orig/RT/Authen/ExternalAuth/LDAP.pm lib/RT/Authen/ExternalAuth/LDAP.pm --- lib.orig/RT/Authen/ExternalAuth/LDAP.pm 2011-03-30 14:18:36.000000000 +0530 +++ lib/RT/Authen/ExternalAuth/LDAP.pm 2011-03-30 14:17:31.000000000 +0530 @@ -476,4 +476,75 @@ # }}} +sub GetEmail { + + my ($service, $username) = @_; + + my $config = $RT::ExternalSettings->{$service}; + $RT::Logger->debug( "Getting email from service:",$service); + + my $base = $config->{'base'}; + my $filter = $config->{'filter'}; + my $group = $config->{'group'}; + my $group_attr = $config->{'group_attr'}; + my $attr_map = $config->{'attr_map'}; + my @attrs = qw(dn mail); + + # Empty parentheses as filters cause Net::LDAP to barf. + # We take care of this by using Net::LDAP::Filter, but + # there's no harm in fixing this right now. + if ($filter eq "()") { undef($filter) }; + + # Now let's get connected + my $ldap = _GetBoundLdapObj($config); + return 0 unless ($ldap); + + $filter = Net::LDAP::Filter->new( '(&(' . + $attr_map->{'ExternalAuthId'} . + '=' . + $username . + ')' . + $filter . + ')' + ); + + $RT::Logger->debug( "LDAP Search get email === ", + "Base:", + $base, + "== Filter:", + $filter->as_string, + "== Attrs:", + join(',',@attrs)); + + my $ldap_msg = $ldap->search( base => $base, + filter => $filter, + attrs => \@attrs); + + unless ($ldap_msg->code == LDAP_SUCCESS || $ldap_msg->code == LDAP_PARTIAL_RESULTS) { + $RT::Logger->debug( "search for", + $filter->as_string, + "failed:", + ldap_error_name($ldap_msg->code), + $ldap_msg->code); + # Didn't even get a partial result - jump straight to the next external auth service + return 0; + } + + unless ($ldap_msg->count == 1) { + $RT::Logger->info( $service, + "AUTH FAILED:", + $username, + "User not found or more than one user found"); + # We got no user, or too many users.. jump straight to the next external auth service + return 0; + } + + my $ldap_mail = $ldap_msg->first_entry->get_value($attr_map->{EmailAddress}); + $RT::Logger->debug( "Found LDAP Mail:", + $ldap_mail); + + return $ldap_mail; + +} + 1; diff -Nbaur lib.orig/RT/Authen/ExternalAuth.pm lib/RT/Authen/ExternalAuth.pm --- lib.orig/RT/Authen/ExternalAuth.pm 2011-03-30 14:03:28.000000000 +0530 +++ lib/RT/Authen/ExternalAuth.pm 2011-03-30 14:14:27.000000000 +0530 @@ -115,7 +115,13 @@ # Does user already exist internally to RT? $session->{'CurrentUser'} = RT::CurrentUser->new(); + my $mail; + if ($config->{'type'} eq 'ldap') { + $mail = RT::Authen::ExternalAuth::LDAP::GetEmail($service,$username); + $session->{'CurrentUser'}->LoadByEmail($mail); + } else { $session->{'CurrentUser'}->Load($username); + } # Unless we have loaded a valid user with a UserID create one. unless ($session->{'CurrentUser'}->Id) {
On Wed Mar 30 03:19:50 2011, TERENCEMO wrote: Show quoted text
> This happens when RT already has users auto-created by email. e.g, a user > foo@testdomain.com is auto-created when added as a Cc. Later, with the > RT::Authen::ExtenalAuth plugin enabled with auto-create set, the user foo > tries to login with the username foo. > > RT finds a user foo in LDAP and checks whether the user exists in RT's > database. This check returns *false* because RT doesn't treat the earlier > user record in the Users table as the same user, since that user's > username is the same as the email address (foo@testdomain.com). So RT > tries to create a new user in the RT database with username foo and email > foo@testdomain.com. But since the earlier record already exists in RT's > Users table with the same email address, it fails since the unique email > constraint is violated.
I believe the multiple-emails branch in the github repo handles this and should be in an upcoming release. -kevin