Salut tout le monde !
Je viens de finir la partie du tuto J4 pour la sécurisation de l'espace d'administration et j'ai une petite faille dans le système lors de l'ajout d'un nouvel utilisateur... Il est en fait possible de rentrer un nouvel utilisateur dans ayant un mot de passe vide.
J'ai eu beau réfléchir à comment régler la chose, étant un total débutant sur cake, je n'ai pas trouvé l'idée pour empêcher ce souci.
Ou alors j'ai zappé un bout qui correspondait
Je mets ici mes codes :
Modèle User.php
<?php
class User extends AppModel{
/**
* Gestion des règles de validation du formulaire
**/
public $validate = array(
'username' => array(
'rule' => 'isUnique',
'allowEmpty'=> false,
'message' => "Ce nom d'utilisateur est déjà pris"
),
'password' => array(
'rule' => 'notEmpty',
'required' => false,
'message' => "Veuillez saisir un mot de passe"
),
'name' => array(
'rule' => 'notEmpty',
'message' => "La confirmation du mdp ne peut être vide"
),
'firstname' => array(
'rule' => 'notEmpty',
'message' => "La confirmation du mdp ne peut être vide"
)
);
function beforeSave($options = array()){
if(!empty($this->data'User']'password'])){
$this->data'User']'password'] = AuthComponent::password($this->data'User']'password']);
}
return true;
}
}
Controller UsersController.php
function admin_index(){
$d'users'] = $this->Paginate('User');
$this->set($d);
}
function admin_edit($id = null){
if($this->request->is('put') OR $this->request->is('post')){
$d = $this->request->data'User'];
if($d'password'] != $d'passwordconfirm']){
$this->Session->setFlash("Les mots de passe ne concordent pas", "notif", array('type'=>'error'));
}else{
if(empty($d'password']))
unset($d'password']);
if($this->User->save($d)){
// Affiche la notification de réussite en fonction de si c'est une modif ou un ajout direct
($this->request->is('put')) ? $this->Session->setFlash("Les informations de l'utilisateur ont bien été modifiées", 'notif'):$this->Session->setFlash("Un nouvel utilisateur a bien été ajouté", 'notif');
//$this->redirect(array('action'=>'index'));
}
}
}elseif($id){
$this->User->id = $id;
$this->request->data = $this->User->read();
}
// Vide la variable $d
$d = array();
$d'lvls'] = array('admin'=>'Adminstrateur', 'contributor'=>'Contributeurs');
$this->set($d);
}
function admin_delete($id){
$this->Session->setFlash("L'utilisateur a bien été supprimé", 'notif');
$this->User->delete($id);
$this->redirect($this->referer());
}
J'ai également une autre incompréhension quant à la manière d'empêcher un utilisateur n'ayant pas le level d'administrateur de pouvoir recourir à la fonction admin.delete() des posts par exemple ou bien carrément lui interdire toute action sur les utilisateurs si ce n'est voir la liste.
Et finalement, quand j'utilise une redirection à la fin de l'enregistrement des données, si jamais il y a des erreurs dans le remplissage des champs, ceux-ci ne s'affichent point, le formulaire n'est pas envoyé mais la redirection est effective contrairement à ce qui se passe dans le tuto Jour 1 pour le système de posts. (la redirection est commentée dans mon script).
Pouvez-vous également m'éclaicir sur ce point ??
Je vous remercie pour votre précieuse aide !
tu fais un if pour chacun
Post c'est pour la modification et Put pour l'ajout
if($this->request->is('post')){
}elseif($this->request->is('put')){
}else{
}
Oui ben les prefixes c'est ceci, tu dis par exemple Admin c'est ton niveau 3 moderateur : niveau 2 et utilisateur niveau 3, et tes fonctions tu le donne le prefixe minimum,par exemple si tu veux l'édition de page ne soit que pour les moderateurs, tu écrit ta fonction
public function moderateur_edit($id = null){}
Après il y a la gestion par ACL mais la je ne connais pas.
Ton erreur viens du faite que tu met
'required'=> false,
. Tu indiques que le champ n'est pas obligatoire, il faut le mettre à true, mais cela il le fait par défaut.
Je viens de tester en supprimant le 'required' => false, Le problème reste entier, il m'ajoute toujours l'utilisateur avec un mdp vide. :(
Et sinon, il est à false pour suivre le tuto de jonathan afin qu'il n'y ait pas obligation d'ajouter à nouveau le mdp lors de l'édition. (je l'avais écrit alors que c'est son option par défaut afin de m'en souvenir lors de la relecture).
Une solution serait de faire la différence entre put et post... mais est-il possible d'indiquer des règles précises en fonction du is()?
Bon j'ai réussis en faisant une condition par "type d'insertion". Et par la même ça m'a résolu mon problème de redirect avec les affichages d'erreurs :)) Donc c'est super chouette !!
Merci beaucoup lepetitnico !
Peux-tu me donner me dire si c'est possible d'empêcher l'utilisation par de certaines fonctions par un utilisateur qui n'est pas administrateur mais par exemple contributeur ?
Dans les tutos grafikarts, il nous est montré comment interdire l'accès à toute la partie du site ayant un prefix mais je n'arrive pas encore à imaginer le procédé pour empêcher l'utilisation (et dissimulation éventuelle) de certaine fonction.
(Enfin en réalité, si j'ai bien une petite idée qui me vient tout droit de mon expérience pure php qui serait de faire des conditions via une variable $_SESSION couplé avec des conditions aux endroits clefs... mais cela ne me semble pas du tout cakephp dans l'esprit ?)
Salut si tu veux par la suite, tu peux avoir plusieurs prefix, et tu met un niveau par prefix. Regarde le tutoriel 4eme jour avec cakephp tutoriel grafikart
Oui, ça j'ai bien compris la possibilité d'utiliser un autre prefix, mais je pense que ça n'a d'intérêt que pour créer un section profil du membre et action des membres qui soient totalement différentes de celles des administrateurs ayant un panneau différent de leur profil personnel... (Je me trompe peut-être mais pour le moment c'est ce que j'ai retiré de tout ce que j'ai appris).
Donc je ne souhaite pas rajouter un prefix membres (ou quel que ce soit le nom...) puisque dans ce site je n'ai pas vocation à avoir des membres mais seulement disons deux (maximum 3) niveaux d'administrateurs de mon pannel d'administration.
Je souhaite donc juste limiter certaines fonctions aux seuls administrateurs de "rang 1".
Ma question est donc : Faut-il passer par des variables session et des conditions ou est-ce que CakePHP propose une solution adaptée à ce "problème" ?
Edit : Désolé pour le gras qui assez violent mais c'est pour que mon interrogation soit bien comprise.
Si je comprends bien avec ce système on est alors obligé de créer autant de fichiers prefix_edit.ctp, prefix_index.ctp qu'on a de prefix en même temps qu'on est obligé de recréer à chaque fois les fonctions préfixées dans le controller ?
C'est très rébarbatif sur le coup... :(
non un exemple: tu autorises les modérateurs à éditer une page alors en conséquence les admins le pourront, ta fonction s'appellera
moderateur_edit($id = null)
, le prefix moderateur indique que les modérateurs ainsi que tout les rangs au dessus pourront utiliser cette fonction.
d'accord mais à quel moment indiques tu quel rang est inférieur ou supérieur à modérateur ?
c'est ds ton appController j'ai une fonction que j'ai récupéré d'un des tutoriels de grafikart :
function isAuthorized($user){
if(!isset($this->request->params'prefix'])){
return true;
}
$roles = array(
'admin' => 10,
'user' => 5
);
if(isset($roles$this->request->params'prefix']])){
$lvlAction = $roles$this->request->params'prefix']];
$lvlUser = $roles$user'role']];
if($lvlUser >= $lvlAction){
return true;
}else{
return false;
}
}
return false;
}
Le composant Auth la détectera automatiquement, met la bien en dehors de ton beforeFilter() surtout.
Je regarderai demain pour gérer ça. Je suis en train d'avancer sur le reste (l'intégration de tinymce) et j'ai un ou deux ptits problèmes. En tout merci beaucoup pour tes réponses lepetitnico !! :)
Je vais faire un sujet à part, afin de pas tout mélanger et que ça reste trouvable pour les gens qui serait susceptible de rencontrer des problèmes similaire.
Bonjour sko,
Pourrais tu mettre la solution qui t'a permis de résoudre ton problème au sujet du mot de passe, c'est à dire en faisant une condition par "type d'insertion". J'aime le soucis que je n'arrive pas à le résoudre.
Merci
Salut,
Pour moi dans ce code :
'password' => array(
'rule' => 'notEmpty',
'required' => false,
'message' => "Veuillez saisir un mot de passe"
),
il y a un truc pas logique, tu as rule qui dit que ça ne doit pas être vide, mais en même temps tu dis qu'il n'est pas requis avec required à false.
A++
Salut zenkiai !
J'ai différencié les post du put comme me le suggérait lepetitnico ! Ce qui en soit me parait ultra logique et donc je ne comprends pas pourquoi Grafikart réussit à le faire marcher dans son tuto en ayant qu'une condition if( put OR post)...
Voici mon code du UserController.php
function admin_edit($id = null){
if($this->request->is('put')){
$d = $this->request->data'User'];
if($d'password'] != $d'passwordconfirm']){
$this->Session->setFlash("Les mots de passe ne concordent pas", "notif", array('type'=>'error'));
}else{
if(empty($d'password']))
unset($d'password']);
if($this->User->save($d)){
// Affiche la notification de réussite en fonction de si c'est une modif ou un ajout direct
($this->request->is('put')) ? $this->Session->setFlash("Les informations de l'utilisateur ont bien été modifiées", 'notif'):$this->Session->setFlash("Un nouvel utilisateur a bien été ajouté", 'notif');
$this->redirect(array('action'=>'index'));
}
}
}elseif($this->request->is('post')){
$d = $this->request->data'User'];
if($d'password'] != $d'passwordconfirm']){
$this->Session->setFlash("Les mots de passe ne concordent pas", "notif", array('type'=>'error'));
}else{
if($this->User->save($d)){
// Affiche la notification de réussite en fonction de si c'est une modif ou un ajout direct
($this->request->is('put')) ? $this->Session->setFlash("Les informations de l'utilisateur ont bien été modifiées", 'notif'):$this->Session->setFlash("Un nouvel utilisateur a bien été ajouté", 'notif');
$this->redirect(array('action'=>'index'));
}
}
En espérant que tu y trouves ta solution zenkiai !
Oui, en effet extrarox, c'était pas logique. J'ai donc viré le required.
Sko
Merci de ta réponse,
En faite lorsque je mets :
'password' => array(
'rule' => 'notEmpty',
'required' => true,
'message' => "Veuillez saisir un mot de passe"
),
il me demande en effet un mot de passe, je suis d'accord. Mais lorsque par exemple je veux changer juste le rôle du membre en admin,
je voudrais qu'il ne me demande pas le mdp. En clair :
En création d'utilisateur => mdp obligatoire
En édition d'utilisateur ( changement de rôle, ou username ) => pas de demande de mdp
Merci
Oui c'est pour ça il faut enlever carrément le required... qui par défaut est considérer à false de toute manière... et après ça marche en faisant la différenciation des post et put
salut,
Je me permet d'ajouter une reponse en se qui concerne la condition:
if($this->request->is('post')){
}elseif($this->request->is('put')){
}
pour ceux qui passerai par là et qui se demande pourquoi sa marche pas
le formulaire est considéré comme post tant que l'ont ne spécifie pas dans:
$this->Form->create('MonForm',array('type'=> post ou put..
je ne comprenais pas avant de me rappeler de cette option, pourquoi la condition 'put' ne fonctionnait pas...