Basics of auth
Some checks failed
🧪✨ Tests Workflow / 🛡️ 🔒 Library Audit (push) Successful in 2m31s
🧪✨ Tests Workflow / 📝 ✨ Code Lint (push) Successful in 2m24s
🧪✨ Tests Workflow / 🛡️ 🔒 License Check (push) Successful in 2m57s
🧪✨ Tests Workflow / 🧪 ✨ Database Migrations (push) Successful in 3m14s
🧪✨ Tests Workflow / 🐙 🔍 Code Sniffer (push) Failing after 2m58s
🧪✨ Tests Workflow / 🧪 ✅ Unit Tests (push) Failing after 1m24s

This commit is contained in:
2026-01-01 15:38:19 -05:00
parent 9f895bbb85
commit d0cee7b48f
35 changed files with 664 additions and 202 deletions

View File

@@ -0,0 +1,66 @@
<?php
declare(strict_types=1);
namespace Siteworxpro\App\Controllers;
use Defuse\Crypto\Exception\BadFormatException;
use Defuse\Crypto\Exception\EnvironmentIsBrokenException;
use League\OAuth2\Server\Exception\OAuthServerException;
use Nyholm\Psr7\ServerRequest;
use Psr\Http\Message\ResponseInterface;
use Siteworxpro\App\Http\JsonResponseFactory;
use Siteworxpro\App\Http\Responses\GenericResponse;
use Siteworxpro\App\OAuth\Entities\AuthorizationCode;
use Siteworxpro\App\OAuth\Entities\Client;
use Siteworxpro\HttpStatus\CodesEnum;
final class AccessTokenController extends Controller
{
/**
* @param ServerRequest $request
* @return ResponseInterface
* @throws BadFormatException
* @throws EnvironmentIsBrokenException
* @throws \JsonException
* @throws OAuthServerException
*/
public function post(ServerRequest $request): ResponseInterface
{
try {
$grantType = $request->getParsedBody()['grant_type'] ?? null;
$client = Client::find($request->getAttribute('client_id'));
if ($client === null) {
return JsonResponseFactory::createJsonResponse(
new GenericResponse('Invalid client'),
CodesEnum::BAD_REQUEST,
);
}
switch ($grantType) {
case 'authorization_code':
return $client
->getAuthorizationServer()
->respondToAccessTokenRequest($request, JsonResponseFactory::createJsonResponse([]));
case 'refresh_token':
break;
default:
return JsonResponseFactory::createJsonResponse(
new GenericResponse('Unsupported grant type'),
CodesEnum::BAD,
);
}
$response = $this->authorizationServer->respondToAccessTokenRequest(
$request,
new Response(),
);
return $response;
} catch (OAuthServerException $e) {
return $e->generateHttpResponse(new Response());
}
}
}

View File

@@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
namespace Siteworxpro\App\Controllers\Admin;
use Nyholm\Psr7\ServerRequest;
use Psr\Http\Message\ResponseInterface;
use Siteworxpro\App\Attributes\Guards\Jwt;
use Siteworxpro\App\Attributes\Guards\Scope;
use Siteworxpro\App\Controllers\Controller;
use Siteworxpro\App\Http\JsonResponseFactory;
use Siteworxpro\App\OAuth\Entities\Client;
#[Jwt]
final class ClientsController extends Controller
{
/**
* @throws \JsonException
*/
#[Scope(['admin:clients:view'])]
public function get(ServerRequest $request): ResponseInterface
{
$clients = Client::all();
return JsonResponseFactory::createJsonResponse($clients->toArray());
}
}

View File

