summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Cornutt <enygma@phpdeveloper.org>2015-06-02 14:39:35 -0500
committerChris Cornutt <enygma@phpdeveloper.org>2015-06-02 14:39:35 -0500
commit4e2c66b7dd4427f8971bd0ddb46c967a4af01a77 (patch)
treeb377de8e389af54e96df3f83ae5c2eaa8f79ec5a
parent28f697f2bb411d1c30648743b46b118e2b365b4f (diff)
downloadgatekeeper-4e2c66b7dd4427f8971bd0ddb46c967a4af01a77.zip
gatekeeper-4e2c66b7dd4427f8971bd0ddb46c967a4af01a77.tar.gz
gatekeeper-4e2c66b7dd4427f8971bd0ddb46c967a4af01a77.tar.bz2
Adding the "closures as policies" handling2.2
-rw-r--r--docs/policies.md25
-rw-r--r--src/Psecio/Gatekeeper/Gatekeeper.php34
2 files changed, 57 insertions, 2 deletions
diff --git a/docs/policies.md b/docs/policies.md
index 2ab5a5b..a3312a3 100644
--- a/docs/policies.md
+++ b/docs/policies.md
@@ -85,3 +85,28 @@ if ($policy->evaluate($user) === true) {
?>
```
+## Using Closures as Policies
+
+You can also use the same structure of you'd like to define policies as closures, letting you do a bit more programmatic evaluation of the data provided. The same rules apply above to how they're evaluated, you just define them differently:
+
+```php
+<?php
+
+Gatekeeper::createPolicy([
+ 'name' => 'eval-closure',
+ 'description' => 'Using a closure to validate policy',
+ 'expression' => function($data) {
+ return ($data->username === 'ccornutt');
+ };
+]);
+
+if (Gatekeeper::evaluatePolicy('eval-closure', $user) === true) {
+ echo "Sweet success!";
+}
+?>
+```
+
+Here we've define the check for a `username` match as a closure and run an evaluation on it.
+
+> **NOTE:** Any checks that happen to have the same name as a policy that lives in the database will be overridden by a closure-based check (which may be advantageous depending on your needs).
+
diff --git a/src/Psecio/Gatekeeper/Gatekeeper.php b/src/Psecio/Gatekeeper/Gatekeeper.php
index 5741252..4af534b 100644
--- a/src/Psecio/Gatekeeper/Gatekeeper.php
+++ b/src/Psecio/Gatekeeper/Gatekeeper.php
@@ -45,6 +45,12 @@ class Gatekeeper
private static $config = array();
/**
+ * Current set of policies (callback versions)
+ * @var array
+ */
+ private static $policies = array();
+
+ /**
* Initialize the Gatekeeper instance, set up environment file and PDO connection
*
* @param string $envPath Environment file path (defaults to CWD)
@@ -588,7 +594,31 @@ class Gatekeeper
*/
public static function evaluatePolicy($name, $data)
{
- $policy = Gatekeeper::findPolicyByName($name);
- return $policy->evaluate($data);
+ // See if it's a closure policy first
+ if (array_key_exists($name, self::$policies)) {
+ $policy = self::$policies[$name];
+ $result = $policy($data);
+ return (!is_bool($result)) ? false : $result;
+ } else {
+ $policy = Gatekeeper::findPolicyByName($name);
+ return $policy->evaluate($data);
+ }
+ }
+
+ /**
+ * Allow for the creation of a policy as a callback too
+ *
+ * @param array $policy Policy settings
+ * @return boolean Success/fail of policy creation
+ */
+ public static function createPolicy(array $policy)
+ {
+ if (is_callable($policy['expression'])) {
+ $name = $policy['name'];
+ self::$policies[$name] = $policy['expression'];
+ return true;
+ } else {
+ return self::handleCreate('createPolicy', array($policy));
+ }
}
} \ No newline at end of file