Added validation to AuthController

This commit is contained in:
Igor Scheller 2019-07-09 22:02:07 +02:00
parent 7414f9b23d
commit 6d5ada2522
6 changed files with 87 additions and 68 deletions

Binary file not shown.

View File

@ -2,7 +2,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Engelsystem\n" "Project-Id-Version: Engelsystem\n"
"POT-Creation-Date: 2019-04-28 15:23+0200\n" "POT-Creation-Date: 2019-04-28 15:23+0200\n"
"PO-Revision-Date: 2019-06-12 16:07+0200\n" "PO-Revision-Date: 2019-06-13 11:54+0200\n"
"Last-Translator: msquare <msquare@notrademark.de>\n" "Last-Translator: msquare <msquare@notrademark.de>\n"
"Language-Team: \n" "Language-Team: \n"
"Language: de_DE\n" "Language: de_DE\n"
@ -1529,9 +1529,8 @@ msgstr "Nachname"
msgid "Entry required!" msgid "Entry required!"
msgstr "Pflichtfeld!" msgstr "Pflichtfeld!"
#: includes/pages/guest_login.php:414 #~ msgid "auth.no-password"
msgid "auth.no-password" #~ msgstr "Gib bitte ein Passwort ein."
msgstr "Gib bitte ein Passwort ein."
#: includes/pages/guest_login.php:418 #: includes/pages/guest_login.php:418
msgid "auth.not-found" msgid "auth.not-found"
@ -1539,9 +1538,8 @@ msgstr ""
"Es wurde kein Engel gefunden. Probiere es bitte noch einmal. Wenn das Problem " "Es wurde kein Engel gefunden. Probiere es bitte noch einmal. Wenn das Problem "
"weiterhin besteht, melde dich im Himmel." "weiterhin besteht, melde dich im Himmel."
#: includes/pages/guest_login.php:451 includes/view/User_view.php:130 #~ msgid "auth.no-nickname"
msgid "auth.no-nickname" #~ msgstr "Gib bitte einen Nick an."
msgstr "Gib bitte einen Nick an."
#: includes/pages/guest_login.php:481 #: includes/pages/guest_login.php:481
#: includes/view/User_view.php:122 #: includes/view/User_view.php:122
@ -2765,3 +2763,9 @@ msgid ""
msgstr "" msgstr ""
"Diese Seite existiert nicht oder Du hast keinen Zugriff. Melde Dich an um " "Diese Seite existiert nicht oder Du hast keinen Zugriff. Melde Dich an um "
"Zugriff zu erhalten!" "Zugriff zu erhalten!"
msgid "validation.password.required"
msgstr "Bitte gib ein Passwort an."
msgid "validation.login.required"
msgstr "Bitte gib einen Loginnamen an."

Binary file not shown.

View File

@ -2,7 +2,7 @@ msgid ""
msgstr "" msgstr ""
"Project-Id-Version: Engelsystem 2.0\n" "Project-Id-Version: Engelsystem 2.0\n"
"POT-Creation-Date: 2017-12-29 19:01+0100\n" "POT-Creation-Date: 2017-12-29 19:01+0100\n"
"PO-Revision-Date: 2018-11-27 00:28+0100\n" "PO-Revision-Date: 2019-06-04 23:41+0200\n"
"Language-Team: \n" "Language-Team: \n"
"MIME-Version: 1.0\n" "MIME-Version: 1.0\n"
"Content-Type: text/plain; charset=UTF-8\n" "Content-Type: text/plain; charset=UTF-8\n"
@ -16,11 +16,17 @@ msgstr ""
"Language: en_US\n" "Language: en_US\n"
"X-Poedit-SearchPath-0: .\n" "X-Poedit-SearchPath-0: .\n"
msgid "auth.no-nickname" #~ msgid "auth.no-nickname"
msgstr "Please enter a nickname." #~ msgstr "Please enter a nickname."
msgid "auth.no-password" #~ msgid "auth.no-password"
msgstr "Please enter a password." #~ msgstr "Please enter a password."
msgid "auth.not-found" msgid "auth.not-found"
msgstr "No user was found. Please try again. If you are still having problems, ask Heaven." msgstr "No user was found. Please try again. If you are still having problems, ask Heaven."
msgid "validation.password.required"
msgstr "The password is required."
msgid "validation.login.required"
msgstr "The login name is required."

View File

