From 86afea9b4e75c93e24f1a528f204e481971a4eaf Mon Sep 17 00:00:00 2001 From: Dave Mc Nicoll Date: Sun, 2 Jun 2024 19:54:55 +0000 Subject: [PATCH] - Reworked the SecurityHandler granting part which now supports NULL as a 'skipping' value. This necessity appeared since a new property in the attribute was added. --- src/Security/SecurityHandler.php | 63 +++++++++++++++++++++----------- 1 file changed, 42 insertions(+), 21 deletions(-) diff --git a/src/Security/SecurityHandler.php b/src/Security/SecurityHandler.php index e22e8c2..4b95969 100644 --- a/src/Security/SecurityHandler.php +++ b/src/Security/SecurityHandler.php @@ -2,6 +2,7 @@ namespace Notes\Security; +use Notes\Common\ReflectedAttribute; use Taxus\Taxus; use Psr\Http\Message\ResponseInterface; @@ -27,10 +28,12 @@ class SecurityHandler { return $this->isLocked($className, $methodName) ? $this->redirectResponse : null; } + # @TODO Must HANDLE REALM ! public function isLocked(string $className, string $methodName) : bool { - if ( $security = $this->getClassAttributes(Attribute\Security::class, $className, $methodName) ) { - return array_pop($security)->locked; + # Searching method first and fallbacking on object if none found + if ( $list = $this->findAttributes(Attribute\Security::class, $className, $methodName) ) { + return array_pop($list)->locked; } return true; @@ -38,15 +41,16 @@ class SecurityHandler { 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; - } - } + $fromObject = $this->findAttributes(Attribute\Taxus::class, $className); + $fromMethod = $this->findAttributes(Attribute\Taxus::class, $className, $methodName); - return call_user_func_array($this->unauthorizeResponse, [ $user, $taxus, $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."); @@ -56,22 +60,39 @@ class SecurityHandler { return null; } - protected function getClassAttributes(string $annotationClass, string $className, string $methodName)/* : \Notes\Attribute|array */ + protected function findAttributes(string $attribute, string $class, ? string $method = null) : array { - $objectResolver = new ObjectResolver($className); + $objectResolver = new ObjectResolver($class); - try { - $method = $objectResolver->reflectedClass->getClassAttributeList( $annotationClass, true, false ); + if ($method) { + $fromMethod = $objectResolver->reflectedClass->getMethods( false ); - # var_dump($method); - } - catch(\Exception $e) { } + if (isset($fromMethod[$method])) { + $attributeList = $fromMethod[$method]->getAttributes($attribute); - if ( $method[$methodName] ?? false ) { - return $method[$methodName]; + if ($attributeList) { + return array_map(fn(ReflectedAttribute $ref) => $ref->object, $attributeList); + } + } } - else { - return array_filter($method, fn($e) => is_object($e)); + + $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 (! isset($item->privilege) || $this->taxus->granted($item->privilege, $user, $item)) { + return true; + } + } + + return false; } }