public function evaluate(User $subject, Policy $policy) { $pass = true; foreach ($policy->getChecks() as $type => $value) { $propertyValue = $subject->getProperty($type); $valueType = gettype($propertyValue); // Ensure all of the things in our policy are true foreach ($value as $test) { $typeNs = __NAMESPACE__ . '\\Test\\Test' . ucwords(strtolower($valueType)); if (class_exists($typeNs)) { $testInstance = new $typeNs($test); if ($testInstance->evaluate($propertyValue) === false) { return false; } } else { throw new \InvalidArgumentException('Test type "' . $valueType . '" does not exist.'); } } } return $pass; }
/** * Adding a check with additional options (like the rule) */ public function testAddCheckWithPolicy() { $policy = new Policy(); $policy->hasUsername('test', ['rule' => Policy::ALL]); $checks = $policy->getChecks(); $addl = $checks['username'][0]->getAddl(); $this->assertEquals($addl['rule'], Policy::ALL); }
/** * Given a subject and a policy, evaluate the pass/fail result of the matching * * @param object $subject Subject to match against * @param \Psecio\PropAuth\Policy $policy Policy to evaluate * @return boolean Pass/fail status of evaluation */ public function evaluate($subject, Policy $policy, array $addl = array()) { $pass = true; $addl = array_merge([$subject], $addl); foreach ($policy->getChecks() as $type => $value) { $method = 'get' . ucwords(strtolower($type)); $propertyValue = null; if ($type !== 'closure' && $type !== 'method' && (isset($subject->{$type}) || $subject->{$type} !== null)) { $propertyValue = $subject->{$type}; } elseif (method_exists($subject, $method)) { $propertyValue = $subject->{$method}(); } elseif (method_exists($subject, 'getProperty')) { $propertyValue = $subject->getProperty($type); } $valueType = gettype($propertyValue); // Ensure all of the things in our policy are true foreach ($value as $test) { // First check for a custom "tester" $typeNs = __NAMESPACE__ . '\\Test\\Test' . ucwords(strtolower($type)); if (!class_exists($typeNs)) { $typeNs = __NAMESPACE__ . '\\Test\\Test' . ucwords(strtolower($valueType)); } if (class_exists($typeNs)) { $testInstance = new $typeNs($test, $addl); if ($testInstance->evaluate($propertyValue) === false) { return false; } } else { throw new \InvalidArgumentException('Test type "' . $valueType . '" does not exist.'); } } } return $pass; }
/** * Given a subject and a policy, evaluate the pass/fail result of the matching * * @param object $subject Subject to match against * @param \Psecio\PropAuth\Policy $policy Policy to evaluate * @throws \InvalidArgumentException If the property value is invalid (null) * @return boolean Pass/fail status of evaluation */ public function evaluate($subject, Policy $policy, array $addl = array()) { $addl = array_merge([$subject], $addl); $checks = $policy->getChecks(); if (empty($checks)) { trigger_error('Policy evaluation was perfomed with no checks', E_USER_WARNING); } foreach ($checks as $type => $value) { $propertyValue = $this->getPropertyValue($type, $subject); if ($propertyValue == null && $type !== 'closure') { throw new \InvalidArgumentException('Invalid property value for "' . $type . '"!'); } $result = $this->executeTests($value, $type, $propertyValue, $addl); // If we have a failure, return false... if ($result === false) { return false; } } return true; }