Des limitations pour vos politiques de sécurité

La gestion des droits utilisateur dans eZ Publish est, vous le savez sans doute, assez précise et autorise un contrôle d'accès avec une granularité très fine. En effet, la plupart des modules du kernel permettent d'en limiter l'accès au moyen de politiques de sécurité que l'on peut attribuer à un utilisateur ou à un groupe d'utilisateurs. C'est particulièrement le cas pour le module content, central au CMS, grâce à ses limitations de fonctions configurables dans le backoffice. Ces limitations nous offrent la possibilité de définir précisément le champ d'action d'un contributeur au niveau du contenu géré par eZ Publish.

Définir ses fonctions de module pour en limiter l'accès

Il est bien sûr possible de définir des règles de sécurité configurables de la même manière pour nos propres modules. Il suffit pour cela de créer une liste de fonctions pour notre module, dans le fichier module.php :

extension/myextension/modules/mymodule/module.php

<?php 
$Module = array('name' => 'mymodule');
 
$ViewList = array();
$ViewList['myview'] = array(
 'script'     => 'view.php',
 'params'     => array(),
 'functions'     => array( 'myfunction' )
);
 
$FunctionList['myfunction'] = array();

Ici nous définissons une fonction pour le module mymodule et nous l'affectons à la vue myview. Cette fonction apparaîtra dans la liste correspondante lors de la définition d'une nouvelle politique de sécurité pour le module mymodule.

Vous retrouverez ce genre de définition dans la plupart des modules du kernel, voire d'extensions développées par eZ Systems ou plus largement par la communauté (c'est le cas par exemple de NovenINIUpdate ).

Ce mode de fonctionnement suffit dans la plupart des cas, mais comment faire si l'on souhaite appliquer des limitations plus poussées comme pour le module content (langue, section, etc...) ?

Définir ses propres limitations

Comme vous l'avez sûrement remarqué, dans l'exemple de module.php ci-dessus, la variable $FunctionList['myfunction'] est un tableau vide, ce qui signifie que la fonction ne prévoit aucune limitation. Pour en ajouter, il suffit de le remplir avec les bonnes valeurs.

Exemple pour une limitation au niveau de la langue :

<?php 
$Module = array('name' => 'mymodule');
 
$ViewList = array();
$ViewList['myview'] = array(
 'script'     => 'view.php',
 'params'     => array(),
 'functions'     => array( 'myfunction' )
);
 
$Language = array(
    'name'=> 'Language',
    'values'=> array(),
    'path' => 'classes/',
    'file' => 'ezcontentlanguage.php',
    'class' => 'eZContentLanguage',
    'function' => 'fetchLimitationList',
    'parameter' => array( false )
);
 
$FunctionList['myfunction'] = array('Language' => $Language);

Nous disons ici à eZ Publish que myfunction possède une limitation du nom de Language et dont il faut aller chercher la liste des valeurs possibles via la méthodeeZContentLanguage::fetchLimitationList(), avec le paramètre false. Il s'agit simplement d'une bien vieille manière d'appeler une fonction de callback datant probablement des premières releases d'eZ Publish 3 (souvenez-vous des premières versions de PHP4 et de toutes ses limitations). Pour les curieux, tout se joue dans la méthode eZPolicyLimitation::allValuesAsArrayWithNames(), à partir de la ligne 249 (dans un eZ Publish 4.3.0).

Nous appelons ici une classe du kernel pour remplir notre tableau de limitation, mais il est bien sûr possible d'utiliser une classe se trouvant dans une extension. Cependant, le système d'autoload de classes n'est pas utilisé ici et un bon vieil include_once est effectué en backend. Aussi, afin d'utiliser une classe se situant dans une extension, il est nécessaire de rajouter une autre clé à notre tableau $Language :

$Language = array(
    'name' => 'Language',
    'values' => array(),
    'extension' => 'myextension',
    'path' => 'classes/',
    'file' => 'myclass.php',
    'class' => 'MyClass',
    'function' => 'fetchLanguageLimitationList',
    'parameter' => array()
);

