Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Force use of IPv4 for LDAP test. #367

Open
wants to merge 2 commits into
base: stable
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 193 additions & 0 deletions lib/RT/Test/LDAP.pm
Original file line number Diff line number Diff line change
@@ -0,0 +1,193 @@
# BEGIN BPS TAGGED BLOCK {{{
#
# COPYRIGHT:
#
# This software is Copyright (c) 1996-2023 Best Practical Solutions, LLC
# <[email protected]>
#
# (Except where explicitly superseded by other copyright notices)
#
#
# LICENSE:
#
# This work is made available to you under the terms of Version 2 of
# the GNU General Public License. A copy of that license should have
# been provided with this software, but in any event can be snarfed
# from www.gnu.org.
#
# This work is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
# 02110-1301 or visit their web page on the internet at
# http://www.gnu.org/licenses/old-licenses/gpl-2.0.html.
#
#
# CONTRIBUTION SUBMISSION POLICY:
#
# (The following paragraph is not intended to limit the rights granted
# to you to modify and distribute this software under the terms of
# the GNU General Public License and is only of importance to you if
# you choose to contribute your changes and enhancements to the
# community by submitting them to Best Practical Solutions, LLC.)
#
# By intentionally submitting any modifications, corrections or
# derivatives to this work, or any other work intended for use with
# Request Tracker, to Best Practical Solutions, LLC, you confirm that
# you are the copyright holder for those contributions and you grant
# Best Practical Solutions, LLC a nonexclusive, worldwide, irrevocable,
# royalty-free, perpetual, license to use, copy, create derivative
# works based on those contributions, and sublicense and distribute
# those contributions and any derivatives thereof.
#
# END BPS TAGGED BLOCK }}}

# Portions Copyright 2023 Andrew Ruthven <[email protected]>

package RT::Test::LDAP;

use strict;
use warnings;
use IO::Socket::INET;

use base 'RT::Test';

sub new {
my $proto = shift;
my %options = @_;
my $class = ref($proto) ? ref($proto) : $proto;
my $self = bless {
ldap_ip => '127.0.0.1',
base_dn => $options{base_dn} || 'dc=bestpractical,dc=com',
}, $class;

# Set a base default. Some tests will add or override portions of this
# hash.
$self->{'externalauth'} = {
'My_LDAP' => {
'type' => 'ldap',
'base' => $self->{'base_dn'},
'filter' => '(objectClass=*)',
'd_filter' => '()',
'tls' => 0,
'net_ldap_args' => [ version => 3 ],
'attr_match_list' => [ 'Name', 'EmailAddress' ],
'attr_map' => {
'Name' => 'uid',
'EmailAddress' => 'mail',
'RealName' => 'cn',
'Gecos' => 'uid',
'NickName' => 'nick',
},
},
};

return $self;
}

sub import {
my $class = shift;

$class->SUPER::import(@_, tests => undef);

eval {
require RT::LDAPImport;
require RT::Authen::ExternalAuth;
require Net::LDAP::Server::Test;
1;
} or do {
RT::Test::plan(
skip_all => 'Unable to test without Net::LDAP and Net::LDAP::Server::Test'
);
};

my %args = @_;
RT::Test::plan( tests => $args{'tests'} ) if $args{tests};

$class->export_to_level(1);
}

sub new_server {
my $self = shift;

$self->{'ldap_port'} = RT::Test->find_idle_port;
my $ldap_socket = IO::Socket::INET->new(
Listen => 5,
Proto => 'tcp',
Reuse => 1,
LocalAddr => $self->{'ldap_ip'},
LocalPort => $self->{'ldap_port'},
)
|| die "Failed to create socket: $IO::Socket::errstr";

$self->{'ldap_server'}
= Net::LDAP::Server::Test->new( $ldap_socket, auto_schema => 1 )
|| die "Failed to spawn test LDAP server on port " . $self->{'ldap_port'};

my $ldap_client
= Net::LDAP->new(join(':', $self->{'ldap_ip'}, $self->{'ldap_port'}))
|| die "Failed to connect to LDAP server: $@";

$ldap_client->bind();
$ldap_client->add($self->{'base_dn'});

return $ldap_client;
}

sub config_set_externalauth {
my $self = shift;
my $settings = shift;

$settings->{'ExternalAuthPriority'} //= ['My_LDAP'];
$settings->{'ExternalInfoPriority'} //= ['My_LDAP'];
$settings->{'AutoCreateNonExternalUsers'} //= 0;
$settings->{'AutoCreate'} //= undef;

while (my ($key, $val) = each %{$settings}) {
RT->Config->Set($key, $val);
}

$self->{'externalauth'}{'My_LDAP'}{'server'} //=
join(':', $self->{'ldap_ip'}, $self->{'ldap_port'});

RT->Config->Set(ExternalSettings => $self->{'externalauth'});
RT->Config->PostLoadCheck;
}

sub config_set_ldapimport {
my $self = shift;
my $settings = shift;

$settings->{'LDAPHost'}
//= 'ldap://' . $self->{'ldap_ip'} . ':' . $self->{'ldap_port'};
$settings->{'LDAPMapping'} //= {
Name => 'uid',
EmailAddress => 'mail',
RealName => 'cn',
};
$settings->{'LDAPBase'} //= $self->{'base_dn'};
$settings->{'LDAPFilter'} //= '(objectClass=User)';
$settings->{'LDAPSkipAutogeneratedGroup'} //= 1;

while (my ($key, $val) = each %{$settings}) {
RT->Config->Set($key, $val);
}
}

