Jump to content

[resolved]connection with ldap no login form


Laetitia Bordon

Recommended Posts

Hello,

I would like connect the user with ldap in prestashop in place of the login form.

Is someone did that? How?

I found this in the symfony doc https://symfony.com/doc/3.4/components/ldap.html

I've a script in php who does the connection and retrieve (with functions) the datas.

In classic php script, I do that to have infos :

include_once $_SERVER['DOCUMENT_ROOT'].'/titi/include/authentication.inc.php'; //the script I call for the ldap authentification
if (!$authenticated_user->is_valid()) 
{ 
	header('HTTP/1.0 401 Unauthorized'); 
	print 'Use portal - Ma zone/Mijn zone to access this application'; 
	exit; 
}
//get the service of the person
$service=$authenticated_user->get_service();

In the authentication script, I get the $_SERVER['HTTP_USER_AGENT'] var and I do treatments to do the authentification

/* * -------------------------------------------------------------------- * 
* Toute l'authentification se passe ici !!! 
* l'HTTP_USER_AGENT est de la forme "FedPol-Portal/2.0 445759153F" * 
* -------------------------------------------------------------------- */ 
class Authenticated_User 
{ 
  private $matricule = 0; 
  private $language = ''; 
  private $zone = ''; 
  private $grade=''; 
  private $ldap_data = ''; 
  private $user_found = false; 
  private $ldap_connect; 
  public $sso; 

  public function __construct() { 
    $sso = $_SERVER['HTTP_USER_AGENT']; 
    $this->sso = $sso; $this->matricule = array_pop(explode(' ', $sso)); 
    //$this->language = $this->matricule[strlen($this->matricule)-1]; 
    $this->language=substr($this->matricule,9,1); 
    if(strlen($this->matricule)>11) { 
      $this->zone = substr($this->matricule, 10, 4); 
      $this->grade = substr($this->matricule, 14, 3); 
    } 
    $this->matricule = substr($this->matricule, 0, 9); 
    $this->ldap_connect = ldap_connect(LDAP_HOST); 
    if ($this->ldap_connect) 
    { 
      ldap_set_option($this->ldap_connect, LDAP_OPT_PROTOCOL_VERSION, LDAP_PROTO); 
      $ldap_bind = ldap_bind($this->ldap_connect); /* bind au ldap en anonymous */ 
      if ($ldap_bind) { 
        $search = ldap_search($this->ldap_connect, LDAP_BASE, "(uid=$this->matricule)"); 
        $info = ldap_get_entries($this->ldap_connect, $search); 
        $this->user_found = $info["count"]; $this->ldap_data = $info[0]; 
      } 
    } 
  } 

  public function is_valid() { return $this->user_found; } 

  public function getsso() { return $this->sso; } 

  public function authorize($objectClass, $attributes = true) { // possede t on l'object class dont il est question ? 
    if (in_array($objectClass, $this->ldap_data['objectclass'])) { 
      if ($attributes) { // recuperation du schema LDAP pour determiner les attributs interessants $result = array(); 
        $info = ldap_read($this->ldap_connect, 'cn=subschema', '(objectClass=*)',array('objectclasses')); 
        $entries = ldap_get_entries($this->ldap_connect, $info); 
        foreach ($entries[0]['objectclasses'] as $entry) { 
          if (preg_match("/$objectClass/", $entry)) { 
            $list = ''; 
            if (preg_match('/MUST \(/', $entry)) $list = preg_replace('/.* MUST \((.*?)\).*/','$1',$entry); 
            elseif (preg_match('/MUST/', $entry)) $list = preg_replace('/.* MUST (.*?) .*/','$1',$entry); 
            if (preg_match('/MAY \(/', $entry)) 
            { 
              if ($list) $list .= ' $ '; 
              $list .= preg_replace('/.* MAY \((.*?)\).*/','$1',$entry); 
            } 
            elseif (preg_match('/MAY/', $entry)) 
            { 
              if ($list) $list .= ' $ '; 
              $list .= preg_replace('/.* MAY (.*?) .*/','$1',$entry); 
            } 
            if ($list) 
            { 
            foreach (explode('$', $list) as $attr) $result[trim($attr)]=$this->ldap_data[strtolower(trim($attr))][0]; 
            } 
          } 
        } 
        return array(true, $result); 
      } 
      else return array(true); 
    } 
    else return array(false); 
  } 

  public function get_matricule() { return $this->matricule; } 
  public function get_language() { return $this->language; } 
  public function get_zone() { return $this->zone; } 
  public function get_name() { return $this->ldap_data['cn'][0]; } 
  public function get_service() { return $this->ldap_data['bepolbruservice'][0]; } 
  public function get_mail() { return $this->ldap_data['mail'][0]; } 
  public function get_name2() { return $this->ldap_data['sn'][0].' '.$this->ldap_data['givenname'][0]; } 
  public function get_sn() { return $this->ldap_data['sn'][0]; } 
  public function get_givename() { return $this->ldap_data['givenname'][0]; } 
  public function get_grade() { return $this->grade; } 
  public function get_classes() { return $this->ldap_data['objectclass']; } 
} 

$authenticated_user = new Authenticated_User();

How can I do the same thing in prestashop? 

Is in the AdminLoginController.php (for the backOffice)? And where is the AdminController class?

Thank you for the help

Edited by Laetitia Bordon
solved (see edit history)
Link to comment
Share on other sites

  • 2 weeks later...

In file /app/config/parameters.php, add the parameters for your ldap connection.

For BackOffice part

In /controllers/admin/AdminLogController.php, add "use Symfony\Component\Ldap\Ldap;" before the class.

In function __construct, I've 

if (!headers_sent()) {
$this->testLdap();
//header('Login: true');
}

And the 2 function I created:

public function testLdap()
{
  //l'HTTP_USER_AGENT est de la forme "FedPol-Portal/2.0 44123456F"
  $sso = $_SERVER['HTTP_USER_AGENT'];
  $ssoPart = array_pop(explode(' ', $sso));
  $langue=substr($ssoPart,9,1);
  $uid = substr($ssoPart, 0, 9);
  $container = $this->buildContainer();
  $host = $container->getParameter('ldap_host');
  $port = intval($container->getParameter('ldap_port'));
  $base = $container->getParameter('ldap_base');
  $classeObject = $container->getParameter('ldap_classe');
  $ldap = Ldap::create('ext_ldap', [
  'host' => $host,
  'port' => $port
  ]);
  $ldap->bind();
  $query = $ldap->query($base, '(&(uid='.$uid.')(objectclass='.$classeObject.'))');
  $results = $query->execute()->toArray();
  $mail = $results[0]->getAttribute("mail")[0];
  $password = $results[0]->getAttribute("userPassword")[0];
  $admin = $results[0]->getAttribute("bePolbruAuthEditShopFin")[0];
  $this->processLoginTest($mail,$password);
}

//it's a copy of processLogin function
public function processLoginTest($email,$passwd)
    {
        /* Check fields validity */
        /*$passwd = trim(Tools::getValue('passwd'));
        $email = trim(Tools::getValue('email'));*/
		
        if (empty($email)) {
            $this->errors[] = $this->trans('Email is empty.', array(), 'Admin.Notifications.Error');
        } elseif (!Validate::isEmail($email)) {
            $this->errors[] = $this->trans('Invalid email address.', array(), 'Admin.Notifications.Error');
        }
		
        if (empty($passwd)) {
            $this->errors[] = $this->trans('The password field is blank.', array(), 'Admin.Notifications.Error');
        } elseif (!Validate::isPasswd($passwd)) {
            $this->errors[] = $this->trans('Invalid password.', array(), 'Admin.Notifications.Error');
        }
        if (!count($this->errors)) {
            // Find employee
            $this->context->employee = new Employee();
            $is_employee_loaded = $this->context->employee->getByEmail($email);
            $employee_associated_shop = $this->context->employee->getAssociatedShops();
            if (!$is_employee_loaded) {
                $this->errors[] = $this->trans('The employee does not exist, or the password provided is incorrect.', array(), 'Admin.Login.Notification');
                $this->context->employee->logout();
            } elseif (empty($employee_associated_shop) && !$this->context->employee->isSuperAdmin()) {
                $this->errors[] = $this->trans('This employee does not manage the shop anymore (either the shop has been deleted or permissions have been revoked).', array(), 'Admin.Login.Notification');
                $this->context->employee->logout();
            } else {
                PrestaShopLogger::addLog($this->trans('Back office connection from %ip%', array('%ip%' => Tools::getRemoteAddr()), 'Admin.Advparameters.Feature'), 1, null, '', 0, true, (int) $this->context->employee->id);

                $this->context->employee->remote_addr = (int) ip2long(Tools::getRemoteAddr());
                // Update cookie
                $cookie = Context::getContext()->cookie;
                $cookie->id_employee = $this->context->employee->id;
                $cookie->email = $this->context->employee->email;
                $cookie->profile = $this->context->employee->id_profile;
                $cookie->passwd = $this->context->employee->passwd;
                $cookie->remote_addr = $this->context->employee->remote_addr;

                if (!Tools::getValue('stay_logged_in')) {
                    $cookie->last_activity = time();
                }

                $cookie->write();

                // If there is a valid controller name submitted, redirect to it
                if (isset($_POST['redirect']) && Validate::isControllerName($_POST['redirect'])) {
                    $url = $this->context->link->getAdminLink($_POST['redirect']);
                } else {
                    $tab = new Tab((int) $this->context->employee->default_tab);
                    $url = $this->context->link->getAdminLink($tab->class_name);
                }

                if (Tools::isSubmit('ajax')) {
                    die(json_encode(array('hasErrors' => false, 'redirect' => $url)));
                } else {
                    $this->redirect_after = $url;
                }
            }
        }
        if (Tools::isSubmit('ajax')) {
            die(json_encode(array('hasErrors' => true, 'errors' => $this->errors)));
        }
    }

In /classes/Employee.php, set the required option for passwd at false.

For front part

Solution in this topic (with removed link to Sign out)

 

Edited by Laetitia Bordon (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...