ACL resource reflection and role inheritance
The new ACL now uses reflection to build its page resources. Previous versions used the page table to build these resources. Why the change? Because the previous method was error prone and did not reflect (sorry) any changes in the web application quickly enough.
Using reflection to build resources
The new method of updating page resources involves building a list of all actions found using reflection, then creating page resources for each of these actions. The acl_resource table is then updated with any new page resources, so that it mirrors the new web application structure. Optionally, the acl_resource table can also be cleared of all page resources before being updated.
Deploying the ACL
Since the new ACL no longer uses the pages table, the database must be primed for it to work. This is done by using the dev.forceAclReload config option, and only has to be done once to insert page resources into the database. Using dev.forceAclReload removes all page resource rows from the database exclusively, so it will not remove other resource types (such as calendar), and uses reflection to insert new page resource rows. Once primed, new page resource rows can be added to the existing database by using the ‘update page resource tree’ button in the access page.
Introducing multiple role inheritance
While the OCMS ACL had always used the very powerful Zend_Acl class from the Zend Framework, the support for multiple role inheritance was not available due to our ACL’s inability to load the necessary data from database. However, the ACL in R440 now has support for multiple role inheritance, and the new analysis page can determine and display inherited rules both via resource rule inheritance and role parent/ancestor rule inheritance (yes, I know - amazing!).
So how does this work? Well the ACL allows roles to have zero, one or multiple parents, so the role inherits the rules applied to the roles parents, if any.
To show how this works, lets suppose we have the following four roles:
- staff, which has no parent
- technician, which has no parent
- exam-staff, which has one parent (staff)
- support, which has two parents (staff and technician)
And this resource tree:
- event
- event/teleconference
- event/class
- event/exam
The default rule does not allow any role to access the resource tree root. Due to resource rule inheritance, this rule will also apply to every resource in the resource tree. With this in mind we define these rules (note that we do not define any rule for the ’support’ role):
- allow staff access to event/class
- allow technician access to event/teleconference
- allow exam-staff access to event
When we load these rules into the ACL and use the analysis tool, we get the following results:

Fig. 1 - Access analysis for staff role
The results in Fig. 1 are not surprising; We explicitly set a rule for the staff role and that resource. This demonstrates the most basic form rule definition in access control.

Fig. 2 - Access analysis for technician role
The results in Fig. 2 are equally boring; We explicitly set a rule for the technician role and that resource. Again, a vanilla rule.

Fig. 3 - Access analysis for support role
Now, according to the results in Fig. 3, the support-staff role has effective rules applied to it. However, no rules were explicitly defined for this role at all. The results show that the permissions were inherited from the staff and technician roles. Very tasty, but what if we define a rule in a child role as well? This is what we did for the exam-staff role.

Fig. 4 - Access analysis for exam-staff role
So, in Fig. 4 we see that the rule we defined for the exam-staff role was effective, and was inherited down the resource tree. We also see that the rule inherited from the staff role was also effected, and overrides the exam-staff rule. This is because the staff role was defined with a more localized resource target. If we had also created a rule for the exam-staff which targeted the event/class resource, it would have taken precedence over the staff rule.
Implementation
Now, to implement the roles in the example above, in code, we would define them as shown below:
// these roles have no parent $acl->addRole( new Zend_Acl_Role( 'staff' ) ); $acl->addRole( new Zend_Acl_Role( 'developer' ) ); // role with single parent $acl->addRole( new Zend_Acl_Role( 'exam-staff' ), 'staff' ); // role with multiple parents $acl->addRole( new Zend_Acl_Role( 'support' ), array( 'staff', 'developer' ) );
Note: I think that roles with parents must be added after the parent roles have been added, or an error will be thrown.
Now, this is all very nice and pretty, but our super-advanced mirror wielding ACL loads its rules from the database. So to define these rules in the database, we need to have the following rows in acl_role and acl_role_parent tables:
TABLE `acl_role` ( `id` SMALLINT(5) UNSIGNED NOT NULL AUTO_INCREMENT, `name` VARCHAR(32) NOT NULL, `description` VARCHAR(32) NOT NULL, ) INSERT INTO `acl_role` VALUES (1, 'technician', 'Teleconference Technician'); INSERT INTO `acl_role` VALUES (2, 'staff', 'General Staff'); INSERT INTO `acl_role` VALUES (3, 'exam-staff', 'Examinations Staff'); INSERT INTO `acl_role` VALUES (4, 'support', 'Help Desk'); TABLE `acl_role_parent` ( `id` SMALLINT(5) UNSIGNED NOT NULL AUTO_INCREMENT, `role_id` SMALLINT(5) UNSIGNED NOT NULL, `parent_role_id` SMALLINT(5) UNSIGNED NOT NULL, ) INSERT INTO `acl_role_parent` VALUES (1, 3, 2); INSERT INTO `acl_role_parent` VALUES (2, 4, 1); INSERT INTO `acl_role_parent` VALUES (3, 4, 2);
Note: If caching is enabled, the ACL cache must be cleared to force it to reload its data from the database.
That’s all for the role definition. Now all you have to do is assign rules to the roles for your resource tree and use the analysis tool to see how it affects the permissions for the roles and their child roles. However, since we already know how to implement regular roles and rules, I will stop here.
So, the ACL the system now auto-builds page resources via reflection, and we now have an idea of how role inheritance works. We’ve only touched the possibilities of multiple role inheritance, as there does not seem to be any limit to the number of parents or how many ancestors a role can have.
In addition, ACL still has at least two more dimensions of complexity: Assertions and Permissions. Although our ACL currently has limited support for these features, the existing features supported by our ACL make it capable of handling almost every access control situation in the OCMS.

Recent Comments