[Rt-commit] rt branch, 4.4/ldap-log-with-email, created. rt-4.4.4-81-g964fc496b2

Michel Rodriguez michel at bestpractical.com
Tue Dec 17 08:08:23 EST 2019


The branch, 4.4/ldap-log-with-email has been created
        at  964fc496b2ca066b74e7fe5de5e17f8ae26bca53 (commit)

- Log -----------------------------------------------------------------
commit 964fc496b2ca066b74e7fe5de5e17f8ae26bca53
Author: michel <michel at bestpractical.com>
Date:   Tue Dec 17 12:06:17 2019 +0100

    Allow using the email address when login in through LDAP.
    
    In that case the username is retrieved from LDAP.

diff --git a/lib/RT/Authen/ExternalAuth/LDAP.pm b/lib/RT/Authen/ExternalAuth/LDAP.pm
index 2cc53f713a..05fcac1c41 100644
--- a/lib/RT/Authen/ExternalAuth/LDAP.pm
+++ b/lib/RT/Authen/ExternalAuth/LDAP.pm
@@ -205,7 +205,6 @@ sub GetAuth {
     my $group_attr      = $config->{'group_attr'};
     my $group_attr_val  = $config->{'group_attr_value'} || 'dn';
     my $group_scope     = $config->{'group_scope'} || 'base';
-    my $attr_map        = $config->{'attr_map'};
     my @attrs           = ('dn');
 
     # Make sure we fetch the user attribute we'll need for the group check
@@ -221,11 +220,8 @@ sub GetAuth {
     my $ldap = _GetBoundLdapObj($config);
     return 0 unless ($ldap);
 
-    $filter = Net::LDAP::Filter->new(   '(&(' .
-                                        $attr_map->{'Name'} .
-                                        '=' .
-                                        escape_filter_value($username) .
-                                        ')' .
+    $filter = Net::LDAP::Filter->new(   '(&' .
+                                        _name_filter( $config, $username) .
                                         $filter .
                                         ')'
                                     );
@@ -354,6 +350,26 @@ sub GetAuth {
 
 }
 
+sub _name_filter {
+    my( $config, $user)= @_;
+    my $attr_map   = $config->{'attr_map'};
+    my $match_attr = $config->{'attr_match_list'};
+    $match_attr = [ 'Name' ] if !$match_attr || ! @$match_attr;
+    my $match_attr_filter=  _or_filter( map { _eq_filter( $attr_map->{$_}, $user) } @$match_attr);
+    return $match_attr_filter;
+
+}
+sub _or_filter {
+    return '(|' . join( '', @_ ) . ')';
+}
+
+sub _eq_filter {
+    my( $attr, $user)= @_;
+    $user = escape_filter_value( $user);
+    return "($attr=$user)";
+}
+
+
 
 sub CanonicalizeUserInfo {
 
@@ -540,11 +556,8 @@ sub UserExists {
         # Construct the complex filter
         $filter = Net::LDAP::Filter->new(           '(&' .
                                                     $filter .
-                                                    '(' .
-                                                    $config->{'attr_map'}->{'Name'} .
-                                                    '=' .
-                                                    escape_filter_value($username) .
-                                                    '))'
+                                                    _name_filter( $config, $username) .
+                                                    ')'
                                         );
     }
 
@@ -583,10 +596,14 @@ sub UserExists {
                             "More than one user with that username!");
         return 0;
     }
+
+    my $ldap_name_attr = $config->{'attr_map'}->{'Name'};
+    my $username_found = $user_found->entry( 0 )->get_value( $ldap_name_attr ) if $ldap_name_attr;
     undef $user_found;
 
     # If we havent returned now, there must be a valid user.
-    return 1;
+    # return the username (in case login was done through an other field, like the email address)
+    return $username_found || 1;
 }
 
 sub UserDisabled {
@@ -603,6 +620,7 @@ sub UserDisabled {
     my $base            = $config->{'base'};
     my $filter          = $config->{'filter'};
     my $d_filter        = $config->{'d_filter'};
+    my $attr_map        = $config->{'attr_map'};
     my $search_filter;
 
     # While LDAP filters must be surrounded by parentheses, an empty set
@@ -625,11 +643,8 @@ sub UserDisabled {
         $search_filter = Net::LDAP::Filter->new(   '(&' .
                                                     $filter .
                                                     $d_filter .
-                                                    '(' .
-                                                    $config->{'attr_map'}->{'Name'} .
-                                                    '=' .
-                                                    escape_filter_value($username) .
-                                                    '))'
+                                                    _name_filter( $config, $username) .
+                                                    ')'
                                                 );
     } else {
         $RT::Logger->debug("You haven't specified an LDAP attribute to match the RT \"Name\" attribute for this service (",
diff --git a/t/externalauth/ldap.t b/t/externalauth/ldap.t
index 671d3fcd95..55c617ef0f 100644
--- a/t/externalauth/ldap.t
+++ b/t/externalauth/ldap.t
@@ -192,6 +192,30 @@ diag "test user update via login";
     );
 }
 
+diag "test login via email address";
+{
+    $m->logout;
+    my $username = "anotheruser";
+    my $base     = "dc=bestpractical,dc=com";
+    my $dn       = "uid=$username,$base";
+    my $entry    = {
+        cn           => $username,
+        mail         => "$username\@invalid.tld",
+        uid          => $username,
+        objectClass  => 'User',
+        userPassword => 'password',
+        employeeType => 'engineer',
+        employeeID   => '234',
+    };
+    $ldap->add( $base );
+    $ldap->add( $dn, attr => [%$entry] );
+    # first login (creates the user)
+    ok( $m->login( $entry->{email}, 'password' ), 'logged in using email address' );
+    # second login
+    $m->logout;
+    ok( $m->login( $entry->{email}, 'password' ), 'logged in existing user using email address' );
+}
+
 $ldap->unbind();
 
 done_testing;

-----------------------------------------------------------------------


More information about the rt-commit mailing list