@@ -4,12 +4,14 @@ 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 Psr\SimpleCache\InvalidArgumentException;
use Siteworxpro\App\Helpers\Rand;
use Siteworxpro\App\Http\JsonResponseFactory;
use Siteworxpro\App\Http\Responses\ServerErrorResponse;
@@ -21,75 +23,64 @@ use Siteworxpro\HttpStatus\CodesEnum;
final class AuthorizeController extends Controller
{
/**
* @throws InvalidArgumentException
* @param ServerRequest $request
* @return Response
* @throws BadFormatException
* @throws EnvironmentIsBrokenException
* @throws \JsonException
*/
// #[\Override] public function post(ServerRequest $request): Response
// {
// $s = $request->getCookieParams()['s'] ?? '';
//
// $password = $request->getParsedBody()['password'] ?? '';
// $email = $request->getParsedBody()['email'] ?? '';
//
// if (!$this->redis->get('session:' . $s)) {
// $this->log->error('Session Timed out', ['session' => $s]);
//
// return $this->sendJsonResponse(
// [
// 'error' => "your login session has timed out. please try again."
// ],
// 400
// );
// }
//
// /** @var AuthorizationRequest $authRequest */
// $authRequest = unserialize($this->redis->get('session:' . $s));
//
// if ($authRequest->isAuthorizationApproved()) {
// $response = $this
// ->authorizationServer
// ->completeAuthorizationRequest($authRequest, $this->sendJsonResponse());
//
// return $this->sendJsonResponse(
// [
// 'success' => true,
// 'location' => $response->getHeader('Location')[0]
// ]
// );
// }
//
// /** @var Client $client */
// $client = $authRequest->getClient();
//
// /** @var LoginInterface $entitiesModel */
// $entitiesModel = $client->entities_model;
//
// /** @var User | null $entity */
// $entity = $entitiesModel::performLogin($email, $password);
// if (!$entity) {
// return $this->sendJsonResponse(
// [
// 'success' => false,
// 'reason' => 'login failed'
// ],
// 401
// );
// }
//
// $authRequest->setUser($entity);
// $authRequest->setAuthorizationApproved(true);
// $response = $this
// ->authorizationServer
// ->completeAuthorizationRequest($authRequest, $this->sendJsonResponse());
//
// $this->redis->delete('session:' . $s);
//
// return $this->sendJsonResponse(
// [
// 'success' => true,
// 'location' => $response->getHeader('Location')[0]
// ]
// );
// }
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) {
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);
return JsonResponseFactory::createJsonResponse([
'success' => true,
'location' => $response->getHeader('Location')[0]
]);
}
/**
* @throws \Exception

View File

@@ -25,6 +25,8 @@ final class CapabilitiesController extends Controller
return JsonResponseFactory::createJsonResponse(new NotFoundResponse($request->getUri()->getPath()));
}
return JsonResponseFactory::createJsonResponse($client->capabilities->toArray());
return JsonResponseFactory::createJsonResponse(array_merge($client->capabilities->toArray(), [
'client_name' => $client->name,
]));
}
}

View File

@@ -0,0 +1,48 @@
<?php
declare(strict_types=1);
namespace Siteworxpro\App\Controllers;
use Nyholm\Psr7\ServerRequest;
use Psr\Http\Message\ResponseInterface;
use Siteworxpro\App\Http\JsonResponseFactory;
use Siteworxpro\App\OAuth\Entities\Client;
use Siteworxpro\App\Services\Facades\Config;
use Siteworxpro\HttpStatus\CodesEnum;
final class OpenIdController extends Controller
{
/**
* @throws \JsonException
*/
public function get(ServerRequest $request): ResponseInterface
{
$clientId = $request->getAttribute('client_id');
$client = Client::find($clientId);
if (!$client) {
return JsonResponseFactory::createJsonResponse(
['error' => 'invalid_client'],
CodesEnum::BAD_REQUEST
);
}
$data = [
'issuer' => Config::get('app.url') . '/' . $clientId,
'authorization_endpoint' => Config::get('app.url') . '/authorize',
'token_endpoint' => Config::get('app.url') . '/client/' . $clientId . '/access_token',
'userinfo_endpoint' => Config::get('app.url') . '/user_info',
'end_session_endpoint' => Config::get('app.url') . '/end-session',
'introspection_endpoint' => Config::get('app.url') . '/introspect',
'revocation_endpoint' => Config::get('app.url') . '/revoke',
'device_authorization_endpoint' => Config::get('app.url') . '/device',
'jwks_uri' => Config::get('app.url') . '/client/' . $clientId . '/jwks',
'grant_types_supported' => $client->grant_types,
'scopes_supported' => $client->scopes->pluck('name')->toArray()
];
return JsonResponseFactory::createJsonResponse($data);
}
}