fix LDAP install for systems without ldap extension (#846)

This commit is contained in:
Kevin Papst
2019-06-11 01:25:49 +02:00
committed by GitHub
parent 0c0e9c2f71
commit 833968a87d
23 changed files with 82 additions and 326 deletions

View File

@@ -21,11 +21,6 @@ class LdapConfiguration
$this->settings = $settings;
}
public function isActivated(): bool
{
return (bool) $this->settings['active'];
}
public function getRoleParameters(): array
{
return (array) $this->settings['role'];

View File

@@ -494,7 +494,6 @@ class Configuration implements ConfigurationInterface
$node
->addDefaultsIfNotSet()
->children()
->booleanNode('active')->defaultFalse()->end()
->arrayNode('connection')
->addDefaultsIfNotSet()
->children()
@@ -591,19 +590,13 @@ class Configuration implements ConfigurationInterface
->end()
->validate()
->ifTrue(static function ($v) {
return $v['active'] && !extension_loaded('ldap');
return null !== $v['connection']['host'] && !extension_loaded('ldap');
})
->thenInvalid('LDAP is activated, but the LDAP PHP extension is not loaded.')
->end()
->validate()
->ifTrue(static function ($v) {
return $v['active'] && empty($v['connection']['host']);
})
->thenInvalid('The "ldap.connection.host" config must be set if LDAP is activated.')
->end()
->validate()
->ifTrue(static function ($v) {
return $v['active'] && empty($v['user']['baseDn']);
return null !== $v['connection']['host'] && empty($v['user']['baseDn']);
})
->thenInvalid('The "ldap.user.baseDn" config must be set if LDAP is activated.')
->end()

View File

@@ -113,7 +113,27 @@ class Kernel extends BaseKernel
$container->setParameter('container.autowiring.strict_mode', true);
$container->setParameter('container.dumper.inline_class_loader', true);
$confDir = $this->getProjectDir() . '/config';
$loader->load($confDir . '/packages/*' . self::CONFIG_EXTS, 'glob');
// if you want to prepend any config, you can do it here
$loader->load($confDir . '/packages/local_before' . self::CONFIG_EXTS, 'glob');
// using this one instead of $loader->load($confDir . '/packages/*' . self::CONFIG_EXTS, 'glob');
// to get rid of the local.yaml from the list, we load it afterwards explicit
$finder = (new Finder())
->files()
->in([$confDir . '/packages/'])
->name('*' . self::CONFIG_EXTS)
->notName('local*' . self::CONFIG_EXTS)
->depth('== 0')
->sortByName()
->followLinks()
;
/** @var SplFileInfo $file */
foreach ($finder as $file) {
$loader->load($file->getPathname());
}
if (is_dir($confDir . '/packages/' . $this->environment)) {
$loader->load($confDir . '/packages/' . $this->environment . '/**/*' . self::CONFIG_EXTS, 'glob');
}

View File

@@ -12,7 +12,6 @@ namespace App\Ldap;
use App\Configuration\LdapConfiguration;
use App\Entity\User;
use Symfony\Component\Security\Core\Authentication\Provider\UserAuthenticationProvider;
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
use Symfony\Component\Security\Core\Exception\AuthenticationServiceException;
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
@@ -49,15 +48,6 @@ class LdapAuthenticationProvider extends UserAuthenticationProvider
$this->userProvider = $userProvider;
}
public function supports(TokenInterface $token)
{
if (!$this->config->isActivated()) {
return false;
}
return parent::supports($token);
}
protected function retrieveUser($username, UsernamePasswordToken $token)
{
$user = $token->getUser();

View File

@@ -9,6 +9,7 @@
namespace App\Ldap;
use App\Configuration\LdapConfiguration;
use Psr\Log\LoggerInterface;
use Symfony\Component\Security\Core\User\UserInterface;
use Zend\Ldap\Exception\LdapException;
@@ -22,20 +23,22 @@ class LdapDriver
/**
* @var Ldap
*/
private $driver;
protected $driver;
/**
* @var LoggerInterface
*/
private $logger;
/**
* @param Ldap $driver Initialized Zend::Ldap Object
* @param LoggerInterface $logger optional logger for write debug messages
*/
public function __construct(Ldap $driver, LoggerInterface $logger = null)
public function __construct(LdapConfiguration $config, LoggerInterface $logger = null)
{
$this->driver = $driver;
if (!class_exists('Zend\Ldap\Ldap')) {
throw new \Exception(
'Zend\Ldap\Ldap is missing, install it with "composer require zendframework/zend-ldap" ' .
'or deactivate LDAP, see https://www.kimai.org/documentation/ldap.html'
);
}
$this->driver = new Ldap($config->getConnectionParameters());
$this->logger = $logger;
}
@@ -64,7 +67,7 @@ class LdapDriver
// searchEntries don't return 'count' key as specified by php native function ldap_get_entries()
$entries['count'] = count($entries);
} catch (LdapException $exception) {
$this->zendExceptionHandler($exception);
$this->ldapExceptionHandler($exception);
throw new LdapDriverException('An error occurred with the search operation.');
}
@@ -85,16 +88,13 @@ class LdapDriver
return $bind instanceof Ldap;
} catch (LdapException $exception) {
$this->zendExceptionHandler($exception, $password);
$this->ldapExceptionHandler($exception, $password);
}
return false;
}
/**
* Treat a Zend Ldap Exception.
*/
protected function zendExceptionHandler(LdapException $exception, string $password = null): void
protected function ldapExceptionHandler(LdapException $exception, string $password = null): void
{
$sanitizedException = null !== $password ? new SanitizingException($exception, $password) : $exception;

View File

@@ -9,7 +9,6 @@
namespace App\Ldap;
use App\Configuration\LdapConfiguration;
use App\Entity\User;
use Psr\Log\LoggerInterface;
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
@@ -37,24 +36,14 @@ class LdapUserProvider implements UserProviderInterface
*/
protected $logger;
public function __construct(LdapManager $ldapManager, LdapConfiguration $config, LoggerInterface $logger = null)
public function __construct(LdapManager $ldapManager, LoggerInterface $logger = null)
{
$this->ldapManager = $ldapManager;
$this->logger = $logger;
$this->activated = $config->isActivated();
}
public function loadUserByUsername($username)
{
// this method is called at least for unknown user, no matter what supportsClass() returns,
// so we have to check if LDAP is activated here as well
if (!$this->activated) {
$ex = new UsernameNotFoundException(sprintf('LDAP is deactivated, user "%s" not searched', $username));
$ex->setUsername($username);
throw $ex;
}
$user = $this->ldapManager->findUserByUsername($username);
if (empty($user)) {
@@ -99,10 +88,6 @@ class LdapUserProvider implements UserProviderInterface
public function supportsClass($class)
{
if (!$this->activated) {
return false;
}
return $class === User::class || $class === 'App\Entity\User';
}

View File

@@ -1,29 +0,0 @@
<?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\Ldap;
use App\Configuration\LdapConfiguration;
use Zend\Ldap\Ldap;
/**
* Overwritten to prevent errors in case:
* LDAP is deactivated and LDAP extension is not loaded
*/
class ZendLdap extends Ldap
{
public function __construct(LdapConfiguration $config)
{
if (!$config->isActivated()) {
return;
}
parent::__construct($config->getConnectionParameters());
}
}