[Netfilter][Tests] Add netfilter unit tests and identity provider outage tests

This commit is contained in:
FreddleSpl0it committed 2026-10-27 12:54:45 +01:00
1 parent 1c7c328a2a
commit b7d24881b1
8 files changed
+1046

No files matched your search

@@ -4,11 +4,19 @@ declare(strict_types=1);
namespace Mailcow\Tests\Auth\Service;
use Exception;
use LdapRecord\Auth\BindException;
use LdapRecord\Auth\Guard;
use LdapRecord\Connection;
use LdapRecord\ConnectionException;
use LdapRecord\DetailedError;
use Mailcow\Auth\IdpUnavailable;
use Mailcow\Auth\Service\IdpLoginService;
use Mailcow\Identity\Model\Settings;
use Mailcow\Identity\Service\LinkService;
use Mailcow\MailboxGroup\Service\TemplateService;
use PDOException;
use PHPUnit\Framework\Attributes\DataProvider;
use PHPUnit\Framework\TestCase;
class IdpLoginServiceTest extends TestCase
@@ -64,4 +72,76 @@ class IdpLoginServiceTest extends TestCase
$this->assertNull($login->mappedTemplate(null));
$this->assertNull($login->mappedTemplate(['unknown']));
}
public function testLdapPasswordIsCheckedWithABindAsTheUser(): void
{
$guard = $this->createMock(Guard::class);
$guard->expects($this->once())->method('bind')->with('uid=a,dc=example,dc=org', 'secret');
$guard->expects($this->once())->method('bindAsConfiguredUser');
$this->assertTrue($this->login()->verifyLdapPassword($this->ldap($guard), 'uid=a,dc=example,dc=org', 'secret'));
}
public function testWrongLdapPassword(): void
{
$guard = $this->createMock(Guard::class);
$guard->method('bind')->willThrowException($this->bindError(49, 'Invalid credentials'));
$guard->expects($this->once())->method('bindAsConfiguredUser');
$this->assertFalse($this->login()->verifyLdapPassword($this->ldap($guard), 'uid=a,dc=example,dc=org', 'wrong'));
}
public function testEmptyLdapPasswordNeverBinds(): void
{
$guard = $this->createMock(Guard::class);
$guard->expects($this->never())->method('bind');
$this->assertFalse($this->login()->verifyLdapPassword($this->ldap($guard), 'uid=a,dc=example,dc=org', ''));
}
public static function ldapOutages(): array
{
return [
'server down' => [-1, "Can't contact LDAP server"],
'timeout' => [-5, 'Timed out'],
'busy' => [51, 'Busy'],
'unavailable' => [52, 'Unavailable'],
];
}
#[DataProvider('ldapOutages')]
public function testLdapOutageIsNoWrongPassword(int $code, string $message): void
{
$guard = $this->createMock(Guard::class);
$guard->method('bind')->willThrowException($this->bindError($code, $message));
$this->expectException(IdpUnavailable::class);
$this->login()->verifyLdapPassword($this->ldap($guard), 'uid=a,dc=example,dc=org', 'secret');
}
public function testFailedStartTlsIsAnOutage(): void
{
$guard = $this->createMock(Guard::class);
$guard->method('bind')->willThrowException(new ConnectionException('Unable to connect'));
$this->expectException(IdpUnavailable::class);
$this->login()->verifyLdapPassword($this->ldap($guard), 'uid=a,dc=example,dc=org', 'secret');
}
private function login(): IdpLoginService
{
return new IdpLoginService(Settings::fromArray([]), $this->createMock(LinkService::class), $this->createMock(TemplateService::class));
}
private function ldap(Guard $guard): Connection
{
$ldap = $this->createMock(Connection::class);
$ldap->method('auth')->willReturn($guard);
return $ldap;
}
private function bindError(int $code, string $message): BindException
{
return BindException::withDetailedError(new Exception($message, $code), new DetailedError($code, $message, null));
}
}