MAPG-181 add stuff to authenticate without password

This commit is contained in:
bence committed 2020-06-28 03:18:51 +02:00
1 parent 4099f1d962
commit 4333240acc
7 files changed
+248 -8

No files matched your search

+100 -4
View File
@@ -1,16 +1,22 @@
<?php namespace MapGuesser\Controller;
use DateTime;
use MapGuesser\Database\Query\Select;
use MapGuesser\Http\Request;
use MapGuesser\Interfaces\Authorization\ISecured;
use MapGuesser\Interfaces\Database\IResultSet;
use MapGuesser\Interfaces\Request\IRequest;
use MapGuesser\Interfaces\Response\IContent;
use MapGuesser\Interfaces\Response\IRedirect;
use MapGuesser\OAuth\GoogleOAuth;
use MapGuesser\PersistentData\PersistentDataManager;
use MapGuesser\PersistentData\Model\User;
use MapGuesser\PersistentData\Model\UserConfirmation;
use MapGuesser\Repository\UserConfirmationRepository;
use MapGuesser\Response\HtmlContent;
use MapGuesser\Response\JsonContent;
use MapGuesser\Response\Redirect;
use MapGuesser\Util\JwtParser;
class UserController implements ISecured
{
@@ -45,6 +51,63 @@ class UserController implements ISecured
return new HtmlContent('account/account', $data);
}
public function getGoogleAuthenticateRedirect(): IRedirect
{
/**
* @var User $user
*/
$user = $this->request->user();
$state = bin2hex(random_bytes(16));
$this->request->session()->set('oauth_state', $state);
$oAuth = new GoogleOAuth(new Request());
$url = $oAuth->getDialogUrl(
$state,
$this->request->getBase() . '/' . \Container::$routeCollection->getRoute('account.googleAuthenticate-action')->generateLink(),
$user->getEmail()
);
return new Redirect($url, IRedirect::TEMPORARY);
}
public function authenticateWithGoogle(): IContent
{
/**
* @var User $user
*/
$user = $this->request->user();
if ($this->request->query('state') !== $this->request->session()->get('oauth_state')) {
$data = ['success' => false];
return new HtmlContent('account/google_authenticate', $data);
}
$oAuth = new GoogleOAuth(new Request());
$tokenData = $oAuth->getToken($this->request->query('code'), $this->request->getBase() . '/' . \Container::$routeCollection->getRoute('account.googleAuthenticate-action')->generateLink());
if (!isset($tokenData['id_token'])) {
$data = ['success' => false];
return new HtmlContent('account/google_authenticate', $data);
}
$jwtParser = new JwtParser($tokenData['id_token']);
$userData = $jwtParser->getPayload();
if ($userData['sub'] !== $user->getGoogleSub()) {
$data = ['success' => false, 'errorText' => 'This Google account is not linked to your account.'];
return new HtmlContent('account/google_authenticate', $data);
}
$authenticatedWithGoogleUntil = new DateTime('+45 seconds');
$this->request->session()->set('authenticated_with_google_until', $authenticatedWithGoogleUntil);
$data = ['success' => true, 'authenticatedWithGoogleUntil' => $authenticatedWithGoogleUntil];
return new HtmlContent('account/google_authenticate', $data);
}
public function getDeleteAccount(): IContent
{
/**
@@ -63,8 +126,13 @@ class UserController implements ISecured
*/
$user = $this->request->user();
if (!$user->checkPassword($this->request->post('password'))) {
$data = ['error' => ['errorText' => 'The given current password is wrong.']];
if (!$this->confirmUserIdentity(
$user,
$this->request->session()->get('authenticated_with_google_until'),
$this->request->post('password'),
$error
)) {
$data = ['error' => ['errorText' => $error]];
return new JsonContent($data);
}
@@ -84,6 +152,8 @@ class UserController implements ISecured
$this->pdm->saveToDb($user);
$this->request->session()->delete('authenticated_with_google_until');
$data = ['success' => true];
return new JsonContent($data);
}
@@ -95,8 +165,13 @@ class UserController implements ISecured
*/
$user = $this->request->user();
if (!$user->checkPassword($this->request->post('password'))) {
$data = ['error' => ['errorText' => 'The given current password is wrong.']];
if (!$this->confirmUserIdentity(
$user,
$this->request->session()->get('authenticated_with_google_until'),
$this->request->post('password'),
$error
)) {
$data = ['error' => ['errorText' => $error]];
return new JsonContent($data);
}
@@ -110,7 +185,28 @@ class UserController implements ISecured
\Container::$dbConnection->commit();
$this->request->session()->delete('authenticated_with_google_until');
$data = ['success' => true];
return new JsonContent($data);
}
private function confirmUserIdentity(User $user, ?DateTime $authenticatedWithGoogleUntil, ?string $password, &$error): bool
{
if ($authenticatedWithGoogleUntil !== null && $authenticatedWithGoogleUntil > new DateTime()) {
return true;
}
if ($password !== null) {
if ($user->checkPassword($password)) {
return true;
}
$error = 'The given current password is wrong.';
return false;
}
$error = 'Could not confirm your identity. Please try again!';
return false;
}
}