[Rt-commit] rt branch 5.0/load-by-user-cf created. rt-5.0.3-146-gd4ddfc4a29

BPS Git Server git at git.bestpractical.com
Wed Nov 16 21:20:18 UTC 2022


This is an automated email from the git hooks/post-receive script. It was
generated because a ref change was pushed to the repository containing
the project "rt".

The branch, 5.0/load-by-user-cf has been created
        at  d4ddfc4a297ad5bb2aa25e4b03c10ee591cd4082 (commit)

- Log -----------------------------------------------------------------
commit d4ddfc4a297ad5bb2aa25e4b03c10ee591cd4082
Author: Jim Brandt <jbrandt at bestpractical.com>
Date:   Mon Nov 14 15:44:35 2022 -0500

    Tests for loading users via UserCFs

diff --git a/t/externalauth/ldap.t b/t/externalauth/ldap.t
index ad304a7319..7ec21081c3 100644
--- a/t/externalauth/ldap.t
+++ b/t/externalauth/ldap.t
@@ -214,6 +214,54 @@ diag "test user update via login";
     );
 }
 
+diag 'Login with UserCF as username';
+
+RT::Test->stop_server();
+
+RT->Config->Set(
+    ExternalSettings => {    # AN EXAMPLE DB SERVICE
+        'My_LDAP' => {
+            'type'            => 'ldap',
+            'server'          => "127.0.0.1:$ldap_port",
+            'base'            => $base,
+            'filter'          => '(objectClass=*)',
+            'd_filter'        => '()',
+            'tls'             => 0,
+            'net_ldap_args'   => [ version => 3 ],
+            'attr_match_list' => [ 'UserCF.Employee ID', 'EmailAddress' ],
+            'attr_map'        => {
+                'Name'                 => 'uid',
+                'EmailAddress'         => 'mail',
+                'FreeformContactInfo'  => [ 'uid', 'mail' ],
+                'CF.Employee Type'     => 'employeeType',
+                'UserCF.Employee Type' => 'employeeType',
+                'UserCF.Employee ID'   => 'employeeID',
+            }
+        },
+    }
+);
+RT->Config->PostLoadCheck;
+
+( $baseurl, $m ) = RT::Test->started_ok();
+
+diag "test uri login";
+{
+    my $testuser = RT::User->new($RT::SystemUser);
+    my ($ok,$msg) = $testuser->Load( 'testuser' );
+    ok($ok,$msg);
+
+    # Reset employee ID to just id
+    $testuser->AddCustomFieldValue( Field => 'Employee ID', Value => '234' );
+    is( $testuser->FirstCustomFieldValue('Employee ID'), 234, 'Employee ID set to 234');
+
+    # Can't use usual login method because it checks for username and for this test,
+    # the username is not the user CF value we are sending
+
+    $m->get($baseurl . "?user=234;pass=password");
+    ok( $m->content =~ m/Logout/i, 'Logged in' );
+    ok( $m->logged_in_as('testuser'), 'Logged in as testuser' );
+}
+
 $ldap->unbind();
 
 done_testing;

commit cbddb34ba7b7827ac42761b7807890976087cadb
Author: Jim Brandt <jbrandt at bestpractical.com>
Date:   Mon Nov 14 15:42:40 2022 -0500

    Support loading users via user custom fields
    
    External auth allows admins to provide a list of attributes
    for users to use in the username box on login, like 'Name'
    or 'EmailAddress' and it will try both. 566b8fa1 added support
    for using UserCFs in mappings, but not as login attributes.
    
    This commit adds support for loading users with UserCFs, so
    configurations like this can now be used:
    
        'attr_match_list' => [
            'UserCF.Employee ID',
            'EmailAddress',
        ],

