2019-06-07 20:48:39 +00:00
|
|
|
<?php
|
|
|
|
|
|
|
|
/*
|
|
|
|
* This file is part of the Kimai time-tracking app.
|
|
|
|
*
|
|
|
|
* For the full copyright and license information, please view the LICENSE
|
|
|
|
* file that was distributed with this source code.
|
|
|
|
*/
|
|
|
|
|
|
|
|
namespace App\Tests\Ldap;
|
|
|
|
|
|
|
|
use App\Configuration\LdapConfiguration;
|
|
|
|
use App\Entity\User;
|
|
|
|
use App\Ldap\LdapDriver;
|
2019-10-24 15:35:05 +00:00
|
|
|
use App\Ldap\LdapDriverException;
|
2019-06-07 20:48:39 +00:00
|
|
|
use App\Ldap\LdapManager;
|
|
|
|
use App\Ldap\LdapUserHydrator;
|
2019-11-10 17:53:56 +00:00
|
|
|
use App\Tests\Mocks\Security\RoleServiceFactory;
|
2019-06-07 20:48:39 +00:00
|
|
|
use PHPUnit\Framework\TestCase;
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @covers \App\Ldap\LdapManager
|
|
|
|
*/
|
|
|
|
class LdapManagerTest extends TestCase
|
|
|
|
{
|
|
|
|
protected function getLdapManager(LdapDriver $driver, $roleConfig = null)
|
|
|
|
{
|
|
|
|
if (null === $roleConfig) {
|
|
|
|
$roleConfig = [
|
|
|
|
'baseDn' => 'ou=groups, dc=kimai, dc=org',
|
|
|
|
'nameAttribute' => 'cn',
|
|
|
|
'userDnAttribute' => 'member',
|
|
|
|
'groups' => [
|
|
|
|
['ldap_value' => 'group1', 'role' => 'ROLE_TEAMLEAD'],
|
|
|
|
['ldap_value' => 'group2', 'role' => 'ROLE_ADMIN'],
|
|
|
|
['ldap_value' => 'group3', 'role' => 'ROLE_CUSTOMER'], // not existing!
|
|
|
|
['ldap_value' => 'group4', 'role' => 'ROLE_SUPER_ADMIN'],
|
|
|
|
],
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
$config = new LdapConfiguration([
|
|
|
|
'user' => [
|
|
|
|
'attributes' => [],
|
|
|
|
'filter' => '(&(objectClass=inetOrgPerson))',
|
|
|
|
'usernameAttribute' => 'uid',
|
2019-06-23 10:38:11 +00:00
|
|
|
'attributesFilter' => '(objectClass=*)',
|
2019-06-07 20:48:39 +00:00
|
|
|
'baseDn' => 'ou=users, dc=kimai, dc=org',
|
|
|
|
],
|
|
|
|
'role' => $roleConfig,
|
|
|
|
]);
|
|
|
|
|
2019-11-10 17:53:56 +00:00
|
|
|
$roles = [
|
2019-06-07 20:48:39 +00:00
|
|
|
'ROLE_TEAMLEAD' => ['ROLE_USER'],
|
|
|
|
'ROLE_ADMIN' => ['ROLE_TEAMLEAD'],
|
|
|
|
'ROLE_SUPER_ADMIN' => ['ROLE_ADMIN']
|
2019-11-10 17:53:56 +00:00
|
|
|
];
|
|
|
|
|
|
|
|
$hydrator = new LdapUserHydrator($config, (new RoleServiceFactory($this))->create($roles));
|
2019-06-07 20:48:39 +00:00
|
|
|
|
|
|
|
return new LdapManager($driver, $hydrator, $config);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testFindUserByUsernameOnZeroResults()
|
|
|
|
{
|
|
|
|
$expected = [
|
|
|
|
'count' => 0
|
|
|
|
];
|
|
|
|
|
2019-11-08 15:10:38 +00:00
|
|
|
$driver = $this->getMockBuilder(LdapDriver::class)->disableOriginalConstructor()->onlyMethods(['search'])->getMock();
|
2019-06-07 20:48:39 +00:00
|
|
|
$driver->expects($this->once())->method('search')->willReturnCallback(function ($baseDn, $filter) use ($expected) {
|
|
|
|
self::assertEquals('ou=users, dc=kimai, dc=org', $baseDn);
|
|
|
|
self::assertEquals('(&(&(objectClass=inetOrgPerson))(uid=foo))', $filter);
|
|
|
|
|
|
|
|
return $expected;
|
|
|
|
});
|
|
|
|
|
|
|
|
$sut = $this->getLdapManager($driver);
|
|
|
|
$actual = $sut->findUserByUsername('foo');
|
|
|
|
self::assertNull($actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testFindUserByUsernameOnMultiResults()
|
|
|
|
{
|
2019-10-24 15:35:05 +00:00
|
|
|
$this->expectException(LdapDriverException::class);
|
|
|
|
$this->expectExceptionMessage('This search must only return a single user');
|
|
|
|
|
2019-06-07 20:48:39 +00:00
|
|
|
$expected = [
|
|
|
|
'count' => 3
|
|
|
|
];
|
|
|
|
|
2019-11-08 15:10:38 +00:00
|
|
|
$driver = $this->getMockBuilder(LdapDriver::class)->disableOriginalConstructor()->onlyMethods(['search'])->getMock();
|
2019-06-07 20:48:39 +00:00
|
|
|
$driver->expects($this->once())->method('search')->willReturnCallback(function ($baseDn, $filter) use ($expected) {
|
|
|
|
self::assertEquals('ou=users, dc=kimai, dc=org', $baseDn);
|
|
|
|
self::assertEquals('(&(&(objectClass=inetOrgPerson))(uid=foo))', $filter);
|
|
|
|
|
|
|
|
return $expected;
|
|
|
|
});
|
|
|
|
|
|
|
|
$sut = $this->getLdapManager($driver);
|
|
|
|
$sut->findUserByUsername('foo');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testFindUserByUsernameOnValidResult()
|
|
|
|
{
|
|
|
|
$expected = [
|
|
|
|
0 => ['dn' => 'foo'],
|
|
|
|
'count' => 1,
|
|
|
|
];
|
|
|
|
|
2019-11-08 15:10:38 +00:00
|
|
|
$driver = $this->getMockBuilder(LdapDriver::class)->disableOriginalConstructor()->onlyMethods(['search'])->getMock();
|
2019-06-07 20:48:39 +00:00
|
|
|
$driver->expects($this->once())->method('search')->willReturnCallback(function ($baseDn, $filter) use ($expected) {
|
|
|
|
self::assertEquals('ou=users, dc=kimai, dc=org', $baseDn);
|
|
|
|
self::assertEquals('(&(&(objectClass=inetOrgPerson))(uid=foo))', $filter);
|
|
|
|
|
|
|
|
return $expected;
|
|
|
|
});
|
|
|
|
|
|
|
|
$sut = $this->getLdapManager($driver);
|
|
|
|
$actual = $sut->findUserByUsername('foo');
|
|
|
|
self::assertInstanceOf(User::class, $actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testFindUserByOnZeroResults()
|
|
|
|
{
|
|
|
|
$expected = [
|
|
|
|
'count' => 0
|
|
|
|
];
|
|
|
|
|
2019-11-08 15:10:38 +00:00
|
|
|
$driver = $this->getMockBuilder(LdapDriver::class)->disableOriginalConstructor()->onlyMethods(['search'])->getMock();
|
2019-06-07 20:48:39 +00:00
|
|
|
$driver->expects($this->once())->method('search')->willReturnCallback(function ($baseDn, $filter) use ($expected) {
|
|
|
|
self::assertEquals('ou=users, dc=kimai, dc=org', $baseDn);
|
|
|
|
self::assertEquals('(&(&(objectClass=inetOrgPerson))(uid=foo))', $filter);
|
|
|
|
|
|
|
|
return $expected;
|
|
|
|
});
|
|
|
|
|
|
|
|
$sut = $this->getLdapManager($driver);
|
|
|
|
$actual = $sut->findUserBy(['uid' => 'foo']);
|
|
|
|
self::assertNull($actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testFindUserByOnMultiResults()
|
|
|
|
{
|
2019-10-24 15:35:05 +00:00
|
|
|
$this->expectException(LdapDriverException::class);
|
|
|
|
$this->expectExceptionMessage('This search must only return a single user');
|
|
|
|
|
2019-06-07 20:48:39 +00:00
|
|
|
$expected = [
|
|
|
|
'count' => 3
|
|
|
|
];
|
|
|
|
|
2019-11-08 15:10:38 +00:00
|
|
|
$driver = $this->getMockBuilder(LdapDriver::class)->disableOriginalConstructor()->onlyMethods(['search'])->getMock();
|
2019-06-07 20:48:39 +00:00
|
|
|
$driver->expects($this->once())->method('search')->willReturnCallback(function ($baseDn, $filter) use ($expected) {
|
|
|
|
self::assertEquals('ou=users, dc=kimai, dc=org', $baseDn);
|
|
|
|
self::assertEquals('(&(&(objectClass=inetOrgPerson))(uid=foo))', $filter);
|
|
|
|
|
|
|
|
return $expected;
|
|
|
|
});
|
|
|
|
|
|
|
|
$sut = $this->getLdapManager($driver);
|
|
|
|
$sut->findUserBy(['uid' => 'foo']);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testFindUserByOnValidResult()
|
|
|
|
{
|
|
|
|
$expected = [
|
|
|
|
0 => ['dn' => 'foo'],
|
|
|
|
'count' => 1,
|
|
|
|
];
|
|
|
|
|
2019-11-08 15:10:38 +00:00
|
|
|
$driver = $this->getMockBuilder(LdapDriver::class)->disableOriginalConstructor()->onlyMethods(['search'])->getMock();
|
2019-06-07 20:48:39 +00:00
|
|
|
$driver->expects($this->once())->method('search')->willReturnCallback(function ($baseDn, $filter) use ($expected) {
|
|
|
|
self::assertEquals('ou=users, dc=kimai, dc=org', $baseDn);
|
|
|
|
self::assertEquals('(&(&(objectClass=inetOrgPerson))(träl=alß#\\\aa=XY\5cZ0)(test=fu=n))', $filter);
|
|
|
|
|
|
|
|
return $expected;
|
|
|
|
});
|
|
|
|
|
|
|
|
$sut = $this->getLdapManager($driver);
|
|
|
|
$actual = $sut->findUserBy(['träl=alß#\\\aa' => 'XY\Z0', 'test' => 'fu=n']);
|
|
|
|
self::assertInstanceOf(User::class, $actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testBind()
|
|
|
|
{
|
|
|
|
$user = (new User())->setUsername('foobar');
|
|
|
|
|
2019-11-08 15:10:38 +00:00
|
|
|
$driver = $this->getMockBuilder(LdapDriver::class)->disableOriginalConstructor()->onlyMethods(['bind'])->getMock();
|
2019-06-07 20:48:39 +00:00
|
|
|
$driver->expects($this->once())->method('bind')->willReturnCallback(function ($bindUser, $password) use ($user) {
|
|
|
|
self::assertSame($user, $bindUser);
|
|
|
|
self::assertEquals('a-very-secret-secret', $password);
|
|
|
|
|
|
|
|
return true;
|
|
|
|
});
|
|
|
|
|
|
|
|
$sut = $this->getLdapManager($driver);
|
|
|
|
$actual = $sut->bind($user, 'a-very-secret-secret');
|
|
|
|
self::assertTrue($actual);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testUpdateUserOnZeroResults()
|
|
|
|
{
|
|
|
|
$user = (new User())->setUsername('foobar');
|
|
|
|
$user->setPreferenceValue('ldap.dn', 'fooooooooooo');
|
|
|
|
$expected = [
|
|
|
|
[
|
|
|
|
0 => ['dn' => 'blub'],
|
|
|
|
'count' => 1,
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'count' => 0,
|
|
|
|
],
|
|
|
|
];
|
|
|
|
|
2019-11-08 15:10:38 +00:00
|
|
|
$driver = $this->getMockBuilder(LdapDriver::class)->disableOriginalConstructor()->onlyMethods(['search'])->getMock();
|
2019-06-07 20:48:39 +00:00
|
|
|
$driver->expects($this->exactly(2))->method('search')->willReturnCallback(function ($baseDn, $filter) use ($expected) {
|
|
|
|
if ($baseDn === 'ou=users, dc=kimai, dc=org') {
|
|
|
|
self::assertEquals('(&(&(objectClass=inetOrgPerson))(uid=foobar))', $filter);
|
|
|
|
|
|
|
|
return $expected[0];
|
|
|
|
} elseif ($baseDn === 'blub') {
|
|
|
|
self::assertEquals('(objectClass=*)', $filter);
|
|
|
|
|
|
|
|
return $expected[1];
|
|
|
|
}
|
|
|
|
$this->fail(sprintf('Unexpected search with baseDn %s', $baseDn));
|
|
|
|
});
|
|
|
|
|
|
|
|
$sut = $this->getLdapManager($driver);
|
|
|
|
|
|
|
|
$userOrig = clone $user;
|
|
|
|
$sut->updateUser($user);
|
|
|
|
self::assertEquals($userOrig, $user);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testUpdateUserOnMultiResults()
|
|
|
|
{
|
2019-10-24 15:35:05 +00:00
|
|
|
$this->expectException(LdapDriverException::class);
|
|
|
|
$this->expectExceptionMessage('This search must only return a single user');
|
|
|
|
|
2019-06-07 20:48:39 +00:00
|
|
|
$user = (new User())->setUsername('foobar');
|
|
|
|
$user->setPreferenceValue('ldap.dn', 'xxxxxxx');
|
|
|
|
|
|
|
|
$expected = [
|
|
|
|
[
|
|
|
|
0 => ['dn' => 'blub'],
|
|
|
|
'count' => 1,
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'count' => 3,
|
|
|
|
],
|
|
|
|
];
|
|
|
|
|
2019-11-08 15:10:38 +00:00
|
|
|
$driver = $this->getMockBuilder(LdapDriver::class)->disableOriginalConstructor()->onlyMethods(['search'])->getMock();
|
2019-06-07 20:48:39 +00:00
|
|
|
$driver->expects($this->exactly(2))->method('search')->willReturnCallback(function ($baseDn, $filter) use ($expected) {
|
|
|
|
if ($baseDn === 'ou=users, dc=kimai, dc=org') {
|
|
|
|
self::assertEquals('(&(&(objectClass=inetOrgPerson))(uid=foobar))', $filter);
|
|
|
|
|
|
|
|
return $expected[0];
|
|
|
|
} elseif ($baseDn === 'blub') {
|
|
|
|
self::assertEquals('(objectClass=*)', $filter);
|
|
|
|
|
|
|
|
return $expected[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->fail(sprintf('Unexpected search with baseDn %s', $baseDn));
|
|
|
|
});
|
|
|
|
|
|
|
|
$sut = $this->getLdapManager($driver);
|
|
|
|
$sut->updateUser($user);
|
|
|
|
}
|
|
|
|
|
|
|
|
public function testUpdateUserOnValidResultWithEmptyRoleBaseDn()
|
|
|
|
{
|
|
|
|
$user = (new User())->setUsername('foobar');
|
|
|
|
$user->setPreferenceValue('ldap.dn', 'sssssss');
|
|
|
|
|
|
|
|
$expected = [
|
|
|
|
[
|
|
|
|
0 => ['dn' => 'blub'],
|
|
|
|
'count' => 1,
|
|
|
|
],
|
|
|
|
[
|
|
|
|
0 => ['dn' => 'blub-updated'],
|
|
|
|
'count' => 1,
|
|
|
|
],
|
|
|
|
];
|
|
|
|
|
2019-11-08 15:10:38 +00:00
|
|
|
$driver = $this->getMockBuilder(LdapDriver::class)->disableOriginalConstructor()->onlyMethods(['search'])->getMock();
|
2019-06-07 20:48:39 +00:00
|
|
|
$driver->expects($this->exactly(2))->method('search')->willReturnCallback(function ($baseDn, $filter) use ($expected) {
|
|
|
|
if ($baseDn === 'ou=users, dc=kimai, dc=org') {
|
|
|
|
self::assertEquals('(&(&(objectClass=inetOrgPerson))(uid=foobar))', $filter);
|
|
|
|
|
|
|
|
return $expected[0];
|
|
|
|
} elseif ($baseDn === 'blub') {
|
|
|
|
self::assertEquals('(objectClass=*)', $filter);
|
|
|
|
|
|
|
|
return $expected[1];
|
|
|
|
}
|
|
|
|
|
|
|
|
$this->fail(sprintf('Unexpected search with baseDn %s', $baseDn));
|
|
|
|
});
|
|
|
|
|
|
|
|
$sut = $this->getLdapManager($driver, [
|
|
|
|
'baseDn' => null,
|
|
|
|
'nameAttribute' => 'cn',
|
|
|
|
'userDnAttribute' => 'member',
|
|
|
|
'groups' => [
|
|
|
|
['ldap_value' => 'group1', 'role' => 'ROLE_TEAMLEAD'],
|
|
|
|
['ldap_value' => 'group2', 'role' => 'ROLE_ADMIN'],
|
|
|
|
['ldap_value' => 'group3', 'role' => 'ROLE_CUSTOMER'], // not existing!
|
|
|
|
['ldap_value' => 'group4', 'role' => 'ROLE_SUPER_ADMIN'],
|
|
|
|
],
|
|
|
|
]);
|
|
|
|
|
|
|
|
$userOrig = clone $user;
|
|
|
|
$sut->updateUser($user);
|
2020-01-31 18:47:34 +00:00
|
|
|
self::assertEquals($userOrig->setEmail('foobar')->setAuth(User::AUTH_LDAP), $user);
|
2019-06-07 20:48:39 +00:00
|
|
|
self::assertEquals($user->getPreferenceValue('ldap.dn'), 'blub-updated');
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getValidConfigsTestData()
|
|
|
|
{
|
|
|
|
return [
|
|
|
|
[
|
|
|
|
[
|
|
|
|
0 => [
|
|
|
|
'dn' => 'blub',
|
|
|
|
'uid' => ['Karl-Heinz'],
|
|
|
|
// just some rubbish data
|
|
|
|
'blub' => ['dfsdfsdf'],
|
|
|
|
'foo' => ['count' => 1, 'bar'],
|
|
|
|
'bar' => ['count' => 1, 'foo', 'xxx'],
|
|
|
|
'xxxxxxxx' => ['https://www.example.com'],
|
|
|
|
'blub1' => ['dfsdfsdf'],
|
|
|
|
],
|
|
|
|
'count' => 1,
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'baseDn' => 'ou=groups, dc=kimai, dc=org',
|
|
|
|
'nameAttribute' => 'cn',
|
|
|
|
'usernameAttribute' => 'cn', // test that "cn" is not set and fallback to "dn" happens
|
|
|
|
'userDnAttribute' => 'member',
|
|
|
|
'groups' => [
|
|
|
|
['ldap_value' => 'group1', 'role' => 'ROLE_TEAMLEAD'],
|
|
|
|
['ldap_value' => 'group2', 'role' => 'ROLE_ADMIN'],
|
|
|
|
['ldap_value' => 'group3', 'role' => 'ROLE_CUSTOMER'], // not existing!
|
|
|
|
['ldap_value' => 'group4', 'role' => 'ROLE_SUPER_ADMIN'],
|
|
|
|
],
|
|
|
|
],
|
|
|
|
'(&(member=blub))'
|
|
|
|
],
|
|
|
|
[
|
|
|
|
[
|
|
|
|
0 => [
|
|
|
|
'dn' => 'blub',
|
|
|
|
'uid' => ['Karl-Heinz'],
|
|
|
|
// just some rubbish data
|
2020-03-06 15:16:31 +00:00
|
|
|
'blub' => ['foo'],
|
2019-06-07 20:48:39 +00:00
|
|
|
'foo' => ['count' => 1, 'bar'],
|
|
|
|
'bar' => ['count' => 1, 'foo', 'xxx'],
|
|
|
|
'xxxxxxxx' => ['https://www.example.com'],
|
2020-03-06 15:16:31 +00:00
|
|
|
'blub1' => ['foo(bar)'],
|
2019-06-07 20:48:39 +00:00
|
|
|
],
|
|
|
|
'count' => 1,
|
|
|
|
],
|
|
|
|
[
|
|
|
|
'baseDn' => 'ou=groups, dc=kimai, dc=org',
|
|
|
|
'nameAttribute' => 'cn',
|
|
|
|
'usernameAttribute' => 'blub1',
|
|
|
|
'userDnAttribute' => 'memberuid',
|
|
|
|
'groups' => [
|
|
|
|
['ldap_value' => 'group1', 'role' => 'ROLE_TEAMLEAD'],
|
|
|
|
['ldap_value' => 'group2', 'role' => 'ROLE_ADMIN'],
|
|
|
|
['ldap_value' => 'group3', 'role' => 'ROLE_CUSTOMER'], // not existing!
|
|
|
|
['ldap_value' => 'group4', 'role' => 'ROLE_SUPER_ADMIN'],
|
|
|
|
],
|
|
|
|
],
|
2020-03-06 15:16:31 +00:00
|
|
|
'(&(memberuid=foo\28bar\29))'
|
2019-06-07 20:48:39 +00:00
|
|
|
],
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @dataProvider getValidConfigsTestData
|
|
|
|
*/
|
|
|
|
public function testUpdateUserOnValidResultWithRolesResult(array $expectedUsers, array $groupConfig, string $expectedGroupQuery)
|
|
|
|
{
|
|
|
|
$expected = [
|
|
|
|
0 => ['dn' => 'blub'],
|
|
|
|
'count' => 1,
|
|
|
|
];
|
|
|
|
|
|
|
|
$expectedGroups = [
|
|
|
|
// ROLE_TEAMLEAD
|
|
|
|
0 => [
|
|
|
|
'cn' => [0 => 'group1'],
|
|
|
|
'member' => [0 => 'uid=user1,ou=users,dc=kimai,dc=org', 1 => 'uid=user2,ou=users,dc=kimai,dc=org'],
|
|
|
|
],
|
|
|
|
// ROLE_ADMIN
|
|
|
|
1 => [
|
|
|
|
'cn' => [0 => 'admin'],
|
|
|
|
'member' => [0 => 'uid=user2,ou=users,dc=kimai,dc=org', 1 => 'uid=user3,ou=users,dc=kimai,dc=org'],
|
|
|
|
],
|
|
|
|
// will be ignored: unknown group
|
|
|
|
2 => [
|
|
|
|
'cn' => [0 => 'kimai_admin'],
|
|
|
|
'member' => [0 => 'uid=user2,ou=users,dc=kimai,dc=org', 1 => 'uid=user3,ou=users,dc=kimai,dc=org'],
|
|
|
|
],
|
|
|
|
// will be ignored: unknown group
|
|
|
|
3 => [
|
|
|
|
'cn' => [0 => 'group3'],
|
|
|
|
'member' => [0 => 'uid=user2,ou=users,dc=kimai,dc=org', 1 => 'uid=user3,ou=users,dc=kimai,dc=org'],
|
|
|
|
],
|
|
|
|
// will be ignored: the counter below does not announce this group!
|
|
|
|
4 => [
|
|
|
|
'cn' => [0 => 'group4'],
|
|
|
|
'member' => [0 => 'uid=user2,ou=users,dc=kimai,dc=org', 1 => 'uid=user3,ou=users,dc=kimai,dc=org'],
|
|
|
|
],
|
|
|
|
'count' => 4
|
|
|
|
];
|
|
|
|
|
2019-11-08 15:10:38 +00:00
|
|
|
$driver = $this->getMockBuilder(LdapDriver::class)->disableOriginalConstructor()->onlyMethods(['search'])->getMock();
|
2019-06-07 20:48:39 +00:00
|
|
|
$driver->expects($this->exactly(3))->method('search')->willReturnCallback(function ($baseDn, $filter, $attributes) use ($expectedUsers, $expectedGroups, $expectedGroupQuery, $expected) {
|
|
|
|
if ($baseDn === 'ou=users, dc=kimai, dc=org') {
|
|
|
|
self::assertEquals('(&(&(objectClass=inetOrgPerson))(uid=Karl-Heinz))', $filter);
|
|
|
|
|
|
|
|
return $expected;
|
|
|
|
} elseif ($baseDn === 'blub') {
|
|
|
|
// user attributes search
|
|
|
|
self::assertEquals('(objectClass=*)', $filter);
|
|
|
|
|
|
|
|
return $expectedUsers;
|
|
|
|
} elseif ($baseDn === 'ou=groups, dc=kimai, dc=org') {
|
|
|
|
// roles search
|
|
|
|
self::assertEquals($expectedGroupQuery, $filter);
|
|
|
|
self::assertEquals([0 => 'cn'], $attributes);
|
|
|
|
|
|
|
|
return $expectedGroups;
|
|
|
|
}
|
|
|
|
$this->fail(sprintf('Unexpected search with baseDn %s', $baseDn));
|
|
|
|
});
|
|
|
|
|
|
|
|
$sut = $this->getLdapManager($driver, $groupConfig);
|
|
|
|
|
|
|
|
$user = (new User())->setUsername('Karl-Heinz');
|
|
|
|
$user->setPreferenceValue('ldap.dn', 'blub');
|
|
|
|
$userOrig = clone $user;
|
2020-01-31 18:47:34 +00:00
|
|
|
$userOrig->setEmail('Karl-Heinz')->setRoles(['ROLE_TEAMLEAD', 'ROLE_ADMIN'])->setAuth(User::AUTH_LDAP);
|
2019-06-07 20:48:39 +00:00
|
|
|
|
|
|
|
$sut->updateUser($user);
|
|
|
|
self::assertEquals($userOrig, $user);
|
|
|
|
self::assertEquals(['ROLE_TEAMLEAD', 'ROLE_ADMIN', 'ROLE_USER'], $user->getRoles());
|
|
|
|
}
|
|
|
|
}
|