Skip to content

Commit

Permalink
Removed Zfc/Rbac dependency and passed all the tests with some change…
Browse files Browse the repository at this point in the history
…s in tests.

Signed-off-by: Mubashir <[email protected]>
  • Loading branch information
ALTAMASH80 committed Jul 8, 2023
1 parent 8d245e3 commit 81e48b9
Show file tree
Hide file tree
Showing 33 changed files with 502 additions and 108 deletions.
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@
"laminas/laminas-eventmanager": "^3.0",
"laminas/laminas-mvc": "^3.0",
"laminas/laminas-servicemanager": "^3.0",
"zfr/rbac": "~1.2",
"laminas/laminas-permissions-rbac": "^3.0",
"doctrine/persistence": "^2.1"
},
"require-dev": {
Expand Down
7 changes: 3 additions & 4 deletions src/Collector/RbacCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,8 @@

namespace LmcRbacMvc\Collector;

use Rbac\Role\HierarchicalRoleInterface;
use Rbac\Role\RoleInterface;
use Rbac\Traversal\RecursiveRoleIterator;
use Laminas\Permissions\Rbac\RoleInterface;
use LmcRbacMvc\Role\RecursiveRoleIterator;
use RecursiveIteratorIterator;
use ReflectionProperty;
use ReflectionException;
Expand Down Expand Up @@ -154,7 +153,7 @@ private function collectIdentityRolesAndPermissions(RoleService $roleService)
foreach ($identityRoles as $role) {
$roleName = $role->getName();

if (!$role instanceof HierarchicalRoleInterface) {
if (empty($role->hasChildren())) {
$this->collectedRoles[] = $roleName;
} else {
$iteratorIterator = new RecursiveIteratorIterator(
Expand Down
5 changes: 2 additions & 3 deletions src/Factory/AuthorizationServiceFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
use LmcRbacMvc\Options\ModuleOptions;
use LmcRbacMvc\Service\AuthorizationService;
use LmcRbacMvc\Service\RoleService;
use Rbac\Rbac;

/**
* Factory to create the authorization service
Expand All @@ -43,8 +42,8 @@ class AuthorizationServiceFactory implements FactoryInterface
*/
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
/* @var Rbac $rbac */
$rbac = $container->get(Rbac::class);
/* @var \Laminas\Permissions\Rbac\Rbac $rbac */
$rbac = $container->get(\Rbac\Rbac::class);

/* @var RoleService $roleService */
$roleService = $container->get(RoleService::class);
Expand Down
5 changes: 2 additions & 3 deletions src/Factory/RbacFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,7 @@
namespace LmcRbacMvc\Factory;

use Interop\Container\ContainerInterface;
use Rbac\Rbac;
use Rbac\Traversal\Strategy\GeneratorStrategy;
use LmcRbacMvc\Rbac\Rbac;
use Laminas\ServiceManager\Factory\FactoryInterface;
use Laminas\ServiceManager\ServiceLocatorInterface;

Expand All @@ -38,7 +37,7 @@ class RbacFactory implements FactoryInterface
*/
public function __invoke(ContainerInterface $container, $requestedName, array $options = null)
{
return new Rbac(new GeneratorStrategy());
return new Rbac();
}

/**
Expand Down
6 changes: 3 additions & 3 deletions src/Factory/RoleServiceFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -27,8 +27,8 @@
use LmcRbacMvc\Role\RoleProviderInterface;
use LmcRbacMvc\Role\RoleProviderPluginManager;
use LmcRbacMvc\Service\RoleService;
use Rbac\Rbac;
use Rbac\Traversal\Strategy\TraversalStrategyInterface;
use LmcRbacMvc\Role\RecursiveRoleIteratorStrategy;
use LmcRbacMvc\Role\TraversalStrategyInterface;

/**
* Factory to create the role service
Expand Down Expand Up @@ -66,7 +66,7 @@ public function __invoke(ContainerInterface $container, $requestedName, array $o
$roleProvider = $pluginManager->get(key($roleProviderConfig), current($roleProviderConfig));

/* @var TraversalStrategyInterface $traversalStrategy */
$traversalStrategy = $container->get(Rbac::class)->getTraversalStrategy();
$traversalStrategy = new RecursiveRoleIteratorStrategy();//$container->get(Rbac::class)->getTraversalStrategy();

$roleService = new RoleService($identityProvider, $roleProvider, $traversalStrategy);
$roleService->setGuestRole($moduleOptions->getGuestRole());
Expand Down
4 changes: 1 addition & 3 deletions src/Permission/PermissionInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,6 @@

namespace LmcRbacMvc\Permission;

use Rbac\Permission\PermissionInterface as BasePermissionInterface;

/**
* Interface that permissions must implement to be used with the AuthorizationService
*
Expand All @@ -30,6 +28,6 @@
* @license MIT
* TODO Remove deprecated interface
*/
interface PermissionInterface extends BasePermissionInterface
interface PermissionInterface
{
}
83 changes: 83 additions & 0 deletions src/Rbac/Rbac.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
<?php

declare(strict_types=1);

namespace LmcRbacMvc\Rbac;

use Laminas\Permissions\Rbac\Rbac as LaminasRbac;
use Laminas\Permissions\Rbac\RoleInterface;
use Laminas\Permissions\Rbac\AssertionInterface;
use Laminas\Permissions\Rbac\Exception;

class Rbac extends LaminasRbac{
/**
* Return all the roles
*
* @return RoleInterface[]
*/
public function getRoles(): array
{
return $this->roles;
}

/**
* Determines if access is granted by checking the role and child roles for permission.
*
* @param RoleInterface|string $role
* @param null|AssertionInterface|Callable $assertion
* @throws Exception\InvalidArgumentException If the role is not found.
* @throws Exception\InvalidArgumentException If the assertion is an invalid type.
*/
public function isGranted($role, string $permission, $assertion = null): bool
{
if ( is_array($role) && $role[0] instanceof RoleInterface) {
$role = $role[0];
}
if (! $this->hasRole($role)) {
throw new Exception\InvalidArgumentException(sprintf(
'No role with name "%s" could be found',
is_object($role) ? $role->getName() : $role
));
}

if (is_string($role)) {
$role = $this->getRole($role);
}

$result = $role->hasPermission($permission);
if (false === $result || null === $assertion) {
return $result;
}

if (
! $assertion instanceof AssertionInterface
&& ! is_callable($assertion)
) {
throw new Exception\InvalidArgumentException(
'Assertions must be a Callable or an instance of Laminas\Permissions\Rbac\AssertionInterface'
);
}

if ($assertion instanceof AssertionInterface) {
return $result && $assertion->assert($this, $role, $permission);
}

// Callable assertion provided.
return $result && $assertion($this, $role, $permission);
}

/**
* Is a role registered?
*
* @param RoleInterface|string $role
*/
public function hasRole($role): bool
{
if(empty($this->roles)){
$this->addRole($role);
}

return parent::hasRole($role);
}

}
6 changes: 2 additions & 4 deletions src/Role/InMemoryRoleProvider.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,7 @@

namespace LmcRbacMvc\Role;

use Rbac\Role\RoleInterface;
use Rbac\Role\HierarchicalRole;
use Rbac\Role\Role;
use Laminas\Permissions\Rbac\RoleInterface;

/**
* Simple role providers that store them in memory (ideal for small websites)
Expand Down Expand Up @@ -99,7 +97,7 @@ protected function getRole($roleName)
$roleConfig = $this->rolesConfig[$roleName];

if (isset($roleConfig['children'])) {
$role = new HierarchicalRole($roleName);
$role = new Role($roleName);
$childRoles = (array)$roleConfig['children'];
foreach ($childRoles as $childRole) {
$childRole = $this->getRole($childRole);
Expand Down
71 changes: 71 additions & 0 deletions src/Role/RecursiveRoleIterator.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,71 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license.
*/

namespace LmcRbacMvc\Role;

use ArrayIterator;
use Laminas\Permissions\Rbac\RoleInterface;
use RecursiveIterator;
use Traversable;

class RecursiveRoleIterator extends ArrayIterator implements RecursiveIterator
{
/**
* Override constructor to accept {@link Traversable} as well
*
* @param RoleInterface[]|Traversable $roles
*/
public function __construct($roles)
{
if ($roles instanceof Traversable) {
$roles = iterator_to_array($roles);
}

parent::__construct($roles);
}

/**
* @return bool
*/
public function valid() : bool
{
return ($this->current() instanceof RoleInterface);
}

/**
* @return bool
*/
public function hasChildren() : bool
{
$current = $this->current();

if (!$current instanceof RoleInterface) {
return false;
}

return $current->hasChildren();
}

/**
* @return RecursiveRoleIterator
*/
public function getChildren() :? RecursiveRoleIterator
{
return new RecursiveRoleIterator($this->current()->getChildren());
}
}
40 changes: 40 additions & 0 deletions src/Role/RecursiveRoleIteratorStrategy.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
<?php
/*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* This software consists of voluntary contributions made by many individuals
* and is licensed under the MIT license.
*/

namespace LmcRbacMvc\Role;

use Laminas\Permissions\Rbac\RoleInterface;
use RecursiveIteratorIterator;

/**
* Create a {@link RecursiveRoleIterator} and wrap it into a {@link RecursiveIteratorIterator}
*/
class RecursiveRoleIteratorStrategy implements TraversalStrategyInterface
{
/**
* @param RoleInterface[] $roles
* @return RecursiveIteratorIterator
*/
public function getRolesIterator($roles)
{
return new RecursiveIteratorIterator(
new RecursiveRoleIterator($roles),
RecursiveIteratorIterator::SELF_FIRST
);
}
}
52 changes: 52 additions & 0 deletions src/Role/Role.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php
declare(strict_types=1);

namespace LmcRbacMvc\Role;

use Laminas\Permissions\Rbac\Role as LaminasRole;
use Laminas\Permissions\Rbac\RoleInterface;

class Role extends LaminasRole {

/**
* Get all child roles
*
* @return RoleInterface[]
*/
public function getChildren(): array
{
if($this->children instanceof \Doctrine\ORM\PersistentCollection )
return $this->children->toArray();
else
return array_values($this->children);
}

/**
* Get the parent roles.
*
* @return RoleInterface[]
*/
public function getParents(): array
{
return $this->parents;
}

/**
* {@inheritDoc}
*/
public function hasChildren()
{
return !empty($this->children);
}

/**
* Check if a role is a descendant.
*/
protected function hasDescendant(RoleInterface $role): bool
{
if(empty($this->children))
$this->children = [];

return parent::hasDescendant($role);
}
}
2 changes: 1 addition & 1 deletion src/Role/RoleProviderInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

namespace LmcRbacMvc\Role;

use Rbac\Role\RoleInterface;
use Laminas\Permissions\Rbac\RoleInterface;

/**
* A role provider is an object that collect roles from string and convert them to RoleInterface instances
Expand Down
Loading

0 comments on commit 81e48b9

Please sign in to comment.