Catégorie : Cakephp

Flux Rss
 

Reflexion sur la gestion des Acl

By esion - the 2008-04-11 17:08:00 - in Cakephp

(0) Comments

Nani desu ka?

Depuis peu je retouche l'ACL sur cakephp 1.2. En fait, le plus difficile est de se lancer. Aujourd'hui je comprends à peu près le fonctionnement néanmoins encore beaucoup de points restent obscurs. Ce n'est propre au framework cakephp mais plus au principe voir même de la philosophie "Acl".

Au commencement il y avait les Aro (les utilisateurs ou les groupes) : Ève. Ensuite arrivent les Aco (les contrôleurs, actions ou directement les objets ) : Adam (oui on sait tous que vous êtes manipulatrices). Il ne manque plus qu'un médiateur : la pomme (la table aros_acos dans cakephp qui définit les permissions : crud).

Je ne m'attarderai pas plus sur le concept (surtout que je dois très mal l'expliquer).

Comment démarrer?

La première fois sur cakephp 1.1 avec les tutoriaux ibm, avec le manuel de cake ou plus simplement avec le l'article de rtconner sur le bakery.

Mais voilà on aime l'aventure et ça fait un moment qu'on est passé sur cake 1.2.

Je me suis retrouvé dans un état d'excitation extrême à la lecture de l'article Gestion des droits d’accès par groupes d’utilisateurs. Simple et clair, je passe à l'action, j'intègre, j'adapte et je commence même un plugin.

Je recommande chaudement d'essayer acl manager plugin qui a la qualité d'être d'une simplicité enfantine à l'installation et à l'utilisation (un gosse qui sait faire un checkout sur svn tout de même) et permet en outre d'avoir un visu sur ce qu'il se passe.

Néanmoins quelque chose me titille.

Une usine à gaz?

