Refactor authentication system (#2602)

Make auth configuration available via UI, remove FOSUserBundle and SAML-Bundle dependency
This commit is contained in:
Kevin Papst
2021-06-10 15:34:13 +02:00
committed by GitHub
parent 286b63e2c8
commit 7f20cb045c
155 changed files with 5590 additions and 1802 deletions

View File

@@ -11,12 +11,14 @@ namespace App\Tests\Saml\Logout;
use App\Entity\User;
use App\Saml\Logout\SamlLogoutHandler;
use App\Saml\SamlAuth;
use Hslavich\OneloginSamlBundle\Security\Authentication\Token\SamlToken;
use App\Saml\SamlAuthFactory;
use App\Saml\Token\SamlToken;
use OneLogin\Saml2\Auth;
use OneLogin\Saml2\Error;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
/**
* @covers \App\Saml\Logout\SamlLogoutHandler
@@ -25,7 +27,7 @@ class SamlLogoutHandlerTest extends TestCase
{
public function testLogout()
{
$auth = $this->getMockBuilder(SamlAuth::class)->disableOriginalConstructor()->getMock();
$auth = $this->getMockBuilder(Auth::class)->disableOriginalConstructor()->getMock();
$auth->expects($this->once())->method('processSLO')->willThrowException(new Error('blub'));
$auth->expects($this->once())->method('getSLOurl')->willReturn('');
@@ -33,13 +35,33 @@ class SamlLogoutHandlerTest extends TestCase
$response = new Response();
$token = new SamlToken([]);
$sut = new SamlLogoutHandler($auth);
$factory = $this->getMockBuilder(SamlAuthFactory::class)->disableOriginalConstructor()->getMock();
$factory->expects($this->once())->method('create')->willReturn($auth);
$sut = new SamlLogoutHandler($factory);
$sut->logout($request, $response, $token);
}
public function testLogoutWithWrongTokenWillNotCallMethods()
{
$auth = $this->getMockBuilder(Auth::class)->disableOriginalConstructor()->getMock();
$auth->expects($this->never())->method('processSLO');
$auth->expects($this->never())->method('getSLOurl');
$request = new Request();
$response = new Response();
$token = new UsernamePasswordToken(new User(), [], 'test');
$factory = $this->getMockBuilder(SamlAuthFactory::class)->disableOriginalConstructor()->getMock();
$factory->expects($this->never())->method('create');
$sut = new SamlLogoutHandler($factory);
$sut->logout($request, $response, $token);
}
public function testLogoutWithLogoutUrl()
{
$auth = $this->getMockBuilder(SamlAuth::class)->disableOriginalConstructor()->getMock();
$auth = $this->getMockBuilder(Auth::class)->disableOriginalConstructor()->getMock();
$auth->expects($this->once())->method('processSLO')->willThrowException(new Error('blub'));
$auth->expects($this->once())->method('getSLOurl')->willReturn('/logout');
$auth->expects($this->once())->method('logout')->willReturnCallback(function () {
@@ -56,7 +78,10 @@ class SamlLogoutHandlerTest extends TestCase
$token->setUser((new User())->setUsername('tony'));
$token->setAttribute('sessionIndex', 'foo-bar');
$sut = new SamlLogoutHandler($auth);
$factory = $this->getMockBuilder(SamlAuthFactory::class)->disableOriginalConstructor()->getMock();
$factory->expects($this->once())->method('create')->willReturn($auth);
$sut = new SamlLogoutHandler($factory);
$sut->logout($request, $response, $token);
}
}

View File

@@ -9,13 +9,16 @@
namespace App\Tests\Saml\Provider;
use App\Configuration\SamlConfiguration;
use App\Configuration\SystemConfiguration;
use App\Entity\User;
use App\Repository\UserRepository;
use App\Saml\Provider\SamlProvider;
use App\Saml\SamlTokenFactory;
use App\Saml\Token\SamlToken;
use App\Saml\User\SamlUserFactory;
use App\Security\DoctrineUserProvider;
use Hslavich\OneloginSamlBundle\Security\Authentication\Token\SamlToken;
use App\Tests\Configuration\TestConfigLoader;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Security\Core\Authentication\Token\AnonymousToken;
use Symfony\Component\Security\Core\Authentication\Token\UsernamePasswordToken;
@@ -27,7 +30,7 @@ use Symfony\Component\Security\Core\User\ChainUserProvider;
*/
class SamlProviderTest extends TestCase
{
protected function getSamlProvider($mapping = null, $loadUser = false, ?SamlUserFactory $userFactory = null): SamlProvider
protected function getSamlProvider(array $mapping = null, ?User $user = null, ?SamlUserFactory $userFactory = null): SamlProvider
{
if (null === $mapping) {
$mapping = [
@@ -43,15 +46,21 @@ class SamlProviderTest extends TestCase
}
if (null === $userFactory) {
$userFactory = new SamlUserFactory($mapping);
$configuration = new SystemConfiguration(new TestConfigLoader([]), [
'saml' => $mapping
]);
$userFactory = new SamlUserFactory(new SamlConfiguration($configuration));
}
$systemConfig = new SystemConfiguration(new TestConfigLoader([]), ['saml' => ['activate' => true]]);
$repository = $this->getMockBuilder(UserRepository::class)->disableOriginalConstructor()->getMock();
if ($loadUser !== false) {
$repository->expects($this->once())->method('loadUserByUsername')->willReturn($loadUser);
if ($user !== null) {
$repository->expects($this->once())->method('loadUserByUsername')->willReturn($user);
}
$userProvider = new ChainUserProvider([new DoctrineUserProvider($repository)]);
$provider = new SamlProvider($repository, $userProvider, new SamlTokenFactory(), $userFactory);
$provider = new SamlProvider($repository, $userProvider, new SamlTokenFactory(), $userFactory, $systemConfig);
return $provider;
}

View File

@@ -1,33 +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\Tests\Saml;
use App\Tests\Mocks\Saml\SamlAuthFactory;
use OneLogin\Saml2\Utils;
use PHPUnit\Framework\TestCase;
/**
* @covers \App\Saml\SamlAuth
*/
class SamlAuthTest extends TestCase
{
public function testCreateToken()
{
$previous = Utils::getProxyVars();
self::assertFalse($previous);
$sut = (new SamlAuthFactory($this))->create(null, true);
$current = Utils::getProxyVars();
self::assertTrue($current);
Utils::setProxyVars($previous);
}
}

View File

@@ -11,7 +11,7 @@ namespace App\Tests\Saml;
use App\Entity\User;
use App\Saml\SamlTokenFactory;
use Hslavich\OneloginSamlBundle\Security\Authentication\Token\SamlToken;
use App\Saml\Token\SamlToken;
use PHPUnit\Framework\TestCase;
/**

View File

@@ -10,7 +10,7 @@
namespace App\Tests\Saml\Security;
use App\Saml\Security\SamlAuthenticationSuccessHandler;
use Hslavich\OneloginSamlBundle\Security\Authentication\Token\SamlToken;
use App\Saml\Token\SamlToken;
use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\Security\Http\HttpUtils;

View File

@@ -0,0 +1,28 @@
<?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\Saml\Token;
use App\Saml\Token\SamlToken;
use App\Saml\Token\SamlTokenInterface;
use PHPUnit\Framework\TestCase;
/**
* @covers \App\Saml\Token\SamlToken
*/
class SamlTokenTest extends TestCase
{
public function testCreateToken()
{
$sut = new SamlToken();
self::assertInstanceOf(SamlTokenInterface::class, $sut);
self::assertNull($sut->getCredentials());
}
}

View File

@@ -9,9 +9,12 @@
namespace App\Tests\Saml\User;
use App\Configuration\SamlConfiguration;
use App\Configuration\SystemConfiguration;
use App\Entity\User;
use App\Saml\Token\SamlToken;
use App\Saml\User\SamlUserFactory;
use Hslavich\OneloginSamlBundle\Security\Authentication\Token\SamlToken;
use App\Tests\Configuration\TestConfigLoader;
use PHPUnit\Framework\TestCase;
/**
@@ -19,6 +22,15 @@ use PHPUnit\Framework\TestCase;
*/
class SamlUserFactoryTest extends TestCase
{
private function createUserFactory(array $saml): SamlUserFactory
{
$configuration = new SystemConfiguration(new TestConfigLoader([]), [
'saml' => $saml
]);
return new SamlUserFactory(new SamlConfiguration($configuration));
}
public function testCreateUserThrowsExceptionOnMissingAttribute()
{
$this->expectException(\RuntimeException::class);
@@ -42,7 +54,7 @@ class SamlUserFactoryTest extends TestCase
$token = new SamlToken();
$token->setAttributes($attributes);
$sut = new SamlUserFactory($mapping);
$sut = $this->createUserFactory($mapping);
$user = $sut->createUser($token);
}
@@ -68,7 +80,7 @@ class SamlUserFactoryTest extends TestCase
$token = new SamlToken();
$token->setAttributes($attributes);
$sut = new SamlUserFactory($mapping);
$sut = $this->createUserFactory($mapping);
$user = $sut->createUser($token);
}
@@ -95,7 +107,7 @@ class SamlUserFactoryTest extends TestCase
$token = new SamlToken();
$token->setAttributes($attributes);
$sut = new SamlUserFactory($mapping);
$sut = $this->createUserFactory($mapping);
$user = $sut->createUser($token);
}
@@ -132,7 +144,7 @@ class SamlUserFactoryTest extends TestCase
$token->setUser('foo@example.com');
$token->setAttributes($attributes);
$sut = new SamlUserFactory($mapping);
$sut = $this->createUserFactory($mapping);
$user = $sut->createUser($token);
self::assertInstanceOf(User::class, $user);
@@ -170,7 +182,7 @@ class SamlUserFactoryTest extends TestCase
$token->setUser('foo@example.com');
$token->setAttributes($attributes);
$sut = new SamlUserFactory($mapping);
$sut = $this->createUserFactory($mapping);
$user = $sut->createUser($token);
self::assertInstanceOf(User::class, $user);