diff --git a/lib/RT/Authen/ExternalAuth.pm b/lib/RT/Authen/ExternalAuth.pm
index 7384c92a91..de21f84909 100644
--- a/lib/RT/Authen/ExternalAuth.pm
+++ b/lib/RT/Authen/ExternalAuth.pm
@@ -419,7 +419,8 @@ sub DoAuth {
 
         # Does user already exist internally to RT?
         $session->{'CurrentUser'} = RT::CurrentUser->new();
-        $session->{CurrentUser}->LoadByCols( $field || 'Name', $username );
+        my $user = LoadUserObject( Field => $field || 'Name', Value => $username );
+        $session->{'CurrentUser'}->Load( $user->Id ) if $user->Id;
 
         # Unless we have loaded a valid user with a UserID create one.
         unless ($session->{'CurrentUser'}->Id) {
@@ -556,8 +557,7 @@ sub UpdateUserInfo {
 
     my $user_disabled   = RT::Authen::ExternalAuth::UserDisabled($username);
 
-    my $UserObj = RT::User->new(RT->SystemUser);
-    $UserObj->LoadByCols($field => $username);
+    my $UserObj = LoadUserObject( Field => $field, Value => $username, );
 
     # If user is disabled, set the RT::Principal to disabled and return out of the function.
     # I think it's a waste of time and energy to update a user's information if they are disabled
@@ -758,6 +758,30 @@ sub AddCustomFieldValue {
     return;
 }
 
+sub LoadUserObject {
+    my %args = (
+        Field => 'Name',
+        Value => undef,
+        @_
+    );
+    my ( $ret, $msg );
+
+    my $user = RT::User->new( RT->SystemUser );
+    if ( my ($cf_name) = $args{'Field'} =~ /^UserCF\.(.+)$/i ) {
+        ( $ret, $msg ) = $user->LoadByCustomFieldValue(
+            CustomField => $cf_name,
+            Value       => $args{'Value'},
+        );
+    }
+    else {
+        # No user CF, normal load
+        ( $ret, $msg ) = $user->LoadByCols( $args{'Field'}, $args{'Value'} );
+    }
+
+    RT->Logger->debug( "Unable to load user " . $args{'Value'} . " from field " . $args{'Field'} ) unless $ret;
+    return $user;
+}
+
 RT::Base->_ImportOverlays();
 
 1;

commit 28f25d8e73339d8ba9aa605e1a840ba021c29f9b
Author: Jim Brandt <jbrandt at bestpractical.com>
Date:   Tue Nov 15 17:21:59 2022 -0500

    Add method to load an object based on a custom field value

diff --git a/lib/RT/Record.pm b/lib/RT/Record.pm
index 13691bf1ad..848a81fda3 100644
--- a/lib/RT/Record.pm
+++ b/lib/RT/Record.pm
@@ -2363,6 +2363,53 @@ sub LoadCustomFieldByIdentifier {
     return $cf;
 }
 
+=head2 LoadByCustomFieldValue
+
+Load an object based on the value of a custom field applied to that
+object. Loads only one object. If the value isn't unique for that
+object type, the first found is returned.
+
+Accepts: CustomField => 'Foo', Value => 'Bar'
+
+Returns: ($status, $message) and loads the object, if successful
+
+=cut
+
+sub LoadByCustomFieldValue {
+    my $self = shift;
+    my %args = (
+        CustomField => undef,
+        Value       => undef,
+        @_
+    );
+
+    my $cf_obj = RT::CustomField->new( RT->SystemUser );
+    my ( $cf_ret, $cf_msg ) = $cf_obj->LoadByName(
+        Name       => $args{'CustomField'},
+        LookupType => $self->CustomFieldLookupType,
+    );
+
+    if ( !$cf_ret ) {
+        RT->Logger->warn( "Unable to load custom field with name " . $args{'CustomField'} . ": $cf_msg" );
+        return ( $cf_ret, $cf_msg );
+    }
+
+    my $ocfv_obj = RT::ObjectCustomFieldValue->new( RT->SystemUser );
+    my ( $ocfv_ret, $ocfv_msg ) = $ocfv_obj->LoadByCols(
+        CustomField => $cf_obj->Id,
+        Content     => $args{'Value'},
+        Disabled    => 0,
+    );
+
+    my ( $ret, $msg );
+    if ( $ocfv_ret && $ocfv_obj->Id ) {
+        # Found an object with that CF, so try to load it
+        ( $ret, $msg ) = $self->LoadById( $ocfv_obj->ObjectId );
+    }
+
+    return wantarray ? ( $ret, $msg ) : $ret;
+}
+
 sub ACLEquivalenceObjects { } 
 
 =head2 HasRight

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


hooks/post-receive
-- 
rt


More information about the rt-commit mailing list