Peut être l'aurez-vous remarqué, dans tous les tutos présentés, aucun ne parle de suppression d'Aro ou Aco (sauf celui d'ibm). Et quand on veut gérer finement des droits il faut le faire en plein, c'est bien beau de créer des Objets dans tous les sens et d'indiquer les permissions mais on commence à administrer, modérer faire évoluer le contenu d'une application, on ne peut pas permettre de laisser des résidus qui pourrait mettre en péril la santé de notre chère appli.

Quand je disais que quelque chose me titille en fait je me suis rendu compte bien tard de cette évidence : les Objets sont créés en double dans l'application. Exemple :

  • Un utilisateur dans la table users => un référent dans la table Aros.
  • Un groupe dans la table groups => un référent dans la table Aros.
  • Une action dans un controller => un référent dans la table Acos.
  • Un produit dans la table products => un référent dans la table Acos.

Problème n°1 : on peut aisément créer un doublon : deux Objets ayant exactement les mêmes attributs.

Problème n°2 : comment je récupère l'id acl de l'objet que je veux supprimer?!

Problème n°3 : ça y est je l'ai supprimé .... woops j'ai oublié de virer les anciennes permission :#

Solution : On s'en tape les burnes contre les murs.

Sauf que le jour où j'ai 10000 produits, 2000 utilisateurs, une tripoté de modérateurs à moitié abrutis (humour cynique), je préfère dès aujourd'hui le choix de l'optimisation.

Mais ça se passe comment à coté?

On sait que différents système utilise l'Acl, gnu/Linux, Windows et sûrement plein d'autres. Cela me parait étrange que l'on s'extasie sur quelque chose qui peut aussi facilement partir en couille.

Et bien, sur nux les entités ne sont pas en doublon (déjà!), on a un compte unix unique (même qu'on le supprime jamais) des groupes uniques ... du coup on ne parle que d'Acl et par extrapolation des permissions.

Alors qu'est-ce qui ne va pas avec cakephp? Est-il trop souple : il permet de considérer des méthodes comme des Acos, il ne sais pas travailler directement avec les objets de la base de données... Il ne sait pas faire de relation direct entre un objet et son homologue aco ou aro?!

Solution?

Je n'en vois qu'une réelement valable, solution Unix style : ne jamais supprimer, autoriser seulement la désactivation.

[update]

La solution de ibm que je viens de découvrir (ils ont mis à jour leur documention woot!!)

On doit passer par la recherche d'alias (en priant que celui-ci soit unique : penser à ajouter un checkUnique dans le modèle pour la création).

$aro = $this->Acl->Aro->findByAlias($alias);

On peut enfin "synchroniser" les tables :/

$this->Acl->Aro->delete($aco['Aro']['id']);

(ça y est j'ai mis 2 lignes de code dans billet!)

 
 

[cakephp]Liens en methode POST - fr

By esion - the 2007-09-20 16:39:00 - in Cakephp

(0) Comments

Le problème :


Cakephp creer des liens hypertext seulement avec la méthode GET. Bien sûr ce n'est pas la meilleur moyen lorsqu'il s'agit d'effacer une ressource (dans la base de donnée), cela devrait être réaliser depuis un méthode POST.

Comment faire


En fait on va creer un formulaire avec un peu de javascript :
Effacer

Lorsque l'utilisateur confirm l'action, cela creer le formulaire qui sera envoyé à l'application.

Dans CakePhp


Helper



J'ai choisis de créer un helper personnalisé qui utilisera celui par défaut, $html->link :
//file: app/views/helpers/html2.php
class Html2Helper extends Helper {
//permet d'utiliser l'helper Html
var $helpers = array('Html');

function link($title, $url = null, $htmlAttributes = array(), $confirmMessage = false, $escapeTitle = true, $return = false) {
//On ajoute le formulaire seulement si confirmMessage est présent:

if ($confirmMessage) {
$confirmMessage = str_replace("'", "\'", $confirmMessage);
$confirmMessage = str_replace('"', '\"', $confirmMessage);
//on ajout le post
$htmlAttributes['onclick']="if (confirm('$confirmMessage')) { var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'post'; f.action = this.href;f.submit(); };return false;";
}
//Et on utilise l'helper de base
$output = $this->Html->link($title, $url, $htmlAttributes, null, $escapeTitle, $return);
return $this->output($output, $return);
}
}
?>

Utilisation : View


On peut donc inserer dans n'importe quelle vue. Il ne faut pas oublier de l'importer dans le controller. Le message de confirmation est obligatoire :

link('post link', '/pages/index', null, 'Es-tu sûr?'); ?>

Controller


Importer l'helper et verification: :
//file: app/controller/pages_controller.php

class PagesController extends AppController {

var $name = 'Posts';
//hell yeah!
var $helpers = array('Html2');
//le composant de requetes
var $components = array('RequestHandler');

function index(){
//Si la requete est en POST : renvoie vrai
if($this->RequestHandler->isPost())
debug('request is post');
else
debug('request is not post T_T');
}
}
?>

Et après ...


On peut modifier ces scripts pour rentrer dans les bonnes grâces d'applications RESTful : PUT, DELETE.
 
 

[cakephp]Link in post method - en

By esion - the 2007-09-20 14:57:00 - in Cakephp

(0) Comments

The problem :


CakePhp helpers does link only with GET method. Well It's not the better way to delete a resource and it should be POST method.

How to


... make a hypertext link with POST method :

Then we should use javascript in order to create a form :
Delete

When the user confirm the action, this will create a form which will be sent to the application.

In CakePhp


The helper


The way I use, I create a custom helper which use the original html->link helper :
//file: app/views/helpers/html2.php
class Html2Helper extends Helper {
//this allow my helper to use the original one
var $helpers = array('Html');

function link($title, $url = null, $htmlAttributes = array(), $confirmMessage = false, $escapeTitle = true, $return = false) {
//add form with post method thanks to javascript only if confirmMessage present

if ($confirmMessage) {
$confirmMessage = str_replace("'", "\'", $confirmMessage);
$confirmMessage = str_replace('"', '\"', $confirmMessage);
//here we set our POST method
$htmlAttributes['onclick']="if (confirm('$confirmMessage')) { var f = document.createElement('form'); f.style.display = 'none'; this.parentNode.appendChild(f); f.method = 'post'; f.action = this.href;f.submit(); };return false;";
}
//we use the link helper to finalized it
$output = $this->Html->link($title, $url, $htmlAttributes, null, $escapeTitle, $return);
return $this->output($output, $return);
}
}
?>

Use it : the view


You can insert into any view. Don't forget to specified it in your controller. Confirm Message is required :

link('post link', '/pages/index', null, 'Are you sure?'); ?>

The Controller


Specify the helper and check this:
//file: app/controller/pages_controller.php

class PagesController extends AppController {

var $name = 'Posts';
//hell yeah! the helper :
var $helpers = array('Html2');
//check the request type :
var $components = array('RequestHandler');

function index(){
//if the request use post method : return true
if($this->RequestHandler->isPost())
debug('request is post');
else
debug('request is not post T_T');
}
}
?>

Then ...


Now you can modify those scripts to fit with RESTful app using PUT, DELETE ...
 
|