Add tests for LDAP sync of users and groups.

This commit is contained in:
Andrew Ruthven 2024-02-03 17:43:10 +13:00
parent dc2991666a
commit b15c99fe1b
9 changed files with 521 additions and 41 deletions

View File

@ -29,18 +29,29 @@
//ldap $c->authenticate_hook['config'] = array(
//ldap 'host' => 'localhost',
//ldap 'port' => '21394',
//ldap 'baseDNUsers' => 'dc=example,dc=com',
//ldap 'mapping_field' => array("username" => "uid",
//ldap "modified" => "modifyTimestamp",
//ldap "fullname" => "cn" ,
//ldap "email" =>"mail"
//ldap 'protocolVersion' => 3,
//ldap 'baseDNUsers' => 'ou=users,dc=example,dc=com',
//ldap 'baseDNGroups' => 'ou=groups,dc=example,dc=com',
//ldap 'mapping_field' => array(
//ldap "username" => "uid",
//ldap "modified" => "modifyTimestamp",
//ldap "fullname" => "cn",
//ldap "email" => "mail"
//ldap ),
//ldap 'group_mapping_field' => array("username" => "cn",
//ldap "modified" => "modifyTimestamp",
//ldap "fullname" => "cn" ,
//ldap "members" =>"memberUid"
//ldap 'group_mapping_field' => array(
//ldap "username" => "cn",
//ldap "modified" => "modifyTimestamp",
//ldap "fullname" => "cn" ,
//ldap "members" => "memberUid",
//ldap ),
//ldap 'format_updated' => array('Y' => array(0,4), 'm' => array(4,2), 'd' => array(6,2), 'H' => array(8,2), 'M' => array(10,2), 'S' => array(12,2))
//ldap 'format_updated' => array(
//ldap 'Y' => array(0,4),
//ldap 'm' => array(4,2),
//ldap 'd' => array(6,2),
//ldap 'H' => array(8,2),
//ldap 'M' => array(10,2),
//ldap 'S' => array(12,2)
//ldap )
//ldap );
//ldap include('drivers_ldap.php');

View File

@ -1,6 +1,6 @@
# Check that no usr record exists
# Check that no ldap usr records exist
QUERY
SELECT active ,email, fullname, last_used, password, username, user_no
SELECT active, email, fullname, last_used, password, username, user_no
FROM usr
WHERE username = 'ldap1';
WHERE username LIKE 'ldap%';
ENDQUERY

View File

