rvr-nextgen/src/Controller/OAuthAuthController.php

80 lines
2.9 KiB
PHP
Raw Normal View History

2023-04-11 17:45:08 +02:00
<?php namespace RVR\Controller;
use DateTime;
use RVR\PersistentData\Model\OAuthToken;
use RVR\PersistentData\Model\User;
2023-04-12 00:02:47 +02:00
use RVR\Repository\OAuthClientRepository;
use SokoWeb\Interfaces\Authentication\IAuthenticationRequired;
2023-04-11 17:45:08 +02:00
use SokoWeb\Interfaces\Response\IRedirect;
use SokoWeb\Response\Redirect;
use SokoWeb\Response\HtmlContent;
class OAuthAuthController implements IAuthenticationRequired
2023-04-11 17:45:08 +02:00
{
2023-04-12 00:02:47 +02:00
private OAuthClientRepository $oAuthClientRepository;
2023-04-19 23:19:22 +02:00
public function __construct()
2023-04-11 17:45:08 +02:00
{
2023-04-12 00:02:47 +02:00
$this->oAuthClientRepository = new OAuthClientRepository();
2023-04-11 17:45:08 +02:00
}
public function isAuthenticationRequired(): bool
2023-04-11 17:45:08 +02:00
{
return true;
2023-04-11 17:45:08 +02:00
}
public function auth()
{
2023-04-19 23:19:22 +02:00
$redirectUri = \Container::$request->query('redirect_uri');
$clientId = \Container::$request->query('client_id');
$scope = \Container::$request->query('scope') ? \Container::$request->query('scope'): '';
$state = \Container::$request->query('state');
$nonce = \Container::$request->query('nonce') ? \Container::$request->query('nonce'): '';
2023-04-11 17:45:08 +02:00
2023-04-12 00:02:47 +02:00
if (!$clientId || !$redirectUri || !$state) {
2023-04-11 17:45:08 +02:00
return new HtmlContent('oauth/oauth_error', ['error' => 'An invalid request was made. Please start authentication again.']);
}
2023-04-12 00:02:47 +02:00
$client = $this->oAuthClientRepository->getByClientId($clientId);
if ($client === null) {
return new HtmlContent('oauth/oauth_error', ['error' => 'Client is not authorized.']);
}
$redirectUriParsed = parse_url($redirectUri);
$redirectUriBase = $redirectUriParsed['scheme'] . '://' . $redirectUriParsed['host'] . $redirectUriParsed['path'];
2023-04-12 00:02:47 +02:00
$redirectUriQuery = [];
if (isset($redirectUriParsed['query'])) {
parse_str($redirectUriParsed['query'], $redirectUriQuery);
}
if (!in_array($redirectUriBase, $client->getRedirectUrisArray())) {
return new HtmlContent('oauth/oauth_error', ['error' => 'Redirect URI \'' . $redirectUriBase .'\' is not allowed for this client.']);
}
2023-04-11 17:45:08 +02:00
/**
* @var ?User $user
*/
2023-04-19 23:19:22 +02:00
$user = \Container::$request->user();
2023-04-11 17:45:08 +02:00
$code = bin2hex(random_bytes(16));
$accessToken = bin2hex(random_bytes(16));
$token = new OAuthToken();
$token->setNonce($nonce);
$token->setScope($scope);
$token->setUser($user);
$token->setCode($code);
$token->setAccessToken($accessToken);
$token->setCreatedDate(new DateTime());
$token->setExpiresDate(new DateTime('+5 minutes'));
2023-04-19 23:19:22 +02:00
\Container::$persistentDataManager->saveToDb($token);
2023-04-11 17:45:08 +02:00
2023-04-12 00:02:47 +02:00
$redirectUriQuery = array_merge($redirectUriQuery, [
2023-04-11 17:45:08 +02:00
'state' => $state,
'code' => $code
2023-04-12 00:02:47 +02:00
]);
$finalRedirectUri = $redirectUriBase . '?' . http_build_query($redirectUriQuery);
2023-04-11 17:45:08 +02:00
return new Redirect($finalRedirectUri, IRedirect::TEMPORARY);
}
}