<html xmlns:lxslt="http://xml.apache.org/xslt" xmlns:saxon="http://icl.com/saxon" xmlns:xalanredirect="org.apache.xalan.xslt.extensions.Redirect"><head>
<META http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>5. ACS 4 Permissions Design</title><link rel="stylesheet" href="ad.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.24"><link rel="home" href="index.html" title="ACS Core"><link rel="up" href="kernel-doc.html" title="7. Kernel Documentation"><link rel="previous" href="permissions-requirements.html" title="4. ACS 4 Permissions Requirements"><link rel="next" href="groups-requirements.html" title="6. ACS 4 Groups Requirements"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><a href="http://www.openacs.org/"><img src="images/alex.jpg" border="0"></a><br><br><a class="topnav" href="/">Home</a><span class="topnav"> : </span><a class="topnav" href="index">Documentation</a><span class="topnav"> : </span><a class="topnav" href="acs-dev.html">Part III. For ACS Developers</a><span class="topnav"> : </span><a class="topnav" href="kernel-doc.html">7. Kernel Documentation</a><span class="topnav"> : </span><strong class="topnav">5. ACS 4 Permissions Design&nbsp;</strong><hr size="1" noshade><div id="permissions-design" class="sect1"><div class="titlepage"><h2 class="title" style="clear: all"><a name="permissions-design"></a><span class="label">5.</span> <span class="title">ACS 4 Permissions Design</span></h2></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt>5.1. <a href="permissions-design.html#permissions-design-essentials">Essentials</a></dt><dt>5.2. <a href="permissions-design.html#permissions-design-intro">Introduction</a></dt><dt>5.3. <a href="permissions-design.html#permissions-design-history">Historical Considerations</a></dt><dt>5.4. <a href="permissions-design.html#permissions-design-competitors">Competitive Analysis</a></dt><dt>5.5. <a href="permissions-design.html#permissions-design-design-tradeoffs">Design Tradeoffs</a></dt><dt>5.6. <a href="permissions-design.html#permissions-design-data-model">Data Model Discussion</a></dt><dt>5.7. <a href="permissions-design.html#permissions-design-transactions">Legal Transactions</a></dt><dt>5.8. <a href="permissions-design.html#permissions-design-api">API</a></dt><dt>5.9. <a href="permissions-design.html#permissions-design-ui">User Interface</a></dt><dt>5.10. <a href="permissions-design.html#permissions-design-configure">Configuration/Parameters</a></dt><dt>5.11. <a href="permissions-design.html#permissions-design-future">Future Improvements/Areas of Likely Change</a></dt><dt>5.12. <a href="permissions-design.html#permissions-design-authors">Authors</a></dt><dt>5.13. <a href="permissions-design.html#permissions-design-rev-history">Revision History</a></dt></dl></div><p><p>
by <a href="mailto:jmp@arsdigita.com" target="_top">John Prevost</a> and <a href="http://planitia.org" target="_top">Rafael H. Schloming</a> 
</p></p><div id="permissions-design-essentials" class="sect2"><div class="titlepage"><h3 class="title"><a name="permissions-design-essentials"></a><span class="label">5.1.</span> <span class="title">Essentials</span></h3></div><div class="itemizedlist"><ul><li><a name="N13328"></a><p>Tcl in <tt>packages/acs-kernel</tt></p></li><li><a name="N13334"></a><p><a href="permissions-requirements.html">ACS 4 Permissions Requirements</a></p></li><li><a name="N13338"></a><p><a href="/doc/sql/display-sql?url=acs-permissions-create.sql&amp;package_key=acs-kernel" target="_top">
SQL file</a></p></li><li><a name="N13343"></a><p><a href="images/permissions-er.png" target="_top">ER diagram</a> 