De cette façon, la classe extension/myextension/classes/myclass.php sera inclue.

Mais que doit retourner ma méthode MyClass:fetchLanguageLimitationList() ? Un petit coup d'oeil à eZContentLanguage::fetchLimitationList() nous montre qu'il doit s'agir d'un tableau simple dont chaque entrée est elle-même un tableau associatif contenant les clés id et name.

  • id sera la valeur enregistrée dans la base de données pour la limitation sur la politique de sécurité
  • name sera simplement le libellé affiché pour la sélection dans le Backoffice.

Voici donc à quoi devra ressembler notre classe MyClass :

class MyClass
{
    /**
     * Fetches the array with names and IDs of the languages used on the site. This method is used by the permission system.
     *
     * @return Array with names and IDs of the languages used on the site.
     * @static
     */
    public static function fetchLanguageLimitationList()
    {
     $langList = eZINI::instance( 'site.ini' )->variable( 'RegionalSettings', 'SiteLanguageList' );
     $aResult = array();
     foreach($langList as $lang)
     {
      if($lang)
      {
       $aResult[] = array(
        'id' => $lang,
        'name' => $lang
       );
      }
     }
 
     return $aResult;
    }
}

Contrôler les accès dans notre module

Maintenant que les limitations sont définies, il reste cependant nécessaire de filtrer les accès à notre module en fonction des droits assignés à tel ou tel utilisateur. En effet, ce contrôle est effectué dans index.php pour le module content, et uniquement pour celui-ci. Nous sommes donc obligés de faire le gendarme nous-mêmes (ce point mérite d'ailleurs d'être optimisé pour les versions futures d'eZ Publish. Pour Fuji peut-être ?).

Tirer partie d'eZJSCore

Le contrôle manuel des limitations en utilisant le framework peut s'avérer un véritable chemin de croix tellement le système est complexe. J'ajouterais par ailleurs qu'il ne s'agit pas de la partie la plus propre du CMS et qu'un peu de nettoyage ne lui ferait pas de mal ! Heureusement, les développeurs Łukasz Serwatka et Andrè Rømcke ont implémenté dans l'extension eZJSCore une méthode de contrôle d'accès simplifiée sous la forme d'un opérateur de template. Cette extension faisant désormais partie de la distribution de base d'eZ Publish, il serait dommage de s'en priver !

Voici donc la meilleure manière de procéder :

extension/myextension/modules/mymodule/myview.php

$userHasAccess = ezjscAccessTemplateFunctions::hasAccessToLimitation( 'mymodule', 'myfunction' ); // Returns a boolean for current user

Récupérer la liste des limitations pour l'utilisateur courant

Malheureusement, eZJSCore ne possède pas de méthode permettant de récupérer les limitations disponibles pour l'utilisateur courant, ce qui peut être pourtant utile pour afficher par exemple une liste déroulante contenant les limitations accordées à l'utilisateur (dans notre cas, les langues disponibles).

Pour cela, il vous faudra écrire une méthode retournant ces limitations de manière simplifiée. En effet, la classe eZUser dispose de la méthode hasAccessTo() mais ce qu'elle retourne est absolument imbitable et demande à être fortement simplifié. Nous allons donc écrire une méthode complémentaire nous retournant des limitations simplifiées.

class MyClass
{
 /**
  * Shorthand method to check user access policy limitations for a given module/policy function.
  * Returns the same array as eZUser::hasAccessTo(), with "simplifiedLimitations".
  * 'simplifiedLimitations' array holds all the limitations names as defined in module.php.
  * If your limitation name is not defined as a key, then your user has full access to this limitation
  * @param string $module Name of the module
  * @param string $function Name of the policy function ($FunctionList element in module.php)
  * @return array
  */
 public static function getSimplifiedUserAccess( $module, $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;
     }
 
     $userAccess['simplifiedLimitations'][$limitationName] = array_unique($userAccess['simplifiedLimitations'][$limitationName]);
    }
   }
  }
  return $userAccess;
 }
}

