Page MenuHomePhabricator

D544.id1951.diff
No OneTemporary

D544.id1951.diff

diff --git a/assets/scss/_ b/assets/scss/_
--- a/assets/scss/_
+++ b/assets/scss/_
@@ -1 +1 @@
-Subproject commit 86179afe8dbcde4e78384da6610b63d85a3ce2ee
+Subproject commit ff25dfd0dcaac968b35dca821a4c05e279166830
diff --git a/bin/classes/permission/PermissionHelper.php b/bin/classes/permission/PermissionHelper.php
--- a/bin/classes/permission/PermissionHelper.php
+++ b/bin/classes/permission/PermissionHelper.php
@@ -1,5 +1,10 @@
<?php namespace permission;
+use GrantModel;
+use spitfire\core\Collection;
+use function collect;
+use function db;
+
/*
* The MIT License
*
@@ -27,14 +32,24 @@
class PermissionHelper
{
- public static function unlock($key, $ids) {
+ public static function unlock($key, $id) : PermissionTestResult
+ {
+
- if (!($ids instanceof \spitfire\core\Collection)) { $ids = collect($ids); }
+ /**
+ * These are defaults, and therefore, the specificity is always 0. This means
+ * that the rules are as generic as they get
+ */
+ if ($id === true || $id === 'true') { return new PermissionTestResult(GrantModel::GRANT_ALLOW, null); }
+ if ($id === false || $id === 'false') { return new PermissionTestResult(GrantModel::GRANT_DENY, null); }
+ if ($id === null || $id === 'null') { return new PermissionTestResult(GrantModel::GRANT_INHERIT, null); }
- $result = \GrantModel::GRANT_INHERIT;
+ $result = GrantModel::GRANT_INHERIT;
$pieces = explode('.', $key);
$resource = null;
- $identities = $ids->each(function ($id) { return db()->table('identity')->get('name', $id)->first(); });
+ $identity = db()->table('identity')->get('name', $id)->first();
+
+ $specificity = null;
while($pieces) {
$fragment = array_shift($pieces);
@@ -44,22 +59,34 @@
$resource = $query->first();
if (!$resource) {
- return (int)$result;
+ return new PermissionTestResult((int)$result, $specificity);
}
- $result = $identities->each(function ($identity) use ($resource) {
- return db()->table('grant')->get('identity', $identity)->where('resource', $resource)->first();
- })->filter()->reduce(function ($carry, $grant) {
- if ($grant->grant == \GrantModel::GRANT_INHERIT) {
- return $carry;
- }
- else {
- return $grant->grant;
- }
- }, $result);
+ $grant = db()->table('grant')->get('identity', $identity)->where('resource', $resource)->first();
+
+ if ($grant) {
+ if ($grant->grant != GrantModel::GRANT_INHERIT) { $result = $grant->grant; }
+
+ /**
+ * The specificity equals the depth of the resource. If we're looking up
+ * the string "app123.posts.create" the specificity of the rule is 1 if
+ * the rule was applied to app123, 2 if it was applied to app123.posts,
+ * etc.
+ *
+ * This allows clients to query rules, determining the that more elaborate
+ * rules are prioritized.
+ */
+ $specificity = $resource;
+ }
}
- return (int)$result;
+ return new PermissionTestResult((int)$result, $specificity);
+ }
+
+ public function unlockAll($key, $ids)
+ {
+
+ return $key->each(function ($key) use ($ids) { return self::unlock($key, $ids); });
}
}
diff --git a/bin/classes/permission/PermissionHelper.php b/bin/classes/permission/PermissionTestResult.php
copy from bin/classes/permission/PermissionHelper.php
copy to bin/classes/permission/PermissionTestResult.php
--- a/bin/classes/permission/PermissionHelper.php
+++ b/bin/classes/permission/PermissionTestResult.php
@@ -3,7 +3,7 @@
/*
* The MIT License
*
- * Copyright 2020 César de la Cal Bretschneider <cesar@magic3w.com>.
+ * Copyright 2021 César de la Cal Bretschneider <cesar@magic3w.com>.
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
@@ -24,42 +24,44 @@
* THE SOFTWARE.
*/
-class PermissionHelper
+class PermissionTestResult
{
- public static function unlock($key, $ids) {
-
- if (!($ids instanceof \spitfire\core\Collection)) { $ids = collect($ids); }
-
- $result = \GrantModel::GRANT_INHERIT;
- $pieces = explode('.', $key);
- $resource = null;
- $identities = $ids->each(function ($id) { return db()->table('identity')->get('name', $id)->first(); });
-
- while($pieces) {
- $fragment = array_shift($pieces);
- $parent = $resource;
- $query = db()->table('resource')->get('key', $fragment)->where('parent', $parent);
-
- $resource = $query->first();
-
- if (!$resource) {
- return (int)$result;
- }
-
- $result = $identities->each(function ($identity) use ($resource) {
- return db()->table('grant')->get('identity', $identity)->where('resource', $resource)->first();
- })->filter()->reduce(function ($carry, $grant) {
- if ($grant->grant == \GrantModel::GRANT_INHERIT) {
- return $carry;
- }
- else {
- return $grant->grant;
- }
- }, $result);
-
- }
+ private $result;
+
+ /**
+ *
+ * @var \ResourceModel
+ */
+ private $path;
+
+ public function __construct($result, \ResourceModel $resource = null)
+ {
+ $this->result = $result;
+ $this->path = $resource? $resource->path() : '';
+ }
+
+ public function getResult()
+ {
+ return $this->result;
+ }
+
+ public function getPath() {
+ return $this->path;
+ }
+
+ public function compare(PermissionTestResult $to) : PermissionTestResult
+ {
+ /**
+ * If the incoming path does not contain this one, we assume that it's not
+ * overriding it.
+ */
+ if (!\Strings::startsWith($to->getPath(), $this->getPath())) { return $this; }
- return (int)$result;
+ /**
+ * If the paths match, we return the longer one.
+ */
+ return strlen($to->getPath()) > strlen($this->getPath())? $to : $this;
}
+
}
diff --git a/bin/controllers/grant.php b/bin/controllers/grant.php
--- a/bin/controllers/grant.php
+++ b/bin/controllers/grant.php
@@ -1,8 +1,9 @@
<?php
use permission\PermissionHelper;
-use spitfire\exceptions\PublicException;
+use permission\PermissionTestResult;
use spitfire\exceptions\HTTPMethodException;
+use spitfire\exceptions\PublicException;
/*
* The MIT License
@@ -35,6 +36,7 @@
//#group
//:app
//~role
+ //$relation: How the user is connected to the resource (like &owner or &creator)
//* world
public function create() {
@@ -103,7 +105,7 @@
$this->view->set('grant', $grant);
}
- catch (spitfire\exceptions\HTTPMethodException$e) {}
+ catch (HTTPMethodException$e) {}
}
public function allow(GrantModel$grant) {
@@ -163,21 +165,38 @@
* Check if the user or an application is available for checking.
*/
if (!$this->authapp && !$this->user) {
- throw new PublicException('Permission denied', 403);
+ //throw new PublicException('Permission denied', 403);
}
if ($this->request->isPost()) {
+
+ $_ret = [];
+
/*
- *
+ * Loop over the query that was sent.
*/
- $resources = collect($_POST['resources']);
- $identities = collect(array_merge(['*'], $_POST['identities']));
-
- $results = $resources->each(function ($resource) use ($identities) {
- return PermissionHelper::unlock($resource, $identities);
- });
+ foreach ($_POST as $index => $query) {
+ $resources = collect($query['resources']);
+ $identities = collect($query['identities']);
+
+ $result = $identities->reduce(function (PermissionTestResult $carry = null, $identity) use ($resources) {
+
+ if ($carry && $carry->getResult() !== GrantModel::GRANT_INHERIT) { return $carry; }
+
+ $results = PermissionHelper::unlockAll($resources, $identity);
+ $top = $results
+ ->reduce(function (PermissionTestResult $c = null, PermissionTestResult $e) {
+ if (!$c) { return $e; }
+ else { return $c->compare($e); }
+ }, null);
+
+ return $top;
+ }, null);
+
+ $_ret[$index] = $result;
+ }
- $this->view->set('result', array_combine($resources->toArray(), $results->toArray()));
+ $this->view->set('result', $_ret);
}
@@ -187,7 +206,7 @@
*
* @param GrantModel $grant
*/
- public function edit(GrantModel$grant) {
+ public function edit(GrantModel$grant = null) {
$appid = $this->authapp? $this->authapp->getSrc()->getId() : '';
@@ -204,7 +223,7 @@
$grant->store();
$this->view->set('updated', true);
}
- catch (spitfire\exceptions\HTTPMethodException$e) {
+ catch (HTTPMethodException$e) {
/*Show the form*/
}
diff --git a/bin/templates/grant/eval.php b/bin/templates/grant/eval.php
--- a/bin/templates/grant/eval.php
+++ b/bin/templates/grant/eval.php
@@ -13,10 +13,10 @@
<form method="POST" action="">
<div class="row l2">
<div class="span l1" id="resources">
- <input type="text" name="resources[]" class="frm-ctrl" placeholder="Resource...">
+ <input type="text" name="0[resources][]" class="frm-ctrl" placeholder="Resource...">
</div>
<div class="span l1" id="identities">
- <input type="text" name="identities[]" class="frm-ctrl" placeholder="Identity...">
+ <input type="text" name="0[identities][]" class="frm-ctrl" placeholder="Identity...">
</div>
</div>
<div class="spacer small"></div>
@@ -34,7 +34,7 @@
</div>
</div>
-<?php if (isset($result)): ?>
+<?php if (isset($result) && isset($result[0])): ?>
<div class="spacer large"></div>
<div class="row l1">
@@ -47,17 +47,17 @@
<div class="span l3">
<div class="spacer medium"></div>
- <?php foreach ($result as $k => $v): ?>
- <?php $resource = permission\ResourceHelper::get($k); ?>
+ <pre>
+ </pre>
+ <?php $v = $result[0]; ?>
<div class="row l3 s3">
<div class="span l2 s2">
- <span class="text:grey-200"><?= $resource && $resource->mnemonic()? $resource->mnemonic()->caption : $k ?></span>
- <span class="text:grey-500"><?= $resource && $resource->mnemonic()? $k : '' ?></span>
+ <span class="text:grey-200"><?= $result[0]->getPath() ?></span>
</div>
<div class="span l1 s1">
- <?php if ($v == -1): ?>
+ <?php if ($v->getResult() == -1): ?>
<span style="color: #900">Denied</span>
- <?php elseif ($v == 0): ?>
+ <?php elseif ($v->getResult() == 0): ?>
<span style="color: #666">Undefined</span>
<?php else: ?>
<span style="color: #090">Granted</span>
@@ -65,7 +65,6 @@
</div>
</div>
<div class="spacer small"></div>
- <?php endforeach; ?>
</div>
</div>
</div>
@@ -79,7 +78,7 @@
var input = document.createElement('input');
input.type = 'text';
input.placeholder = 'Identity...';
- input.name = 'identities[]';
+ input.name = '0[identities][]';
input.className = 'frm-ctrl';
document.getElementById('identities').appendChild(input);
@@ -91,7 +90,7 @@
var input = document.createElement('input');
input.type = 'text';
input.placeholder = 'Resource...';
- input.name = 'resources[]';
+ input.name = '0[resources][]';
input.className = 'frm-ctrl';
document.getElementById('resources').appendChild(input);

File Metadata

Mime Type
text/plain
Expires
Tue, Apr 13, 10:33 PM (3 w, 6 d ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
6824
Default Alt Text
D544.id1951.diff (10 KB)

Event Timeline