Je suis plutot d'accord avec lionel. Dans de nombreux cas, l'utilisation d'un attribut "transcient" (declare avec attr_accessor) est une tres bonne solution. Dans les tests unitaires cela n'est pas un probleme puisque le test doit se comporter comme l'application, donc il doit specifier un user avec les bons droits (le fameux "en tant que").
C'est plutot dans les taches rake que tu risques de rencontrer des soucis. Pour ma part je trouve que les cancan et compagnie, c'est vite l'usine a gaz. Le 27 février 2013 06:46, Lionel Bouton <[email protected]> a écrit : > Le 26/02/2013 23:03, Francis a écrit : > > Un model ne peut pas savoir qui est l'utilisateur actuel, c'est le > > boulot du controlleur. > > Non, par contre il doit savoir qui le modifie s'il veut pouvoir faire > son boulot (implémenter les règles métier qui le concerne et donc en > particulier le contrôle d'accès). Ou alors il ne faut jamais faire de > model.save dans un contrôleur mais appeler un objet intermédiaire qui > sait faire le contrôle d'accès, mais ça risque de devenir lourd très > rapidement. > > Confier le boulot au modèle permet de l'utiliser en-dehors d'un > contrôleur sans court-circuité les contrôles d'accès et/ou d'éviter de > dupliquer le code de vérification entre les contrôleurs (dupliquer c'est > mal, mais quand en plus c'est du code qui gère les droits d'écriture sur > les objets de l'application c'est dangereux). > > Donc à mon sens le contrôleur doit au minimum demander au modèle de > valider que l'objet qui va le modifier (l'acteur) en a le droit avant de > faire le save. Je suis même partisan d'aller plus loin pour éviter les > erreurs de codage : un modèle balance une SecurityError si on ne lui a > pas passé un acteur adéquat. > > Comme je n'avais rien trouvé qui faisait ça il y a 6/7 ans quand je me > suis penché sur le sujet, j'ai codé un module qui lorsqu'il est inclus > dans un modèle ajoute : > - un "attr_accessor :actor", > - quelques méthodes en plus pour tester un acteur sans faire le save > (typiquement pour pouvoir déterminer si une fonctionnalité est > disponible à un acteur), > - un appel d'une méthode writable_by? avec l'acteur stocké dans le > modèle dans la chaîne de validation qui permet au dev d'implémenter les > validations concernant les droits d'accès. > Comme indiqué plus haut par défaut (:actor => nil) ça ne passe pas et > balance une SecurityError avec un message destiné à être mis en log (le > codeur du hook a pour responsabilité de lever une SecurityError aussi si > l'acteur passé n'est pas valide). Le coe de writable_by? ressemble en > général à une whitelist, mais c'est du code quit peut en pratique tester > ce qu'on veut. En particulier j'ai du code qui vérifie pour certains > modèles si des attributs précis ont changé pour n'autoriser cette > opération qu'à certains rôles... > > À partir de ce principe il y a des raffinements pour rendre ça robuste > et un minimum intrusif pour les utilisateurs des modèles (de tête) : > * :actor est réinitialisé à chaque save (le comportement par défaut est > de refuser le save sans valeur dans :actor), il est protégé contre le > mass assignment, ... > * les associations sont gérées également en permettant plusieurs options > selon les règles métiers les concernant lorsqu'ils sont également sauvés : > - passer l'acteur initial aux modèles associés, > - passer le modèle en tant qu'acteur aux modèles associés, > - court-circuiter la validation de l'acteur pour les modèles associés. > - ... > * un "super-acteur" unique qui a tous les droits (ce qui permet de > facilement trouver à quels endroits dans le code les contrôles sont > court-circuités), en pratique c'est surtout utilisé dans les tests > unitaires qui n'ont pas pour but de vérifier la gestion des droits. > > Ce n'est pas open-source : il a évolué dans le bon sens mais il reste > trop lié au reste du code pour être publiable et j'ai toujours manqué de > temps pour le nettoyer (et l'améliorer). > > Lionel > > -- > -- > Vous avez reçu ce message, car vous êtes abonné au groupe "Railsfrance" de > Google Groups. > Pour transmettre des messages à ce groupe, envoyez un e-mail à l'adresse > [email protected] > Pour résilier votre abonnement envoyez un e-mail à l'adresse > [email protected] > --- > Vous recevez ce message, car vous êtes abonné au groupe Google > Groupes Railsfrance. > Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le > concernant, envoyez un e-mail à l'adresse > [email protected]. > Pour plus d'options, visitez le site > https://groups.google.com/groups/opt_out . > > > -- -- Vous avez reçu ce message, car vous êtes abonné au groupe "Railsfrance" de Google Groups. Pour transmettre des messages à ce groupe, envoyez un e-mail à l'adresse [email protected] Pour résilier votre abonnement envoyez un e-mail à l'adresse [email protected] --- Vous recevez ce message, car vous êtes abonné au groupe Google Groupes Railsfrance. Pour vous désabonner de ce groupe et ne plus recevoir d'e-mails le concernant, envoyez un e-mail à l'adresse [email protected]. Pour plus d'options, visitez le site https://groups.google.com/groups/opt_out .
