Optimized draft for LawPermissionChecker

This commit is contained in:
Kevin Frantz 2018-12-08 20:25:29 +01:00
parent 8afb91c690
commit 7575ef5edf
5 changed files with 193 additions and 83 deletions

View File

@ -2,116 +2,117 @@
namespace App\Domain\LawManagement; namespace App\Domain\LawManagement;
use App\Entity\Source\SourceInterface;
use PhpCollection\CollectionInterface; use PhpCollection\CollectionInterface;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use App\Entity\Meta\RightInterface; use App\Entity\Meta\RightInterface;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use App\Entity\Meta\LawInterface;
use App\Domain\RightManagement\RightChecker;
/** /**
* @todo Implement checking by operation sources * @todo Implement checking by operation sources
* @todo chek if recievers are still neccessary and if they should be implemented
* *
* @author kevinfrantz * @author kevinfrantz
*/ */
class LawPermissionCheckerService implements LawPermissionCheckerServiceInterface final class LawPermissionCheckerService implements LawPermissionCheckerServiceInterface
{ {
/** /**
* @var SourceInterface * @var LawInterface
*/ */
private $clientSource; private $law;
/** /**
* @var SourceInterface * @param Collection|RightInterface[] $rights
*/ * @param string $value
private $requestedSource; * @param string $attribut
/**
* @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
* *
* @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 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|RightInterface[] $rights
* * the rights which exist
* @param CollectionInterface $rights the rights which exist
* *
* @return bool * @return bool
*/ */
private function isGranted(CollectionInterface $rights): bool private function isGranted(Collection $rights, RightInterface $client): bool
{ {
/* if (0 === $rights->count()) {
* @var RightInterface return false;
*/
foreach ($rights as $right) {
if ($clientSources->contains($right)) {
}
} }
$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(); $this->law = $law;
$rightsByPermission = $this->getRightsByPermission($requestedSourceRights);
$rightsbyClient = $this->getRightsByClient($rightsByPermission);
} }
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 return $this->isGranted($rights, $client);
{
$this->requestedSource = $requestedSource;
}
public function setType(string $type): void
{
$this->permissionType = $type;
} }
} }

View File

@ -2,7 +2,7 @@
namespace App\Domain\LawManagement; 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. * Allows to check if a source has rights on a source.
@ -11,16 +11,10 @@ use App\Entity\Source\SourceInterface;
*/ */
interface LawPermissionCheckerServiceInterface 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;
} }

View File

@ -5,6 +5,7 @@ namespace App\Domain\SourceManagement;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use App\Entity\Source\SourceInterface; use App\Entity\Source\SourceInterface;
use Doctrine\Common\Collections\ArrayCollection; use Doctrine\Common\Collections\ArrayCollection;
use App\Entity\Attribut\MemberRelationAttributInterface;
final class SourceMemberInformation implements SourceMemberInformationInterface final class SourceMemberInformation implements SourceMemberInformationInterface
{ {
@ -23,6 +24,9 @@ final class SourceMemberInformation implements SourceMemberInformationInterface
$this->source = $source; $this->source = $source;
} }
/**
* @param Collection|MemberRelationAttributInterface[] $members
*/
private function itterateOverMembers(Collection $members): void private function itterateOverMembers(Collection $members): void
{ {
foreach ($members as $member) { foreach ($members as $member) {

View File

@ -3,13 +3,20 @@
namespace App\Entity\Attribut; namespace App\Entity\Attribut;
use Doctrine\Common\Collections\Collection; use Doctrine\Common\Collections\Collection;
use App\Entity\Meta\RightInterface;
/** /**
* @author kevinfrantz * @author kevinfrantz
*/ */
interface RightsAttributInterface interface RightsAttributInterface
{ {
/**
* @param Collection|RightInterface[] $rights
*/
public function setRights(Collection $rights): void; public function setRights(Collection $rights): void;
/**
* @return Collection|RightInterface[]
*/
public function getRights(): Collection; public function getRights(): Collection;
} }

View File

@ -0,0 +1,104 @@
<?php
namespace Unit\Domain\LawManagement;
use PHPUnit\Framework\TestCase;
use App\Domain\LawManagement\LawPermissionCheckerService;
use App\Domain\LawManagement\LawPermissionCheckerServiceInterface;
use App\Entity\Source\SourceInterface;
use App\Entity\Source\AbstractSource;
use App\Entity\Meta\Right;
use App\DBAL\Types\LayerType;
use App\DBAL\Types\RightType;
use App\Entity\Meta\Law;
use App\Entity\Meta\LawInterface;
use App\Entity\Meta\RightInterface;
use Doctrine\Common\Collections\ArrayCollection;
class LawPermissionCheckerTest extends TestCase
{
/**
* @var LawPermissionCheckerServiceInterface
*/
protected $lawPermissionChecker;
/**
* @var LawInterface
*/
protected $law;
/**
* @var RightInterface
*/
protected $client;
private function getSourceMock(): SourceInterface
{
return new class() extends AbstractSource {
};
}
public function setUp(): void
{
$this->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);
}
}