Skip to content

Commit

Permalink
fix: use the provided assertion to determine the rule type
Browse files Browse the repository at this point in the history
If the provided assertion has run, it, and it alone, should be used to determine the rule type returned.

When a `true` value is returned, the rule type is returned as defined.

When a `false` value is returned, the rule type returned is the inverse of the one defined.

Fixes #2

Signed-off-by: Matthew Weier O'Phinney <[email protected]>
  • Loading branch information
weierophinney committed Sep 22, 2020
1 parent 8715047 commit 54289a1
Showing 1 changed file with 47 additions and 28 deletions.
75 changes: 47 additions & 28 deletions src/Acl.php
Original file line number Diff line number Diff line change
Expand Up @@ -999,44 +999,36 @@ protected function getRuleType(
Role\RoleInterface $role = null,
$privilege = null
) {
// get the rules for the $resource and $role
// Pull all rules for the specified $resource and $role
if (null === ($rules = $this->getRules($resource, $role))) {
return;
// No rules discovered
return null;
}

// follow $privilege
if (null === $privilege) {
if (isset($rules['allPrivileges'])) {
$rule = $rules['allPrivileges'];
} else {
return;
}
} elseif (! isset($rules['byPrivilegeId'][$privilege])) {
return;
} else {
// Follow $privilege
$rule = null;
if (null === $privilege && isset($rules['allPrivileges'])) {
// No privilege specified, but allPrivileges rule exists
$rule = $rules['allPrivileges'];
}

if (null !== $privilege && isset($rules['byPrivilegeId'][$privilege])) {
// Privilege specified, and found in ruleset
$rule = $rules['byPrivilegeId'][$privilege];
}

// check assertion first
if ($rule['assert']) {
$assertion = $rule['assert'];
$assertionValue = $assertion->assert(
$this,
($this->isAllowedRole instanceof Role\RoleInterface) ? $this->isAllowedRole : $role,
($this->isAllowedResource instanceof Resource\ResourceInterface) ? $this->isAllowedResource : $resource,
$this->isAllowedPrivilege
);
if (null === $rule) {
// No rule identified
return null;
}

if (null === $rule['assert'] || $assertionValue) {
return $rule['type'];
} elseif (null !== $resource || null !== $role || null !== $privilege) {
return;
} elseif (self::TYPE_ALLOW === $rule['type']) {
return self::TYPE_DENY;
// Was a custom assertion supplied? Use it to retrieve the rule type.
if ($rule['assert']) {
return $this->getRuleTypeFromAssertion($rule['assert'], $rule['type'], $role, $resource);
}

return self::TYPE_ALLOW;
// Return the type supplied with the rule.
return $rule['type'];
}

/**
Expand Down Expand Up @@ -1112,4 +1104,31 @@ public function getResources()
{
return array_keys($this->resources);
}

/**
* Run the assertion to determine what rule type is selected
*
* Runs the assertion. When the assertion returns true, return the rule type
* as defined; otherwise, return its inversion.
*
* @param string $ruleType
* @return string
*/
private function getRuleTypeFromAssertion(
Assertion\AssertionInterface $assertion,
$ruleType,
Role\RoleInterface $role = null,
Resource\ResourceInterface $resource = null
) {
if ($assertion->assert(
$this,
$this->isAllowedRole instanceof Role\RoleInterface ? $this->isAllowedRole : $role,
$this->isAllowedResource instanceof Resource\ResourceInterface ? $this->isAllowedResource : $resource,
$this->isAllowedPrivilege
)) {
return $ruleType;
}

return $ruleType === self::TYPE_ALLOW ? self::TYPE_DENY : self::TYPE_ALLOW;
}
}

0 comments on commit 54289a1

Please sign in to comment.