You've already forked php-auth
generated from siteworxpro/Php-Template
Basics of auth
Some checks failed
🧪✨ Tests Workflow / 🛡️ 🔒 License Check (push) Successful in 54s
🧪✨ Tests Workflow / 🧪 ✨ Database Migrations (push) Failing after 1m4s
🧪✨ Tests Workflow / 🛡️ 🔒 Library Audit (push) Successful in 1m14s
🧪✨ Tests Workflow / 📝 ✨ Code Lint (push) Successful in 1m10s
🧪✨ Tests Workflow / 🐙 🔍 Code Sniffer (push) Successful in 1m19s
🧪✨ Tests Workflow / 🧪 ✅ Unit Tests (push) Failing after 1m12s
Some checks failed
🧪✨ Tests Workflow / 🛡️ 🔒 License Check (push) Successful in 54s
🧪✨ Tests Workflow / 🧪 ✨ Database Migrations (push) Failing after 1m4s
🧪✨ Tests Workflow / 🛡️ 🔒 Library Audit (push) Successful in 1m14s
🧪✨ Tests Workflow / 📝 ✨ Code Lint (push) Successful in 1m10s
🧪✨ Tests Workflow / 🐙 🔍 Code Sniffer (push) Successful in 1m19s
🧪✨ Tests Workflow / 🧪 ✅ Unit Tests (push) Failing after 1m12s
This commit is contained in:
@@ -13,8 +13,6 @@ use Siteworxpro\App\Controllers\AccessTokenController;
|
||||
use Siteworxpro\App\Controllers\AuthorizeController;
|
||||
use Siteworxpro\App\Controllers\CapabilitiesController;
|
||||
use Siteworxpro\App\Controllers\HealthcheckController;
|
||||
use Siteworxpro\App\Controllers\IndexController;
|
||||
use Siteworxpro\App\Controllers\OpenApiController;
|
||||
use Siteworxpro\App\Controllers\OpenIdController;
|
||||
use Siteworxpro\App\Http\JsonResponseFactory;
|
||||
use Siteworxpro\App\Http\Middleware\CorsMiddleware;
|
||||
|
||||
@@ -73,12 +73,6 @@ use Symfony\Component\Console\Output\OutputInterface;
|
||||
* @method mixed progress(integer $total = null)
|
||||
* @method Spinner spinner(string $label = null, string ...$characters = null)
|
||||
* @method mixed padding(integer $length = 0, string $char = '.')
|
||||
* @method mixed input(string $prompt, Util\Reader\ReaderInterface $reader = null)
|
||||
* @method mixed confirm(string $prompt, Util\Reader\ReaderInterface $reader = null)
|
||||
* @method mixed password(string $prompt, Util\Reader\ReaderInterface $reader = null)
|
||||
* @method mixed checkboxes(string $prompt, array $options, Util\Reader\ReaderInterface $reader = null)
|
||||
* @method mixed radio(string $prompt, array $options, Util\Reader\ReaderInterface $reader = null)
|
||||
* @method mixed animation(string $art, TerminalObject\Helper\Sleeper $sleeper = null)
|
||||
* @method mixed columns(array $data, $column_count = null)
|
||||
* @method mixed clear()
|
||||
* @method CLImate clearLine()
|
||||
@@ -146,6 +140,9 @@ class ClimateOutput extends ConsoleSectionOutput implements ConsoleOutputInterfa
|
||||
$this->verbosity = $level;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function getVerbosity(): int
|
||||
{
|
||||
return $this->verbosity;
|
||||
|
||||
@@ -21,7 +21,12 @@ class ListClients extends Command
|
||||
$this->addArgument('client-id', null, 'Filter by client ID');
|
||||
}
|
||||
|
||||
public function __invoke(ArgvInput|InputInterface $input, ClimateOutput|OutputInterface $output): int
|
||||
/**
|
||||
* @param ArgvInput|InputInterface $input
|
||||
* @param ClimateOutput $output
|
||||
* @return int
|
||||
*/
|
||||
public function __invoke(ArgvInput|InputInterface $input, $output): int
|
||||
{
|
||||
if ($input->getArgument('client-id')) {
|
||||
$client = Client::find($input->getArgument('client-id'));
|
||||
@@ -57,7 +62,7 @@ class ListClients extends Command
|
||||
|
||||
$outputArray = [];
|
||||
|
||||
$clients->map(function (Client $client) use (&$outputArray, $input) {
|
||||
$clients->map(function (Client $client) use (&$outputArray) {
|
||||
$outputValues = [
|
||||
'ID' => $client->id,
|
||||
'Name' => $client->name,
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Siteworxpro\App\Cli\Commands\User;
|
||||
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Siteworxpro\App\Cli\Commands\Command;
|
||||
use Siteworxpro\App\Models\ClientUser;
|
||||
use Siteworxpro\App\Models\User;
|
||||
@@ -18,6 +19,7 @@ class Add extends Command
|
||||
{
|
||||
public function __invoke($input, $output): int
|
||||
{
|
||||
/** @var Collection<Client> $clients */
|
||||
$clients = Client::whereJsonContains('grant_types', 'authorization_code')
|
||||
->get(['id', 'name']);
|
||||
|
||||
@@ -51,6 +53,7 @@ class Add extends Command
|
||||
|
||||
$email = $helper->ask($input, $output, $emailQuestion);
|
||||
|
||||
/** @var User| null $user */
|
||||
$user = User::where('email', $email)->first();
|
||||
if ($user) {
|
||||
$output->yellow('A user with this email already exists. Associating the user with the client.');
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Siteworxpro\App\CommandBus\Handlers\OAuth;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
use Siteworxpro\App\Attributes\CommandBus\HandlesCommand;
|
||||
use Siteworxpro\App\CommandBus\Commands\Command;
|
||||
use Siteworxpro\App\CommandBus\Exceptions\CommandHandlerException;
|
||||
@@ -22,7 +23,7 @@ class CreateClient extends CommandHandler
|
||||
$client = new Client();
|
||||
$client->name = $command->getClientName();
|
||||
$client->description = $command->getClientDescription();
|
||||
$client->grant_types = $command->getClientGrants();
|
||||
$client->grant_types = new Collection($command->getClientGrants()); // @phpstan-ignore-line assign.propertyType
|
||||
|
||||
$client->save();
|
||||
|
||||
|
||||
@@ -103,7 +103,7 @@ final class AuthorizeController extends Controller
|
||||
|
||||
if (
|
||||
isset($request->getCookieParams()['s']) &&
|
||||
Redis::exists('session:' . $request->getCookieParams()['s'] ?? '')
|
||||
Redis::exists('session:' . $request->getCookieParams()['s'])
|
||||
) {
|
||||
$s = $request->getCookieParams()['s'];
|
||||
} else {
|
||||
|
||||
@@ -1,66 +0,0 @@
|
||||
<?php
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Siteworxpro\App\Controllers;
|
||||
|
||||
use Nyholm\Psr7\ServerRequest;
|
||||
use Psr\Http\Message\ResponseInterface;
|
||||
use Siteworxpro\App\Attributes\Guards;
|
||||
use Siteworxpro\App\CommandBus\Commands\ExampleCommand;
|
||||
use Siteworxpro\App\Docs\TokenSecurity;
|
||||
use Siteworxpro\App\Docs\UnauthorizedResponse;
|
||||
use Siteworxpro\App\Http\JsonResponseFactory;
|
||||
use OpenApi\Attributes as OA;
|
||||
use Siteworxpro\App\Http\Responses\GenericResponse;
|
||||
use Siteworxpro\App\Services\Facades\CommandBus;
|
||||
|
||||
/**
|
||||
* Class IndexController
|
||||
*
|
||||
* This class handles the index route of the application.
|
||||
*/
|
||||
final class IndexController extends Controller
|
||||
{
|
||||
/**
|
||||
* Handles the GET request for the index route.
|
||||
*
|
||||
* @throws \JsonException
|
||||
*/
|
||||
#[Guards\Jwt]
|
||||
#[Guards\Scope(['get.index', 'status.check'])]
|
||||
#[Guards\RequireAllScopes]
|
||||
#[OA\Get(path: '/', security: [new TokenSecurity()], tags: ['Examples'])]
|
||||
#[OA\Response(
|
||||
response: '200',
|
||||
description: 'An Example Response',
|
||||
content: new OA\JsonContent(ref: '#/components/schemas/GenericResponse')
|
||||
)]
|
||||
#[UnauthorizedResponse]
|
||||
public function get(ServerRequest $request): ResponseInterface
|
||||
{
|
||||
$command = new ExampleCommand($request->getQueryParams()['name'] ?? 'Guest');
|
||||
$greeting = CommandBus::handle($command);
|
||||
|
||||
return JsonResponseFactory::createJsonResponse(new GenericResponse('Server is running. ' . $greeting));
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the POST request for the index route.
|
||||
*
|
||||
* @throws \JsonException
|
||||
*/
|
||||
#[Guards\Jwt]
|
||||
#[Guards\Scope(['post.index'])]
|
||||
#[OA\Post(path: '/', security: [new TokenSecurity()], tags: ['Examples'])]
|
||||
#[OA\Response(
|
||||
response: '200',
|
||||
description: 'An Example Response',
|
||||
content: new OA\JsonContent(ref: '#/components/schemas/GenericResponse')
|
||||
)]
|
||||
#[UnauthorizedResponse]
|
||||
public function post(ServerRequest $request): ResponseInterface
|
||||
{
|
||||
return JsonResponseFactory::createJsonResponse(new GenericResponse('POST request received'));
|
||||
}
|
||||
}
|
||||
@@ -7,18 +7,15 @@ namespace Siteworxpro\App\GrpcHandlers;
|
||||
use GRPC\Greeter\GreeterInterface;
|
||||
use GRPC\Greeter\HelloReply;
|
||||
use GRPC\Greeter\HelloRequest;
|
||||
use Siteworxpro\App\CommandBus\Commands\ExampleCommand;
|
||||
use Siteworxpro\App\Services\Facades\CommandBus;
|
||||
use Spiral\RoadRunner\GRPC;
|
||||
|
||||
class GreeterHandler implements GreeterInterface
|
||||
{
|
||||
public function SayHello(GRPC\ContextInterface $ctx, HelloRequest $in): HelloReply // phpcs:ignore
|
||||
{
|
||||
$command = new ExampleCommand($in->getName());
|
||||
|
||||
$reply = new HelloReply();
|
||||
$reply->setMessage(CommandBus::handle($command));
|
||||
$reply->setMessage('Hello ' . $in->getName());
|
||||
|
||||
return $reply;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ declare(strict_types=1);
|
||||
|
||||
namespace Siteworxpro\App\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Model as ORM;
|
||||
use Siteworxpro\App\Helpers\Ulid;
|
||||
|
||||
@@ -12,8 +13,8 @@ use Siteworxpro\App\Helpers\Ulid;
|
||||
*
|
||||
* @package Siteworxpro\App\Models
|
||||
* @method static static|null find(string $id, array $columns = ['*'])
|
||||
* @method static where(string $column, string $operator = null, string $value = null, string $boolean = 'and')
|
||||
* @method static whereJsonContains(string $column, mixed $value, string $boolean = 'and', bool $not = false)
|
||||
* @method static Builder where(string $column, string $operator = null, string $value = null, string $boolean = 'and')
|
||||
* @method static Builder whereJsonContains(string $column, mixed $value, string $boolean = 'and', bool $not = false)
|
||||
*/
|
||||
abstract class Model extends ORM
|
||||
{
|
||||
|
||||
@@ -29,16 +29,15 @@ class AccessTokenRepository implements AccessTokenRepositoryInterface
|
||||
|
||||
public function persistNewAccessToken(AccessTokenEntityInterface | AccessToken $accessTokenEntity): void
|
||||
{
|
||||
$accessTokenEntity->save();
|
||||
if ($accessTokenEntity instanceof AccessToken) {
|
||||
$accessTokenEntity->save();
|
||||
}
|
||||
}
|
||||
|
||||
public function revokeAccessToken(string $tokenId): void
|
||||
{
|
||||
$accessToken = AccessToken::find($tokenId);
|
||||
|
||||
if ($accessToken) {
|
||||
$accessToken->delete();
|
||||
}
|
||||
$accessToken?->delete();
|
||||
}
|
||||
|
||||
public function isAccessTokenRevoked(string $tokenId): bool
|
||||
|
||||
@@ -18,12 +18,11 @@ class AuthCodeRepository implements AuthCodeRepositoryInterface
|
||||
|
||||
public function persistNewAuthCode(AuthCodeEntityInterface | AuthorizationCode $authCodeEntity): void
|
||||
{
|
||||
$authCodeEntity->save();
|
||||
if ($authCodeEntity instanceof AuthorizationCode) {
|
||||
$authCodeEntity->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function revokeAuthCode(string $codeId): void
|
||||
{
|
||||
$authCode = AuthorizationCode::find($codeId);
|
||||
|
||||
@@ -17,11 +17,11 @@ class AccessToken extends RedisModel implements AccessTokenEntityInterface
|
||||
{
|
||||
use AccessTokenTrait;
|
||||
|
||||
private Client |null $client = null;
|
||||
private ClientEntityInterface | Client |null $client = null;
|
||||
|
||||
private string | null $userIdentifier = null;
|
||||
|
||||
/** @var ScopeEntityInterface|Scope[] */
|
||||
/** @var ScopeEntityInterface[]|Scope[] */
|
||||
private array $scopes = [];
|
||||
|
||||
public function getClient(): ClientEntityInterface
|
||||
@@ -29,7 +29,10 @@ class AccessToken extends RedisModel implements AccessTokenEntityInterface
|
||||
return $this->client;
|
||||
}
|
||||
|
||||
private function convertToJWT(): Token
|
||||
/**
|
||||
* @return Token
|
||||
*/
|
||||
private function convertToJWT(): Token // @phpstan-ignore method.unused
|
||||
{
|
||||
$this->initJwtConfiguration();
|
||||
|
||||
|
||||
@@ -15,7 +15,7 @@ class AuthorizationCode extends RedisModel implements AuthCodeEntityInterface
|
||||
{
|
||||
use AuthCodeTrait;
|
||||
|
||||
private Client | null $client = null;
|
||||
private ClientEntityInterface | Client | null $client = null;
|
||||
|
||||
private string | null $userIdentifier = null;
|
||||
|
||||
|
||||
@@ -35,7 +35,7 @@ use Siteworxpro\App\OAuth\ScopeRepository;
|
||||
* @property string $description
|
||||
* @property string $private_key
|
||||
* @property string $encryption_key
|
||||
* @property Collection<string> $grant_types
|
||||
* @property Collection $grant_types
|
||||
* @property bool $confidential
|
||||
*
|
||||
* @property-read ClientCapabilities $capabilities
|
||||
@@ -66,7 +66,10 @@ class Client extends Model implements ClientEntityInterface
|
||||
|
||||
public static function byClientId(string $clientId): ?Client
|
||||
{
|
||||
return self::where('client_id', $clientId)->first();
|
||||
/** @var Client|null $client */
|
||||
$client = self::where('client_id', $clientId)->first();
|
||||
|
||||
return $client;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -11,7 +11,7 @@ use League\OAuth2\Server\Entities\RefreshTokenEntityInterface;
|
||||
|
||||
class RefreshToken extends RedisModel implements RefreshTokenEntityInterface
|
||||
{
|
||||
private AccessToken | null $accessToken = null;
|
||||
private AccessTokenEntityInterface | AccessToken | null $accessToken = null;
|
||||
|
||||
protected static function getRedisPrefix(): string
|
||||
{
|
||||
|
||||
@@ -18,12 +18,11 @@ class RefreshTokenRepository implements RefreshTokenRepositoryInterface
|
||||
|
||||
public function persistNewRefreshToken(RefreshTokenEntityInterface | RefreshToken $refreshTokenEntity): void
|
||||
{
|
||||
$refreshTokenEntity->save();
|
||||
if ($refreshTokenEntity instanceof RefreshToken) {
|
||||
$refreshTokenEntity->save();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function revokeRefreshToken(string $tokenId): void
|
||||
{
|
||||
$token = RefreshToken::find($tokenId);
|
||||
|
||||
@@ -13,7 +13,10 @@ class ScopeRepository implements ScopeRepositoryInterface
|
||||
{
|
||||
public function getScopeEntityByIdentifier(string $identifier): ?ScopeEntityInterface
|
||||
{
|
||||
return Scope::where('name', $identifier)->first();
|
||||
/** @var Scope $scope */
|
||||
$scope = Scope::where('name', $identifier)->first();
|
||||
|
||||
return $scope;
|
||||
}
|
||||
|
||||
public function finalizeScopes(
|
||||
|
||||
Reference in New Issue
Block a user