diff --git a/src/Pluf/Auth/LdapBackend.php b/src/Pluf/Auth/LdapBackend.php new file mode 100644 index 0000000..650a6db --- /dev/null +++ b/src/Pluf/Auth/LdapBackend.php @@ -0,0 +1,133 @@ +getOne($sql->gen()); + } + + /** + * Given an array with the authentication data, auth the user and return it. + */ + public static function authenticate($auth_data) + { + $password = $auth_data['password']; + $login = $auth_data['login']; + + // Small security check against the login + if (preg_match('/[^A-Za-z0-9\-\_]/', $login)) { + return false; + } + + // We check the user against the LDAP server, if it works we + // are happy, if not return false. + + + $ldap_dn = Pluf::f('auth_ldap_dn', 'ou=users,dc=example,dc=com'); + $ldap_user = Pluf::f('auth_ldap_user', null); + $ldap_password = Pluf::f('auth_ldap_password', null); + $ldap_version = Pluf::f('auth_ldap_version', 3); + $ldap_user_key = Pluf::f('auth_ldap_user_key', 'uid'); + // If auth_ldap_password_key, it will use crypt hash control + // to test the login password, else it will bind. + $ldap_password_key = Pluf::f('auth_ldap_password_key', null); + $ldap_surname_key = Pluf::f('auth_ldap_surname_key', 'sn'); + $ldap_givenname_key = Pluf::f('auth_ldap_givenname_key', 'cn'); + $ldap_email_key = Pluf::f('auth_ldap_email_key', 'email'); + + + $ldap = ldap_connect(Pluf::f('auth_ldap_host', 'localhost')); + ldap_set_option($ldap, LDAP_OPT_PROTOCOL_VERSION, + Pluf::f('auth_ldap_version', 3)); + if (!ldap_bind($ldap, $ldap_user, $ldap_password)) { + Pluf_Log::warn(sprintf('Cannot bind to the ldap server, user:%s, password:***', $ldap_user)); + ldap_close($ldap); + return false; + } + // Go for a search + $search = ldap_search($ldap, $ldap_dn, + $ldap_user_id.'='.$login); + $n = ldap_get_entries($ldap, $search); + if ($n['count'] != 1) { + ldap_close($ldap); + return false; + } + $entry = ldap_first_entry($ldap, $search); + // We get all the data first, the bind or hash control is done + // later. If we control with bind now, we need to search again + // to have an $entry resource to get the values. + list($family_name,) = ldap_get_values($ldap, $entry, $ldap_surname_key); + list($first_name,) = ldap_get_values($ldap, $entry, $ldap_givenname_key); + list($email,) = ldap_get_values($ldap, $entry, $ldap_email_key); + + if ($ldap_password_key) { + // Password authentication. + list($ldap_hash,) = ldap_get_values($ldap, $entry, $ldap_password_key); + $ldap_hash = substr($ldap_hash, 7); + $salt = substr($ldap_hash, 0, 12); + $hash = crypt($password, $salt); + if ($ldap_hash != $hash) { + ldap_close($ldap); + return false; + } + } else { + // Bind authentication + if (!ldap_bind($lda, $login, $password)) { + ldap_close($ldap); + return false; + } + } + // We get the user values as the + // Now we get the user and we create it if not available + $user = self::getUser($login); + if ($user) { + ldap_close($ldap); + return $user; + } + // Need to create it + ldap_close($ldap); + $user = new Pluf_User(); + $user->active = true; + $user->login = $login; + $user->password = $password; + $user->last_name = $family_name; + $user->first_name = $first_name; + $user->email = $email; + $user->create(); + return $user; + } +} + diff --git a/src/Pluf/Auth/ModelBackend.php b/src/Pluf/Auth/ModelBackend.php new file mode 100644 index 0000000..4205a00 --- /dev/null +++ b/src/Pluf/Auth/ModelBackend.php @@ -0,0 +1,57 @@ +getOne($sql->gen()); + } + + /** + * Given an array with the authentication data, auth the user and return it. + */ + public static function authenticate($auth_data) + { + $password = $auth_data['password']; + $login = $auth_data['login']; + $user = self::getUser($login); + if (!$user) { + return false; + } + if (!$user->active) { + return false; + } + return ($user->checkPassword($password)) ? $user : false; + } +} + diff --git a/src/Pluf/Views.php b/src/Pluf/Views.php index dfed244..14abc45 100644 --- a/src/Pluf/Views.php +++ b/src/Pluf/Views.php @@ -81,11 +81,15 @@ class Pluf_Views $success_url = $request->REQUEST['_redirect_after']; } $error = ''; - if ($request->method == 'POST' - and isset($request->POST['login']) - and isset($request->POST['password'])) { - $users = new Pluf_User(); - if (false === ($user = $users->checkCreditentials($request->POST['login'], $request->POST['password']))) { + if ($request->method == 'POST') { + foreach (Pluf::f('auth_backends', array('Pluf_Auth_ModelBackend')) + as $backend) { + $user = $backend::authenticate($request->POST); + if ($user !== false) { + break; + } + } + if (false === $user) { $error = __('The login or the password is not valid. The login and the password are case sensitive.'); } else { if (!$request->session->getTestCookie()) {