Index: openacs-4/packages/acs-core-docs/www/permissions-tediously-explained.html =================================================================== RCS file: /usr/local/cvsroot/openacs-4/packages/acs-core-docs/www/permissions-tediously-explained.html,v diff -u -r1.6 -r1.7 --- openacs-4/packages/acs-core-docs/www/permissions-tediously-explained.html 20 Aug 2003 16:20:16 -0000 1.6 +++ openacs-4/packages/acs-core-docs/www/permissions-tediously-explained.html 14 Oct 2003 11:02:58 -0000 1.7 @@ -1,7 +1,6 @@ - -
+
by Vadim Nasardinov. Modified and converted to Docbook XML by Roberto Mello -
+
The general permissions system has a relatively complex data model in OpenACS 4.x. Developers who haven't had the time to learn the internals of the data model may end up writing seemingly correct code that crashes their system in @@ -15,9 +14,9 @@ system internals.
In OpenACS 4.x, most of the interesting tables are expected to extend (subtype) - the acs_objects table, i.e. they are expected to have an integer - primary key column that references the object_id column of - acs_objects. + the acs_objects table, i.e. they are expected to have an integer + primary key column that references the object_id column of + acs_objects.
create table acs_objects (
object_id integer
@@ -43,14 +42,14 @@
);
This means that any interesting entity (object) - in the system has an entry in the acs_objects. This + in the system has an entry in the acs_objects. This allows developers to define relationships between any two entities A and B by defining a relationship between their corresponding entries - in the acs_objects table. One of the applications of this + in the acs_objects table. One of the applications of this powerful capability is the general permissions system.
- At the heart of the permission system are two tables: acs_privileges - and acs_permissions. + At the heart of the permission system are two tables: acs_privileges + and acs_permissions.
create table acs_privileges (
privilege varchar2(100) not null
@@ -73,20 +72,20 @@
primary key (object_id, grantee_id, privilege)
);
- The acs_privileges table stores + The acs_privileges table stores named privileges like read, write, delete, create, and - admin. The acs_permissions + admin. The acs_permissions table stores assertions of the form:
- Who (grantee_id) can do what (privilege) - on which object (object_id). + Who (grantee_id) can do what (privilege) + on which object (object_id).
The naive approach to managing system security would be to require application developers to store permission information explicitly about every object, i.e. if the system has 100,000 and 1,000 users who have the read privilege on all objects, then we would need to store 100,000,000 entries of the form: -
Table�11.1.�
object_id | grantee_id | privilege |
---|---|---|
object_id_1 | user_id_1 | 'read' |
object_id_1 | user_id_2 | 'read' |
... | ||
object_id_1 | user_id_n | 'read' |
object_id_2 | user_id_1 | 'read' |
object_id_2 | user_id_2 | 'read' |
... | ||
object_id_2 | user_id_n | 'read' |
... | ||
... | ||
object_id_m | user_id_1 | 'read' |
object_id_m | user_id_2 | 'read' |
... | ||
object_id_m | user_id_n | 'read' |
+
Table�11.1.�
object_id | grantee_id | privilege |
---|---|---|
object_id_1 | user_id_1 | 'read' |
object_id_1 | user_id_2 | 'read' |
... | ||
object_id_1 | user_id_n | 'read' |
object_id_2 | user_id_1 | 'read' |
object_id_2 | user_id_2 | 'read' |
... | ||
object_id_2 | user_id_n | 'read' |
... | ||
... | ||
object_id_m | user_id_1 | 'read' |
object_id_m | user_id_2 | 'read' |
... | ||
object_id_m | user_id_n | 'read' |
Although quite feasible, this approach fails to take advantage of the fact that objects in the system are commonly organized hierarchally, and permissions usually follow the hierarchical structure, so that if user @@ -98,42 +97,42 @@ necessity to explicitly maintain security information for every single object. There are three kinds of hierarchies involved. These are discussed in the following sections. -
Suppose objects A, B, ..., and F form the following hierarchy. -
Table�11.2.�
A - object_id=10 + Table�11.2.�
- This can be represented in the + This can be represented in the acs_objects table by the following entries: - + The first entry tells us that object 20 is the descendant of object 10, and the third entry shows that object 40 is the descendant of object 20. By running a CONNECT BY query, we can compute that object 40 is the second-generation descendant of object 10. With this in mind, if we want to record the fact that user Joe has the read privilege on objects A, ..., F, we only need to record one entry in the - acs_permissions table. - + acs_permissions table. + The fact that Joe can also read B, C, ..., and F can be derived by ascertaining that these objects are children of A by traversing the context hierarchy. As it turns out, hierarchical queries are expensive. As Rafael Schloming put it so aptly, Oracle can't deal with hierarchies for shit. One way to solve this problem is to cache a flattened view of the context tree like so: - + Note that the number of entries in the flattened view grows exponentially with respect to the depth of the context tree. For instance, if you have a fully populated binary tree with a depth of n, then the number of entries @@ -143,7 +142,7 @@ Despite its potentially great storage costs, maintaining a flattened representation of the context tree is exactly what OpenACS 4.x does. The flattened context tree is stored in the - acs_object_context_index table. + acs_object_context_index table. create table acs_object_context_index ( object_id @@ -154,7 +153,7 @@ constraint acs_obj_context_idx_anc_id_fk references acs_objects(object_id), n_generations integer not null - constraint acs_obj_context_idx_n_gen_ck check (n_generations >= 0), + constraint acs_obj_context_idx_n_gen_ck check (n_generations >= 0), constraint acs_object_context_index_pk primary key (object_id, ancestor_id) ) organization index; @@ -168,8 +167,8 @@ has, and exponentially with respect to the depth of the context tree. |