notes/src/Security/SecurityHandler.php
Dave Mc Nicoll dd680c8a9a v2.0.0b
2024-06-04 13:33:11 +00:00

102 lines
3.3 KiB
PHP

<?php declare(strict_types = 1);
namespace Notes\Security;
use Notes\Common\ReflectedAttribute;
use Taxus\Taxus;
use Psr\Http\Message\ResponseInterface;
use Notes\ObjectResolver;
use Taxus\TaxusGrantEnum;
class SecurityHandler {
protected ResponseInterface $redirectResponse;
protected ? \Closure $unauthorizeResponse;
protected ? Taxus $taxus;
public function __construct(ResponseInterface $redirectResponse, ? \Closure $unauthorizeResponse = null, ? Taxus $taxus = null) {
$this->redirectResponse = $redirectResponse;
$this->unauthorizeResponse = $unauthorizeResponse;
$this->taxus = $taxus;
}
public function verify(string $className, string $methodName) : ? ResponseInterface
{
return $this->isLocked($className, $methodName) ? $this->redirectResponse : null;
}
# @TODO Must HANDLE REALM !
public function isLocked(string $className, string $methodName) : bool
{
# Searching method first and fallbacking on object if none found
if ( $list = $this->findAttributes(Attribute\Security::class, $className, $methodName) ) {
return array_shift($list)->locked;
}
return true;
}
public function taxus(string $className, string $methodName, object $user = null) : ? ResponseInterface
{
$fromObject = $this->findAttributes(Attribute\Taxus::class, $className);
$fromMethod = $this->findAttributes(Attribute\Taxus::class, $className, $methodName);
if ($fromMethod || $fromObject) {
if ( $this->taxusGrantPermission($fromMethod, $user) || $this->taxusGrantPermission($fromObject, $user) ) {
return null;
}
if ($this->unauthorizeResponse) {
return call_user_func_array($this->unauthorizeResponse, [ $user, ['method' => $fromMethod, 'object' => $fromObject ], $className, $methodName ]);
}
else {
throw new \ErrorException("Unauthorized response given.");
}
}
return null;
}
protected function findAttributes(string $attribute, string $class, ? string $method = null) : array
{
$objectResolver = new ObjectResolver($class);
if ($method) {
$fromMethod = $objectResolver->reflectedClass->getMethods( false );
if (isset($fromMethod[$method])) {
$attributeList = $fromMethod[$method]->getAttributes($attribute);
if ($attributeList) {
return array_map(fn(ReflectedAttribute $ref) => $ref->object, $attributeList);
}
}
}
$attributeList = $objectResolver->reflectedClass->getAttributes(false, $attribute) ?: $objectResolver->reflectedClass->getAttributes(true, $attribute);
if ($attributeList) {
return array_map(fn(ReflectedAttribute $ref) => $ref->object, $attributeList);
}
return [];
}
protected function taxusGrantPermission(array $attributeList, object $user = null) : bool
{
foreach ($attributeList as $item) {
if ( $grant = $this->taxus->granted($item->privilege, $user, $item) ) {
if (is_bool($grant) ? $grant : $grant === TaxusGrantEnum::Authorized) {
return true;
}
}
}
return false;
}
}