Changed `src/` code and templates to use the new user model

main
Igor Scheller 6 years ago committed by msquare
parent 8e62c4c52c
commit d15946df2d

@ -20,6 +20,7 @@ return [
\Engelsystem\Helpers\TranslationServiceProvider::class, \Engelsystem\Helpers\TranslationServiceProvider::class,
\Engelsystem\Http\ResponseServiceProvider::class, \Engelsystem\Http\ResponseServiceProvider::class,
\Engelsystem\Http\Psr7ServiceProvider::class, \Engelsystem\Http\Psr7ServiceProvider::class,
\Engelsystem\Helpers\AuthenticatorServiceProvider::class,
\Engelsystem\Renderer\TwigServiceProvider::class, \Engelsystem\Renderer\TwigServiceProvider::class,
\Engelsystem\Middleware\RouteDispatcherServiceProvider::class, \Engelsystem\Middleware\RouteDispatcherServiceProvider::class,
\Engelsystem\Middleware\RequestHandlerServiceProvider::class, \Engelsystem\Middleware\RequestHandlerServiceProvider::class,
@ -30,7 +31,6 @@ return [
// Application middleware // Application middleware
'middleware' => [ 'middleware' => [
// Basic initialization // Basic initialization
\Engelsystem\Middleware\SendResponseHandler::class, \Engelsystem\Middleware\SendResponseHandler::class,
\Engelsystem\Middleware\ExceptionHandler::class, \Engelsystem\Middleware\ExceptionHandler::class,
@ -41,6 +41,8 @@ return [
// The application code // The application code
\Engelsystem\Middleware\ErrorHandler::class, \Engelsystem\Middleware\ErrorHandler::class,
\Engelsystem\Middleware\RouteDispatcher::class, \Engelsystem\Middleware\RouteDispatcher::class,
// Handle request
\Engelsystem\Middleware\RequestHandler::class, \Engelsystem\Middleware\RequestHandler::class,
], ],
]; ];

@ -28,7 +28,7 @@ function engelsystem_email_to_user($recipient_user, $title, $message, $not_if_it
$recipient_user['email'], $recipient_user['email'],
$title, $title,
'emails/mail', 'emails/mail',
['user' => $recipient_user['Nick'], 'message' => $message] ['username' => $recipient_user['Nick'], 'message' => $message]
); );
$translator->setLocale($locale); $translator->setLocale($locale);

