From 7575ef5edf14494003bf6049a350397590d84e50 Mon Sep 17 00:00:00 2001 From: Kevin Frantz Date: Sat, 8 Dec 2018 20:25:29 +0100 Subject: [PATCH] Optimized draft for LawPermissionChecker --- .../LawPermissionCheckerService.php | 147 +++++++++--------- .../LawPermissionCheckerServiceInterface.php | 14 +- .../SourceMemberInformation.php | 4 + .../Attribut/RightsAttributInterface.php | 7 + .../LawPermissionCheckerTest.php | 104 +++++++++++++ 5 files changed, 193 insertions(+), 83 deletions(-) create mode 100644 application/tests/Unit/Domain/LawManagement/LawPermissionCheckerTest.php diff --git a/application/src/Domain/LawManagement/LawPermissionCheckerService.php b/application/src/Domain/LawManagement/LawPermissionCheckerService.php index e2412cc..517edf0 100644 --- a/application/src/Domain/LawManagement/LawPermissionCheckerService.php +++ b/application/src/Domain/LawManagement/LawPermissionCheckerService.php @@ -2,116 +2,117 @@ namespace App\Domain\LawManagement; -use App\Entity\Source\SourceInterface; use PhpCollection\CollectionInterface; use Doctrine\Common\Collections\ArrayCollection; use App\Entity\Meta\RightInterface; use Doctrine\Common\Collections\Collection; +use App\Entity\Meta\LawInterface; +use App\Domain\RightManagement\RightChecker; /** * @todo Implement checking by operation sources + * @todo chek if recievers are still neccessary and if they should be implemented * * @author kevinfrantz */ -class LawPermissionCheckerService implements LawPermissionCheckerServiceInterface +final class LawPermissionCheckerService implements LawPermissionCheckerServiceInterface { /** - * @var SourceInterface + * @var LawInterface */ - private $clientSource; + private $law; /** - * @var SourceInterface - */ - private $requestedSource; - - /** - * @var - */ - private $permissionType; - - private function getRightsByPermission(Collection $rights): Collection - { - $result = new ArrayCollection(); - /* - * @var RightInterface - */ - foreach ($rights as $right) { - if ($right->getType() === $this->permissionType) { - $result->add($right); - } - } - - return $result; - } - - private function getRightsByClient(Collection $rights): Collection - { - $result = new ArrayCollection(); - /* - * @var RightInterface - */ - foreach ($rights as $right) { - if ($right->getReciever() === $this->clientSource) { - $result->add($right); - } - } - - return $result; - } - - /** - * @todo Implement + * @param Collection|RightInterface[] $rights + * @param string $value + * @param string $attribut * - * @return CollectionInterface the sources to which the client belongs to + * @return Collection|RightInterface[] */ - private function getAllClientMemberships(): Collection + private function getFilteredRights(Collection $rights, string $value, string $attribut): Collection { + $result = new ArrayCollection(); + foreach ($rights as $right) { + if ($right->{'get'.$attribut}() === $value) { + $result->add($right); + } + } + + return $result; } + /** + * @param Collection|RightInterface[] $rights + * @param string $type + * + * @return Collection + */ + private function getRightsByType(Collection $rights, string $type): Collection + { + return $this->getFilteredRights($rights, $type, 'Type'); + } + + /** + * @param Collection|RightInterface[] $rights + * @param string $layer + * + * @return Collection + */ + private function getRightsByLayer(Collection $rights, string $layer): Collection + { + return $this->getFilteredRights($rights, $layer, 'Layer'); + } + + /** + * @todo seems like this can be solved on a nicer way + * + * @param Collection|RightInterface[] $rights + * + * @return Collection|RightInterface[] + */ private function sortByPriority(Collection $rights): Collection { + $iterator = $rights->getIterator(); + $iterator->uasort(function ($first, $second) { + return (int) $first->getPriority() > (int) $second->getPriority() ? 1 : -1; + }); + $sorted = new ArrayCollection(); + foreach ($iterator as $right) { + $sorted->add($right); + } + + return $sorted; } /** - * @todo Implement priority function for locking - * - * @param CollectionInterface $rights the rights which exist + * @param CollectionInterface|RightInterface[] $rights + * the rights which exist * * @return bool */ - private function isGranted(CollectionInterface $rights): bool + private function isGranted(Collection $rights, RightInterface $client): bool { - /* - * @var RightInterface - */ - foreach ($rights as $right) { - if ($clientSources->contains($right)) { - } + if (0 === $rights->count()) { + return false; } + $right = $rights[0]; + $rightChecker = new RightChecker($right); - return $result; + return $rightChecker->isGranted($client->getLayer(), $client->getType(), $client->getSource()); } - public function checkPermission(): bool + public function __construct(LawInterface $law) { - $requestedSourceRights = $this->requestedSource->getLaw()->getRights(); - $rightsByPermission = $this->getRightsByPermission($requestedSourceRights); - $rightsbyClient = $this->getRightsByClient($rightsByPermission); + $this->law = $law; } - public function setClientSource(SourceInterface $clientSource): void + public function hasPermission(RightInterface $client): bool { - $this->clientSource = $clientSource; - } + $rights = clone $this->law->getRights(); + $rights = $this->getRightsByType($rights, $client->getType()); + $rights = $this->getRightsByLayer($rights, $client->getLayer()); + $rights = $this->sortByPriority($rights); - public function setRequestedSource(SourceInterface $requestedSource): void - { - $this->requestedSource = $requestedSource; - } - - public function setType(string $type): void - { - $this->permissionType = $type; + return $this->isGranted($rights, $client); } } diff --git a/application/src/Domain/LawManagement/LawPermissionCheckerServiceInterface.php b/application/src/Domain/LawManagement/LawPermissionCheckerServiceInterface.php index b8cc554..b890d7f 100644 --- a/application/src/Domain/LawManagement/LawPermissionCheckerServiceInterface.php +++ b/application/src/Domain/LawManagement/LawPermissionCheckerServiceInterface.php @@ -2,7 +2,7 @@ namespace App\Domain\LawManagement; -use App\Entity\Source\SourceInterface; +use App\Entity\Meta\RightInterface; /** * Allows to check if a source has rights on a source. @@ -11,16 +11,10 @@ use App\Entity\Source\SourceInterface; */ interface LawPermissionCheckerServiceInterface { - public function setRequestedSource(SourceInterface $requestedSource): void; - - public function setClientSource(SourceInterface $clientSource): void; - - public function checkPermission(): bool; - /** - * Sets the permission type. + * Checks if the client has the right for executing. * - * @param string $type + * @return bool */ - public function setType(string $type): void; + public function hasPermission(RightInterface $client): bool; } diff --git a/application/src/Domain/SourceManagement/SourceMemberInformation.php b/application/src/Domain/SourceManagement/SourceMemberInformation.php index 46ac8ee..d920e65 100644 --- a/application/src/Domain/SourceManagement/SourceMemberInformation.php +++ b/application/src/Domain/SourceManagement/SourceMemberInformation.php @@ -5,6 +5,7 @@ namespace App\Domain\SourceManagement; use Doctrine\Common\Collections\Collection; use App\Entity\Source\SourceInterface; use Doctrine\Common\Collections\ArrayCollection; +use App\Entity\Attribut\MemberRelationAttributInterface; final class SourceMemberInformation implements SourceMemberInformationInterface { @@ -23,6 +24,9 @@ final class SourceMemberInformation implements SourceMemberInformationInterface $this->source = $source; } + /** + * @param Collection|MemberRelationAttributInterface[] $members + */ private function itterateOverMembers(Collection $members): void { foreach ($members as $member) { diff --git a/application/src/Entity/Attribut/RightsAttributInterface.php b/application/src/Entity/Attribut/RightsAttributInterface.php index 5ec968c..b3fce83 100644 --- a/application/src/Entity/Attribut/RightsAttributInterface.php +++ b/application/src/Entity/Attribut/RightsAttributInterface.php @@ -3,13 +3,20 @@ namespace App\Entity\Attribut; use Doctrine\Common\Collections\Collection; +use App\Entity\Meta\RightInterface; /** * @author kevinfrantz */ interface RightsAttributInterface { + /** + * @param Collection|RightInterface[] $rights + */ public function setRights(Collection $rights): void; + /** + * @return Collection|RightInterface[] + */ public function getRights(): Collection; } diff --git a/application/tests/Unit/Domain/LawManagement/LawPermissionCheckerTest.php b/application/tests/Unit/Domain/LawManagement/LawPermissionCheckerTest.php new file mode 100644 index 0000000..c06b345 --- /dev/null +++ b/application/tests/Unit/Domain/LawManagement/LawPermissionCheckerTest.php @@ -0,0 +1,104 @@ +client = new Right(); + $this->law = new Law(); + $this->lawPermissionChecker = new LawPermissionCheckerService($this->law); + } + + public function testGeneralPermission(): void + { + $source = $this->getSourceMock(); + $this->client->setSource($source); + $this->client->setLayer(LayerType::SOURCE); + $this->client->setType(RightType::READ); + $permission = $this->lawPermissionChecker->hasPermission($this->client); + $this->assertFalse($permission); + $lawRight = clone $this->client; + $this->law->getRights()->add($lawRight); + $permission = $this->lawPermissionChecker->hasPermission($this->client); + $this->assertTrue($permission); + $this->client->setType(RightType::WRITE); + $permission = $this->lawPermissionChecker->hasPermission($this->client); + $this->assertFalse($permission); + } + + public function testMemberPermission(): void + { + $parentSource = $this->getSourceMock(); + $source = $this->getSourceMock(); + $this->client->setSource($source); + $this->client->setLayer(LayerType::SOURCE); + $this->client->setType(RightType::READ); + $source->getMemberRelation()->getMemberships()->add($parentSource); + $parentSource->getMemberRelation()->getMembers()->add($source); + $lawRight = clone $this->client; + $lawRight->setSource($parentSource); + $this->law->getRights()->add($lawRight); + $permission = $this->lawPermissionChecker->hasPermission($this->client); + $this->assertTrue($permission); + $this->law->setRights(new ArrayCollection()); + $permission = $this->lawPermissionChecker->hasPermission($this->client); + $this->assertFalse($permission); + } + + public function testSort(): void + { + $source = $this->getSourceMock(); + $this->client->setSource($source); + $this->client->setLayer(LayerType::SOURCE); + $this->client->setType(RightType::READ); + $right1 = clone $this->client; + $right1->setPriority(123); + $right1->setGrant(false); + $right2 = clone $this->client; + $right2->setPriority(456); + $right2->setGrant(true); + $this->law->setRights(new ArrayCollection([$right1, $right2])); + $permission = $this->lawPermissionChecker->hasPermission($this->client); + $this->assertFalse($permission); + $right2->setPriority(789); + $right1->setPriority(101112); + $permission = $this->lawPermissionChecker->hasPermission($this->client); + $this->assertTrue($permission); + } +}