@ -8,6 +8,8 @@ use Engelsystem\Http\Request;
use Engelsystem\Http\Response; use Engelsystem\Http\Response;
use Engelsystem\Http\UrlGeneratorInterface; use Engelsystem\Http\UrlGeneratorInterface;
use Engelsystem\Models\User\User; use Engelsystem\Models\User\User;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpFoundation\Session\SessionInterface;
class AuthController extends BaseController class AuthController extends BaseController
@ -53,7 +55,22 @@ class AuthController extends BaseController
*/ */
public function login() public function login()
{ {
return $this->response->withView('pages/login'); return $this->showLogin();
}
/**
* @param bool $showRecovery
* @return Response
*/
protected function showLogin($showRecovery = false)
{
$errors = Collection::make(Arr::flatten($this->session->get('errors', [])));
$this->session->remove('errors');
return $this->response->withView(
'pages/login',
['errors' => $errors, 'show_password_recovery' => $showRecovery]
);
} }
/** /**
@ -64,15 +81,18 @@ class AuthController extends BaseController
*/ */
public function postLogin(Request $request): Response public function postLogin(Request $request): Response
{ {
$return = $this->authenticateUser($request->get('login', ''), $request->get('password', '')); $data = $this->validate($request, [
if (!$return instanceof User) { 'login' => 'required',
return $this->response->withView( 'password' => 'required',
'pages/login', ]);
['errors' => [$return], 'show_password_recovery' => true]
);
}
$user = $return; $user = $this->auth->authenticate($data['login'], $data['password']);
if (!$user instanceof User) {
$this->session->set('errors', $this->session->get('errors', []) + ['auth.not-found']);
return $this->showLogin(true);
}
$this->session->invalidate(); $this->session->invalidate();
$this->session->set('user_id', $user->id); $this->session->set('user_id', $user->id);
@ -93,28 +113,4 @@ class AuthController extends BaseController
return $this->response->redirectTo($this->url->to('/')); return $this->response->redirectTo($this->url->to('/'));
} }
/**
* Verify the user and password
*
* @param $login
* @param $password
* @return User|string
*/
protected function authenticateUser(string $login, string $password)
{
if (!$login) {
return 'auth.no-nickname';
}
if (!$password) {
return 'auth.no-password';
}
if (!$user = $this->auth->authenticate($login, $password)) {
return 'auth.not-found';
}
return $user;
}
} }

View File

