New Jamaica scenario: blockmasks

"[email protected]" <[email protected]> Mon, 27 Apr 2009 07:15:42 +0200
Newsgroups gmane.comp.cms.xaraya.devel
Organization Xaraya
Message-ID <[email protected]>
The jamaica.blockmasks scenario was created primarily to explore the 
idea of anonymous masks.

An anonymous mask is a mask that is not registered in the privileges table.
A basic assumption since the creation of the privileges module has been 
that all masks are registered in a central place. This is thought to 
make it possible to better manage them, an example being the 
functionality of testing them against users in the privileges module.

In fact this has not lived up to expectations, I think.

For one thing it doesn't appear there are a lot of useful things you can 
do with masks except test them, at least not that I have found. For 
anther the testing itself is limited. In particular, since instances 
often change in security checks during runtime, such "altered" security 
checks are not present in the table and therefore cannot be tested 
against. Some modules like articles have specific functionality to 
create security check variants on the fly in order to gain flexibility.

Given all this I'm revisiting the assumption of having registered masks 
as a rule and focusing in this scenario on creating them on the fly. 
But, where in other cases in general one takes an existing mask and 
alters its instance definition, in this case the masks are assembled 
completely from scratch and therefore have no registered counterpart 
with a name in the privileges table: they are "anonymous".

The first step in going in this direction is to create a dataproperty 
for capturing the definition of an anonymous mask. The property, called 
access and residing in the privileges module, really only captures 2 
things: an access level and a flag to signal behavior when a security 
check fails (the "catch", called "failure" here). Why only these 2? It 
is assumed that all the other necessary data for a mask (module, 
component and instance) will be gotten from the context of the security 
check being executed. The access property has a check method which is a 
wrapper for a security check for receiving this information.

The scenario applies this idea of anonymous masks to the blocks system 
in Xaraya. In jamaica blocks are being rewritten to be represented by 
classes, with common functionality residing in a parent BasicBlock 
class. The common stuff includes the security check a block's display 
function usually has. By applying an anonymous mask here we can make 
that security check be defined at runtime for whatever block happens to 
be displaying.

The context of a block displaying (module, component, instance) is known 
automatically, so all that needs to be added is the catch and access 
level which the access property collects. In this case the property 
collects that data on the block's modify_instance page and stores it in 
the block definition itself. When the block displays, its definition is 
gotten from the blocks_instances table, and the access level and catch 
information along with it (saving a call to the privileges table to get 
a mask), and that information is inserted in the security check.

The same principle can be applied to other functions than displaying the 
block. The scenario's UI lets you define anonymous masks for displaying, 
modifying and deleting blocks on the modify_instance page, and adding 
them on the corresponding block_type page. The nice things about this is 
that adding security to a block becomes part of the block's overall 
creation process, as it all happens on the same page.

For this scenario the user menu block was converted to a class (not yet 
in jamaica), and the same principle applied to the view access of the 
modules displayed by the menu. The application to the single submenu 
items of each module is left to a future exercise.

Finally, the access property can also collect, as an alternative to an 
access level, a required group membership, in which case its check 
method will evaluate whether the current user is a member of that group 
when deciding whether he is allowed to see or modify an item. This seems 
particularly useful in the case of blocks, which are often meant to be 
seen by only certain groups.