|
|
<?php |
|
|
|
|
|
namespace Kanboard\Core\Security; |
|
|
|
|
|
use LogicException; |
|
|
use Kanboard\Core\Base; |
|
|
use Kanboard\Event\AuthFailureEvent; |
|
|
use Kanboard\Event\AuthSuccessEvent; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class AuthenticationManager extends Base |
|
|
{ |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
const EVENT_SUCCESS = 'auth.success'; |
|
|
const EVENT_FAILURE = 'auth.failure'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private $providers = array(); |
|
|
|
|
|
public function reset() |
|
|
{ |
|
|
$this->providers = []; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function register(AuthenticationProviderInterface $provider) |
|
|
{ |
|
|
$this->providers[$provider->getName()] = $provider; |
|
|
return $this; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getProvider($name) |
|
|
{ |
|
|
if (! isset($this->providers[$name])) { |
|
|
throw new LogicException('Authentication provider not found: '.$name); |
|
|
} |
|
|
|
|
|
return $this->providers[$name]; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function checkCurrentSession() |
|
|
{ |
|
|
if ($this->userSession->isLogged()) { |
|
|
foreach ($this->filterProviders('SessionCheckProviderInterface') as $provider) { |
|
|
if (! $provider->isValidSession()) { |
|
|
$this->logger->debug('Invalidate session for '.$this->userSession->getUsername()); |
|
|
session_flush(); |
|
|
$this->preAuthentication(); |
|
|
return false; |
|
|
} |
|
|
} |
|
|
} |
|
|
|
|
|
return true; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function preAuthentication() |
|
|
{ |
|
|
foreach ($this->filterProviders('PreAuthenticationProviderInterface') as $provider) { |
|
|
if ($provider->authenticate() && $this->userProfile->initialize($provider->getUser())) { |
|
|
$this->dispatcher->dispatch(new AuthSuccessEvent($provider->getName()), self::EVENT_SUCCESS); |
|
|
return true; |
|
|
} |
|
|
} |
|
|
|
|
|
return false; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function passwordAuthentication($username, $password, $fireEvent = true) |
|
|
{ |
|
|
foreach ($this->filterProviders('PasswordAuthenticationProviderInterface') as $provider) { |
|
|
$provider->setUsername($username); |
|
|
$provider->setPassword($password); |
|
|
|
|
|
if ($provider->authenticate() && $this->userProfile->initialize($provider->getUser())) { |
|
|
if ($fireEvent) { |
|
|
$this->dispatcher->dispatch(new AuthSuccessEvent($provider->getName()), self::EVENT_SUCCESS); |
|
|
} |
|
|
|
|
|
return true; |
|
|
} |
|
|
} |
|
|
|
|
|
if ($fireEvent) { |
|
|
$this->dispatcher->dispatch(new AuthFailureEvent($username), self::EVENT_FAILURE); |
|
|
} |
|
|
|
|
|
return false; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function oauthAuthentication($name) |
|
|
{ |
|
|
$provider = $this->getProvider($name); |
|
|
|
|
|
if ($provider->authenticate() && $this->userProfile->initialize($provider->getUser())) { |
|
|
$this->dispatcher->dispatch(new AuthSuccessEvent($provider->getName()), self::EVENT_SUCCESS); |
|
|
return true; |
|
|
} |
|
|
|
|
|
$this->dispatcher->dispatch(new AuthFailureEvent, self::EVENT_FAILURE); |
|
|
|
|
|
return false; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
public function getPostAuthenticationProvider() |
|
|
{ |
|
|
$providers = $this->filterProviders('PostAuthenticationProviderInterface'); |
|
|
|
|
|
if (empty($providers)) { |
|
|
throw new LogicException('You must have at least one Post-Authentication Provider configured'); |
|
|
} |
|
|
|
|
|
return array_pop($providers); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
private function filterProviders($interface) |
|
|
{ |
|
|
$interface = '\Kanboard\Core\Security\\'.$interface; |
|
|
|
|
|
return array_filter($this->providers, function(AuthenticationProviderInterface $provider) use ($interface) { |
|
|
return is_a($provider, $interface); |
|
|
}); |
|
|
} |
|
|
} |
|
|
|