sub config_set_ldapimport_group {
my $self = shift;
my $settings = shift;

$settings->{'LDAPGroupBase'} //= $self->{'base_dn'};
$settings->{'LDAPGroupFilter'} //= '(objectClass=Group)';

while (my ($key, $val) = each %{$settings}) {
RT->Config->Set($key, $val);
}
}

1;
107 changes: 36 additions & 71 deletions t/externalauth/ldap.t
Original file line number Diff line number Diff line change
@@ -1,21 +1,13 @@
use strict;
use warnings;

use RT::Test tests => undef;
use RT::Test::LDAP tests => undef;

eval { require RT::Authen::ExternalAuth; require Net::LDAP::Server::Test; 1; } or do {
plan skip_all => 'Unable to test without Net::LDAP and Net::LDAP::Server::Test';
};


my $ldap_port = RT::Test->find_idle_port;
ok( my $server = Net::LDAP::Server::Test->new( $ldap_port, auto_schema => 1 ),
"spawned test LDAP server on port $ldap_port" );
my $test = RT::Test::LDAP->new();
my $base = $test->{'base_dn'};
my $ldap = $test->new_server();

my $ldap = Net::LDAP->new("localhost:$ldap_port");
$ldap->bind();
my $username = "testuser";
my $base = "dc=bestpractical,dc=com";
my $dn = "uid=$username,$base";
my $entry = {
cn => $username,
Expand Down Expand Up @@ -62,40 +54,24 @@ ok( $delegate_cf->Create(
);
ok( $delegate_cf->AddToObject( RT::User->new( RT->SystemUser ) ), 'applied Delegate globally' );

RT->Config->Set( ExternalAuthPriority => ['My_LDAP'] );
RT->Config->Set( ExternalInfoPriority => ['My_LDAP'] );
RT->Config->Set( AutoCreateNonExternalUsers => 0 );
RT->Config->Set( AutoCreate => undef );
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' => [ 'Name', 'EmailAddress' ],
'attr_map' => {
'Name' => 'uid',
'EmailAddress' => 'mail',
'FreeformContactInfo' => [ 'uid', 'mail' ],
'CF.Employee Type' => 'employeeType',
'UserCF.Employee Type' => 'employeeType',
'UserCF.Employee ID' => sub {
my %args = @_;
return ( 'employeeType', 'employeeID' ) unless $args{external_entry};
return (
$args{external_entry}->get_value('employeeType') // '',
$args{external_entry}->get_value('employeeID') // '',
);
},
}
},
}
);
RT->Config->PostLoadCheck;
# Just wholesale replace the default attr_map.
$test->{'externalauth'}{'My_LDAP'}{'attr_map'} = {
'Name' => 'uid',
'EmailAddress' => 'mail',
'FreeformContactInfo' => [ 'uid', 'mail' ],
'CF.Employee Type' => 'employeeType',
'UserCF.Employee Type' => 'employeeType',
'UserCF.Employee ID' => sub {
my %args = @_;
return ( 'employeeType', 'employeeID' ) unless $args{external_entry};
return (
$args{external_entry}->get_value('employeeType') // '',
$args{external_entry}->get_value('employeeID') // '',
);
},
};

$test->config_set_externalauth();

my ( $baseurl, $m ) = RT::Test->started_ok();

Expand Down Expand Up @@ -216,31 +192,20 @@ 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;
$test->stop_server();

$test->{'externalauth'}{'My_LDAP'}{'attr_match_list'}
= [ 'UserCF.Employee ID', 'EmailAddress' ];
$test->{'externalauth'}{'My_LDAP'}{'attr_map'} = {
'Name' => 'uid',
'EmailAddress' => 'mail',
'FreeformContactInfo' => [ 'uid', 'mail' ],
'CF.Employee Type' => 'employeeType',
'UserCF.Employee Type' => 'employeeType',
'UserCF.Employee ID' => 'employeeID',
};

$test->config_set_externalauth();

( $baseurl, $m ) = RT::Test->started_ok();

Expand Down
43 changes: 5 additions & 38 deletions t/externalauth/ldap_email_login.t
Original file line number Diff line number Diff line change
@@ -1,46 +1,13 @@
use strict;
use warnings;

use RT::Test tests => undef;
use RT::Test::LDAP tests => undef;

eval { require RT::Authen::ExternalAuth; require Net::LDAP::Server::Test; 1; } or do {
plan skip_all => 'Unable to test without Net::LDAP and Net::LDAP::Server::Test';
};
my $test = RT::Test::LDAP->new();
my $base = $test->{'base_dn'};
my $ldap = $test->new_server();

my $ldap_port = RT::Test->find_idle_port;
ok( my $server = Net::LDAP::Server::Test->new( $ldap_port, auto_schema => 1 ),
"spawned test LDAP server on port $ldap_port" );

my $ldap = Net::LDAP->new("localhost:$ldap_port");
$ldap->bind();

my $base = 'dc=bestpractical,dc=com';

RT->Config->Set( ExternalAuthPriority => ['My_LDAP'] );
RT->Config->Set( ExternalInfoPriority => ['My_LDAP'] );
RT->Config->Set( AutoCreate => undef );
RT->Config->Set(
ExternalSettings => {
'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' => [ 'Name', 'EmailAddress' ],
'attr_map' => {
'Name' => 'uid',
'EmailAddress' => 'mail',
'RealName' => 'cn',
'Gecos' => 'uid',
'NickName' => 'nick',
}
},
}
);
RT->Config->PostLoadCheck;
$test->config_set_externalauth();

my ( $baseurl, $m ) = RT::Test->started_ok();

Expand Down
Loading