</p></li></ul></div></div><div id="permissions-design-intro" class="sect2"><div class="titlepage"><h3 class="title"><a name="permissions-design-intro"></a><span class="label">5.2.</span> <span class="title">Introduction</span></h3></div><p>The goal of the Permissions system is to provide generic means to both
programmers and site administrators to designate operations (methods) as
requiring permissions, and then to check, grant, or revoke permissions via a
consistent interface. For example, we might decide that the transaction that
bans a user from a sub-site is an operation a site administrator is able to
assign to a particular user. Or perhaps an application developer might decide
that viewing a certain set of pages within the application is an operation to
be individually granted or revoked from a user. It's expected that the
Permissions system will be seeing a lot of use - almost every page will make
at least one permissions API call, and some will make several.</p><p>For programmers, the Permissions API provides a means to work with access
control in a consistent manner. If a programmer's ACS package defines new
methods for itself, the Permissions API must provide simple calls to
determine whether the current user is authorized to perform the given method.
In addition, using the Permissions API, queries should easily select only
those package objects on which a user has certain permissions.</p><p>For site administrators and other authorized users, the Permissions UI
provides a means to aggregate the primitive operations (methods) made
available by the programmer into logical privileges (like read, write, and
admin) that can be granted and revoked.</p></div><div id="permissions-design-history" class="sect2"><div class="titlepage"><h3 class="title"><a name="permissions-design-history"></a><span class="label">5.3.</span> <span class="title">Historical Considerations</span></h3></div><p>In earlier versions of the ACS, permissions and access control was handled
on a module-by-module basis, often even on a page-by-page basis. For example,
a typical module might allow any registered user to access its pages
read-only, but only allow members of a certain group to make changes. The way
this group was determined also varied greatly between modules. Some modules
used "roles", while others did not. Other modules did all access
control based simply on coded rules regarding who can act on a given database
row based on the information in that row.</p><p>Problems resulting from this piecemeal approach to permissions and access
control were many, the two major ones being inconsistency, and
repeated/redundant code. Thus the drive in ACS 4 to provide a unified,
consistent permissions system that both programmers and administrators can
readily use.</p></div><div id="permissions-design-competitors" class="sect2"><div class="titlepage"><h3 class="title"><a name="permissions-design-competitors"></a><span class="label">5.4.</span> <span class="title">Competitive Analysis</span></h3></div><p><i>None available as of 10/2000.</i></p></div><div id="permissions-design-design-tradeoffs" class="sect2"><div class="titlepage"><h3 class="title"><a name="permissions-design-design-tradeoffs"></a><span class="label">5.5.</span> <span class="title">Design Tradeoffs</span></h3></div><p>The core of the permissions data model is quite simple. Unfortunately, the
hierarchical nature of default permissions entails quite a number of tree
queries which could slow the system down. Since every page will have at least
one permissions check, a number of views and auxiliary tables
(de-normalizations of the data model) have been created to speed up access
queries. As a consequence, speed of updates are decreased and requirements
for additional storage space increase.</p></div><div id="permissions-design-data-model" class="sect2"><div class="titlepage"><h3 class="title"><a name="permissions-design-data-model"></a><span class="label">5.6.</span> <span class="title">Data Model Discussion</span></h3></div><p>As described in section V., the core of the permissions data model is
simple, though a number of views and auxiliary tables exist to ensure
adequate performance. The core model consists of five tables:</p><div class="variablelist"><dl><dt><a name="N13387"></a><span class="term"><tt>acs_methods</tt>

</span></dt><dd><p>The set of all defined methods.</p></dd><dt><a name="N13396"></a><span class="term"><tt>acs_privileges</tt>

</span></dt><dd><p>The set of all defined privileges.</p></dd><dt><a name="N13405"></a><span class="term"><tt>acs_privilege_method_rules</tt>

</span></dt><dd><p>A relation describing the set of methods <strong>directly</strong>
associated with each privilege.</p></dd><dt><a name="N13417"></a><span class="term"><tt>acs_privilege_hierarchy</tt>

</span></dt><dd><p>A relation describing which privileges <strong>directly</strong>
"contain" other privileges.</p></dd><dt><a name="N13429"></a><span class="term"><tt>acs_permissions</tt>

</span></dt><dd><p>A table with one (<i>party</i>, <i>object</i>, <i>privilege</i>)
row for every privilege <strong>directly</strong> granted on any object in
the system - this is a denormalization of
<tt>acs_privilege_method_rules</tt> and
<tt>acs_privilege_hierarchy</tt></p></dd></dl></div><p>There are also a number of views to make it easier to ask specific
questions about permissions. For example, a number of the above tables
describe "direct" or explicit permissions. Inheritance and default
values can, however, introduce permissions which are not directly specified.
(For example, read access on a bboard allows read access on all the messages
in the bboard.)</p><p>The following views provide flattened versions of inherited
information:</p><div class="variablelist"><dl><dt><a name="N13462"></a><span class="term"><tt>acs_privilege_method_map</tt>

