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
56 changes: 24 additions & 32 deletions src/AuthorizationService.php
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
use Authorization\Policy\ResolverInterface;
use Authorization\Policy\Result;
use Authorization\Policy\ResultInterface;
use Closure;

class AuthorizationService implements AuthorizationServiceInterface
{
Expand Down Expand Up @@ -84,33 +85,22 @@ protected function performCheck(?IdentityInterface $user, string $action, mixed
$result = $policy->before($user, $resource, $action);

if ($result !== null) {
return $this->resultTypeCheck($result);
return $result;
}
}

$handler = $this->getCanHandler($policy, $action);
$result = $handler($user, $resource);

return $this->resultTypeCheck($result);
}

/**
* Check result type.
*
* @param mixed $result Result from policy class instance.
* @return \Authorization\Policy\ResultInterface|bool
* @throws \Authorization\Exception\Exception If $result argument is not a boolean or ResultInterface instance.
*/
protected function resultTypeCheck(mixed $result): ResultInterface|bool
{
if (is_bool($result) || $result instanceof ResultInterface) {
return $result;
}
assert(
is_bool($result) || $result instanceof ResultInterface,
new Exception(sprintf(
'Authorization check method must return `%s` or `bool`.',
ResultInterface::class
))
);

throw new Exception(sprintf(
'Pre-authorization check must return `%s`, `bool` or `null`.',
ResultInterface::class
));
return $result;
}

/**
Expand All @@ -130,37 +120,39 @@ public function applyScope(?IdentityInterface $user, string $action, $resource):
*
* @param mixed $policy Policy object.
* @param string $action Action name.
* @return callable
* @return \Closure
* @throws \Authorization\Policy\Exception\MissingMethodException
*/
protected function getCanHandler(mixed $policy, string $action): callable
protected function getCanHandler(mixed $policy, string $action): Closure
{
$method = 'can' . ucfirst($action);

if (!method_exists($policy, $method) && !method_exists($policy, '__call')) {
throw new MissingMethodException([$method, $action, get_class($policy)]);
}
assert(
method_exists($policy, $method) || method_exists($policy, '__call'),
new MissingMethodException([$method, $action, get_class($policy)])
);

return [$policy, $method];
return [$policy, $method](...);
}

/**
* Returns a policy scope action handler.
*
* @param mixed $policy Policy object.
* @param string $action Action name.
* @return callable
* @return \Closure
* @throws \Authorization\Policy\Exception\MissingMethodException
*/
protected function getScopeHandler(mixed $policy, string $action): callable
protected function getScopeHandler(mixed $policy, string $action): Closure
{
$method = 'scope' . ucfirst($action);

if (!method_exists($policy, $method)) {
throw new MissingMethodException([$method, $action, get_class($policy)]);
}
assert(
method_exists($policy, $method) || method_exists($policy, '__call'),
new MissingMethodException([$method, $action, get_class($policy)])
);

return [$policy, $method];
return [$policy, $method](...);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/Middleware/AuthorizationMiddleware.php
Original file line number Diff line number Diff line change
Expand Up @@ -179,7 +179,7 @@ protected function buildIdentity(
if (!$identity instanceof IdentityInterface) {
throw new RuntimeException(sprintf(
'Invalid identity returned by decorator. `%s` does not implement `%s`.',
is_object($identity) ? get_class($identity) : gettype($identity),
get_debug_type($identity),
IdentityInterface::class
));
}
Expand Down