MAPG-181 add stuff to authenticate without password
This commit is contained in:
7 files changed
+248
-8
No files matched your search
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in new issue
Block a user