Cette méthode nous retourne un tableau contenant le résultat de eZUser::hasAccessTo(), complété d'une clé simplifiedLimitations. Cette dernière est également un tableau contenant quant à lui les précieuses limitations.

Dans notre exemple, pour un utilisateur auquel nous aurions affecté une limitation Language autorisant uniquement fre-FR et eng-GB, ce tableau contiendrait :

$limitations = MyClass::getSimplifiedUserAccess( 'mymodule', 'myfunction' );
print_r( $limitations['simplifiedLimitations'] );
 
// Result
Array
(
    [Language] => Array
        (
            [0] => fre-FR
            [1] => eng-GB
        )
 
)

Dans notre module où nous devons afficher une liste déroulante des langues autorisées, nous aurions donc :

extension/myextension/modules/mymodule/myview.php

$tpl = eZTemplate::factory(); // Template init – from 4.3.0
 
$authorizedLang = eZINI::instance('site.ini')->variable( 'RegionalSettings', 'SiteLanguageList' ); // Default is all languages
$limitations = MyClass::getSimplifiedUserAccess( 'mymodule', 'myfunction' );
 
if( isset( $limitations['simplifiedLimitations']['Language'] ) ) // Found limitations on language. These will be the only available in the dropdown menu
 $authorizedLang = $limitations['simplifiedLimitations']['Language'];
 
$tpl->setVariable( 'languages', $authorizedLang );
 
$Result['content'] = $tpl->fetch( 'design:mydesignsubdir/myview.tpl' );

extension/myextension/design/standard/templates/mydesignsubdir/myview.tpl

<select name="LanguageSelection">
{foreach $languages as $language}
 <option value=”{$language}”>{$language}</option>
{/foreach}
</select>

Conclusion

En résumé, mettre en oeuvre des limitations pour des politiques de sécurité au sein de modules personnalisés dans eZ Publish n'est pas une mince affaire. A titre personnel, il m'aura fallu plusieurs jours de fouille dans le kernel et beaucoup de patience pour comprendre les mécanismes des politiques de sécurité et ainsi vous exposer ce tutoriel.

En outre et à la lumière de ce qui précède, il est clair que ce système nécessiterait un sérieux rafraîchissement pour les prochaines versions d'eZ Publish... La roadmap de Fuji est-elle toujours ouverte ? ;-)

Je tiens particulièrement à remercier Nicolas Pastorino , Damien Pobel et André Rømcke qui ont largement contribué à me mettre sur la voie :-).

Cadeau bonus

Pour tous ceux qui ont eu le courage de lire ce long billet jusqu'au bout et qui souhaitent savoir comment faire pour appliquer les règles de sécurité sur les onglets dans le nouveau Backoffice (eZ Publish 4.3.0 et supérieur), voici comment faire :

extension/myextension/settings/menu.ini.append.php

<?php /* #?ini charset="utf-8"?
 
[NavigationPart]
Part[mynavigationpart]=My NavigationPart description
 
[TopAdminMenu]
Tabs[]=mytab
 
[Topmenu_mytab]
NavigationPartIdentifier=mynavigationpart
Name=INI Config
Tooltip=My Tooltip
URL[]
URL[default]=mymodule/myview
Enabled[]
Enabled[default]=true
Enabled[browse]=false
Enabled[edit]=false
Shown[]
Shown[default]=true
Shown[navigation]=true
Shown[browse]=false
 
# Ajouter simplement le controle d'acces pour la fonction par defaut de votre module
PolicyList[]=mymodule/myfunction
 
*/ ?>

Enjoy !


Commentaires

plaque psoriasis (par plaque psoriasis)

This blog is great i love reading your posts. Keep up the great work! You know, a lot of people are hunting around for this info, you could help them greatly.


CBSE RESULTS (par CBSE RESULTS)

CBSE declared its <a href="https://cbseresult2016-nic.in/">CBSE RESULTS</a> and there's jubilation and remorse all around depending upon how well someone has been able to score.


