You've already forked php-auth
generated from siteworxpro/Php-Template
All checks were successful
🧪✨ Tests Workflow / 🧪 ✨ Database Migrations (push) Successful in -21s
🧪✨ Tests Workflow / 🛡️ 🔒 License Check (push) Successful in -22s
🧪✨ Tests Workflow / 🛡️ 🔒 Library Audit (push) Successful in -12s
🧪✨ Tests Workflow / 📝 ✨ Code Lint (push) Successful in -20s
🧪✨ Tests Workflow / 🐙 🔍 Code Sniffer (push) Successful in -14s
🧪✨ Tests Workflow / 🧪 ✅ Unit Tests (push) Successful in -36s
164 lines
5.6 KiB
PHP
164 lines
5.6 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Siteworxpro\App\Controllers;
|
|
|
|
use Defuse\Crypto\Exception\BadFormatException;
|
|
use Defuse\Crypto\Exception\EnvironmentIsBrokenException;
|
|
use HansOtt\PSR7Cookies\SetCookie;
|
|
use League\OAuth2\Server\Exception\OAuthServerException;
|
|
use League\OAuth2\Server\RequestTypes\AuthorizationRequest;
|
|
use Nyholm\Psr7\Response;
|
|
use Nyholm\Psr7\ServerRequest;
|
|
use Nyholm\Psr7\Stream;
|
|
use Siteworxpro\App\Events\Login\LoginFailed;
|
|
use Siteworxpro\App\Events\Login\LoginSuccess;
|
|
use Siteworxpro\App\Helpers\Rand;
|
|
use Siteworxpro\App\Http\JsonResponseFactory;
|
|
use Siteworxpro\App\Http\Responses\ServerErrorResponse;
|
|
use Siteworxpro\App\OAuth\Entities\Client;
|
|
use Siteworxpro\App\Services\Facades\Dispatcher;
|
|
use Siteworxpro\App\Services\Facades\Logger;
|
|
use Siteworxpro\App\Services\Facades\Redis;
|
|
use Siteworxpro\HttpStatus\CodesEnum;
|
|
|
|
final class AuthorizeController extends Controller
|
|
{
|
|
/**
|
|
* @param ServerRequest $request
|
|
* @return Response
|
|
* @throws BadFormatException
|
|
* @throws EnvironmentIsBrokenException
|
|
* @throws \JsonException
|
|
*/
|
|
public function post(ServerRequest $request): Response
|
|
{
|
|
$s = $request->getCookieParams()['s'] ?? '';
|
|
|
|
$password = $request->getParsedBody()['password'] ?? '';
|
|
$email = $request->getParsedBody()['email'] ?? '';
|
|
|
|
if (!Redis::get('session:' . $s)) {
|
|
Logger::warning('Session Timed out', ['session' => $s]);
|
|
|
|
return JsonResponseFactory::createJsonResponse([]);
|
|
}
|
|
|
|
/** @var AuthorizationRequest $authRequest */
|
|
$authRequest = unserialize(Redis::get('session:' . $s));
|
|
|
|
/** @var Client $client */
|
|
$client = $authRequest->getClient();
|
|
|
|
$authorizationServer = $client->getAuthorizationServer();
|
|
|
|
if ($authRequest->isAuthorizationApproved()) {
|
|
$response = $authorizationServer
|
|
->completeAuthorizationRequest($authRequest, JsonResponseFactory::createJsonResponse([]));
|
|
|
|
return JsonResponseFactory::createJsonResponse([
|
|
'success' => true,
|
|
'location' => $response->getHeader('Location')[0]
|
|
]);
|
|
}
|
|
|
|
$user = $client->loginUser($email, $password);
|
|
|
|
if (!$user) {
|
|
Dispatcher::push(new LoginFailed($request, $client));
|
|
|
|
return JsonResponseFactory::createJsonResponse([
|
|
'success' => false,
|
|
'reason' => 'login failed'
|
|
], CodesEnum::UNAUTHORIZED);
|
|
}
|
|
|
|
$authRequest->setUser($user);
|
|
$authRequest->setAuthorizationApproved(true);
|
|
$response = $authorizationServer
|
|
->completeAuthorizationRequest($authRequest, JsonResponseFactory::createJsonResponse([]));
|
|
|
|
Redis::del('session:' . $s);
|
|
|
|
Dispatcher::push(new LoginSuccess($request, $client, $user));
|
|
|
|
return JsonResponseFactory::createJsonResponse([
|
|
'success' => true,
|
|
'location' => $response->getHeader('Location')[0]
|
|
]);
|
|
}
|
|
|
|
/**
|
|
* @throws \Exception
|
|
*/
|
|
public function get(ServerRequest $request): Response
|
|
{
|
|
try {
|
|
if (!file_exists('public/index.html')) {
|
|
throw new \RuntimeException('Frontend not built. Please run `npm run build`.');
|
|
}
|
|
$contents = file_get_contents('public/index.html');
|
|
|
|
if ($request->getQueryParams()['e']) {
|
|
return new Response(
|
|
200,
|
|
['content-type' => 'text/html'],
|
|
Stream::create($contents)
|
|
);
|
|
}
|
|
|
|
if (
|
|
isset($request->getCookieParams()['s']) &&
|
|
Redis::exists('session:' . $request->getCookieParams()['s'])
|
|
) {
|
|
$s = $request->getCookieParams()['s'];
|
|
} else {
|
|
$s = Rand::string();
|
|
}
|
|
|
|
$clientId = $request->getQueryParams()['client_id'] ?? '';
|
|
Logger::info('Authorization request', ['client_id' => $clientId]);
|
|
|
|
$client = Client::byClientId($clientId);
|
|
if ($client === null) {
|
|
Logger::warning('Invalid client in authorization request', ['client_id' => $clientId]);
|
|
throw OAuthServerException::invalidClient($request);
|
|
}
|
|
|
|
$authRequest = $client->getAuthorizationServer()->validateAuthorizationRequest($request);
|
|
Redis::set('session:' . $s, serialize($authRequest), 'EX', 60 * 60 * 24);
|
|
|
|
$response = new Response(
|
|
200,
|
|
['content-type' => 'text/html'],
|
|
Stream::create($contents)
|
|
);
|
|
|
|
$cookie = new SetCookie('s', $s, time() + 3600, '/', secure: true);
|
|
|
|
/** @var Response $response */
|
|
$response = $cookie->addToResponse($response);
|
|
|
|
return $response;
|
|
} catch (OAuthServerException $e) {
|
|
return new Response(
|
|
CodesEnum::TEMPORARY_REDIRECT->value,
|
|
[
|
|
'Location' => sprintf(
|
|
'/authorize?e=%s&client_id=%s&response_type=%s&redirect_uri=%s#/error',
|
|
$e->getMessage(),
|
|
$request->getQueryParams()['client_id'] ?? '',
|
|
$request->getQueryParams()['response_type'] ?? '',
|
|
$request->getQueryParams()['redirect_uri'] ?? ''
|
|
)
|
|
]
|
|
);
|
|
} catch (\Exception $e) {
|
|
Logger::error($e->getMessage(), ['exception' => $e]);
|
|
|
|
return JsonResponseFactory::createJsonResponse(new ServerErrorResponse($e));
|
|
}
|
|
}
|
|
}
|