Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,9 @@
"stan": "@phpstan",
"stan-baseline": "tools/phpstan --generate-baseline",
"stan-setup": "phive install",
"rector-setup": "cp composer.json composer.backup && composer require --dev rector/rector:\"~2.3.1\" && mv composer.backup composer.json",
"rector-check": "vendor/bin/rector process --dry-run",
"rector-fix": "vendor/bin/rector process",
"test": "phpunit",
"test-coverage": "phpunit --coverage-clover=clover.xml"
},
Expand Down
55 changes: 55 additions & 0 deletions rector.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
<?php
declare(strict_types=1);

use Rector\Caching\ValueObject\Storage\FileCacheStorage;
use Rector\CodeQuality\Rector\FuncCall\CompactToVariablesRector;
use Rector\CodeQuality\Rector\If_\ExplicitBoolCompareRector;
use Rector\CodingStyle\Rector\Assign\SplitDoubleAssignRector;
use Rector\CodingStyle\Rector\Catch_\CatchExceptionNameMatchingTypeRector;
use Rector\CodingStyle\Rector\Stmt\NewlineAfterStatementRector;
use Rector\Config\RectorConfig;
use Rector\DeadCode\Rector\ClassMethod\RemoveUselessReturnTagRector;
use Rector\Php74\Rector\Closure\ClosureToArrowFunctionRector;
use Rector\Php80\Rector\Class_\ClassPropertyAssignToConstructorPromotionRector;
use Rector\Set\ValueObject\SetList;
use Rector\TypeDeclaration\Rector\Class_\TypedPropertyFromCreateMockAssignRector;
use Rector\TypeDeclaration\Rector\ClassMethod\ReturnTypeFromStrictFluentReturnRector;

$cacheDir = getenv('RECTOR_CACHE_DIR') ?: sys_get_temp_dir() . DIRECTORY_SEPARATOR . 'rector';

return RectorConfig::configure()
->withPaths([
__DIR__ . '/src',
__DIR__ . '/tests',
])

->withCache(
cacheClass: FileCacheStorage::class,
cacheDirectory: $cacheDir,
)

->withPhpSets()
->withAttributesSets()

->withSets([
SetList::CODE_QUALITY,
SetList::CODING_STYLE,
SetList::DEAD_CODE,
SetList::EARLY_RETURN,
SetList::INSTANCEOF,
SetList::TYPE_DECLARATION,
])

->withSkip([
__DIR__ . '/tests/comparisons',
ClassPropertyAssignToConstructorPromotionRector::class,
CatchExceptionNameMatchingTypeRector::class,
ClosureToArrowFunctionRector::class,
RemoveUselessReturnTagRector::class,
CompactToVariablesRector::class,
ReturnTypeFromStrictFluentReturnRector::class,
SplitDoubleAssignRector::class,
NewlineAfterStatementRector::class,
ExplicitBoolCompareRector::class,
TypedPropertyFromCreateMockAssignRector::class,
]);
3 changes: 2 additions & 1 deletion src/AuthorizationPlugin.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@
namespace Authorization;

use Authorization\Command\PolicyCommand;
use Bake\Command\SimpleBakeCommand;
use Cake\Console\CommandCollection;
use Cake\Core\BasePlugin;

