test(IT): Test Ldap Import check use cases

Signed-off-by: Rubén D <nuxsmin@syspass.org>
This commit is contained in:
Rubén D
2024-10-25 20:31:36 +02:00
parent f7aa81a176
commit 8ab83bae47
9 changed files with 241 additions and 85 deletions

View File

@@ -59,7 +59,7 @@ final class CheckController extends SimpleControllerBase
* @throws SPException
*/
#[Action(ResponseType::JSON)]
public function checkAction(bool $useConfigParams): ActionResponse
public function checkAction(bool $useConfigParams = true): ActionResponse
{
if ($useConfigParams) {
$ldapParams = LdapParams::fromConfig($this->configData);

View File

@@ -26,7 +26,7 @@ declare(strict_types=1);
namespace SP\Domain\Auth\Providers\Ldap;
use Laminas\Ldap\Collection;
use Iterator;
use Laminas\Ldap\Exception\LdapException as LaminasLdapException;
use Laminas\Ldap\Ldap as LaminasLdap;
use SP\Core\Events\Event;
@@ -106,7 +106,7 @@ final class LdapActions implements LdapActionsService
$searchResults = $this->getResults($filter, ['dn']);
if ($searchResults->count() === 0) {
if (iterator_count($searchResults) === 0) {
$this->eventDispatcher->notify(
'ldap.search.group',
new Event(
@@ -135,7 +135,7 @@ final class LdapActions implements LdapActionsService
return null;
},
$searchResults->toArray()
iterator_to_array($searchResults)
)
)
);
@@ -159,16 +159,14 @@ final class LdapActions implements LdapActionsService
*
* @param string $filter Filtro a utilizar
* @param array|null $attributes Atributos a devolver
* @param string|null $searchBase
*
* @return Collection
* @throws LdapException
*/
private function getResults(
string $filter,
?array $attributes = [],
?string $searchBase = null
): Collection {
): Iterator {
if (empty($searchBase)) {
$searchBase = $this->searchBase;
}
@@ -190,7 +188,7 @@ final class LdapActions implements LdapActionsService
*/
public function getAttributes(string $filter): AttributeCollection
{
$searchResults = $this->getResults($filter)->getFirst();
$searchResults = $this->getResults($filter)->current();
if ($searchResults === null) {
return new AttributeCollection();
@@ -237,8 +235,6 @@ final class LdapActions implements LdapActionsService
array $attributes = self::USER_ATTRIBUTES,
?string $searchBase = null
): LdapResults {
$results = $this->getResults($filter, $attributes, $searchBase);
return new LdapResults($results->count(), $results);
return new LdapResults($this->getResults($filter, $attributes, $searchBase));
}
}

View File

@@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/**
* sysPass
@@ -32,12 +33,17 @@ use Iterator;
*/
readonly class LdapResults
{
public function __construct(private int $count, private Iterator $iterator)
private int $count;
public function __construct(private Iterator $iterator)
{
$this->count = iterator_count($this->iterator);
}
public function getIterator(): Iterator
{
$this->iterator->rewind();
return $this->iterator;
}

View File

@@ -26,7 +26,7 @@ declare(strict_types=1);
namespace SP\Tests\Domain\Auth\Providers\Ldap;
use Laminas\Ldap\Collection;
use ArrayIterator;
use Laminas\Ldap\Ldap;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\MockObject\Exception;
@@ -61,8 +61,7 @@ class LdapActionsTest extends UnitaryTestCase
public function testGetObjects(): void
{
$filter = 'test';
$collection = $this->createStub(Collection::class);
$collection->method('count')->willReturn(10);
$iterator = new ArrayIterator(range(0, 9));
$attributes = array_map(fn() => self::$faker->colorName, range(0, 9));
$searchBase = self::$faker->colorName;
@@ -75,11 +74,11 @@ class LdapActionsTest extends UnitaryTestCase
Ldap::SEARCH_SCOPE_SUB,
$attributes,
)
->willReturn($collection);
->willReturn($iterator);
$out = $this->ldapActions->getObjects($filter, $attributes, $searchBase);
self::assertEquals(new LdapResults(10, $collection), $out);
self::assertEquals(new LdapResults($iterator), $out);
}
/**
@@ -120,8 +119,8 @@ class LdapActionsTest extends UnitaryTestCase
*/
public function testGetAttributes(): void
{
$collection = $this->createMock(Collection::class);
$attributes = $this->buildAttributes();
$iterator = new ArrayIterator([$attributes]);
$this->ldap->expects(self::once())
->method('search')
@@ -131,9 +130,7 @@ class LdapActionsTest extends UnitaryTestCase
Ldap::SEARCH_SCOPE_SUB,
[],
)
->willReturn($collection);
$collection->expects(self::once())->method('getFirst')->willReturn($attributes);
->willReturn($iterator);
$out = $this->ldapActions->getAttributes('a_filter');
@@ -191,8 +188,14 @@ class LdapActionsTest extends UnitaryTestCase
*/
public function testSearchGroupsDn(): void
{
$expected = [
[],
[
'dn' => self::$faker->name,
],
];
$filter = 'test';
$collection = $this->createMock(Collection::class);
$iterator = new ArrayIterator($expected);
$this->ldap->expects(self::once())
->method('search')
@@ -202,17 +205,7 @@ class LdapActionsTest extends UnitaryTestCase
Ldap::SEARCH_SCOPE_SUB,
['dn'],
)
->willReturn($collection);
$collection->expects(self::once())->method('count')->willReturn(1);
$expected = [
[],
[
'dn' => self::$faker->name,
],
];
$collection->expects(self::once())->method('toArray')->willReturn($expected);
->willReturn($iterator);
$out = $this->ldapActions->searchGroupsDn($filter);
@@ -226,7 +219,7 @@ class LdapActionsTest extends UnitaryTestCase
public function testSearchGroupsDnNoGroups(): void
{
$filter = 'test';
$collection = $this->createMock(Collection::class);
$iterator = new ArrayIterator();
$this->ldap->expects(self::once())
->method('search')
@@ -236,14 +229,12 @@ class LdapActionsTest extends UnitaryTestCase
Ldap::SEARCH_SCOPE_SUB,
['dn'],
)
->willReturn($collection);
->willReturn($iterator);
$this->eventDispatcher->expects(self::once())
->method('notify')
->with('ldap.search.group');
$collection->expects(self::once())->method('count')->willReturn(0);
$this->expectException(LdapException::class);
$this->expectExceptionMessage('Error while searching the group RDN');
$this->expectExceptionCode(LdapCodeEnum::NO_SUCH_OBJECT->value);

View File

@@ -26,6 +26,7 @@ declare(strict_types=1);
namespace SP\Tests\Domain\Auth\Providers\Ldap;
use ArrayIterator;
use EmptyIterator;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;
@@ -162,7 +163,7 @@ class LdapMsAdsTest extends UnitaryTestCase
->expects(self::once())
->method('getObjects')
->with($groupsFilter, ['dn'], $userDn)
->willReturn(new LdapResults(1, new EmptyIterator()));
->willReturn(new LdapResults(new ArrayIterator([1])));
$this->eventDispatcher
->expects(self::once())
@@ -196,7 +197,7 @@ class LdapMsAdsTest extends UnitaryTestCase
->expects(self::once())
->method('getObjects')
->with($groupsFilter, ['dn'], $userDn)
->willReturn(new LdapResults(0, new EmptyIterator()));
->willReturn(new LdapResults(new EmptyIterator()));
$this->eventDispatcher
->expects(self::once())

View File

@@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/*
* sysPass
@@ -25,6 +26,7 @@ declare(strict_types=1);
namespace SP\Tests\Domain\Auth\Providers\Ldap;
use ArrayIterator;
use EmptyIterator;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\Attributes\Group;
@@ -161,7 +163,7 @@ class LdapStdTest extends UnitaryTestCase
->expects(self::once())
->method('getObjects')
->with($groupsFilter, ['dn'])
->willReturn(new LdapResults(1, new EmptyIterator()));
->willReturn(new LdapResults(new ArrayIterator([1])));
$this->eventDispatcher
->expects(self::once())
@@ -195,7 +197,7 @@ class LdapStdTest extends UnitaryTestCase
->expects(self::once())
->method('getObjects')
->with($groupsFilter, ['dn'])
->willReturn(new LdapResults(0, new EmptyIterator()));
->willReturn(new LdapResults(new EmptyIterator()));
$this->eventDispatcher
->expects(self::once())

View File

@@ -56,7 +56,7 @@ class LdapCheckTest extends UnitaryTestCase
{
$ldapData = $this->getLdapData();
$ldapResults = new LdapResults(10, new ArrayIterator($ldapData));
$ldapResults = new LdapResults(new ArrayIterator($ldapData));
$this->ldapActionsService
->expects($this->once())
@@ -148,7 +148,7 @@ class LdapCheckTest extends UnitaryTestCase
$ldapData = $this->getLdapData();
$ldapResults = new LdapResults(10, new ArrayIterator($ldapData));
$ldapResults = new LdapResults(new ArrayIterator($ldapData));
$this->ldapActionsService
->expects($this->exactly(3))
@@ -182,8 +182,8 @@ class LdapCheckTest extends UnitaryTestCase
$ldapDataUsers = $this->getLdapData();
$ldapDataGroups = $this->getLdapData();
$ldapResultsUsers = new LdapResults(10, new ArrayIterator($ldapDataUsers));
$ldapResultsGroups = new LdapResults(10, new ArrayIterator($ldapDataGroups));
$ldapResultsUsers = new LdapResults(new ArrayIterator($ldapDataUsers));
$ldapResultsGroups = new LdapResults(new ArrayIterator($ldapDataGroups));
$this->ldapActionsService
->expects($this->exactly(3))

View File

@@ -1,4 +1,5 @@
<?php
declare(strict_types=1);
/*
* sysPass
@@ -52,11 +53,10 @@ use SP\Tests\UnitaryTestCase;
class LdapImportTest extends UnitaryTestCase
{
private LdapImport $ldapImport;
private UserService|MockObject $userService;
private UserGroupService|MockObject $userGroupService;
private LdapActionsService|MockObject $ldapActionsService;
private LdapConnectionHandler|MockObject $ldapConnection;
private LdapImport $ldapImport;
private UserService|MockObject $userService;
private UserGroupService|MockObject $userGroupService;
private LdapActionsService|MockObject $ldapActionsService;
public static function emptyNameOrLoginProvider(): array
{
@@ -142,7 +142,7 @@ class LdapImportTest extends UnitaryTestCase
->expects($this->once())
->method('getObjects')
->with('test_filter')
->willReturn(new LdapResults(100, new ArrayIterator($entry)));
->willReturn(new LdapResults(new ArrayIterator($entry)));
$user = new User(
[
@@ -164,7 +164,7 @@ class LdapImportTest extends UnitaryTestCase
$out = $this->ldapImport->importUsers($ldapParams, $ldapImportParams);
$this->assertEquals(1, $out->getSyncedObjects());
$this->assertEquals(100, $out->getTotalObjects());
$this->assertEquals(1, $out->getTotalObjects());
$this->assertEquals(0, $out->getErrorObjects());
}
@@ -192,6 +192,9 @@ class LdapImportTest extends UnitaryTestCase
'mail' => [
'me@email.com'
]
],
[
'test' => ['test']
]
];
@@ -199,7 +202,7 @@ class LdapImportTest extends UnitaryTestCase
->expects($this->once())
->method('getObjects')
->with($filter)
->willReturn(new LdapResults(100, new ArrayIterator($entry)));
->willReturn(new LdapResults(new ArrayIterator($entry)));
$user = new User(
[
@@ -221,7 +224,7 @@ class LdapImportTest extends UnitaryTestCase
$out = $this->ldapImport->importUsers($ldapParams, $ldapImportParams);
$this->assertEquals(1, $out->getSyncedObjects());
$this->assertEquals(100, $out->getTotalObjects());
$this->assertEquals(2, $out->getTotalObjects());
$this->assertEquals(0, $out->getErrorObjects());
}
@@ -243,7 +246,7 @@ class LdapImportTest extends UnitaryTestCase
->expects($this->once())
->method('getObjects')
->with('test_filter')
->willReturn(new LdapResults(100, new ArrayIterator($entry)));
->willReturn(new LdapResults(new ArrayIterator($entry)));
$this->userService
->expects($this->never())
@@ -275,6 +278,9 @@ class LdapImportTest extends UnitaryTestCase
'mail' => [
'me@email.com'
]
],
[
'test' => ['test']
]
];
@@ -282,7 +288,7 @@ class LdapImportTest extends UnitaryTestCase
->expects($this->once())
->method('getObjects')
->with('test_filter')
->willReturn(new LdapResults(100, new ArrayIterator($entry)));
->willReturn(new LdapResults(new ArrayIterator($entry)));
$user = new User(
[
@@ -305,7 +311,7 @@ class LdapImportTest extends UnitaryTestCase
$out = $this->ldapImport->importUsers($ldapParams, $ldapImportParams);
$this->assertEquals(0, $out->getSyncedObjects());
$this->assertEquals(100, $out->getTotalObjects());
$this->assertEquals(2, $out->getTotalObjects());
$this->assertEquals(1, $out->getErrorObjects());
}
@@ -326,6 +332,9 @@ class LdapImportTest extends UnitaryTestCase
'test_group' => [
'Test Group'
]
],
[
'test' => ['test']
]
];
@@ -333,7 +342,7 @@ class LdapImportTest extends UnitaryTestCase
->expects($this->once())
->method('getObjects')
->with('test_filter')
->willReturn(new LdapResults(100, new ArrayIterator($entry)));
->willReturn(new LdapResults(new ArrayIterator($entry)));
$group = new UserGroup(
[
@@ -350,7 +359,7 @@ class LdapImportTest extends UnitaryTestCase
$out = $this->ldapImport->importGroups($ldapParams, $ldapImportParams);
$this->assertEquals(1, $out->getSyncedObjects());
$this->assertEquals(100, $out->getTotalObjects());
$this->assertEquals(2, $out->getTotalObjects());
}
/**
@@ -371,6 +380,9 @@ class LdapImportTest extends UnitaryTestCase
'test_group' => [
'Test Group'
]
],
[
'test' => ['test']
]
];
@@ -378,7 +390,7 @@ class LdapImportTest extends UnitaryTestCase
->expects($this->once())
->method('getObjects')
->with($filter)
->willReturn(new LdapResults(100, new ArrayIterator($entry)));
->willReturn(new LdapResults(new ArrayIterator($entry)));
$group = new UserGroup(
[
@@ -395,7 +407,7 @@ class LdapImportTest extends UnitaryTestCase
$out = $this->ldapImport->importGroups($ldapParams, $ldapImportParams);
$this->assertEquals(1, $out->getSyncedObjects());
$this->assertEquals(100, $out->getTotalObjects());
$this->assertEquals(2, $out->getTotalObjects());
}
/**
@@ -410,13 +422,17 @@ class LdapImportTest extends UnitaryTestCase
self::$faker->password
);
$ldapImportParams = new LdapImportParamsDto(100, 200, 'test_login', 'test_user', 'test_group', 'test_filter');
$entry = [[]];
$entry = [
[
'test' => ['test']
]
];
$this->ldapActionsService
->expects($this->once())
->method('getObjects')
->with('test_filter')
->willReturn(new LdapResults(100, new ArrayIterator($entry)));
->willReturn(new LdapResults(new ArrayIterator($entry)));
$this->userGroupService
->expects($this->never())
@@ -425,7 +441,7 @@ class LdapImportTest extends UnitaryTestCase
$out = $this->ldapImport->importGroups($ldapParams, $ldapImportParams);
$this->assertEquals(0, $out->getSyncedObjects());
$this->assertEquals(100, $out->getTotalObjects());
$this->assertEquals(1, $out->getTotalObjects());
$this->assertEquals(0, $out->getErrorObjects());
}
@@ -446,6 +462,9 @@ class LdapImportTest extends UnitaryTestCase
'test_group' => [
'Test Group'
]
],
[
'test' => ['test']
]
];
@@ -453,7 +472,7 @@ class LdapImportTest extends UnitaryTestCase
->expects($this->once())
->method('getObjects')
->with('test_filter')
->willReturn(new LdapResults(100, new ArrayIterator($entry)));
->willReturn(new LdapResults(new ArrayIterator($entry)));
$group = new UserGroup(
[
@@ -471,7 +490,7 @@ class LdapImportTest extends UnitaryTestCase
$out = $this->ldapImport->importGroups($ldapParams, $ldapImportParams);
$this->assertEquals(0, $out->getSyncedObjects());
$this->assertEquals(100, $out->getTotalObjects());
$this->assertEquals(2, $out->getTotalObjects());
$this->assertEquals(1, $out->getErrorObjects());
}
@@ -482,14 +501,13 @@ class LdapImportTest extends UnitaryTestCase
$this->userService = $this->createMock(UserService::class);
$this->userGroupService = $this->createMock(UserGroupService::class);
$this->ldapActionsService = $this->createMock(LdapActionsService::class);
$this->ldapConnection = $this->createMock(LdapConnectionHandler::class);
$this->ldapImport = new LdapImport(
$this->application,
$this->userService,
$this->userGroupService,
$this->ldapActionsService,
$this->ldapConnection
$this->createMock(LdapConnectionHandler::class)
);
}
}

View File

@@ -26,7 +26,7 @@ declare(strict_types=1);
namespace SP\Tests\Modules\Web\Controllers\ConfigLdap;
use Laminas\Ldap\Collection;
use ArrayIterator;
use Laminas\Ldap\Ldap;
use PHPUnit\Framework\Attributes\Group;
use PHPUnit\Framework\Attributes\Test;
@@ -53,24 +53,23 @@ class ConfigLdapTest extends IntegrationTestCase
#[BodyChecker('outputCheckerCheck')]
public function check()
{
$collection = self::createStub(Collection::class);
$collection->method('count')
->willReturn(2);
$collection->method('valid')
->willReturn(true, true, false);
$collection->method('current')
->willReturn([
'count' => self::$faker->randomNumber(2),
'dn' => self::$faker->userName(),
'email' => [self::$faker->email(), self::$faker->email()],
'member' => self::$faker->userName(),
'memberUid' => self::$faker->uuid(),
'uniqueMember' => self::$faker->uuid()
]);
$results = array_map(
fn() => [
'count' => 5,
'dn' => self::$faker->userName(),
'email' => [self::$faker->email(), self::$faker->email()],
'member' => self::$faker->userName(),
'memberUid' => self::$faker->uuid(),
'uniqueMember' => self::$faker->uuid()
],
range(0, 4)
);
$iterator = new ArrayIterator($results);
$ldap = self::createStub(Ldap::class);
$ldap->method('search')
->willReturn($collection);
->willReturn($iterator);
$data = [
'ldap_server' => self::$faker->domainName(),
@@ -92,6 +91,104 @@ class ConfigLdapTest extends IntegrationTestCase
IntegrationTestCase::runApp($container);
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws Exception
*/
#[Test]
#[BodyChecker('outputCheckerCheckImport')]
public function checkImport()
{
$results = array_map(
fn() => [
'count' => 5,
'dn' => self::$faker->userName(),
'email' => [self::$faker->email(), self::$faker->email()],
'member' => self::$faker->userName(),
'memberUid' => self::$faker->uuid(),
'uniqueMember' => self::$faker->uuid()
],
range(0, 4)
);
$iterator = new ArrayIterator($results);
$ldap = self::createStub(Ldap::class);
$ldap->method('search')
->willReturn($iterator);
$data = [
'ldap_server' => self::$faker->domainName(),
'ldap_server_type' => 1,
'ldap_binduser' => self::$faker->userName(),
'ldap_bindpass' => self::$faker->password(),
'ldap_base' => 'dc=test',
'ldap_group' => 'cn=group,dc=test',
'ldap_tls_enabled' => self::$faker->boolean(),
'ldap_import_groups' => true,
'ldap_import_filter' => ''
];
$container = $this->buildContainer(
IntegrationTestCase::buildRequest('post', 'index.php', ['r' => 'configLdap/checkImport'], $data),
[
Ldap::class => $ldap
]
);
IntegrationTestCase::runApp($container);
}
/**
* @throws ContainerExceptionInterface
* @throws NotFoundExceptionInterface
* @throws Exception
*/
#[Test]
#[BodyChecker('outputCheckerCheckImportWithFilter')]
public function checkImportWithFilter()
{
$results = array_map(
fn() => [
'count' => 5,
'dn' => self::$faker->userName(),
'email' => [self::$faker->email(), self::$faker->email()],
'member' => self::$faker->userName(),
'memberUid' => self::$faker->uuid(),
'uniqueMember' => self::$faker->uuid()
],
range(0, 4)
);
$iterator = new ArrayIterator($results);
$ldap = self::createStub(Ldap::class);
$ldap->method('search')
->willReturn($iterator);
$data = [
'ldap_server' => self::$faker->domainName(),
'ldap_server_type' => 1,
'ldap_binduser' => self::$faker->userName(),
'ldap_bindpass' => self::$faker->password(),
'ldap_base' => 'dc=test',
'ldap_group' => 'cn=group,dc=test',
'ldap_tls_enabled' => self::$faker->boolean(),
'ldap_import_groups' => true,
'ldap_import_filter' => 'a_filter'
];
$container = $this->buildContainer(
IntegrationTestCase::buildRequest('post', 'index.php', ['r' => 'configLdap/checkImport'], $data),
[
Ldap::class => $ldap
]
);
IntegrationTestCase::runApp($container);
}
/**
* @param string $output
* @return void
@@ -107,8 +204,53 @@ class ConfigLdapTest extends IntegrationTestCase
self::assertCount(1, $filter);
self::assertEquals('OK', $json->status);
self::assertEquals(['LDAP connection OK', 'Objects found: 1'], $json->description);
self::assertEquals(['LDAP connection OK', 'Objects found: 5'], $json->description);
self::assertCount(5, $json->data->items[0]->items);
self::assertNotEmpty($json->data->items[0]->items[0]);
self::assertEquals('person', $json->data->items[0]->type);
}
/**
* @param string $output
* @return void
*/
private function outputCheckerCheckImport(string $output): void
{
$json = json_decode($output);
$crawler = new Crawler($json->data->template);
$filter = $crawler->filterXPath(
'//div[@id="box-popup"]/table[@class="popup-data"]/tbody/tr[@id="ldap-results"]'
)->extract(['id']);
self::assertCount(1, $filter);
self::assertEquals('OK', $json->status);
self::assertEquals(['LDAP connection OK', 'Objects found: 10'], $json->description);
self::assertCount(5, $json->data->items[0]->items);
self::assertNotEmpty($json->data->items[0]->items[0]);
self::assertEquals('person', $json->data->items[0]->type);
self::assertCount(5, $json->data->items[1]->items);
self::assertNotEmpty($json->data->items[1]->items[0]);
self::assertEquals('group', $json->data->items[1]->type);
}
/**
* @param string $output
* @return void
*/
private function outputCheckerCheckImportWithFilter(string $output): void
{
$json = json_decode($output);
$crawler = new Crawler($json->data->template);
$filter = $crawler->filterXPath(
'//div[@id="box-popup"]/table[@class="popup-data"]/tbody/tr[@id="ldap-results"]'
)->extract(['id']);
self::assertCount(1, $filter);
self::assertEquals('OK', $json->status);
self::assertEquals(['LDAP connection OK', 'Objects found: 5'], $json->description);
self::assertCount(5, $json->data->items[0]->items);
self::assertNotEmpty($json->data->items[0]->items[0]);
}
}