@ -1,3 +1,9 @@
# Copyright (c) 2021-2024 Andrew Ruthven <andrew@etc.gen.nz>
# Portions Copyright (c) Best Practical Solutions, LLC
# <sales@bestpractical.com>, licensed under the GPL v2.
#
# Test with LDAP auth logging in as a user which is in neither the DB
# or LDAP.
BEGINPERL
if ($debug) { $ENV{'LDAP_DEBUG'} = 1 };
@ -5,9 +11,6 @@ use Net::LDAP::Server::Test;
use Net::LDAP;
use IO::Socket::INET;
#my $port = find_idle_port();
#my $ldap_port = RT::Test->find_idle_port;
my $ldap_port = 21394;
my $ldap_socket = IO::Socket::INET->new(
Listen => 5,
@ -58,7 +61,7 @@ ENDDATA
# Check that no usr record has been created.
QUERY
SELECT active, email, fullname, last_used, password, username, user_no
FROM usr
FROM usr
WHERE username = 'ldap2';
ENDQUERY

View File

@ -0,0 +1,119 @@
HTTP/1.1 207 Multi-Status
Date: Dow, 01 Jan 2000 00:00:00 GMT
DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule
DAV: extended-mkcol, bind, addressbook, calendar-auto-schedule, calendar-proxy
ETag: "ed58709591152964fd4a584af5b55d79"
Content-Length: 942
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
<multistatus xmlns="DAV:">
<response>
<href>/caldav.php/</href>
<propstat>
<prop>
<resourcetype>
<collection/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/resource1/</href>
<propstat>
<prop>
<resourcetype>
<collection/>
<principal/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/resource2/</href>
<propstat>
<prop>
<resourcetype>
<collection/>
<principal/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/ldap1/</href>
<propstat>
<prop>
<resourcetype>
<collection/>
<principal/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</multistatus>
active: >1<
email: >ldap1@example.com<
fullname: >LDAP 1<
last_used: >NULL<
password: >NULL<
user_no: >1001<
username: >ldap1<
active: >1<
email: >ldap2@example.com<
fullname: >LDAP 2<
last_used: >NULL<
password: >NULL<
user_no: >1002<
username: >ldap2<
active: >1<
email: >NULL<
fullname: >ldap_group1<
last_used: >NULL<
password: >NULL<
user_no: >1003<
username: >ldap_group1<
active: >1<
email: >NULL<
fullname: >ldap_group2<
last_used: >NULL<
password: >NULL<
user_no: >1004<
username: >ldap_group2<
active: >1<
email: >NULL<
fullname: >ldap_group3<
last_used: >NULL<
password: >NULL<
user_no: >1005<
username: >ldap_group3<
active: >1<
email: >NULL<
fullname: >ldap_group4<
last_used: >NULL<
password: >NULL<
user_no: >1006<
username: >ldap_group4<
group_name: >ldap_group1<
user_name: >ldap1<
group_name: >ldap_group2<
user_name: >ldap2<
group_name: >ldap_group3<
user_name: >NULL<
group_name: >ldap_group4<
user_name: >NULL<

View File

@ -0,0 +1,112 @@
# Copyright (c) 2021-2024 Andrew Ruthven <andrew@etc.gen.nz>
# Portions Copyright (c) Best Practical Solutions, LLC
# <sales@bestpractical.com>, licensed under the GPL v2.
#
BEGINPERL
if ($debug) { $ENV{'LDAP_DEBUG'} = 1 };
use Net::LDAP::Server::Test;
use Net::LDAP;
use IO::Socket::INET;
my $ldap_port = 21394;
my $ldap_socket = IO::Socket::INET->new(
Listen => 5,
Proto => 'tcp',
Reuse => 1,
LocalPort => $ldap_port,
);
# Keep it around after this block exits.
$evaled{'ldap_server'} = Net::LDAP::Server::Test->new( $ldap_socket, auto_schema => 1 );
my $ldap = Net::LDAP->new("localhost:$ldap_port") || die "Failed to instantiate Net::LDAP: $!";
$ldap->bind();
my $base = "dc=example,dc=com";
my $users = "ou=users,$base";
my $groups = "ou=groups,$base";
$ldap->add( $base );
for my $username (qw/ldap1 ldap2/) {
my $dn = "uid=$username,$users";
(my $cn = $username) =~ s/ldap(\d+)/LDAP $1/;
my $entry = {
cn => $cn,
mail => "$username\@example.com",
uid => $username,
objectClass => 'User',
userPassword => $username,
modifyTimestamp => 20240203001020,
};
$ldap->add( $dn, attr => [%$entry] );
}
for my $group (qw/ldap_group1 ldap_group2/) {
my $dn = "cn=$group,$groups";
(my $member = $group) =~ s/_group//;
my $entry = {
cn => $group,
objectClass => 'groupofNames',
memberUid => $member,
modifyTimestamp => 20240203001020,
};
$ldap->add( $dn, attr => [%$entry] );
}
# Create some empty groups.
for my $group (qw/ldap_group3 ldap_group4/) {
my $dn = "cn=$group,$groups";
my $entry = {
cn => $group,
objectClass => 'groupofNames',
modifyTimestamp => 20240203001020,
};
$ldap->add( $dn, attr => [%$entry] );
}
# We need to keep the client around, otherwise the test server will exit.
$evaled{'ldap_client'} = $ldap;
#sleep 60;
ENDPERL
SCRIPT=../scripts/cron-sync-ldap.php regression_ldap.host
# Testing logging in as one of the users - should work.
TYPE=PROPFIND
URL=http://regression_ldap.host/caldav.php/
HEADER=Content-Type: text/xml
HEADER=Depth: 1
AUTH=ldap1:ldap1
HEAD
BEGINDATA
<?xml version="1.0" encoding="utf-8" ?>
<D:propfind xmlns:D="DAV:">
<D:prop>
<D:resourcetype/>
</D:prop>
</D:propfind>
ENDDATA
# Check that a usr record has been created for all users and groups
QUERY
SELECT active, email, fullname, last_used, password, username, user_no
FROM usr
WHERE username LIKE 'ldap%'
ORDER BY username;
ENDQUERY
# Check that ldap1 is a member of ldap_qroup1 and ldap2 is a member of
# ldap_group2, and that ldap_group3 is empty.
QUERY
SELECT grp_u.username AS group_name, usr_u.username AS user_name
FROM principal AS grp_p
left join group_member ON (grp_p.principal_id = group_member.group_id)
left join principal AS usr_p ON (group_member.member_id = usr_p.principal_id)
left join usr AS usr_u ON (usr_p.user_no = usr_u.user_no)
left join usr AS grp_u ON (grp_p.user_no = grp_u.user_no)
WHERE grp_u.username LIKE 'ldap_group%'
ORDER BY group_name, user_name;
ENDQUERY

View File

@ -0,0 +1,122 @@
HTTP/1.1 207 Multi-Status
Date: Dow, 01 Jan 2000 00:00:00 GMT
DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule
DAV: extended-mkcol, bind, addressbook, calendar-auto-schedule, calendar-proxy
ETag: "ed58709591152964fd4a584af5b55d79"
Content-Length: 942
Content-Type: text/xml; charset="utf-8"
<?xml version="1.0" encoding="utf-8" ?>
<multistatus xmlns="DAV:">
<response>
<href>/caldav.php/</href>
<propstat>
<prop>
<resourcetype>
<collection/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/resource1/</href>
<propstat>
<prop>
<resourcetype>
<collection/>
<principal/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/resource2/</href>
<propstat>
<prop>
<resourcetype>
<collection/>
<principal/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
<response>
<href>/caldav.php/ldap1/</href>
<propstat>
<prop>
<resourcetype>
<collection/>
<principal/>
</resourcetype>
</prop>
<status>HTTP/1.1 200 OK</status>
</propstat>
</response>
</multistatus>
active: >1<
email: >ldap1@example.com<
fullname: >LDAP 1<
last_used: >NULL<
password: >NULL<
user_no: >1001<
username: >ldap1<
active: >1<
email: >ldap2@example.com<
fullname: >LDAP 2<
last_used: >NULL<
password: >NULL<
user_no: >1002<
username: >ldap2<
active: >1<
email: >NULL<
fullname: >ldap_group1<
last_used: >NULL<
password: >NULL<
user_no: >1003<
username: >ldap_group1<
active: >1<
email: >NULL<
fullname: >ldap_group2<
last_used: >NULL<
password: >NULL<
user_no: >1004<
username: >ldap_group2<
active: >1<
email: >NULL<
fullname: >ldap_group3<
last_used: >NULL<
password: >NULL<
user_no: >1005<
username: >ldap_group3<
active: >1<
email: >NULL<
fullname: >ldap_group4<
last_used: >NULL<
password: >NULL<
user_no: >1006<
username: >ldap_group4<
group_name: >ldap_group1<
user_name: >ldap2<
group_name: >ldap_group2<
user_name: >ldap1<
group_name: >ldap_group2<
user_name: >ldap2<
group_name: >ldap_group3<
user_name: >ldap1<
group_name: >ldap_group4<
user_name: >NULL<

View File

@ -0,0 +1,125 @@
# Copyright (c) 2021-2024 Andrew Ruthven <andrew@etc.gen.nz>
# Portions Copyright (c) Best Practical Solutions, LLC
# <sales@bestpractical.com>, licensed under the GPL v2.
#
# In this test we create LDAP records that are slightly different from
# the previous test to make sure that changes are reflected.
#
# Database will start with:
# ldap_group1: ldap1
# ldap_group2: ldap2
# ldap_group3: <empty>
# ldap_group4: ldap1
#
# We will change that to:
# ldap_group1: ldap2
# ldap_group2: ldap1, ldap2
# ldap_group3: ldap1
# ldap_group4: <empty>
#
BEGINPERL
if ($debug) { $ENV{'LDAP_DEBUG'} = 1 };
use Net::LDAP::Server::Test;
use Net::LDAP;
use IO::Socket::INET;
my $ldap_port = 21394;
my $ldap_socket = IO::Socket::INET->new(
Listen => 5,
Proto => 'tcp',
Reuse => 1,
LocalPort => $ldap_port,
);
# Keep it around after this block exits.
$evaled{'ldap_server'} = Net::LDAP::Server::Test->new( $ldap_socket, auto_schema => 1 );
my $ldap = Net::LDAP->new("localhost:$ldap_port") || die "Failed to instantiate Net::LDAP: $!";
$ldap->bind();
my $base = "dc=example,dc=com";
my $users = "ou=users,$base";
my $groups = "ou=groups,$base";
$ldap->add( $base );
for my $username (qw/ldap1 ldap2/) {
my $dn = "uid=$username,$users";
(my $cn = $username) =~ s/ldap(\d+)/LDAP $1/;
my $entry = {
cn => $cn,
mail => "$username\@example.com",
uid => $username,
objectClass => 'User',
userPassword => $username,
modifyTimestamp => 20240203001020,
};
$ldap->add( $dn, attr => [%$entry] );
}
make_group($ldap, 'ldap_group1', 'ldap2');
make_group($ldap, 'ldap_group2', 'ldap1', 'ldap2');
make_group($ldap, 'ldap_group3', 'ldap1');
make_group($ldap, 'ldap_group4');
# We need to keep the client around, otherwise the test server will exit.
$evaled{'ldap_client'} = $ldap;
sleep 60;
sub make_group {
my $ldap = shift;
my $name = shift;
my @users = @_;
my $dn = "cn=$name,$groups";
my $entry = {
cn => $name,
objectClass => 'groupofNames',
(@users
? (memberUid => [ @users ])
: ()
),
modifyTimestamp => 20240203001020,
};
$ldap->add( $dn, attr => [%$entry] );
}
ENDPERL
SCRIPT=../scripts/cron-sync-ldap.php regression_ldap.host
# Testing logging in as one of the users - should work.
TYPE=PROPFIND
URL=http://regression_ldap.host/caldav.php/
HEADER=Content-Type: text/xml
HEADER=Depth: 1
AUTH=ldap1:ldap1
HEAD
BEGINDATA
<?xml version="1.0" encoding="utf-8" ?>
<D:propfind xmlns:D="DAV:">
<D:prop>
<D:resourcetype/>
</D:prop>
</D:propfind>
ENDDATA
# Check that a usr record has been created for all users and groups
QUERY
SELECT active, email, fullname, last_used, password, username, user_no
FROM usr
WHERE username LIKE 'ldap%'
ORDER BY username;
ENDQUERY
# Check that ldap1 is a member of ldap_qroup1 and ldap2 is a member of
# ldap_group2, and that ldap_group3 is empty.
QUERY
SELECT grp_u.username AS group_name, usr_u.username AS user_name
FROM principal AS grp_p
left join group_member ON (grp_p.principal_id = group_member.group_id)
left join principal AS usr_p ON (group_member.member_id = usr_p.principal_id)
left join usr AS usr_u ON (usr_p.user_no = usr_u.user_no)
left join usr AS grp_u ON (grp_p.user_no = grp_u.user_no)
WHERE grp_u.username LIKE 'ldap_group%'
ORDER BY group_name, user_name;
ENDQUERY

View File

@ -2,7 +2,7 @@ HTTP/1.1 207 Multi-Status
Date: Dow, 01 Jan 2000 00:00:00 GMT
DAV: 1, 2, 3, access-control, calendar-access, calendar-schedule
DAV: extended-mkcol, bind, addressbook, calendar-auto-schedule, calendar-proxy
ETag: "ed58709591152964fd4a584af5b55d79"
ETag: "dc507be383f0899568adb9d02a1ddb03"
Content-Length: 942
Content-Type: text/xml; charset="utf-8"
@ -44,7 +44,7 @@ Content-Type: text/xml; charset="utf-8"
</propstat>
</response>
<response>
<href>/caldav.php/ldap1/</href>
<href>/caldav.php/ldap3/</href>
<propstat>
<prop>
<resourcetype>
@ -58,10 +58,10 @@ Content-Type: text/xml; charset="utf-8"
</multistatus>
active: >1<
email: >ldap1@example.com<
fullname: >ldap1<
email: >ldap3@example.com<
fullname: >ldap3<
last_used: >NULL<
password: >NULL<
user_no: >1001<
username: >ldap1<
user_no: >1007<
username: >ldap3<

View File

@ -2,6 +2,8 @@
# Portions Copyright (c) Best Practical Solutions, LLC
# <sales@bestpractical.com>, licensed under the GPL v2.
#
# Test logging in using an LDAP user that doesn't exist in the
# database, should be copied over.
BEGINPERL
if ($debug) { $ENV{'LDAP_DEBUG'} = 1 };
@ -9,9 +11,6 @@ use Net::LDAP::Server::Test;
use Net::LDAP;
use IO::Socket::INET;
#my $port = find_idle_port();
#my $ldap_port = RT::Test->find_idle_port;
my $ldap_port = 21394;
my $ldap_socket = IO::Socket::INET->new(
Listen => 5,
@ -30,7 +29,7 @@ my $users = "ou=users,$base";
my $groups = "ou=groups,$base";
$ldap->add( $base );
for my $username (qw/ldap1 ldap2/) {
for my $username (qw/ldap3 ldap4/) {
my $dn = "uid=$username,$users";
my $entry = {
cn => $username,
@ -42,17 +41,6 @@ for my $username (qw/ldap1 ldap2/) {
$ldap->add( $dn, attr => [%$entry] );
}
for my $group (qw/group1 group2/) {
my $dn = "cn=$group,$groups";
(my $member = $group) =~ s/group/ldap/;
my $entry = {
cn => $group,
objectClass => 'groupofNames',
member => "cn=$member,$users",
};
$ldap->add( $dn, attr => [%$entry] );
}
# We need to keep the client around, otherwise the test server will exit.
$evaled{'ldap_client'} = $ldap;
#sleep 100;
@ -62,7 +50,7 @@ TYPE=PROPFIND
URL=http://regression_ldap.host/caldav.php/
HEADER=Content-Type: text/xml
HEADER=Depth: 1
AUTH=ldap1:ldap1
AUTH=ldap3:ldap3
HEAD
BEGINDATA
@ -77,7 +65,7 @@ ENDDATA
# Check that a usr record has been created.
QUERY
SELECT active, email, fullname, last_used, password, username, user_no
FROM usr
WHERE username = 'ldap1';
FROM usr
WHERE username = 'ldap3';
ENDQUERY