diff options
author | Frédéric Guillot <fguillot@users.noreply.github.com> | 2014-04-20 19:24:40 -0400 |
---|---|---|
committer | Frédéric Guillot <fguillot@users.noreply.github.com> | 2014-04-20 19:24:40 -0400 |
commit | dea5f99363d4cf8e9ffff967c8cbdb38c8c50507 (patch) | |
tree | cadeb605c8c4f919dd3e1f8d43cfec6fe980ec6d /models | |
parent | 1b05f20d58474f053ee8a09343389b34a7f39fb7 (diff) |
Add LDAP authentication
Diffstat (limited to 'models')
-rw-r--r-- | models/ldap.php | 81 | ||||
-rw-r--r-- | models/user.php | 56 |
2 files changed, 130 insertions, 7 deletions
diff --git a/models/ldap.php b/models/ldap.php new file mode 100644 index 00000000..95401211 --- /dev/null +++ b/models/ldap.php @@ -0,0 +1,81 @@ +<?php + +namespace Model; + +require_once __DIR__.'/base.php'; + +/** + * LDAP model + * + * @package model + * @author Frederic Guillot + */ +class Ldap extends Base +{ + /** + * Authenticate a user + * + * @access public + * @param string $username Username + * @param string $password Password + * @return bool + */ + public function authenticate($username, $password) + { + if (! function_exists('ldap_connect')) { + die('The PHP LDAP extension is required'); + } + + $ldap = ldap_connect(LDAP_SERVER, LDAP_PORT); + + if (! is_resource($ldap)) { + die('Unable to connect to the LDAP server: "'.LDAP_SERVER.'"'); + } + + ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, 3); + ldap_set_option($ldap, LDAP_OPT_REFERRALS, 0); + + if (@ldap_bind($ldap, sprintf(LDAP_USER_DN, $username), $password)) { + return $this->create($username); + } + + return false; + } + + /** + * Create automatically a new local user after the LDAP authentication + * + * @access public + * @param string $username Username + * @return bool + */ + public function create($username) + { + $userModel = new User($this->db, $this->event); + $user = $userModel->getByUsername($username); + + // There is an existing user account + if ($user) { + + if ($user['is_ldap_user'] == 1) { + + // LDAP user already created + return true; + } + else { + + // There is already a local user with that username + return false; + } + } + + // Create a LDAP user + $values = array( + 'username' => $username, + 'is_admin' => 0, + 'is_ldap_user' => 1, + ); + + return $userModel->create($values); + } +} diff --git a/models/user.php b/models/user.php index 5815b673..c5017ac6 100644 --- a/models/user.php +++ b/models/user.php @@ -57,7 +57,7 @@ class User extends Base return $this->db ->table(self::TABLE) ->asc('username') - ->columns('id', 'username', 'is_admin', 'default_project_id') + ->columns('id', 'username', 'is_admin', 'default_project_id', 'is_ldap_user') ->findAll(); } @@ -81,8 +81,13 @@ class User extends Base */ public function create(array $values) { - if (isset($values['confirmation'])) unset($values['confirmation']); - $values['password'] = \password_hash($values['password'], PASSWORD_BCRYPT); + if (isset($values['confirmation'])) { + unset($values['confirmation']); + } + + if (isset($values['password'])) { + $values['password'] = \password_hash($values['password'], PASSWORD_BCRYPT); + } return $this->db->table(self::TABLE)->save($values); } @@ -154,6 +159,7 @@ class User extends Base $user['id'] = (int) $user['id']; $user['default_project_id'] = (int) $user['default_project_id']; $user['is_admin'] = (bool) $user['is_admin']; + $user['is_ldap_user'] = (bool) $user['is_ldap_user']; $_SESSION['user'] = $user; } @@ -242,9 +248,9 @@ class User extends Base if ($v->execute()) { // Check password - $user = $this->getById($_SESSION['user']['id']); + list($authenticated,) = $this->authenticate($_SESSION['user']['username'], $values['current_password']); - if ($user !== false && \password_verify($values['current_password'], $user['password'])) { + if ($authenticated) { return array(true, array()); } else { @@ -275,13 +281,23 @@ class User extends Base if ($result) { - $user = $this->getByUsername($values['username']); + list($authenticated, $method) = $this->authenticate($values['username'], $values['password']); - if ($user !== false && \password_verify($values['password'], $user['password'])) { + if ($authenticated === true) { // Create the user session + $user = $this->getByUsername($values['username']); $this->updateSession($user); + // Update login history + $lastLogin = new LastLogin($this->db, $this->event); + $lastLogin->create( + $method, + $user['id'], + $this->getIpAddress(), + $this->getUserAgent() + ); + // Setup the remember me feature if (! empty($values['remember_me'])) { $rememberMe = new RememberMe($this->db, $this->event); @@ -302,6 +318,32 @@ class User extends Base } /** + * Authenticate a user + * + * @access public + * @param string $username Username + * @param string $password Password + * @return array + */ + public function authenticate($username, $password) + { + // Database authentication + $user = $this->db->table(self::TABLE)->eq('username', $username)->eq('is_ldap_user', 0)->findOne(); + $authenticated = $user && \password_verify($password, $user['password']); + $method = LastLogin::AUTH_DATABASE; + + // LDAP authentication + if (! $authenticated && LDAP_AUTH) { + require __DIR__.'/ldap.php'; + $ldap = new Ldap($this->db, $this->event); + $authenticated = $ldap->authenticate($username, $password); + $method = LastLogin::AUTH_LDAP; + } + + return array($authenticated, $method); + } + + /** * Get the user agent of the connected user * * @access public |