@ -4,15 +4,21 @@ namespace Engelsystem\Test\Unit\Controllers;
use Engelsystem\Controllers\AuthController; use Engelsystem\Controllers\AuthController;
use Engelsystem\Helpers\Authenticator; use Engelsystem\Helpers\Authenticator;
use Engelsystem\Http\Exceptions\ValidationException;
use Engelsystem\Http\Request; use Engelsystem\Http\Request;
use Engelsystem\Http\Response; use Engelsystem\Http\Response;
use Engelsystem\Http\UrlGeneratorInterface; use Engelsystem\Http\UrlGeneratorInterface;
use Engelsystem\Http\Validation\Validates;
use Engelsystem\Http\Validation\Validator;
use Engelsystem\Models\User\Settings; use Engelsystem\Models\User\Settings;
use Engelsystem\Models\User\User; use Engelsystem\Models\User\User;
use Engelsystem\Test\Unit\HasDatabase; use Engelsystem\Test\Unit\HasDatabase;
use Illuminate\Support\Collection;
use PHPUnit\Framework\MockObject\MockObject; use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase; use PHPUnit\Framework\TestCase;
use Symfony\Component\HttpFoundation\Session\Session;
use Symfony\Component\HttpFoundation\Session\SessionInterface; use Symfony\Component\HttpFoundation\Session\SessionInterface;
use Symfony\Component\HttpFoundation\Session\Storage\MockArraySessionStorage;
class AuthControllerTest extends TestCase class AuthControllerTest extends TestCase
{ {
@ -21,6 +27,7 @@ class AuthControllerTest extends TestCase
/** /**
* @covers \Engelsystem\Controllers\AuthController::__construct * @covers \Engelsystem\Controllers\AuthController::__construct
* @covers \Engelsystem\Controllers\AuthController::login * @covers \Engelsystem\Controllers\AuthController::login
* @covers \Engelsystem\Controllers\AuthController::showLogin
*/ */
public function testLogin() public function testLogin()
{ {
@ -31,6 +38,10 @@ class AuthControllerTest extends TestCase
/** @var Authenticator|MockObject $auth */ /** @var Authenticator|MockObject $auth */
list(, $session, $url, $auth) = $this->getMocks(); list(, $session, $url, $auth) = $this->getMocks();
$session->expects($this->once())
->method('get')
->with('errors', [])
->willReturn(['foo' => 'bar']);
$response->expects($this->once()) $response->expects($this->once())
->method('withView') ->method('withView')
->with('pages/login') ->with('pages/login')
@ -42,7 +53,6 @@ class AuthControllerTest extends TestCase
/** /**
* @covers \Engelsystem\Controllers\AuthController::postLogin * @covers \Engelsystem\Controllers\AuthController::postLogin
* @covers \Engelsystem\Controllers\AuthController::authenticateUser
*/ */
public function testPostLogin() public function testPostLogin()
{ {
@ -51,10 +61,12 @@ class AuthControllerTest extends TestCase
$request = new Request(); $request = new Request();
/** @var Response|MockObject $response */ /** @var Response|MockObject $response */
$response = $this->createMock(Response::class); $response = $this->createMock(Response::class);
/** @var SessionInterface|MockObject $session */
/** @var UrlGeneratorInterface|MockObject $url */ /** @var UrlGeneratorInterface|MockObject $url */
/** @var Authenticator|MockObject $auth */ /** @var Authenticator|MockObject $auth */
list(, $session, $url, $auth) = $this->getMocks(); list(, , $url, $auth) = $this->getMocks();
$session = new Session(new MockArraySessionStorage());
/** @var Validator|MockObject $validator */
$validator = new Validator(new Validates());
$user = new User([ $user = new User([
'name' => 'foo', 'name' => 'foo',
@ -63,7 +75,7 @@ class AuthControllerTest extends TestCase
'api_key' => '', 'api_key' => '',
'last_login_at' => null, 'last_login_at' => null,
]); ]);
$user->forceFill(['id' => 42,]); $user->forceFill(['id' => 42]);
$user->save(); $user->save();
$settings = new Settings(['language' => 'de_DE', 'theme' => '']); $settings = new Settings(['language' => 'de_DE', 'theme' => '']);
@ -76,41 +88,42 @@ class AuthControllerTest extends TestCase
->with('foo', 'bar') ->with('foo', 'bar')
->willReturnOnConsecutiveCalls(null, $user); ->willReturnOnConsecutiveCalls(null, $user);
$response->expects($this->exactly(3)) $response->expects($this->once())
->method('withView') ->method('withView')
->withConsecutive( ->with('pages/login', ['errors' => Collection::make(['auth.not-found']), 'show_password_recovery' => true])
['pages/login', ['errors' => ['auth.no-nickname'], 'show_password_recovery' => true]],
['pages/login', ['errors' => ['auth.no-password'], 'show_password_recovery' => true]],
['pages/login', ['errors' => ['auth.not-found'], 'show_password_recovery' => true]])
->willReturn($response); ->willReturn($response);
$response->expects($this->once()) $response->expects($this->once())
->method('redirectTo') ->method('redirectTo')
->with('news') ->with('news')
->willReturn($response); ->willReturn($response);
$session->expects($this->once()) // No credentials
->method('invalidate');
$session->expects($this->exactly(2))
->method('set')
->withConsecutive(
['user_id', 42],
['locale', 'de_DE']
);
$controller = new AuthController($response, $session, $url, $auth); $controller = new AuthController($response, $session, $url, $auth);
$controller->setValidator($validator);
try {
$controller->postLogin($request); $controller->postLogin($request);
$this->fail('Login without credentials possible');
} catch (ValidationException $e) {
}
$request = new Request(['login' => 'foo']); // Missing password
$request = new Request([], ['login' => 'foo']);
try {
$controller->postLogin($request); $controller->postLogin($request);
$this->fail('Login without password possible');
} catch (ValidationException $e) {
}
$request = new Request(['login' => 'foo', 'password' => 'bar']);
// No user found // No user found
$request = new Request([], ['login' => 'foo', 'password' => 'bar']);
$controller->postLogin($request); $controller->postLogin($request);
$this->assertEquals([], $session->all());
// Authenticated user // Authenticated user
$controller->postLogin($request); $controller->postLogin($request);
$this->assertNotNull($user->last_login_at); $this->assertNotNull($user->last_login_at);
$this->assertEquals(['user_id' => 42, 'locale' => 'de_DE'], $session->all());
} }
/** /**