</span></dt><dd><p>Map of privileges to the methods they contain either directly or because
of another privilege which is included (at any depth).</p></dd><dt><a name="N13471"></a><span class="term"><tt>acs_object_grantee_priv_map</tt>

</span></dt><dd><p>Relation on (<i>object</i>, <i>party</i>, <i>privilege</i>) for
privileges from <tt>acs_privileges</tt>) granted directly on the object, or
on the context of the object (at any depth).</p></dd><dt><a name="N13493"></a><span class="term"><tt>acs_object_party_privilege_map</tt>

</span></dt><dd><p>Relation on (<i>object</i>, <i>party</i>, <i>privilege</i>) for
privileges directly from <tt>acs_object_grantee_priv_map</tt> or also because
a party is a member of a group (at any depth).</p></dd><dt><a name="N13515"></a><span class="term"><tt>acs_object_party_method_map</tt>

</span></dt><dd><p>Relation with every (<i>object</i>, <i>party</i>, <i>method</i>)
tuple implied by the above trees.</p></dd></dl></div><p>In general, <strong>only <tt>acs_object_party_method_map</tt></strong>
should be used for queries from other modules. The other views are
intermediate steps in building that query.</p><p>The data model also includes two simple PL/SQL procedures
(<tt>acs_permission.grant_permission</tt> and
<tt>acs_permission.revoke_permission</tt>) for granting and revoking a
specific privilege for a specific user on a specific object.</p><p>To sum up, the PL/SQL procedures are meant to be used to grant or revoke
permissions. The five base tables represent the basic data model of the
system, with a set of views provided to convert them into a format suitable
for joining to answer specific questions. The exact means by which this
transformation takes place should not be depended on, since they may change
for efficiency reasons.</p><p>The transformations done create a set of default permissions, in
which:</p><div class="itemizedlist"><ul><li><a name="N13556"></a><p>parties get the privileges of any groups they are directly or indirectly
a member of</p></li><li><a name="N13559"></a><p>privileges get associated with the methods of any other privileges they
have taken methods from (at any level) (see
<tt>acs_privilege_hierarchy</tt>)</p></li><li><a name="N13566"></a><p>objects get access control from direct grants, or inherit permissions
from their context (unless the "don't inherit" flag is
set)</p></li></ul></div></div><div id="permissions-design-transactions" class="sect2"><div class="titlepage"><h3 class="title"><a name="permissions-design-transactions"></a><span class="label">5.7.</span> <span class="title">Legal Transactions</span></h3></div><p>There are three essential areas in which all transactions in the
permissions system fall:</p><div class="itemizedlist"><ul><li><a name="N13576"></a><p>Modification of methods and privileges</p></li><li><a name="N13579"></a><p>Modification of permissions</p></li><li><a name="N13582"></a><p>Queries on permissions</p></li></ul></div><p><strong>"Modification of methods and privileges."</strong> This
refers to actions that happen mainly at package installation time - a package
will create a number of methods for its own use, then associate them with the
system's standard privileges, or new privileges which the package has
created. The association step might also happen later, if the site-wide
administrator chooses to change permissions policy.</p><p>These steps involve directly manipulating the <tt>acs_methods</tt>,
<tt>acs_privileges</tt>, and <tt>acs_privilege_method_rules</tt> tables. A
web page for manipulating these features should be limited to site-wide
administrators.</p><p><strong>"Modification of permissions"</strong> - involves fairly
common operations. Users are typically able to administer permissions for
objects they themselves create. The two basic operations here are
"grant" and "revoke". Granting permissions is done via
<tt>acs_permissions.grant_permission</tt>, and revocation via
<tt>acs_permissions.revoke_permission</tt>. These directly manipulate the
<tt>acs_permissions</tt> table.</p><p>Web pages for making these changes are available to all users, so they
should not be in an admin area. In order to grant and revoke permissions on
an object, the user must have the <tt>administer_privileges</tt> method
permission on that object.</p><p><strong>"Queries on permissions"</strong> - by far the most
common operation is querying the permissions database. Several kinds of
questions are commonly asked: First, and most commonly, "Can this party
perform this method on this object?" Two Tcl functions are provided to
answer this - one which returns a boolean, the other of which results in an
error page. These tcl functions directly access the
<tt>acs_object_party_method_map</tt>.</p><p>The second most commonly asked question occurs when a list of objects is
being displayed, often in order to provide appropriate UI functionality:
"For this party, what methods are available on these objects?"
Here, the SQL query needs to filter based on whether the party/user can
perform some operation on the object. This is done via a join or sub-select
against <tt>acs_object_party_method_map</tt>, or by calling the Tcl functions
for appropriate methods.</p><p>Finally, when administering the permissions for an object, a web page
needs to know all permissions directly granted on that object. This is done
by querying against <tt>acs_permissions</tt>.</p></div><div id="permissions-design-api" class="sect2"><div class="titlepage"><h3 class="title"><a name="permissions-design-api"></a><span class="label">5.8.</span> <span class="title">API</span></h3></div><p>The API to the permissions system consists of a few well-known tables,
plus a pair of PL/SQL procedures and a pair of Tcl functions.</p><p><strong>Tables</strong></p><p><tt>acs_methods</tt>, <tt>acs_privileges</tt>, and
<tt>acs_privilege_method_rules</tt> manage the set of permissions in the
system. At installation time, a package will add to these three tables to
introduce new permissions into the system.</p><p>The main table for queries is <tt>acs_object_party_method_map</tt>, which
contains (<i>object</i>, <i>party</i>, <i>method</i>) triples for all
allowed operations in the system.</p><p>Also of interest for queries is <tt>acs_permissions</tt>, which lists
directly granted privileges. Neither <tt>acs_object_party_method_map</tt>
(which is a view) nor <tt>acs_permissions</tt> should be updated
directly.</p><p><strong>PL/SQL Procedures</strong></p><p><tt>acs_permissions.grant_permission</tt> introduces new permissions for
an object. It should be given an (<i>object</i>, <i>party</i>,
<i>privilege</i>) triple, and will always succeed. If the permission is
already in the system, no change occurs. The interface for this procedure
is:</p><blockquote><table border="0" cellpadding="5" cellspacing="0"><tr><td class="codeblock"><pre>
procedure grant_permission (
  object_id    acs_permissions.object_id%TYPE,
  grantee_id   acs_permissions.grantee_id%TYPE,
  privilege    acs_permissions.privilege%TYPE
);
</pre></td></tr></table></blockquote><p><tt>acs_permissions.revoke_permission</tt> removes a permission entry
given a triple. It always succeeds--if a permission does not exist, nothing
changes. The interface for this procedure is:</p><blockquote><table border="0" cellpadding="5" cellspacing="0"><tr><td class="codeblock"><pre>
procedure revoke_permission (
  object_id    acs_permissions.object_id%TYPE,
  grantee_id   acs_permissions.grantee_id%TYPE,
  privilege    acs_permissions.privilege%TYPE
);
</pre></td></tr></table></blockquote><p>These procedures are defined in <a href="http://acs40.arsdigita.com/doc/sql/display-sql?url=acs-permissions-create.sql&amp;package_key=acs-kernel" target="_top">
<tt>permissions-create.sql</tt></a></p><p><strong>Tcl Procedures</strong></p><p>Two tcl procedures provide a simple call for the query, "Can this
user perform this method on this object?" One returns true or false, the
other presents an error page.</p><p>To receive a true or false value, Tcl code should call:</p><blockquote><table border="0" cellpadding="5" cellspacing="0"><tr><td class="codeblock"><pre>
ad_permission_p $object_id $object_type $method -user_id $user_id
</pre></td></tr></table></blockquote><p>If the <tt>user_id</tt> argument is left out, then the currently logged in
user is checked. To create an error page, Tcl code should call:</p><blockquote><table border="0" cellpadding="5" cellspacing="0"><tr><td class="codeblock"><pre>
ad_require_permission $object_id $object_type $method
</pre></td></tr></table></blockquote><p>These procedures are defined in <tt>acs-permissions-procs.tcl</tt>.</p></div><div id="permissions-design-ui" class="sect2"><div class="titlepage"><h3 class="title"><a name="permissions-design-ui"></a><span class="label">5.9.</span> <span class="title">User Interface</span></h3></div><p>All users of the permissions system are the same at the user-interface
level. If you have the <tt>administer_privileges</tt> method permission on an
object, then you may edit privileges for that object with the UI.</p><p>The UI currently provides a list of all granted permissions on the object.
If the user wishes to revoke privileges, she may select a set of grants,
choose revoke, confirm their deletion, and be returned to the same page after
those privileges have been revoked.</p><p>Granting permissions currently (as of 10/2000) works by providing a list
of all possible permissions and a list of all parties in the system. (For
large sites, some future search mechanism will be necessary.) After choosing
privileges to grant, the user is returned to the "edit privileges for
one object" screen.</p><p>If it makes sense, the system will also display a checkbox which the user
may select to toggle whether permissions are inherited from the object's
context.</p><p>There are a number of potential future enhancements for the permissions
UI, outlined below.</p></div><div id="permissions-design-configure" class="sect2"><div class="titlepage"><h3 class="title"><a name="permissions-design-configure"></a><span class="label">5.10.</span> <span class="title">Configuration/Parameters</span></h3></div><p>There are no configuration options for the permissions system.</p></div><div id="permissions-design-future" class="sect2"><div class="titlepage"><h3 class="title"><a name="permissions-design-future"></a><span class="label">5.11.</span> <span class="title">Future Improvements/Areas of Likely Change</span></h3></div><p>The most important future changes to the Permissions system are likely to
be in the UI:</p><div class="itemizedlist"><ul><li><a name="N13788"></a><p>There should be a page displaying a list of all objects for which the
current user is allowed to administer privileges.</p></li><li><a name="N13791"></a><p>Users should be able to view the permissions on any object, or perhaps on
objects which they have the "read_permissions" method. This would
allow them to see what grants are affecting their objects through
inheritance.</p></li></ul></div></div><div id="permissions-design-authors" class="sect2"><div class="titlepage"><h3 class="title"><a name="permissions-design-authors"></a><span class="label">5.12.</span> <span class="title">Authors</span></h3></div><div class="variablelist"><dl><dt><a name="N13799"></a><span class="term">System creator

