[cvs] [Wiki] changed: Doc/Dev/PermsPackage
Wiki Guest
wikiguest at horde.org
Fri Oct 3 03:37:14 UTC 2008
guest [66.66.8.61] Thu, 02 Oct 2008 23:37:14 -0400
Modified page: http://wiki.horde.org/Doc/Dev/PermsPackage
New Revision: 2.0
Change log: Rewrote with more in-depth explanations
@@ -1,34 +1,89 @@
-This is a brief synopsis of the steps required to add arbitrary
per-application permissions to the Horde permission system.
-In this example we'll add the permission "arbitrary_permission" to
module foo.
++Horde Permissions Framework+
+There are three aspects to the permissions framework. The first is
to tell Horde what permissions your application has. Horde uses a
unified tree structure to track all permissions, with each application
having a branch off the root. In your application, you must create a
list of permissions that Horde will then merge with other applications.
-in foo/lib/api.php:
+Next, an administrator needs to be able to assign or revoke
privileges. This part is completely abstracted and there isnt much
to say for developers. Horde itself has a UI for administering
permissions, but its just a front-end to the permissions API.
Therefore, your application can choose to manage permissions in its
own UI or business logic, but it doesnt strictly need to (and
probably shouldnt).
+
+The most important part is to enforce them. As a developer, you need
to add code into your business logic to check permissions before doing
something protected. None of the framework is useful without this step.
+
+++Defining Available Permissions++
+To allow Horde to manage your permissions, it needs to know what they
are. This is where the design stage comes in. Internally, Horde
identifies permissions via a tree.
+
+Each application defines its portion of the tree. Whenever the Horde
API is invoked, it needs to resolve a permission name, so it calls a
function called _app_perms() within each application (if it exists)
and merges its results.
+In this example we'll add the permission "arbitrary_permission" to
application foo.
+
+In foo/lib/api.php:
<code type="php">
$_services['perms'] = array(
'args' => array(),
'type' => '{urn:horde}stringArray'
);
-</code>
-and
-
-<code type="php">
function _foo_perms()
{
static $perms = array();
if (!empty($perms)) {
return $perms;
- }
+ }
$perms['tree']['foo']['arbitrary_permission'] = false;
$perms['title']['foo:arbitrary_permission'] = _("Textual description");
$perms['type']['foo:arbitrary_permission'] = 'boolean';
- $perms['param']['foo:arbitrary_permission'] = array();
-
return $perms;
}
</code>
+
+Now you can go to the Horde administration workflow and click on
Permissions. On this page, you will be able to see the permissions
tree. Add a child node for your foo application. Then when you add
a child to the foo application, you will see your new permission in
the list of permissions (the only item in this list in this example).
+
+This example is obviously very simplistic. The flexibility comes in
when populating the above list dynamically from persistent storage.
For example, if your application manages widgets, you can make a
database call in _foo_perms() and loop over your result set.
+
+<code type="php">
+while(($row = ($resultSet->next()) !== null) {
+ $widgetId = $row[widgetId];
+ $widgetName = $row[widgetName];
+
+ $perms['tree']['foo'][$widgetId] = false;
+ $perms['title'][foo:$widgetId] = $widgetName
+}
+</code>
+
+Using this strategy, one can create ACLs that apply to a specific
object, rather than static permissions, like create widgets.
Permissions can even be nested. One can create a static permission
called widgets whose permission mappings represent what a given user
can do to ALL widgets, then dynamically add children permissions for
specific widgets.
+
+Notice the use of $perms[type]. There are two types of
permissions, which determine the levels of that permission a user may
have. In the first example, type Boolean, the user either has the
permission, or they dont. The second type (default if not specified)
is matrix, which allows for various levels, specifically, SHOW,
READ, EDIT, and DELETE. A user may have any of these levels assigned,
or none.
+
+++Applying Permissions / Persistent Storage++
+
+This part of the process is completely abstracted and your
application shouldnt deal with it. However, it is obviously
important to understand. Horde exposes its API via two classes: Perms
and Horde_Permission.
+Perms contains the actions one performs, such as adding or removing
permissions. Horde_Permission is an entity class that represents a
permission. The PhpDocumentor documentation at
http://dev.horde.org/api/framework/ (choose the Horde_Perms package)
covers these classes fairly well.
+Note that the Permissions class is a singleton. The instance is
usually already defined in a global variable $GLOBALS[perms]. Its
also possible to access the static singleton method like so:
+<code type="php">
+$perms = &Perms::singleton();
+</code>
+
+To add a new permission (assuming its already defined) into
persistent storage, use Perms::newPermission(), which gives you back a
Horde_Permission object that you can then populate with users and
permission assignments. Calling Perms::addPermission() with that same
object will push it into persistent storage so that the specified
users will have the permission.
+
+<code type="php">
+global $perms;
+$p = $perms->newPermission('foo:arbitrary_permission');
+$p->addUserPermission(someUser, PERMS_SHOW | PERMS_READ |
PERMS_EDIT | PERMS_DELETE);
+$perms->addPermission($p);
+</code>
+
+++Using / Enforcing Permissions++
+
+None of this code matters if your application doesnt actually check
these permissions. This is best done in your business logic and NOT
at the user interface level. To check if a user has a given
permission, simply call Perms::hasPermission() through the singleton
object. For example:
+
+<code type="php">
+public function myBusinessMethod($widgetId)
+{
+ if(!$GLOBALS[perms]->hasPermission(foo:$widgetId,
Auth::getUser(), PERMS_EDIT))
+ throw new Exception(_("Access denied."));
+
+ // your business code
+}
+</code>
+
Then, once you have created an object that you wish to apply those
permissions to,
<code type="php">
@@ -37,5 +92,4 @@
$perms->addPermission($p);
</code>
After that, you should see the permission that you created on the
permissions administration page.
-
More information about the cvs
mailing list