implemented checking of source source attributs

This commit is contained in:
Kevin Frantz
2019-01-01 20:38:13 +01:00
parent 878eae62db
commit 1ee710e608
4 changed files with 179 additions and 3 deletions

View File

@@ -4,9 +4,9 @@ namespace App\Domain\SecureLoadManagement;
use App\Entity\Source\SourceInterface;
use App\Entity\Meta\RightInterface;
use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
use Doctrine\Common\Persistence\ObjectRepository;
use App\Domain\SecureManagement\SecureSourceChecker;
use App\Exception\SourceAccessDenied;
/**
* @author kevinfrantz
@@ -71,6 +71,6 @@ final class SecureSourceLoader implements SecureSourceLoaderInterface
if ($secureSourceChecker->hasPermission($requestedRight)) {
return $source;
}
throw new AccessDeniedHttpException();
throw new SourceAccessDenied();
}
}

View File

@@ -5,6 +5,7 @@ namespace App\Domain\SecureManagement;
use App\Entity\Meta\RightInterface;
use App\Entity\Source\SourceInterface;
use App\Domain\LawManagement\LawPermissionCheckerService;
use App\Exception\SourceAccessDenied;
/**
* @author kevinfrantz
@@ -24,10 +25,77 @@ final class SecureSourceChecker implements SecureSourceCheckerInterface
$this->source = $source;
}
/**
* @param string $methodName
*
* @return bool
*/
private function isGetter(string $methodName): bool
{
return 'get' === substr($methodName, 0, 3);
}
/**
* @param mixed $value
*
* @return bool
*/
private function isSource($value): bool
{
return $value instanceof SourceInterface;
}
/**
* @param string $methodName
*
* @return SourceInterface|null
*/
private function getExpectedSource(string $methodName): ?SourceInterface
{
try {
return $this->source->{$methodName}();
} catch (\TypeError $typeError) {
return null;
}
}
/**
* @param RightInterface $requestedRight
*
* @throws SourceAccessDenied It's important to fire this exception to reduce complexity in debuging
*
* @return bool
*/
private function itterateOverSourceAttributs(RightInterface $requestedRight): bool
{
foreach (get_class_methods($this->source) as $methodName) {
if ($this->isGetter($methodName)) {
$attributExpectedSource = $this->getExpectedSource($methodName);
if ($attributExpectedSource) {
$requestedSubSourceRight = clone $requestedRight;
$requestedSubSourceRight->setSource($attributExpectedSource);
if ($this->isSource($attributExpectedSource)) {
$methodSecureSourceChecker = new self($attributExpectedSource);
if (!$methodSecureSourceChecker->hasPermission($requestedSubSourceRight)) {
throw new SourceAccessDenied('Access denied for subsource!');
}
}
}
}
}
return true;
}
/**
* {@inheritdoc}
*
* @see \App\Domain\SecureManagement\SecureSourceCheckerInterface::hasPermission()
*/
public function hasPermission(RightInterface $requestedRight): bool
{
$law = new LawPermissionCheckerService($this->source->getLaw());
return $law->hasPermission($requestedRight);
return $law->hasPermission($requestedRight) && $this->itterateOverSourceAttributs($requestedRight);
}
}

View File

@@ -3,6 +3,7 @@
namespace App\Domain\SecureManagement;
use App\Entity\Meta\RightInterface;
use App\Exception\SourceAccessDenied;
/**
* @author kevinfrantz
@@ -10,6 +11,8 @@ use App\Entity\Meta\RightInterface;
interface SecureSourceCheckerInterface
{
/**
* @throws SourceAccessDenied
*
* @param RightInterface $right
*
* @return bool