This repository has been archived on 2025-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
notes-security/src/SecurityHandler.php

72 lines
2.3 KiB
PHP

<?php declare(strict_types = 1);
namespace Notes\Security;
use Taxus\Taxus;
use Psr\Http\Message\ResponseInterface;
use Notes\ObjectResolver;
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
{
# Should generate an equivalent of Ulmus's object reflection here !
if ( $security = $this->getClassAttributes(Attribute\Security::class, $className, $methodName) ) {
return array_pop($security)->locked ? $this->redirectResponse : null;
}
return null;
}
public function taxus(string $className, string $methodName, object $user = null) : ? ResponseInterface
{
if ($taxus = $this->getClassAttributes(Attribute\Taxus::class, $className, $methodName)) {
if ($this->unauthorizeResponse) {
foreach ($taxus as $item) {
if (!isset($item->privilege) || $this->taxus->granted($item->privilege, $user, $item)) {
return null;
}
}
return call_user_func_array($this->unauthorizeResponse, [ $user, $taxus, $className, $methodName ]);
}
else {
throw new \ErrorException("Unauthorized response given.");
}
}
return null;
}
protected function getClassAttributes(string $annotationClass, string $className, string $methodName)/* : \Notes\Annotation|array */
{
$objectResolver = new ObjectResolver($className, true, true, false, true);
try {
$method = $objectResolver->getAttributeListFromClassname( $annotationClass, false );
}
catch(\Exception $e) { }
if ( $method[$methodName] ?? false ) {
return $method[$methodName];
}
else {
return array_filter($method, fn($e) => is_object($e));
}
}
}