-
Notifications
You must be signed in to change notification settings - Fork 23
Hotfix/45 #49
Hotfix/45 #49
Changes from all commits
c8a28fa
e6dbec9
10ffa7c
125d819
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -9,6 +9,8 @@ | |
|
||
namespace Zend\Permissions\Rbac; | ||
|
||
use ZendTest\Permissions\Rbac\RoleTest; | ||
|
||
class Rbac | ||
{ | ||
/** | ||
|
@@ -82,29 +84,109 @@ public function hasRole($role) : bool | |
); | ||
} | ||
|
||
if (is_string($role)) { | ||
return isset($this->roles[$role]); | ||
return $this->roleSearchIncludingChildren($this->roles, $role); | ||
} | ||
|
||
/** | ||
* @param $obj|Array | ||
* @param $needle|String | ||
* @return bool | ||
*/ | ||
private function roleSearchIncludingChildren($obj, $needle) : bool | ||
{ | ||
$rv = 0; | ||
|
||
if (is_array($obj)) { | ||
foreach ($obj as $role) { | ||
$roleName = $role->getName(); | ||
if (is_string($needle)) { | ||
if ($roleName === $needle) { | ||
$rv++; | ||
} | ||
} elseif (is_object($needle) && (get_class($needle) == 'Zend\Permissions\Rbac\Role')) { | ||
if ($roleName == $needle->getName()) { | ||
$rv++; | ||
} | ||
} | ||
$rv += $this->roleSearchIncludingChildren($role, $needle); | ||
} | ||
} else { | ||
$children = $obj->getChildren(); | ||
|
||
// need to make sure the children are arrays (meaning they are added correctly) | ||
if (! is_array($children)) { | ||
return $rv ? true : false; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There is zero possibility of |
||
} elseif (! count($children)) { | ||
if (is_object($needle) && (get_class($needle) == 'Zend\Permissions\Rbac\Role')) { | ||
if ($obj->getName() == $needle->getName()) { | ||
$rv++; | ||
} | ||
} | ||
} else { | ||
foreach ($children as $child) { | ||
$roleName = $child->getName(); | ||
if (is_string($needle)) { | ||
if ($roleName === $needle) { | ||
$rv++; | ||
} | ||
} elseif (is_object($needle) && (get_class($needle) == 'Zend\Permissions\Rbac\Role')) { | ||
if ($roleName == $needle->getName()) { | ||
$rv++; | ||
} | ||
} | ||
$rv += $this->roleSearchIncludingChildren($child, $needle); | ||
} | ||
} | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just like the other block, we could do the following:
Making these changes and the previous ones I suggested would eliminate unnecessary cycles when we've already determined a matching child is present. |
||
} | ||
|
||
$roleName = $role->getName(); | ||
return isset($this->roles[$roleName]) | ||
&& $this->roles[$roleName] === $role; | ||
return $rv ? true : false; | ||
} | ||
|
||
/** | ||
* Get a registered role by name | ||
* | ||
* @throws Exception\InvalidArgumentException if role is not found. | ||
*/ | ||
public function getRole(string $roleName) : RoleInterface | ||
public function getRole(string $needle) : RoleInterface | ||
{ | ||
if (! isset($this->roles[$roleName])) { | ||
throw new Exception\InvalidArgumentException(sprintf( | ||
'No role with name "%s" could be found', | ||
$roleName | ||
)); | ||
// tricky thing here is that $this->roles are an array of RoleInterface objects | ||
foreach ($this->roles as $role) { | ||
if ($role->getName() == $needle) { | ||
return $role; | ||
} else { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Since your if ($role->getName() === $needle) {
return $role;
}
$role = $this->getRoleSearchingChildren($role, $needle);
if ($role !== null) {
return $role;
} |
||
$role = $this->getRoleSearchingChildren($role, $needle); | ||
if ($role != null) { | ||
return $role; | ||
} | ||
} | ||
} | ||
|
||
throw new Exception\InvalidArgumentException(sprintf( | ||
'No role with name "%s" could be found', | ||
$needle | ||
)); | ||
} | ||
|
||
/** | ||
* @param $obj RoleInterface | ||
* @param $needle String | ||
* @return null|RoleInterface | ||
*/ | ||
private function getRoleSearchingChildren($obj, $needle) | ||
{ | ||
if (($obj instanceof RoleInterface) && ($obj->getName() == $needle)) { | ||
return $obj; | ||
} else { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Same comment as for |
||
$children = $obj->getChildren(); | ||
if (is_array($children) && ($children != null)) { | ||
$result = ''; | ||
foreach ($children as $child) { | ||
$result = $this->getRoleSearchingChildren($child, $needle); | ||
} | ||
return $result; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This part is confusing - do you want to return the first match, or the last? If the last, why? |
||
} | ||
} | ||
return $this->roles[$roleName]; | ||
return null; | ||
} | ||
|
||
/** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -122,6 +122,13 @@ public function testHasRole() | |
$this->assertNotEquals($snafu, $this->rbac->getRole('snafu')); | ||
$this->assertTrue($this->rbac->hasRole('snafu')); | ||
$this->assertFalse($this->rbac->hasRole($snafu)); | ||
|
||
// check child is found | ||
$parent = new TestAsset\RoleTest('parent'); | ||
$child = new TestAsset\RoleTest('child'); | ||
$parent->addChild($child); | ||
$this->rbac->addRole($parent); | ||
$this->assertTrue($this->rbac->hasRole('child')); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be a separate test entirely. |
||
} | ||
|
||
public function testHasRoleWithInvalidElement() | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This section could be condensed dramatically: