Jump to content

Authentification par id customer


Recommended Posts

Bonjour,

je vais essayer d'être clair.
j'ai un client B2B dont certains clients ont plusieurs comptes. Chacun de ces comptes a le même email et même password ........ !
Il souhaite que ces clients s'identifient avec leur numéro de compte client.
Pour corser le tout il va aussi avoir des clients particuliers qui eux se loggueront avec leur email.

Mon idée est donc d'avoir une table avec la correspondance id_customer<->numéro de compte. (ça c'est ma sauce )
j'ai déjà vérifié PS permet d'avoir plusieurs customers avec le meme email(pas de contrainte unique sur email)

Il me suffirait donc de modifier le test de login en cherchant l'id_customer à partir du compte  puis en vérifiant le password pour logger le bon id_customer.

Sauf que je n'arrive pas à trouver ou se trouve cette vérification email/password... je cherche désespérément et même la bière chaude ne m'aide pas !

Quelle classe? Quel controler ?

Idéalement : Ou se fait le select ... where email=xxx and password=yyy ???????

A la limite  modifier le coeur de PS ne me dérange pas si je peux m'insérer ou je veux !

Merci d'avance

Link to comment
Share on other sites

40 minutes ago, Eolia said:

dans customer.php =>  getByEmail()

Merci Eolia, suis passé à coté sans voir !!
La fatigue je présume puis l'énervement.

Ca devrait le faire avec un override sur le filtre à air

Grand merci!

Link to comment
Share on other sites

  • 1 month later...

Bonjour,

je viens mettre ma solution à mon problème qui était :
Prestashop 1.7.4.2
Permettre à un client de se logger avec un identifiant client unique. Le client pouvant avoir plusieurs comptes prestashop mais UNE SEULE adresse email (la même pour tous ses comptes).

Je tiens une table customer_cptes contenant id_customer (celui de prestashop) et num_compte (numéro du compte client chez mon client)

- je modifie la classe /classes/Customer.php (ou override si certains y arrivent, mais pour moi ça ne veut pas marcher...)
=> dans la fonction getByEmail je rajoute un else :

        if (Validate::isEmail($email)){
        	//----------- code original de la fonction
            if (!Validate::isEmail($email) || ($plaintextPassword && !Validate::isPasswd($plaintextPassword))) {
                die(Tools::displayError());
            }

            $shopGroup = Shop::getGroupFromShop(Shop::getContextShopID(), false);

            $sql = new DbQuery();
            $sql->select('c.`passwd`');
            $sql->from('customer', 'c');
            $sql->where('c.`email` = \''.pSQL($email).'\'');
            if (Shop::getContext() == Shop::CONTEXT_SHOP && $shopGroup['share_customer']) {
                $sql->where('c.`id_shop_group` = '.(int) Shop::getContextShopGroupID());
            } else {
                $sql->where('c.`id_shop` IN ('.implode(', ', Shop::getContextListShopID(Shop::SHARE_CUSTOMER)).')');
            }

            if ($ignoreGuest) {
                $sql->where('c.`is_guest` = 0');
            }
            $sql->where('c.`deleted` = 0');

            $passwordHash = Db::getInstance()->getValue($sql);
            try {
                // @var \PrestaShop\PrestaShop\Core\Crypto\Hashing $crypto 
                $crypto = ServiceLocator::get('\\PrestaShop\\PrestaShop\\Core\\Crypto\\Hashing');
            } catch (CoreException $e) {
                return false;
            }

            $shouldCheckPassword = !is_null($plaintextPassword);
            if ($shouldCheckPassword && !$crypto->checkHash($plaintextPassword, $passwordHash)) {
                return false;
            }

            $sql = new DbQuery();
            $sql->select('c.*');
            $sql->from('customer', 'c');
            $sql->where('c.`email` = \''.pSQL($email).'\'');
            if (Shop::getContext() == Shop::CONTEXT_SHOP && $shopGroup['share_customer']) {
                $sql->where('c.`id_shop_group` = '.(int) Shop::getContextShopGroupID());
            } else {
                $sql->where('c.`id_shop` IN ('.implode(', ', Shop::getContextListShopID(Shop::SHARE_CUSTOMER)).')');
            }
            if ($ignoreGuest) {
                $sql->where('c.`is_guest` = 0');
            }
            $sql->where('c.`deleted` = 0');

            $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($sql);

            if (!$result) {
                return false;
            }

            $this->id = $result['id_customer'];
            foreach ($result as $key => $value) {
                if (property_exists($this, $key)) {
                    $this->{$key} = $value;
                }
            }

            if ($shouldCheckPassword && !$crypto->isFirstHash($plaintextPassword, $passwordHash)) {
                $this->passwd = $crypto->hash($plaintextPassword);
                $this->update();
            }

            return $this;
        }else{
            //--------------------------------------------------------------------------
            //-- complement par CSID
            //-- ce n'est pas un email qui a été saisi on presume que c'est un id client
            //-- on va lire l'id du client pour recupérer l'id PS correspondant
            //-- puis on va traiter comme normal en changeant les select pour les faire
            //-- sur l'id customer et non sur l'email

            if ($plaintextPassword && !Validate::isPasswd($plaintextPassword)) {
                die(Tools::displayError());
            }

            $shopGroup = Shop::getGroupFromShop(Shop::getContextShopID(), false);

            //-- recherche l'id_customer dans ps_customer_cptes à partir de l'identifiant saisi
            if ($cust = Db::getInstance()->getRow("select * from "._DB_PREFIX_."customer_cptes a,"._DB_PREFIX_."customer c where a.num_compte='".pSQL($email)."' and c.id_customer=a.id_customer") ){
                $id_customer=$cust['id_customer'];
                $email=$cust['email'];
            }else{
                return false;
            }

            //-- lecture et vérification du password
            $sql = new DbQuery();
            $sql->select('c.`passwd`');
            $sql->from('customer', 'c');
            $sql->where('c.`id_customer` = \''.pSQL($id_customer).'\'');
            if (Shop::getContext() == Shop::CONTEXT_SHOP && $shopGroup['share_customer']) {
                $sql->where('c.`id_shop_group` = '.(int) Shop::getContextShopGroupID());
            } else {
                $sql->where('c.`id_shop` IN ('.implode(', ', Shop::getContextListShopID(Shop::SHARE_CUSTOMER)).')');
            }

            if ($ignoreGuest) {
                $sql->where('c.`is_guest` = 0');
            }
            $sql->where('c.`deleted` = 0');

            $passwordHash = Db::getInstance()->getValue($sql);
            try {
                // @var \PrestaShop\PrestaShop\Core\Crypto\Hashing $crypto 
                $crypto = ServiceLocator::get('\\PrestaShop\\PrestaShop\\Core\\Crypto\\Hashing');
            } catch (CoreException $e) {
                return false;
            }

            $shouldCheckPassword = !is_null($plaintextPassword);
            if ($shouldCheckPassword && !$crypto->checkHash($plaintextPassword, $passwordHash)) {
                return false;
            }

            //-- lecture du customer
            $sql = new DbQuery();
            $sql->select('c.*');
            $sql->from('customer', 'c');
            $sql->where('c.`id_customer` = \''.pSQL($id_customer).'\'');
            if (Shop::getContext() == Shop::CONTEXT_SHOP && $shopGroup['share_customer']) {
                $sql->where('c.`id_shop_group` = '.(int) Shop::getContextShopGroupID());
            } else {
                $sql->where('c.`id_shop` IN ('.implode(', ', Shop::getContextListShopID(Shop::SHARE_CUSTOMER)).')');
            }
            if ($ignoreGuest) {
                $sql->where('c.`is_guest` = 0');
            }
            $sql->where('c.`deleted` = 0');

            $result = Db::getInstance(_PS_USE_SQL_SLAVE_)->getRow($sql);

            if (!$result) {
                return false;
            }

            $this->id = $result['id_customer'];
            foreach ($result as $key => $value) {
                if (property_exists($this, $key)) {
                    $this->{$key} = $value;
                }
            }

            if ($shouldCheckPassword && !$crypto->isFirstHash($plaintextPassword, $passwordHash)) {
                $this->passwd = $crypto->hash($plaintextPassword);
                $this->update();
            }

            return $this;

        }

- puis j'ai besoin que le formulaire ne me bloque pas si on saisi autre chose qu'un email.
=> je modifie la classe /classes/form/CustomerLoginFormatter.php (même remarque que précédemment : ou override pour être propre)
    je change le type obligatoire du champ email et j'enleve la contrainte "isEmail"

   public function getFormat()
    {
        return [
            'back' => (new FormField)
                ->setName('back')
                ->setType('hidden'),
            'email' => (new FormField)
                ->setName('email')
//                ->setType('email')
                ->setType('text')
                ->setRequired(true)
                ->setLabel($this->translator->trans(
                    'Email', [], 'Shop.Forms.Labels'
                ))
//                ->addConstraint('isEmail'),
                ,
            'password' => (new FormField)
                ->setName('password')
                ->setType('password')
                ->setRequired(true)
                ->setLabel($this->translator->trans(
                    'Password', [], 'Shop.Forms.Labels'
                ))
                ->addConstraint('isPasswd'),
        ];
    }

 

!!! Attention !!!  je reste persuadé que ce genre de manip peut être problématique. En effet dans mon cas il sous entend qu'on peut avoir plusieurs lignes dans ps_customer avec la même adresse email. Or j'ai vu à plusieurs reprises des modules et des fonctions de PS qui utilisent l'adresse email comme identifiant unique. Le risque est donc grand que dans certains cas le compte client lu ne soit pas le bon...

Et il n'est pas bon de modifier les classes directement. Faut-il le rappeler?

A vous de voir si c'est jouable ou pas.

Si ce post vous permet au moins d'avoir des pistes c'est déjà ça !

Edited by csid (see edit history)
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...