Expand All @@ -33,7 +34,7 @@ class AuthorizationPlugin extends BasePlugin
*/
public function console(CommandCollection $commands): CommandCollection
{
if (class_exists('Bake\Command\SimpleBakeCommand')) {
if (class_exists(SimpleBakeCommand::class)) {
$commands->add('bake policy', PolicyCommand::class);
}

Expand Down
8 changes: 2 additions & 6 deletions src/AuthorizationService.php
Original file line number Diff line number Diff line change
Expand Up @@ -29,15 +29,11 @@ class AuthorizationService implements AuthorizationServiceInterface
{
/**
* Authorization policy resolver.
*
* @var \Authorization\Policy\ResolverInterface
*/
protected ResolverInterface $resolver;

/**
* Track whether authorization was checked.
*
* @var bool
*/
protected bool $authorizationChecked = false;

Expand Down Expand Up @@ -144,7 +140,7 @@ protected function getCanHandler(mixed $policy, string $action): Closure

assert(
method_exists($policy, $method) || method_exists($policy, '__call'),
new MissingMethodException([$method, $action, get_class($policy)]),
new MissingMethodException([$method, $action, $policy::class]),
);

/** @phpstan-ignore callable.nonCallable */
Expand All @@ -165,7 +161,7 @@ protected function getScopeHandler(mixed $policy, string $action): Closure

assert(
method_exists($policy, $method) || method_exists($policy, '__call'),
new MissingMethodException([$method, $action, get_class($policy)]),
new MissingMethodException([$method, $action, $policy::class]),
);

/** @phpstan-ignore callable.nonCallable */
Expand Down
15 changes: 6 additions & 9 deletions src/Command/PolicyCommand.php
Original file line number Diff line number Diff line change
Expand Up @@ -16,10 +16,12 @@
*/
namespace Authorization\Command;

use Authorization\IdentityInterface;
use Bake\Command\SimpleBakeCommand;
use Cake\Console\Arguments;
use Cake\Console\ConsoleIo;
use Cake\Console\ConsoleOptionParser;
use Cake\ORM\Query\SelectQuery;
use Cake\Utility\Inflector;
use RuntimeException;

Expand All @@ -30,14 +32,9 @@ class PolicyCommand extends SimpleBakeCommand
{
/**
* Path to Policy directory
*
* @var string
*/
public string $pathFragment = 'Policy/';

/**
* @var string
*/
protected string $type;

/**
Expand Down Expand Up @@ -91,13 +88,13 @@ public function templateData(Arguments $arguments): array
$imports = [];
$className = $data['namespace'] . '\\' . $name;
if ($type === 'table') {
$className = "{$data['namespace']}\Model\\Table\\{$name}{$suffix}";
$imports[] = 'Cake\ORM\Query\SelectQuery';
$className = sprintf('%s\Model\Table\%s%s', $data['namespace'], $name, $suffix);
$imports[] = SelectQuery::class;
} elseif ($type === 'entity') {
$className = "{$data['namespace']}\Model\\Entity\\{$name}";
$className = sprintf('%s\Model\Entity\%s', $data['namespace'], $name);
$imports[] = $className;
}
$imports[] = 'Authorization\\IdentityInterface';
$imports[] = IdentityInterface::class;

$variable = Inflector::variable($name);
if ($variable === 'user') {
Expand Down
12 changes: 6 additions & 6 deletions src/Controller/Component/AuthorizationComponent.php
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public function authorize(mixed $resource, ?string $action = null): void
}

if (is_object($resource)) {
$name = get_class($resource);
$name = $resource::class;
} elseif (is_string($resource)) {
$name = $resource;
} else {
Expand Down Expand Up @@ -131,7 +131,7 @@ protected function performCheck(
}

$identity = $this->getIdentity($request);
if ($identity === null) {
if (!$identity instanceof IdentityInterface) {
return $this->getService($request)->{$method}(null, $action, $resource);
}

Expand All @@ -156,7 +156,7 @@ public function applyScope(mixed $resource, ?string $action = null, mixed ...$op
$action = $this->getDefaultAction($request);
}
$identity = $this->getIdentity($request);
if ($identity === null) {
if (!$identity instanceof IdentityInterface) {
return $this->getService($request)->applyScope(null, $action, $resource);
}

Expand Down Expand Up @@ -233,7 +233,7 @@ protected function getService(ServerRequestInterface $request): AuthorizationSer
$serviceAttribute = $this->getConfig('serviceAttribute');
$service = $request->getAttribute($serviceAttribute);
if (!$service instanceof AuthorizationServiceInterface) {
$type = is_object($service) ? get_class($service) : gettype($service);
$type = get_debug_type($service);
throw new InvalidArgumentException(sprintf(
'Expected that `%s` would be an instance of %s, but got %s',
$serviceAttribute,
Expand Down Expand Up @@ -261,7 +261,7 @@ protected function getIdentity(ServerRequestInterface $request): ?IdentityInterf
return $identity;
}
if (!$identity instanceof IdentityInterface) {
$type = is_object($identity) ? get_class($identity) : gettype($identity);
$type = get_debug_type($identity);
throw new InvalidArgumentException(sprintf(
'Expected that `%s` would be an instance of %s, but got %s',
$identityAttribute,
Expand Down Expand Up @@ -328,7 +328,7 @@ protected function getDefaultAction(ServerRequest $request): string
return $action;
}
if (!is_string($name)) {
$type = is_object($name) ? get_class($name) : gettype($name);
$type = get_debug_type($name);
$message = sprintf('Invalid action type for `%s`. Expected `string` or `null`, got `%s`.', $action, $type);
throw new UnexpectedValueException($message);
}
Expand Down
2 changes: 0 additions & 2 deletions src/Exception/ForbiddenException.php
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,6 @@ class ForbiddenException extends Exception

/**
* Policy check result.
*
* @var \Authorization\Policy\ResultInterface|null
*/
protected ?ResultInterface $result = null;

Expand Down
10 changes: 2 additions & 8 deletions src/IdentityDecorator.php
Original file line number Diff line number Diff line change
Expand Up @@ -39,8 +39,6 @@ class IdentityDecorator implements IdentityInterface

/**
* Authorization Service
*
* @var \Authorization\AuthorizationServiceInterface
*/
protected AuthorizationServiceInterface $authorization;

Expand Down Expand Up @@ -105,7 +103,7 @@ public function getOriginalData(): ArrayAccess|array
public function __call(string $method, array $args): mixed
{
if (!is_object($this->identity)) {
throw new BadMethodCallException("Cannot call `{$method}`. Identity data is not an object.");
throw new BadMethodCallException(sprintf('Cannot call `%s`. Identity data is not an object.', $method));
}

if (!method_exists($this->identity, $method)) {
Expand Down Expand Up @@ -163,11 +161,7 @@ public function offsetExists(mixed $offset): bool
*/
public function offsetGet(mixed $offset): mixed
{
if (isset($this->identity[$offset])) {
return $this->identity[$offset];
}

return null;
return $this->identity[$offset] ?? null;
}

/**
Expand Down
10 changes: 2 additions & 8 deletions src/Middleware/AuthorizationMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,15 +69,11 @@ class AuthorizationMiddleware implements MiddlewareInterface

/**
* Authorization service or application instance.
*
* @var \Authorization\AuthorizationServiceInterface|\Authorization\AuthorizationServiceProviderInterface
*/
protected AuthorizationServiceInterface|AuthorizationServiceProviderInterface $subject;

/**
* The container instance from the application
*
* @var \Cake\Core\ContainerInterface|null
*/
protected ?ContainerInterface $container = null;

Expand Down Expand Up @@ -190,10 +186,8 @@ protected function buildIdentity(

if (is_callable($class)) {
$identity = $class($service, $identity);
} else {
if (!$identity instanceof IdentityInterface) {
$identity = new $class($service, $identity);
}
} elseif (!$identity instanceof IdentityInterface) {
$identity = new $class($service, $identity);
}

if (!$identity instanceof IdentityInterface) {
Expand Down
2 changes: 1 addition & 1 deletion src/Middleware/UnauthorizedHandler/HandlerFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ public static function create(string $name): HandlerInterface
$message = sprintf(
'Handler should implement `%s`, got `%s`.',
HandlerInterface::class,
get_class($instance),
$instance::class,
);
throw new RuntimeException($message);
}
Expand Down
9 changes: 2 additions & 7 deletions src/Middleware/UnauthorizedHandler/RedirectHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -108,12 +108,8 @@ protected function getUrl(ServerRequestInterface $request, array $options): stri
if ($uri->getQuery()) {
$redirect .= '?' . $uri->getQuery();
}
$query = urlencode($options['queryParam']) . '=' . urlencode($redirect);
if (str_contains($url, '?')) {
$query = '&' . $query;
} else {
$query = '?' . $query;
}
$query = urlencode((string)$options['queryParam']) . '=' . urlencode($redirect);
$query = str_contains((string)$url, '?') ? '&' . $query : '?' . $query;

$url .= $query;
}
Expand All @@ -122,7 +118,6 @@ protected function getUrl(ServerRequestInterface $request, array $options): stri
}

/**
* @param \Psr\Http\Message\ServerRequestInterface $request
* @param array<string, mixed> $options
* @return bool
*/
Expand Down
2 changes: 0 additions & 2 deletions src/Policy/Exception/MissingMethodException.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,6 @@ class MissingMethodException extends Exception
{
/**
* Template string that has attributes sprintf()'ed into it.
*
* @var string
*/
protected string $_messageTemplate = 'Method `%s` for invoking action `%s` has not been defined in `%s`.';
}
6 changes: 2 additions & 4 deletions src/Policy/Exception/MissingPolicyException.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,8 +24,6 @@ class MissingPolicyException extends Exception
{
/**
* Template string that has attributes sprintf()'ed into it.
*
* @var string
*/
protected string $_messageTemplate = 'Policy for `%s` has not been defined.';

Expand All @@ -38,13 +36,13 @@ class MissingPolicyException extends Exception
public function __construct(object|string|array $resource, ?int $code = null, ?Throwable $previous = null)
{
if (is_object($resource)) {
$resourceClass = get_class($resource);
$resourceClass = $resource::class;
if (
method_exists($resource, 'getRepository') &&
$resource->getRepository() &&
$resource->getRepository() instanceof RepositoryInterface
) {
$repositoryClass = get_class($resource->getRepository());
$repositoryClass = $resource->getRepository()::class;
$resource = sprintf($this->_messageTemplate, $resourceClass);
$queryMessage = ' This resource looks like a `Query`. If you are using `OrmResolver`, ' .
'you should create a new policy class for your `%s` class in `src/Policy/`.';
Expand Down
6 changes: 2 additions & 4 deletions src/Policy/MapResolver.php
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,6 @@ class MapResolver implements ResolverInterface

/**
* The DIC instance from the application
*
* @var \Cake\Core\ContainerInterface|null
*/
protected ?ContainerInterface $container;

Expand Down Expand Up @@ -101,7 +99,7 @@ public function getPolicy($resource): mixed
throw new InvalidArgumentException($message);
}

$class = get_class($resource);
$class = $resource::class;

if (!isset($this->map[$class])) {
throw new MissingPolicyException($resource);
Expand All @@ -117,7 +115,7 @@ public function getPolicy($resource): mixed
return $policy;
}

if ($this->container && $this->container->has($policy)) {
if ($this->container instanceof ContainerInterface && $this->container->has($policy)) {
return $this->container->get($policy);
}

Expand Down
Loading
Loading