Education (par thomasedison)

It took me perpetually to realize what I should do likewise. I knew there were journeys, yet couldn't discover how to put a guide marker on the objective area.


likes (par how to gain followers on instagram)

Great post.


Login (par q)

Thanks for sharing such information! I'll come back to this page again.


Kingroot (par Kingroot Apk)

See how to root conveniently and quickly via Kingroot APK. Install it instantly to your devices, phones and tablets. No PC required. Download ...


CBSE RESULT 2017 (par CBSE RESULT 2017)

thanks for the nice website keep it up
<a href="http://www.cbseboardresultnic.in/...s-2017-with-marks.html">cbse 10th result 2017</a>
<a href="http://www.cbseboardresultnic.in/...s-2017-with-marks.html">cbse result</a>


download videroder latest app (par download videroder latest app)

Videoder is an android app that lets you download music and videos from youtube, facebook, instagram, vimeo, dailymotion etc for free. http://illusionsofwar.org/the-fas...l-to-download-youtube-videos-on-mac/


rolex replca (par sdjj@mail.com)

that tool the texture of the http://watches.rolexreplicauk.co.uk replica rolex; 12 o'clock position is now more retro, completely like Antique "B-UHR" http://www.replicasonline.co.uk replica watches uk, there is http://www.mmwatches.co.uk replica watches uk a bar when the standard, the following drape a triangle and two two garden points (all luminous coating), compared to the average 12 points to eliminate the big bar when the standard.


apk download (par apk download)


Download mod apkGames and modded apps here at apkreal.com for Free.


BMI CALCULATOR (par 1782329@gmail.com)

Very interesting set out the theme!!learned a lot for myself! thank you! http://calculatorbmi.org


Assignmentinc (par Assignmentinc)

Thanks for Nice and Informative Post. This article is really contains lot more information about This Topic.
https://www.assignmentinc.com


MBA Project Help (par MBA Project Help)

Hi buddy, your blog' s design is simple and clean and i like it. Your blog posts about Online Dissertation Help are superb. Please keep them coming. Greets!!


C Programming Project Help (par C Programming Project Help)

Good way of telling, good post to take facts regarding my presentation subject matter, which i am going to deliver in my college


Content Creation Service (par Content Creation Service)

My friend recommended this blog and he was totally right keep up the fantastic work!


java homework assignments (par java homework assignments)

This is really a great stuff for sharing. Keep it up .Thanks for sharing.


Law Assignment Help Assistance (par Law Assignment Help Assistance)

This is great information for students. This article is very helpful i really like this blog thanks. I also have some information relevant for online dissertation help.


Psychology Assignment Help Assistance (par Psychology Assignment Help Assistance)

Get the dissertation writing service students look for these days with the prime focus being creating a well researched and lively content on any topic.


Buy Coursework Assignment Help (par Buy Coursework Assignment Help)

Well thanks for posting such an outstanding idea. I like this blog & I like the topic and thinking of making it right.


Finance Assignment (par Finance Assignment)

I appreciate your efforts in preparing this post. I really like your blog articles.


Biology Assignment Help Service (par Biology Assignment Help Service)

Amazing article thanks or sharing..


sprint corporate (par sprint corporate)

Unfortunately, I can not help you! I'm not good at this. Sorry!((


tnks (par تور ارمنستان)

بیشتر راجع به ارمنستان مطالعه کنید و ممنون از سایت خوبتون


qswq (par qwwsq)


Il existe de nombreuses causes de faible estime de soi, et certaines personnes aiment utiliser une norme comme objectif trop élevé, de sorte qu'ils ne parviennent pas à répondre aux exigences en état d'échec


Cool (par Anna)

Excellent article, read in one breath! Thank you!
http://eyebrowthreadinginfo.com


Thanks to the author! (par Mark)

Very easy to understand the material! Thanks to the author!
http://maddenmobilhack.com


Help (par write my dissertation)

In fact, most of the kernel's modules can restrict access through security policies that can be attributed to users or groups of users.