@ -1,6 +1,7 @@
<?php <?php
use Carbon\Carbon; use Carbon\Carbon;
use Engelsystem\Models\User\User;
/** /**
* Renders user settings page * Renders user settings page
@ -279,6 +280,14 @@ function Users_table_header_link($column, $label, $order_by)
*/ */
function User_shift_state_render($user) function User_shift_state_render($user)
{ {
if ($user instanceof User) {
$userModel = $user;
$user = [
'Gekommen' => $userModel->state->arrived,
'UID' => $user->id,
];
}
if (!$user['Gekommen']) { if (!$user['Gekommen']) {
return ''; return '';
} }

@ -1,4 +1,4 @@
{{ __('Hi %s,', [user]) }} {{ __('Hi %s,', [username]) }}
{{ __('here is a message for you from the %s:', [config('app_name')]) }} {{ __('here is a message for you from the %s:', [config('app_name')]) }}
{{ message|raw }} {{ message|raw }}

@ -1,4 +1,4 @@
{% set theme = user.color|default(config('theme')) %} {% set theme = user.settings.theme|default(config('theme')) %}
<!DOCTYPE html> <!DOCTYPE html>
<html lang="{{ session_get('locale')|split('_')[0]|escape('html_attr') }}"> <html lang="{{ session_get('locale')|split('_')[0]|escape('html_attr') }}">
<head> <head>

@ -21,7 +21,8 @@
<span class="icon-bar"></span> <span class="icon-bar"></span>
</button> </button>
<a class="navbar-brand" href="{{ url('/') }}"> <a class="navbar-brand" href="{{ url('/') }}">
<span class="icon-icon_angel"></span> <strong class="visible-lg-inline">{{ config('app_name')|upper }}</strong> <span class="icon-icon_angel"></span>
<strong class="visible-lg-inline">{{ config('app_name')|upper }}</strong>
</a> </a>
</div> </div>
@ -51,7 +52,7 @@
{{ menuUserHints() }} {{ menuUserHints() }}
{% if has_permission_to('user_myshifts') %} {% if has_permission_to('user_myshifts') %}
{{ elements.toolbar_item(user.Nick, url('users', {'action': 'view'}), 'users', 'icon icon-icon_angel') }} {{ elements.toolbar_item(user.name, url('users', {'action': 'view'}), 'users', 'icon icon-icon_angel') }}
{% endif %} {% endif %}
{% if has_permission_to('user_settings') or has_permission_to('logout') %} {% if has_permission_to('user_settings') or has_permission_to('logout') %}

@ -4,6 +4,7 @@ namespace Engelsystem\Exceptions\Handlers;
use Engelsystem\Application; use Engelsystem\Application;
use Engelsystem\Container\Container; use Engelsystem\Container\Container;
use Engelsystem\Helpers\Authenticator;
use Engelsystem\Http\Request; use Engelsystem\Http\Request;
use Throwable; use Throwable;
use Whoops\Handler\JsonResponseHandler; use Whoops\Handler\JsonResponseHandler;
@ -81,9 +82,15 @@ class Whoops extends Legacy implements HandlerInterface
*/ */
protected function getData() protected function getData()
{ {
global $user;
$data = []; $data = [];
$user = null;
if ($this->app->has('authenticator')) {
/** @var Authenticator $authenticator */
$authenticator = $this->app->get('authenticator');
$user = $authenticator->user();
}
$data['user'] = $user; $data['user'] = $user;
$data['Booted'] = $this->app->isBooted(); $data['Booted'] = $this->app->isBooted();

@ -0,0 +1,56 @@
<?php
namespace Engelsystem\Helpers;
use Engelsystem\Models\BaseModel;
use Engelsystem\Models\User\User;
use Engelsystem\Models\User\User as UserRepository;
use Symfony\Component\HttpFoundation\Session\Session;
class Authenticator
{
/** @var UserRepository */
protected $user = null;
/** @var Session */
protected $session;
/** @var BaseModel */
protected $userRepository;
/**
* @param Session $session
* @param UserRepository $userRepository
*/
public function __construct(Session $session, UserRepository $userRepository)
{
$this->session = $session;
$this->userRepository = $userRepository;
}
/**
* @return User|null
*/
public function user()
{
if ($this->user) {
return $this->user;
}
$userId = $this->session->get('uid');
if (!$userId) {
return null;
}
$user = $this
->userRepository
->find($userId);
if (!$user) {
return null;
}
$this->user = $user;
return $user;
}
}

@ -0,0 +1,17 @@
<?php
namespace Engelsystem\Helpers;
use Engelsystem\Container\ServiceProvider;
class AuthenticatorServiceProvider extends ServiceProvider
{
public function register()
{
/** @var Authenticator $authenticator */
$authenticator = $this->app->make(Authenticator::class);
$this->app->instance(Authenticator::class, $authenticator);
$this->app->instance('authenticator', $authenticator);
}
}

@ -2,6 +2,7 @@
namespace Engelsystem\Middleware; namespace Engelsystem\Middleware;
use Engelsystem\Helpers\Authenticator;
use Engelsystem\Helpers\Translator; use Engelsystem\Helpers\Translator;
use Engelsystem\Http\Request; use Engelsystem\Http\Request;
use Engelsystem\Http\Response; use Engelsystem\Http\Response;
@ -35,12 +36,17 @@ class LegacyMiddleware implements MiddlewareInterface
/** @var ContainerInterface */ /** @var ContainerInterface */
protected $container; protected $container;
/** @var Authenticator */
protected $auth;
/** /**
* @param ContainerInterface $container * @param ContainerInterface $container
* @param Authenticator $auth
*/ */
public function __construct(ContainerInterface $container) public function __construct(ContainerInterface $container, Authenticator $auth)
{ {
$this->container = $container; $this->container = $container;
$this->auth = $auth;
} }
/** /**
@ -56,7 +62,6 @@ class LegacyMiddleware implements MiddlewareInterface
ServerRequestInterface $request, ServerRequestInterface $request,
RequestHandlerInterface $handler RequestHandlerInterface $handler
): ResponseInterface { ): ResponseInterface {
global $user;
global $privileges; global $privileges;
global $page; global $page;
@ -68,7 +73,7 @@ class LegacyMiddleware implements MiddlewareInterface
$page = str_replace('-', '_', $page); $page = str_replace('-', '_', $page);
} }
if ($page == '/') { if ($page == '/') {
$page = isset($user) ? 'news' : 'login'; $page = $this->auth->user() ? 'news' : 'login';
} }
$title = $content = ''; $title = $content = '';

@ -30,7 +30,7 @@ abstract class BaseModel extends Model
* *
* @param mixed $id * @param mixed $id
* @param array $columns * @param array $columns
* @return Builder|Builder[]|Collection|Model|null * @return Builder|Builder[]|Collection|static|null
*/ */
public static function find($id, $columns = ['*']) public static function find($id, $columns = ['*'])
{ {

@ -2,11 +2,23 @@
namespace Engelsystem\Renderer\Twig\Extensions; namespace Engelsystem\Renderer\Twig\Extensions;
use Engelsystem\Helpers\Authenticator;
use Twig_Extension as TwigExtension; use Twig_Extension as TwigExtension;
use Twig_Function as TwigFunction; use Twig_Function as TwigFunction;
class Authentication extends TwigExtension class Authentication extends TwigExtension
{ {
/** @var Authenticator */
protected $auth;
/**
* @param Authenticator $auth
*/
public function __construct(Authenticator $auth)
{
$this->auth = $auth;
}
/** /**
* @return TwigFunction[] * @return TwigFunction[]
*/ */
@ -19,18 +31,26 @@ class Authentication extends TwigExtension
]; ];
} }
/**
* @return bool
*/
public function isAuthenticated() public function isAuthenticated()
{ {
global $user; return (bool)$this->auth->user();
return !empty($user);
} }
/**
* @return bool
*/
public function isGuest() public function isGuest()
{ {
return !$this->isAuthenticated(); return !$this->isAuthenticated();
} }
/**
* @param $privilege
* @return bool
*/
public function checkAuth($privilege) public function checkAuth($privilege)
{ {
global $privileges; global $privileges;

@ -2,11 +2,23 @@
namespace Engelsystem\Renderer\Twig\Extensions; namespace Engelsystem\Renderer\Twig\Extensions;
use Engelsystem\Helpers\Authenticator;
use Twig_Extension as TwigExtension; use Twig_Extension as TwigExtension;
use Twig_Extension_GlobalsInterface as GlobalsInterface; use Twig_Extension_GlobalsInterface as GlobalsInterface;
class Globals extends TwigExtension implements GlobalsInterface class Globals extends TwigExtension implements GlobalsInterface
{ {
/** @var Authenticator */
protected $auth;
/**
* @param Authenticator $auth
*/
public function __construct(Authenticator $auth)
{
$this->auth = $auth;
}
/** /**
* Returns a list of global variables to add to the existing list. * Returns a list of global variables to add to the existing list.
* *
@ -14,10 +26,10 @@ class Globals extends TwigExtension implements GlobalsInterface
*/ */
public function getGlobals() public function getGlobals()
{ {
global $user; $user = $this->auth->user();
return [ return [
'user' => isset($user) ? $user : [], 'user' => $user ? $user : [],
]; ];
} }
} }

@ -5,6 +5,7 @@ namespace Engelsystem\Test\Unit\Exceptions\handlers;
use Engelsystem\Application; use Engelsystem\Application;
use Engelsystem\Exceptions\Handlers\Whoops; use Engelsystem\Exceptions\Handlers\Whoops;
use Engelsystem\Helpers\Authenticator;
use Engelsystem\Http\Request; use Engelsystem\Http\Request;
use Exception; use Exception;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
@ -23,15 +24,23 @@ class WhoopsTest extends TestCase
{ {
/** @var Application|Mock $app */ /** @var Application|Mock $app */
$app = $this->createMock(Application::class); $app = $this->createMock(Application::class);
/** @var Authenticator|Mock $auth */
$auth = $this->createMock(Authenticator::class);
/** @var Request|Mock $request */ /** @var Request|Mock $request */
$request = $this->createMock(Request::class); $request = $this->createMock(Request::class);
$request->expects($this->once())
->method('isXmlHttpRequest')
->willReturn(true);
/** @var WhoopsRunnerInterface|Mock $whoopsRunner */ /** @var WhoopsRunnerInterface|Mock $whoopsRunner */
$whoopsRunner = $this->getMockForAbstractClass(WhoopsRunnerInterface::class); $whoopsRunner = $this->getMockForAbstractClass(WhoopsRunnerInterface::class);
/** @var PrettyPageHandler|Mock $prettyPageHandler */ /** @var PrettyPageHandler|Mock $prettyPageHandler */
$prettyPageHandler = $this->createMock(PrettyPageHandler::class); $prettyPageHandler = $this->createMock(PrettyPageHandler::class);
/** @var JsonResponseHandler|Mock $jsonResponseHandler */
$jsonResponseHandler = $this->createMock(JsonResponseHandler::class);
/** @var Exception|Mock $exception */
$exception = $this->createMock(Exception::class);
$request->expects($this->once())
->method('isXmlHttpRequest')
->willReturn(true);
$prettyPageHandler $prettyPageHandler
->expects($this->atLeastOnce()) ->expects($this->atLeastOnce())
->method('setApplicationPaths'); ->method('setApplicationPaths');
@ -41,16 +50,13 @@ class WhoopsTest extends TestCase
$prettyPageHandler $prettyPageHandler
->expects($this->once()) ->expects($this->once())
->method('addDataTable'); ->method('addDataTable');
/** @var JsonResponseHandler|Mock $jsonResponseHandler */
$jsonResponseHandler = $this->createMock(JsonResponseHandler::class);
$jsonResponseHandler->expects($this->once()) $jsonResponseHandler->expects($this->once())
->method('setJsonApi') ->method('setJsonApi')
->with(true); ->with(true);
$jsonResponseHandler->expects($this->once()) $jsonResponseHandler->expects($this->once())
->method('addTraceToOutput') ->method('addTraceToOutput')
->with(true); ->with(true);
/** @var Exception|Mock $exception */
$exception = $this->createMock(Exception::class);
$app->expects($this->exactly(3)) $app->expects($this->exactly(3))
->method('make') ->method('make')
@ -64,6 +70,18 @@ class WhoopsTest extends TestCase
$prettyPageHandler, $prettyPageHandler,
$jsonResponseHandler $jsonResponseHandler
); );
$app->expects($this->once())
->method('has')
->with('authenticator')
->willReturn(true);
$app->expects($this->once())
->method('get')
->with('authenticator')
->willReturn($auth);
$auth->expects($this->once())
->method('user')
->willReturn(null);
$whoopsRunner $whoopsRunner
->expects($this->exactly(2)) ->expects($this->exactly(2))

@ -0,0 +1,25 @@
<?php
namespace Engelsystem\Test\Unit\Helpers;
use Engelsystem\Application;
use Engelsystem\Helpers\Authenticator;
use Engelsystem\Helpers\AuthenticatorServiceProvider;
use Engelsystem\Test\Unit\ServiceProviderTest;
class AuthenticatorServiceProviderTest extends ServiceProviderTest
{
/**
* @covers \Engelsystem\Helpers\AuthenticatorServiceProvider::register()
*/
public function testRegister()
{
$app = new Application();
$serviceProvider = new AuthenticatorServiceProvider($app);
$serviceProvider->register();
$this->assertInstanceOf(Authenticator::class, $app->get(Authenticator::class));
$this->assertInstanceOf(Authenticator::class, $app->get('authenticator'));
}
}

@ -0,0 +1,55 @@
<?php
namespace Engelsystem\Test\Unit\Helpers;
use Engelsystem\Helpers\Authenticator;
use Engelsystem\Models\User\User;
use Engelsystem\Test\Unit\Helpers\Stub\UserModelImplementation;
use Engelsystem\Test\Unit\ServiceProviderTest;
use PHPUnit\Framework\MockObject\MockObject;
use Symfony\Component\HttpFoundation\Session\Session;
class AuthenticatorTest extends ServiceProviderTest
{
/**
* @covers \Engelsystem\Helpers\Authenticator::__construct(
* @covers \Engelsystem\Helpers\Authenticator::user
*/
public function testUser()
{
/** @var Session|MockObject $session */
$session = $this->createMock(Session::class);
/** @var UserModelImplementation|MockObject $userRepository */
$userRepository = new UserModelImplementation();
/** @var User|MockObject $user */
$user = $this->createMock(User::class);
$session->expects($this->exactly(3))
->method('get')
->with('uid')
->willReturnOnConsecutiveCalls(
null,
42,
1337
);
$auth = new Authenticator($session, $userRepository);
// Not in session
$this->assertEquals(null, $auth->user());
// Unknown user
UserModelImplementation::$id = 42;
$this->assertEquals(null, $auth->user());
// User found
UserModelImplementation::$id = 1337;
UserModelImplementation::$user = $user;
$this->assertEquals($user, $auth->user());
// User cached
UserModelImplementation::$id = null;
UserModelImplementation::$user = null;
$this->assertEquals($user, $auth->user());
}
}

@ -0,0 +1,29 @@
<?php
namespace Engelsystem\Test\Unit\Helpers\Stub;
use Engelsystem\Models\User\User;
use InvalidArgumentException;
class UserModelImplementation extends User
{
/** @var User */
public static $user = null;
/** @var int */
public static $id = null;
/**
* @param mixed $id
* @param array $columns
* @return User|null
*/
public static function find($id, $columns = ['*'])
{
if ($id != static::$id) {
throw new InvalidArgumentException('Wrong user ID searched');
}
return self::$user;
}
}

@ -2,6 +2,7 @@
namespace Engelsystem\Test\Unit\Middleware; namespace Engelsystem\Test\Unit\Middleware;
use Engelsystem\Helpers\Authenticator;
use Engelsystem\Helpers\Translator; use Engelsystem\Helpers\Translator;
use Engelsystem\Http\Request; use Engelsystem\Http\Request;
use Engelsystem\Middleware\LegacyMiddleware; use Engelsystem\Middleware\LegacyMiddleware;
@ -23,9 +24,11 @@ class LegacyMiddlewareTest extends TestCase
{ {
/** @var ContainerInterface|MockObject $container */ /** @var ContainerInterface|MockObject $container */
$container = $this->getMockForAbstractClass(ContainerInterface::class); $container = $this->getMockForAbstractClass(ContainerInterface::class);
/** @var Authenticator|MockObject $auth */
$auth = $this->createMock(Authenticator::class);
/** @var LegacyMiddleware|MockObject $middleware */ /** @var LegacyMiddleware|MockObject $middleware */
$middleware = $this->getMockBuilder(LegacyMiddleware::class) $middleware = $this->getMockBuilder(LegacyMiddleware::class)
->setConstructorArgs([$container]) ->setConstructorArgs([$container, $auth])
->setMethods(['loadPage', 'renderPage']) ->setMethods(['loadPage', 'renderPage'])
->getMock(); ->getMock();
/** @var Request|MockObject $defaultRequest */ /** @var Request|MockObject $defaultRequest */
@ -70,6 +73,10 @@ class LegacyMiddlewareTest extends TestCase
$defaultRequest $defaultRequest
); );
$auth->expects($this->atLeastOnce())
->method('user')
->willReturn(false);
$translator->expects($this->exactly(2)) $translator->expects($this->exactly(2))
->method('translate') ->method('translate')
->willReturnOnConsecutiveCalls( ->willReturnOnConsecutiveCalls(

@ -2,16 +2,23 @@
namespace Engelsystem\Test\Unit\Renderer\Twig\Extensions; namespace Engelsystem\Test\Unit\Renderer\Twig\Extensions;
use Engelsystem\Helpers\Authenticator;
use Engelsystem\Models\User\User;
use Engelsystem\Renderer\Twig\Extensions\Authentication; use Engelsystem\Renderer\Twig\Extensions\Authentication;
use PHPUnit\Framework\MockObject\MockObject;
class AuthenticationTest extends ExtensionTest class AuthenticationTest extends ExtensionTest
{ {
/** /**
* @covers \Engelsystem\Renderer\Twig\Extensions\Authentication::__construct
* @covers \Engelsystem\Renderer\Twig\Extensions\Authentication::getFunctions * @covers \Engelsystem\Renderer\Twig\Extensions\Authentication::getFunctions
*/ */
public function testGetFunctions() public function testGetFunctions()
{ {
$extension = new Authentication(); /** @var Authenticator|MockObject $auth */
$auth = $this->createMock(Authenticator::class);
$extension = new Authentication($auth);
$functions = $extension->getFunctions(); $functions = $extension->getFunctions();
$this->assertExtensionExists('is_user', [$extension, 'isAuthenticated'], $functions); $this->assertExtensionExists('is_user', [$extension, 'isAuthenticated'], $functions);
@ -25,15 +32,24 @@ class AuthenticationTest extends ExtensionTest
*/ */
public function testIsAuthenticated() public function testIsAuthenticated()
{ {
global $user; /** @var Authenticator|MockObject $auth */
$user = []; $auth = $this->createMock(Authenticator::class);
$user = new User();
$auth->expects($this->exactly(4))
->method('user')
->willReturnOnConsecutiveCalls(
null,
null,
$user,
$user
);
$extension = new Authentication(); $extension = new Authentication($auth);
$this->assertFalse($extension->isAuthenticated()); $this->assertFalse($extension->isAuthenticated());
$this->assertTrue($extension->isGuest()); $this->assertTrue($extension->isGuest());
$user = ['lorem' => 'ipsum'];
$this->assertTrue($extension->isAuthenticated()); $this->assertTrue($extension->isAuthenticated());
$this->assertFalse($extension->isGuest()); $this->assertFalse($extension->isGuest());
} }
@ -46,7 +62,10 @@ class AuthenticationTest extends ExtensionTest
global $privileges; global $privileges;
$privileges = []; $privileges = [];
$extension = new Authentication(); /** @var Authenticator|MockObject $auth */
$auth = $this->createMock(Authenticator::class);
$extension = new Authentication($auth);
$this->assertFalse($extension->checkAuth('foo.bar')); $this->assertFalse($extension->checkAuth('foo.bar'));

@ -2,25 +2,36 @@
namespace Engelsystem\Test\Unit\Renderer\Twig\Extensions; namespace Engelsystem\Test\Unit\Renderer\Twig\Extensions;
use Engelsystem\Helpers\Authenticator;
use Engelsystem\Models\User\User;
use Engelsystem\Renderer\Twig\Extensions\Globals; use Engelsystem\Renderer\Twig\Extensions\Globals;
use PHPUnit\Framework\MockObject\MockObject;
class GlobalsTest extends ExtensionTest class GlobalsTest extends ExtensionTest
{ {
/** /**
* @covers \Engelsystem\Renderer\Twig\Extensions\Globals::__construct
* @covers \Engelsystem\Renderer\Twig\Extensions\Globals::getGlobals * @covers \Engelsystem\Renderer\Twig\Extensions\Globals::getGlobals
*/ */
public function testGetGlobals() public function testGetGlobals()
{ {
global $user; /** @var Authenticator|MockObject $auth */
$user = []; $auth = $this->createMock(Authenticator::class);
$user = new User();
$extension = new Globals(); $auth->expects($this->exactly(2))
->method('user')
->willReturnOnConsecutiveCalls(
null,
$user
);
$extension = new Globals($auth);
$globals = $extension->getGlobals(); $globals = $extension->getGlobals();
$this->assertGlobalsExists('user', [], $globals); $this->assertGlobalsExists('user', [], $globals);
$user['foo'] = 'bar';
$globals = $extension->getGlobals(); $globals = $extension->getGlobals();
$this->assertGlobalsExists('user', ['foo' => 'bar'], $globals); $this->assertGlobalsExists('user', $user, $globals);
} }
} }

Loading…
Cancel
Save