Limiting within ViewList, possible?

Author Message

Clemens T

Monday 03 October 2005 8:36:27 am

Hey all, my module.php file (of my extension) looks like this:

$Module = array( 'name' => 'myModule', 
		'variable_params' => true );

$ViewList = array();
$ViewList['overzicht'] = array(
    'script' => 'overzicht.php',
    'params' => array ( 'filter' ) );

$ViewList['details'] = array(
    'script' => 'details.php',
    'params' => array ( 'rfcid' ));

How can I limit the access PER VIEW for a user (so some users have access to 'details' view and some to 'overzicht' view, and some, to both)? Is this an ezpublish feature, or should I handle it in some other way?

Thanks a lot,
Clemens Timmermans

Kristof Coomans

Monday 03 October 2005 11:55:12 am

You'll have to use the key 'functions' in a <i>$ViewList</i> entry to tell eZ which policy functions you'll need to run a specific view:

$ViewList['overzicht'] = array(
    'script' => 'overzicht.php',
    'params' => array( 'filter' )
    'functions' => array( 'read' )
);

The 'functions' entry must be an array, but after investigation of index.php I think only the first item in the array is taken into account in policy checking. Please correct me if I'm wrong.

Now you need to define another array in module.php, called <i>$FunctionList</i>. This array will contain a list of the policy functions.
A simple policy will look like this:

$FunctionList = array( );
$FunctionList['read']=array( );

Did you notice that the 'read' entry in $FunctionList is also an array? That's because you can also define complex policies with function limitations. Complex policies however are not cheked by index.php. You will need to check them in your view.
An example of a complex policy, which defines a file to include and an object method to be called:

$ClassID = array(
    'name'=> 'Class',
    'values'=> array(),
    'path' => 'classes/',
    'file' => 'ezcontentclass.php',
    'class' => 'eZContentClass',
    'function' => 'fetchList',
    'parameter' => array( 0, false )
    );
$FunctionList['read'] = array( 'Class' => $ClassID );

When you edit a policy, you select <i>myModule</i> and the function <i>read</i>, the file 'kernel/classes/ezcontentclass.php' will be included. A new instance of eZContentClass will be made (always with an empty array as parameter). On this object, the method fetchList will be called with the parameters 0 and false. The called method must return an array where each item is another array with the keys 'name' and 'id'. These values will become options in a multiple select box, with id as the value and name as the caption. The label for the select box will be the value associated with the key 'name' in your limitation array. A shame that only files from the kernel can be included by this way.

Note that the value of the key 'name' in the function limitation needs to be the same as the key you use for your limitation in $FunctionList, because there seems to be some inconsistency in eZ's code: when editing the policies the 'name' key in the limitation list is used, and this is the one that get's stored in the database. But when displaying the policies, the key of the limitation array in the $FunctionList is used.

You can also define the options for the select box without the need to call a function. For example, the owner limitation for content/edit is defined as follows:

$Assigned = array(
    'name'=> 'Owner',
    'values'=> array(
        array(
            'Name' => 'Self',
            'value' => '1')
        )
    );

Node and Subtree limitations are an exception. The values are handled by the role module itself (with the content browser), so you will only need to define that you want to use them:

$Node = array(
    'name'=> 'Node',
    'values'=> array()
    );

$Subtree = array(
    'name'=> 'Subtree',
    'values'=> array()
    );

...

$FunctionList['read'] = array( 'Class' => $ClassID,
                               'Section' => $SectionID,
                               'Owner' => $Assigned,
                               'Node' => $Node,
                               'Subtree' => $Subtree);

If node limitations are used, all other limitations will be dropped by default when creating the policy. But you can change this behaviour by defining an array with limitations that need to be dropped:

$FunctionList['create'] = array( 'Class' => $ClassID,
                                 'Section' => $SectionID,
                                 'ParentClass' => $ParentClassID,
                                 'Node' => array_merge(  $Node, array( 'DropList' => array( 'ParentClass', 'Section' ) ) ),
                                 'Subtree' => $Subtree
                                 );

The droplist is currently broken (eZ publish 3.6.2).

So far this explanation of policy programming.

independent eZ Publish developer and service provider | http://blog.coomanskristof.be | http://ezpedia.org

Xavier Dutoit

Tuesday 04 October 2005 12:22:22 am

Many thanks for this detailled analysis.
X+

http://www.sydesy.com

Clemens T

Tuesday 04 October 2005 5:29:33 am

I'll read it later on, thanks for the (on first sight) wonderful contribution!

Kristof Coomans

Thursday 23 November 2006 2:27:32 am

<b>A shame that only files from the kernel can be included by this way.</b>

This has been fixed in eZ publish 3.8.7 ( http://issues.ez.no/9092 ). You can now use the key 'extension' to define the name of the extension in which the file to include is placed.

independent eZ Publish developer and service provider | http://blog.coomanskristof.be | http://ezpedia.org

Piotrek Karaś

Thursday 20 November 2008 4:49:35 am

Hi there,

I've just written a wrapper that I intend to take care of two things:
- include calling for user object,
- provide slightly simplified/aggregated limitation array, so that it can be faster, easier and cleaner to verify limited access.

public static function getSimplifiedUserAccess( string $module, string $function )
{
    $user = eZUser::currentUser();
    $userAccess = $user->hasAccessTo( $module, $function );

    $userAccess['simplifiedLimitations'] = array();
    if( $userAccess['accessWord'] == 'limited' )
    {
        foreach( $userAccess['policies'] as $policy )
        {
            foreach( $policy as $limitationName => $limitationList )
            {
                foreach( $limitationList as $limitationValue )
                {
                    $userAccess['simplifiedLimitations'][$limitationName][] = $limitationValue;
                }
            }
        }
    }
    return $userAccess;
}

1) Do you think the above approach is a good one?
2) Have I reinvented the wheel? Is there a ready solution for that?

Thanks,
Piotrek

--
Company: mediaSELF Sp. z o.o., http://www.mediaself.pl
eZ references: http://ez.no/partners/worldwide_partners/mediaself
eZ certified developer: http://ez.no/certification/verify/272585
eZ blog: http://ez.ryba.eu

Jérôme Vieilledent

Wednesday 03 February 2010 12:21:34 am

Hello !

I just reported 2 tickets about this subject :

  • http://issues.ez.no/IssueView.php?Id=16112&activeItem=1 (with Piotrek's function)
  • http://issues.ez.no/IssueView.php?Id=16113&activeItem= (for the eZJSCore policy checks to be implemented in the kernel :))

Bertrand Dunogier

Wednesday 03 February 2010 12:33:19 am

I was wondering if it wouldn't be appropriate to try using a struct to return these simplified permissions, the way it is done in the eZ Components ( http://www.ezcomponents.org/contributing/coding_standards#structs ). I kind of like the idea.

http://www.ezcomponents.org/contributing/coding_standards#structs

Bertrand Dunogier
eZ Systems Engineering, Lyon
http://twitter.com/bdunogier
http://gplus.to/BertrandDunogier

Jérôme Vieilledent

Wednesday 03 February 2010 1:04:09 am

Yep, this would be much cleaner :)

Powered by eZ Publish™ CMS Open Source Web Content Management. Copyright © 1999-2014 eZ Systems AS (except where otherwise noted). All rights reserved.