diff options
-rw-r--r-- | config/routes.php | 3 | ||||
-rw-r--r-- | includes/pages/guest_login.php | 18 | ||||
-rw-r--r-- | src/Controllers/AuthController.php | 36 | ||||
-rw-r--r-- | src/Http/Response.php | 23 | ||||
-rw-r--r-- | src/Http/UrlGeneratorServiceProvider.php | 1 | ||||
-rw-r--r-- | src/Middleware/LegacyMiddleware.php | 4 | ||||
-rw-r--r-- | tests/Unit/Controllers/AuthControllerTest.php | 42 | ||||
-rw-r--r-- | tests/Unit/Controllers/CreditsControllerTest.php | 2 | ||||
-rw-r--r-- | tests/Unit/Http/ResponseTest.php | 19 | ||||
-rw-r--r-- | tests/Unit/Http/UrlGeneratorServiceProviderTest.php | 4 |
10 files changed, 128 insertions, 24 deletions
diff --git a/config/routes.php b/config/routes.php index 6f61ec71..6cc0ce8b 100644 --- a/config/routes.php +++ b/config/routes.php @@ -11,6 +11,9 @@ $route->get('/', function () { }); $route->get('/credits', 'CreditsController@index'); +// Authentication +$route->get('/logout', 'AuthController@logout'); + // Stats $route->get('/metrics', 'Metrics\\Controller@metrics'); $route->get('/stats', 'Metrics\\Controller@stats'); diff --git a/includes/pages/guest_login.php b/includes/pages/guest_login.php index b079b9fe..d152a092 100644 --- a/includes/pages/guest_login.php +++ b/includes/pages/guest_login.php @@ -25,14 +25,6 @@ function register_title() } /** - * @return string - */ -function logout_title() -{ - return __('Logout'); -} - -/** * Engel registrieren * * @return string @@ -379,16 +371,6 @@ function entry_required() } /** - * @return bool - */ -function guest_logout() -{ - session()->invalidate(); - redirect(page_link_to('start')); - return true; -} - -/** * @return string */ function guest_login() diff --git a/src/Controllers/AuthController.php b/src/Controllers/AuthController.php new file mode 100644 index 00000000..cdaee167 --- /dev/null +++ b/src/Controllers/AuthController.php @@ -0,0 +1,36 @@ +<?php + +namespace Engelsystem\Controllers; + +use Engelsystem\Http\Response; +use Engelsystem\Http\UrlGeneratorInterface; +use Symfony\Component\HttpFoundation\Session\SessionInterface; + +class AuthController extends BaseController +{ + /** @var Response */ + protected $response; + + /** @var SessionInterface */ + protected $session; + + /** @var UrlGeneratorInterface */ + protected $url; + + public function __construct(Response $response, SessionInterface $session, UrlGeneratorInterface $url) + { + $this->response = $response; + $this->session = $session; + $this->url = $url; + } + + /** + * @return Response + */ + public function logout() + { + $this->session->invalidate(); + + return $this->response->redirectTo($this->url->to('/')); + } +} diff --git a/src/Http/Response.php b/src/Http/Response.php index 58cd7662..1a7c8209 100644 --- a/src/Http/Response.php +++ b/src/Http/Response.php @@ -121,4 +121,27 @@ class Response extends SymfonyResponse implements ResponseInterface return $new; } + + /** + * Return an redirect instance + * + * This method retains the immutability of the message and returns + * an instance with the updated status and headers + * + * @param string $path + * @param int $status + * @param array $headers + * @return Response + */ + public function redirectTo($path, $status = 302, $headers = []) + { + $response = $this->withStatus($status); + $response = $response->withHeader('location', $path); + + foreach ($headers as $name => $value) { + $response = $response->withAddedHeader($name, $value); + } + + return $response; + } } diff --git a/src/Http/UrlGeneratorServiceProvider.php b/src/Http/UrlGeneratorServiceProvider.php index 9b9988aa..774e3e35 100644 --- a/src/Http/UrlGeneratorServiceProvider.php +++ b/src/Http/UrlGeneratorServiceProvider.php @@ -11,5 +11,6 @@ class UrlGeneratorServiceProvider extends ServiceProvider $urlGenerator = $this->app->make(UrlGenerator::class); $this->app->instance(UrlGenerator::class, $urlGenerator); $this->app->instance('http.urlGenerator', $urlGenerator); + $this->app->bind(UrlGeneratorInterface::class, UrlGenerator::class); } } diff --git a/src/Middleware/LegacyMiddleware.php b/src/Middleware/LegacyMiddleware.php index bd3987d2..af2c6a70 100644 --- a/src/Middleware/LegacyMiddleware.php +++ b/src/Middleware/LegacyMiddleware.php @@ -183,10 +183,6 @@ class LegacyMiddleware implements MiddlewareInterface $title = register_title(); $content = guest_register(); return [$title, $content]; - case 'logout': - $title = logout_title(); - $content = guest_logout(); - return [$title, $content]; case 'admin_questions': $title = admin_questions_title(); $content = admin_questions(); diff --git a/tests/Unit/Controllers/AuthControllerTest.php b/tests/Unit/Controllers/AuthControllerTest.php new file mode 100644 index 00000000..c5349cda --- /dev/null +++ b/tests/Unit/Controllers/AuthControllerTest.php @@ -0,0 +1,42 @@ +<?php + +namespace Engelsystem\Test\Unit\Controllers; + +use Engelsystem\Controllers\AuthController; +use Engelsystem\Http\Response; +use Engelsystem\Http\UrlGeneratorInterface; +use PHPUnit\Framework\MockObject\MockObject; +use PHPUnit\Framework\TestCase; +use Symfony\Component\HttpFoundation\Session\SessionInterface; + +class AuthControllerTest extends TestCase +{ + /** + * @covers \Engelsystem\Controllers\AuthController::__construct + * @covers \Engelsystem\Controllers\AuthController::logout + */ + public function testLogout() + { + /** @var Response|MockObject $response */ + $response = $this->createMock(Response::class); + /** @var SessionInterface|MockObject $session */ + $session = $this->getMockForAbstractClass(SessionInterface::class); + /** @var UrlGeneratorInterface|MockObject $url */ + $url = $this->getMockForAbstractClass(UrlGeneratorInterface::class); + + $session->expects($this->once()) + ->method('invalidate'); + + $response->expects($this->once()) + ->method('redirectTo') + ->with('https://foo.bar/'); + + $url->expects($this->once()) + ->method('to') + ->with('/') + ->willReturn('https://foo.bar/'); + + $controller = new AuthController($response, $session, $url); + $controller->logout(); + } +} diff --git a/tests/Unit/Controllers/CreditsControllerTest.php b/tests/Unit/Controllers/CreditsControllerTest.php index 3ce92cb1..42ea4ea1 100644 --- a/tests/Unit/Controllers/CreditsControllerTest.php +++ b/tests/Unit/Controllers/CreditsControllerTest.php @@ -1,6 +1,6 @@ <?php -namespace Unit\Controllers; +namespace Engelsystem\Test\Unit\Controllers; use Engelsystem\Config\Config; use Engelsystem\Controllers\CreditsController; diff --git a/tests/Unit/Http/ResponseTest.php b/tests/Unit/Http/ResponseTest.php index 6f20ff67..34f76513 100644 --- a/tests/Unit/Http/ResponseTest.php +++ b/tests/Unit/Http/ResponseTest.php @@ -85,4 +85,23 @@ class ResponseTest extends TestCase $response = new Response(); $response->withView('foo'); } + + /** + * @covers \Engelsystem\Http\Response::redirectTo + */ + public function testRedirectTo() + { + $response = new Response(); + $newResponse = $response->redirectTo('http://foo.bar/lorem', 301, ['test' => 'ing']); + + $this->assertNotEquals($response, $newResponse); + $this->assertEquals(301, $newResponse->getStatusCode()); + $this->assertArraySubset( + [ + 'location' => ['http://foo.bar/lorem'], + 'test' => ['ing'], + ], + $newResponse->getHeaders() + ); + } } diff --git a/tests/Unit/Http/UrlGeneratorServiceProviderTest.php b/tests/Unit/Http/UrlGeneratorServiceProviderTest.php index c396c05a..61bf3e7c 100644 --- a/tests/Unit/Http/UrlGeneratorServiceProviderTest.php +++ b/tests/Unit/Http/UrlGeneratorServiceProviderTest.php @@ -3,6 +3,7 @@ namespace Engelsystem\Test\Unit\Http; use Engelsystem\Http\UrlGenerator; +use Engelsystem\Http\UrlGeneratorInterface; use Engelsystem\Http\UrlGeneratorServiceProvider; use Engelsystem\Test\Unit\ServiceProviderTest; use PHPUnit\Framework\MockObject\MockObject; @@ -25,7 +26,8 @@ class UrlGeneratorServiceProviderTest extends ServiceProviderTest ->method('instance') ->withConsecutive( [UrlGenerator::class, $urlGenerator], - ['http.urlGenerator', $urlGenerator] + ['http.urlGenerator', $urlGenerator], + [UrlGeneratorInterface::class, $urlGenerator] ); $serviceProvider = new UrlGeneratorServiceProvider($app); |