</span></dt><dd><p><a href="mailto:rhs@mit.edu" target="_top">Rafael H. Schloming</a></p></dd><dt><a name="N13807"></a><span class="term">System owner

</span></dt><dd><p><a href="mailto:rhs@mit.edu" target="_top">Rafael H. Schloming</a></p></dd><dt><a name="N13815"></a><span class="term">Documentation author

</span></dt><dd><p><a href="mailto:jmp@arsdigita.com" target="_top">John Prevost</a></p></dd></dl></div></div><div id="permissions-design-rev-history" class="sect2"><div class="titlepage"><h3 class="title"><a name="permissions-design-rev-history"></a><span class="label">5.13.</span> <span class="title">Revision History</span></h3></div><div class="informaltable" id="N13827"><a name="N13827"></a><table cellpadding="5" cellspacing="0" border="1"><colgroup><col><col><col><col></colgroup><tbody><tr><td xmlns="http://www.w3.org/TR/xhtml1/transitional"><strong xmlns="">Document Revision #</strong></td><td xmlns="http://www.w3.org/TR/xhtml1/transitional"><strong xmlns="">Action Taken, Notes</strong></td><td xmlns="http://www.w3.org/TR/xhtml1/transitional"><strong xmlns="">When?</strong></td><td xmlns="http://www.w3.org/TR/xhtml1/transitional"><strong xmlns="">By Whom?</strong></td></tr><tr><td xmlns="http://www.w3.org/TR/xhtml1/transitional">0.1</td><td xmlns="http://www.w3.org/TR/xhtml1/transitional">Creation</td><td xmlns="http://www.w3.org/TR/xhtml1/transitional">9/11/2000</td><td xmlns="http://www.w3.org/TR/xhtml1/transitional">John Prevost</td></tr><tr><td xmlns="http://www.w3.org/TR/xhtml1/transitional">0.2</td><td xmlns="http://www.w3.org/TR/xhtml1/transitional">Edited for ACS 4 Beta release</td><td xmlns="http://www.w3.org/TR/xhtml1/transitional">10/04/2000</td><td xmlns="http://www.w3.org/TR/xhtml1/transitional">Kai Wu</td></tr></tbody></table></div></div></div><div class="navfooter"><hr size="1" noshade><table width="100%"><tr><td width="40%" align="left"><a class="bottomnav" href="permissions-requirements.html">Prev</a>&nbsp;</td><td width="20%" align="center"><a href="mailto:acs-docs@arsdigita.com"><address class="nav">acs-docs@arsdigita.com</address></a></td><td width="40%" align="right">&nbsp;<a class="bottomnav" href="groups-requirements.html">Next</a></td></tr></table></div></body></html>