Release 2.26 (#5189)
* bring back deprecated methods * bump packages * fix SAML redirect * config flag for break times * use class constant instead of string in attributes * throw if all tags were not found - fixes #4792
This commit is contained in:
@@ -188,6 +188,14 @@ abstract class APIControllerBaseTest extends ControllerBaseTest
|
||||
]);
|
||||
}
|
||||
|
||||
protected function assertBadRequestResponse(Response $response): void
|
||||
{
|
||||
$this->assertApiException($response, [
|
||||
'code' => Response::HTTP_BAD_REQUEST,
|
||||
'message' => 'Bad Request'
|
||||
]);
|
||||
}
|
||||
|
||||
protected function assertApiAccessDenied(HttpKernelBrowser $client, string $url, string $message = 'Forbidden'): void
|
||||
{
|
||||
$this->request($client, $url);
|
||||
|
||||
@@ -1173,18 +1173,9 @@ class TimesheetControllerTest extends APIControllerBaseTest
|
||||
$this->assertIsArray($result[0]);
|
||||
self::assertApiResponseTypeStructure('TimesheetCollection', $result[0]);
|
||||
|
||||
$query = ['tags' => ['Nothing-2-see', 'here']];
|
||||
$this->assertAccessIsGranted($client, '/api/timesheets', 'GET', $query);
|
||||
|
||||
$content = $client->getResponse()->getContent();
|
||||
self::assertIsString($content);
|
||||
$result = json_decode($content, true);
|
||||
|
||||
self::assertIsArray($result);
|
||||
self::assertNotEmpty($result);
|
||||
self::assertEquals(20, \count($result));
|
||||
$this->assertIsArray($result[0]);
|
||||
self::assertApiResponseTypeStructure('TimesheetCollection', $result[0]);
|
||||
$query = ['tags' => ['Nothing-2-see', 'not-existing-here']];
|
||||
$this->request($client, '/api/timesheets', 'GET', $query);
|
||||
$this->assertBadRequestResponse($client->getResponse());
|
||||
}
|
||||
|
||||
public function testRestartAction(): void
|
||||
|
||||
@@ -10,11 +10,13 @@
|
||||
namespace App\Tests\Controller\Auth;
|
||||
|
||||
use App\Configuration\SamlConfiguration;
|
||||
use App\Configuration\SamlConfigurationInterface;
|
||||
use App\Configuration\SystemConfiguration;
|
||||
use App\Controller\Auth\SamlController;
|
||||
use App\Saml\SamlAuthFactory;
|
||||
use App\Tests\Configuration\TestConfigLoader;
|
||||
use App\Tests\Mocks\Saml\SamlAuthFactoryFactory;
|
||||
use App\Tests\Mocks\SecurityFactory;
|
||||
use App\Tests\Mocks\SystemConfigurationFactory;
|
||||
use OneLogin\Saml2\Auth;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
@@ -28,19 +30,14 @@ use Symfony\Component\Security\Http\SecurityRequestAttributes;
|
||||
*/
|
||||
class SamlControllerTest extends TestCase
|
||||
{
|
||||
/**
|
||||
* @param array $settings
|
||||
* @param array $loaderSettings
|
||||
* @return SystemConfiguration
|
||||
*/
|
||||
protected function getSystemConfigurationMock(array $settings, array $loaderSettings = [])
|
||||
protected function getSystemConfigurationMock(array $settings, array $loaderSettings = []): SystemConfiguration
|
||||
{
|
||||
$loader = new TestConfigLoader($loaderSettings);
|
||||
|
||||
return SystemConfigurationFactory::create($loader, $settings);
|
||||
}
|
||||
|
||||
protected function getDefaultSettings(bool $activated = true)
|
||||
protected function getDefaultSettings(bool $activated = true): array
|
||||
{
|
||||
return [
|
||||
'saml' => [
|
||||
@@ -66,10 +63,15 @@ class SamlControllerTest extends TestCase
|
||||
|
||||
$factory = $this->getMockBuilder(SamlAuthFactory::class)->disableOriginalConstructor()->getMock();
|
||||
|
||||
$sut = new SamlController($factory, $this->getSamlConfiguration());
|
||||
$sut = $this->getSut($factory, $this->getSamlConfiguration());
|
||||
$sut->assertionConsumerServiceAction();
|
||||
}
|
||||
|
||||
public function getSut(SamlAuthFactory $authFactory, SamlConfigurationInterface $samlConfiguration): SamlController
|
||||
{
|
||||
return new SamlController($authFactory, $samlConfiguration, (new SecurityFactory($this))->create());
|
||||
}
|
||||
|
||||
public function testMetadataAction(): void
|
||||
{
|
||||
$expectedXmlString = <<<EOD
|
||||
@@ -101,7 +103,7 @@ class SamlControllerTest extends TestCase
|
||||
$factory = $this->getMockBuilder(SamlAuthFactory::class)->disableOriginalConstructor()->getMock();
|
||||
$factory->expects($this->once())->method('create')->willReturn($oauth);
|
||||
|
||||
$sut = new SamlController($factory, $this->getSamlConfiguration());
|
||||
$sut = $this->getSut($factory, $this->getSamlConfiguration());
|
||||
$result = $sut->metadataAction();
|
||||
|
||||
self::assertEquals('xml', $result->headers->get('Content-Type'));
|
||||
@@ -129,7 +131,7 @@ class SamlControllerTest extends TestCase
|
||||
|
||||
$factory = $this->getMockBuilder(SamlAuthFactory::class)->disableOriginalConstructor()->getMock();
|
||||
|
||||
$sut = new SamlController($factory, $this->getSamlConfiguration());
|
||||
$sut = $this->getSut($factory, $this->getSamlConfiguration());
|
||||
$sut->loginAction($request);
|
||||
}
|
||||
|
||||
@@ -140,7 +142,7 @@ class SamlControllerTest extends TestCase
|
||||
|
||||
$factory = $this->getMockBuilder(SamlAuthFactory::class)->disableOriginalConstructor()->getMock();
|
||||
|
||||
$sut = new SamlController($factory, $this->getSamlConfiguration(false));
|
||||
$sut = $this->getSut($factory, $this->getSamlConfiguration(false));
|
||||
$sut->loginAction(new Request());
|
||||
}
|
||||
|
||||
@@ -151,7 +153,7 @@ class SamlControllerTest extends TestCase
|
||||
|
||||
$factory = $this->getMockBuilder(SamlAuthFactory::class)->disableOriginalConstructor()->getMock();
|
||||
|
||||
$sut = new SamlController($factory, $this->getSamlConfiguration(false));
|
||||
$sut = $this->getSut($factory, $this->getSamlConfiguration(false));
|
||||
$sut->metadataAction();
|
||||
}
|
||||
|
||||
@@ -162,7 +164,7 @@ class SamlControllerTest extends TestCase
|
||||
|
||||
$factory = $this->getMockBuilder(SamlAuthFactory::class)->disableOriginalConstructor()->getMock();
|
||||
|
||||
$sut = new SamlController($factory, $this->getSamlConfiguration(false));
|
||||
$sut = $this->getSut($factory, $this->getSamlConfiguration(false));
|
||||
$sut->logoutAction();
|
||||
}
|
||||
|
||||
@@ -173,7 +175,7 @@ class SamlControllerTest extends TestCase
|
||||
|
||||
$factory = $this->getMockBuilder(SamlAuthFactory::class)->disableOriginalConstructor()->getMock();
|
||||
|
||||
$sut = new SamlController($factory, $this->getSamlConfiguration(false));
|
||||
$sut = $this->getSut($factory, $this->getSamlConfiguration(false));
|
||||
$sut->assertionConsumerServiceAction();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -290,6 +290,7 @@ class ConfigurationTest extends TestCase
|
||||
'break_warning_duration' => 0,
|
||||
'long_running_duration' => 0,
|
||||
'require_activity' => true,
|
||||
'break_time_active' => false,
|
||||
],
|
||||
'duration_increment' => 15,
|
||||
'time_increment' => 15,
|
||||
|
||||
31
tests/Mocks/SecurityFactory.php
Normal file
31
tests/Mocks/SecurityFactory.php
Normal file
@@ -0,0 +1,31 @@
|
||||
<?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\Mocks;
|
||||
|
||||
use App\Entity\User;
|
||||
use Symfony\Bundle\SecurityBundle\Security;
|
||||
use Symfony\Component\DependencyInjection\ContainerInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
|
||||
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
|
||||
|
||||
class SecurityFactory extends AbstractMockFactory
|
||||
{
|
||||
public function create(): Security
|
||||
{
|
||||
$interface = $this->createMock(TokenInterface::class);
|
||||
$interface->method('getUser')->willReturn(new User());
|
||||
$storage = $this->createMock(TokenStorageInterface::class);
|
||||
$storage->method('getToken')->willReturn($interface);
|
||||
$container = $this->createMock(ContainerInterface::class);
|
||||
$container->method('get')->willReturn($storage);
|
||||
|
||||
return new Security($container);
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,7 @@ use App\Saml\Security\SamlAuthenticationSuccessHandler;
|
||||
use PHPUnit\Framework\TestCase;
|
||||
use Symfony\Component\HttpFoundation\RedirectResponse;
|
||||
use Symfony\Component\HttpFoundation\Request;
|
||||
use Symfony\Component\Routing\Generator\UrlGeneratorInterface;
|
||||
use Symfony\Component\Security\Http\HttpUtils;
|
||||
|
||||
/**
|
||||
@@ -22,19 +23,9 @@ use Symfony\Component\Security\Http\HttpUtils;
|
||||
*/
|
||||
class SamlAuthenticationSuccessHandlerTest extends TestCase
|
||||
{
|
||||
public function testWithAlwaysUseDefaultTargetPath(): void
|
||||
{
|
||||
$httpUtils = new HttpUtils($this->getUrlGenerator());
|
||||
$handler = new SamlAuthenticationSuccessHandler($httpUtils, ['always_use_default_target_path' => true]);
|
||||
$defaultTargetPath = $httpUtils->generateUri($this->getRequest('/sso/login'), $this->getOption($handler, 'default_target_path', '/'));
|
||||
$response = $handler->onAuthenticationSuccess($this->getRequest('/login', 'http://localhost/relayed'), $this->getSamlToken());
|
||||
$this->assertInstanceOf(RedirectResponse::class, $response);
|
||||
$this->assertTrue($response->isRedirect($defaultTargetPath));
|
||||
}
|
||||
|
||||
public function testRelayState(): void
|
||||
{
|
||||
$handler = new SamlAuthenticationSuccessHandler(new HttpUtils($this->getUrlGenerator()), ['always_use_default_target_path' => false]);
|
||||
$handler = new SamlAuthenticationSuccessHandler(new HttpUtils($this->getUrlGenerator()));
|
||||
$response = $handler->onAuthenticationSuccess($this->getRequest('/sso/login', 'http://localhost/relayed'), $this->getSamlToken());
|
||||
$this->assertInstanceOf(RedirectResponse::class, $response);
|
||||
$this->assertTrue($response->isRedirect('http://localhost/relayed'));
|
||||
@@ -43,8 +34,8 @@ class SamlAuthenticationSuccessHandlerTest extends TestCase
|
||||
public function testWithoutRelayState(): void
|
||||
{
|
||||
$httpUtils = new HttpUtils($this->getUrlGenerator());
|
||||
$handler = new SamlAuthenticationSuccessHandler($httpUtils, ['always_use_default_target_path' => false]);
|
||||
$defaultTargetPath = $httpUtils->generateUri($this->getRequest('/sso/login'), $this->getOption($handler, 'default_target_path', '/'));
|
||||
$handler = new SamlAuthenticationSuccessHandler($httpUtils);
|
||||
$defaultTargetPath = $httpUtils->generateUri($this->getRequest('/sso/login'), '/');
|
||||
$response = $handler->onAuthenticationSuccess($this->getRequest(), $this->getSamlToken());
|
||||
$this->assertInstanceOf(RedirectResponse::class, $response);
|
||||
$this->assertTrue($response->isRedirect($defaultTargetPath));
|
||||
@@ -53,16 +44,16 @@ class SamlAuthenticationSuccessHandlerTest extends TestCase
|
||||
public function testRelayStateLoop(): void
|
||||
{
|
||||
$httpUtils = new HttpUtils($this->getUrlGenerator());
|
||||
$handler = new SamlAuthenticationSuccessHandler($httpUtils, ['always_use_default_target_path' => false]);
|
||||
$loginPath = $httpUtils->generateUri($this->getRequest('/sso/login'), $this->getOption($handler, 'login_path', '/login'));
|
||||
$handler = new SamlAuthenticationSuccessHandler($httpUtils);
|
||||
$loginPath = $httpUtils->generateUri($this->getRequest('/sso/login'), '/login');
|
||||
$response = $handler->onAuthenticationSuccess($this->getRequest($loginPath), $this->getSamlToken());
|
||||
$this->assertInstanceOf(RedirectResponse::class, $response);
|
||||
$this->assertTrue(!$response->isRedirect($loginPath));
|
||||
}
|
||||
|
||||
private function getUrlGenerator()
|
||||
private function getUrlGenerator(): UrlGeneratorInterface
|
||||
{
|
||||
$urlGenerator = $this->getMockBuilder('Symfony\Component\Routing\Generator\UrlGeneratorInterface')->getMock();
|
||||
$urlGenerator = $this->getMockBuilder(UrlGeneratorInterface::class)->getMock();
|
||||
$urlGenerator
|
||||
->expects($this->any())
|
||||
->method('generate')
|
||||
@@ -74,7 +65,7 @@ class SamlAuthenticationSuccessHandlerTest extends TestCase
|
||||
return $urlGenerator;
|
||||
}
|
||||
|
||||
private function getRequest($path = '/', $relayState = null)
|
||||
private function getRequest(string $path = '/', ?string $relayState = null): Request
|
||||
{
|
||||
$params = [];
|
||||
if (null !== $relayState) {
|
||||
@@ -84,7 +75,7 @@ class SamlAuthenticationSuccessHandlerTest extends TestCase
|
||||
return Request::create($path, 'get', $params);
|
||||
}
|
||||
|
||||
private function getSamlToken()
|
||||
private function getSamlToken(): SamlToken
|
||||
{
|
||||
$user = new User();
|
||||
$user->setUserIdentifier('admin');
|
||||
@@ -94,17 +85,4 @@ class SamlAuthenticationSuccessHandlerTest extends TestCase
|
||||
|
||||
return $token;
|
||||
}
|
||||
|
||||
private function getOption($handler, $name, $default = null)
|
||||
{
|
||||
$reflection = new \ReflectionObject($handler);
|
||||
$options = $reflection->getProperty('options');
|
||||
$options->setAccessible(true);
|
||||
$arr = $options->getValue($handler);
|
||||
if (!\is_array($arr) || !isset($arr[$name])) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return $arr[$name];
|
||||
}
|
||||
}
|
||||
|
||||
@@ -599,11 +599,6 @@ parameters:
|
||||
count: 2
|
||||
path: Controller/Auth/SamlControllerTest.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Tests\\\\Controller\\\\Auth\\\\SamlControllerTest\\:\\:getDefaultSettings\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
path: Controller/Auth/SamlControllerTest.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Tests\\\\Controller\\\\Auth\\\\SamlControllerTest\\:\\:getSystemConfigurationMock\\(\\) has parameter \\$loaderSettings with no value type specified in iterable type array\\.$#"
|
||||
count: 1
|
||||
@@ -2364,51 +2359,6 @@ parameters:
|
||||
count: 1
|
||||
path: Saml/SamlProviderTest.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Tests\\\\Saml\\\\Security\\\\SamlAuthenticationSuccessHandlerTest\\:\\:getOption\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
path: Saml/Security/SamlAuthenticationSuccessHandlerTest.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Tests\\\\Saml\\\\Security\\\\SamlAuthenticationSuccessHandlerTest\\:\\:getOption\\(\\) has parameter \\$default with no type specified\\.$#"
|
||||
count: 1
|
||||
path: Saml/Security/SamlAuthenticationSuccessHandlerTest.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Tests\\\\Saml\\\\Security\\\\SamlAuthenticationSuccessHandlerTest\\:\\:getOption\\(\\) has parameter \\$handler with no type specified\\.$#"
|
||||
count: 1
|
||||
path: Saml/Security/SamlAuthenticationSuccessHandlerTest.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Tests\\\\Saml\\\\Security\\\\SamlAuthenticationSuccessHandlerTest\\:\\:getOption\\(\\) has parameter \\$name with no type specified\\.$#"
|
||||
count: 1
|
||||
path: Saml/Security/SamlAuthenticationSuccessHandlerTest.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Tests\\\\Saml\\\\Security\\\\SamlAuthenticationSuccessHandlerTest\\:\\:getRequest\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
path: Saml/Security/SamlAuthenticationSuccessHandlerTest.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Tests\\\\Saml\\\\Security\\\\SamlAuthenticationSuccessHandlerTest\\:\\:getRequest\\(\\) has parameter \\$path with no type specified\\.$#"
|
||||
count: 1
|
||||
path: Saml/Security/SamlAuthenticationSuccessHandlerTest.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Tests\\\\Saml\\\\Security\\\\SamlAuthenticationSuccessHandlerTest\\:\\:getRequest\\(\\) has parameter \\$relayState with no type specified\\.$#"
|
||||
count: 1
|
||||
path: Saml/Security/SamlAuthenticationSuccessHandlerTest.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Tests\\\\Saml\\\\Security\\\\SamlAuthenticationSuccessHandlerTest\\:\\:getSamlToken\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
path: Saml/Security/SamlAuthenticationSuccessHandlerTest.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Tests\\\\Saml\\\\Security\\\\SamlAuthenticationSuccessHandlerTest\\:\\:getUrlGenerator\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
path: Saml/Security/SamlAuthenticationSuccessHandlerTest.php
|
||||
|
||||
-
|
||||
message: "#^Method App\\\\Tests\\\\Timesheet\\\\Calculator\\\\BillableCalculatorTest\\:\\:getTestData\\(\\) has no return type specified\\.$#"
|
||||
count: 1
|
||||
|
||||
Reference in New Issue
Block a user