Improving ldap auth
This commit is contained in:
parent
b87faad0c9
commit
64772d190c
7 changed files with 78 additions and 61 deletions
|
@ -51,20 +51,17 @@ class LoginController extends Controller
|
|||
}
|
||||
|
||||
$username = param($request, 'username');
|
||||
$user = $this->database->query('SELECT `id`, `email`, `username`, `password`,`is_admin`, `active`, `current_disk_quota`, `max_disk_quota` FROM `users` WHERE `username` = ? OR `email` = ? LIMIT 1', [$username, $username])->fetch();
|
||||
$user = $this->database->query('SELECT `id`, `email`, `username`, `password`,`is_admin`, `active`, `current_disk_quota`, `max_disk_quota`, `ldap` FROM `users` WHERE `username` = ? OR `email` = ? LIMIT 1', [$username, $username])->fetch();
|
||||
|
||||
if ($this->config['ldap']['enabled']) {
|
||||
$result = $this->ldapLogin($username, param($request, 'password'), $user);
|
||||
if ($result) {
|
||||
$user = $this->database->query('SELECT `id`, `email`, `username`, `password`,`is_admin`, `active`, `current_disk_quota`, `max_disk_quota` FROM `users` WHERE `username` = ? OR `email` = ? LIMIT 1', [$username, $username])->fetch();
|
||||
}
|
||||
$user = $this->ldapLogin($request, $username, param($request, 'password'), $user);
|
||||
}
|
||||
|
||||
$validator = ValidationChecker::make()
|
||||
->rules([
|
||||
'login' => $user && password_verify(param($request, 'password'), $user->password),
|
||||
'maintenance' => !isset($this->config['maintenance']) || !$this->config['maintenance'] || $user->is_admin,
|
||||
'user_active' => $user->active,
|
||||
'maintenance' => !isset($this->config['maintenance']) || !$this->config['maintenance'] || $user->is_admin ?? false,
|
||||
'user_active' => $user->active ?? false,
|
||||
])
|
||||
->onFail(function ($rule) {
|
||||
$alerts = [
|
||||
|
@ -119,29 +116,55 @@ class LoginController extends Controller
|
|||
}
|
||||
|
||||
/**
|
||||
* @param Request $request
|
||||
* @param string $username
|
||||
* @param string $password
|
||||
* @param $dbUser
|
||||
* @return bool
|
||||
* @throws \Slim\Exception\HttpNotFoundException
|
||||
* @throws \Slim\Exception\HttpUnauthorizedException
|
||||
*/
|
||||
protected function ldapLogin(string $username, string $password, $dbUser)
|
||||
protected function ldapLogin(Request $request, string $username, string $password, $dbUser)
|
||||
{
|
||||
if (!extension_loaded('ldap')) {
|
||||
$this->logger->error('The LDAP extension is not loaded.');
|
||||
return false;
|
||||
}
|
||||
|
||||
$server = ldap_connect($this->config['ldap']['host'], $this->config['ldap']['port']);
|
||||
|
||||
$server = $this->ldapConnect();
|
||||
if (!$server) {
|
||||
$this->session->alert(lang('ldap_cant_connect'), 'warning');
|
||||
return false;
|
||||
return $dbUser;
|
||||
}
|
||||
if (!@ldap_bind($server, $this->getLdapRdn($username), $password)) {
|
||||
if ($dbUser && !$dbUser->ldap) {
|
||||
return $dbUser;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
if (!$dbUser) {
|
||||
$email = $username;
|
||||
if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
|
||||
$search = ldap_search($server, $this->config['ldap']['user_domain'].','.$this->config['ldap']['base_domain'], 'uid='.addslashes($username), ['mail']);
|
||||
$entry = ldap_first_entry($server, $search);
|
||||
$email = @ldap_get_values($server, $entry, 'mail')[0] ?? platform_mail($username.rand(0, 100)); // if the mail is not set, generate a placeholder
|
||||
}
|
||||
/** @var UserQuery $userQuery */
|
||||
$userQuery = make(UserQuery::class);
|
||||
$userQuery->create($email, $username, $password, 0, 1, (int) $this->getSetting('default_user_quota', -1), null, 1);
|
||||
return $userQuery->get($request, $this->database->getPdo()->lastInsertId());
|
||||
}
|
||||
|
||||
ldap_set_option($server, LDAP_OPT_PROTOCOL_VERSION, 3);
|
||||
ldap_set_option($server, LDAP_OPT_REFERRALS, 0);
|
||||
ldap_set_option($server, LDAP_OPT_NETWORK_TIMEOUT, 10);
|
||||
if (!password_verify($password, $dbUser->password)) {
|
||||
$userQuery = make(UserQuery::class);
|
||||
$userQuery->update($dbUser->id, $dbUser->email, $username, $password, $dbUser->is_admin, $dbUser->active, $dbUser->max_disk_quota, $dbUser->ldap);
|
||||
return $userQuery->get($request, $dbUser->id);
|
||||
}
|
||||
|
||||
return $dbUser;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $username
|
||||
* @return string
|
||||
*/
|
||||
private function getLdapRdn(string $username)
|
||||
{
|
||||
$bindString = 'uid='.addslashes($username);
|
||||
if ($this->config['ldap']['user_domain'] !== null) {
|
||||
$bindString .= ','.$this->config['ldap']['user_domain'];
|
||||
|
@ -151,40 +174,6 @@ class LoginController extends Controller
|
|||
$bindString .= ','.$this->config['ldap']['base_domain'];
|
||||
}
|
||||
|
||||
if (!@ldap_bind($server, $bindString, $password)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!$dbUser) {
|
||||
$email = $username;
|
||||
if (!filter_var($username, FILTER_VALIDATE_EMAIL)) {
|
||||
$search = ldap_search($server, $this->config['ldap']['user_domain'].','.$this->config['ldap']['base_domain'], 'uid='.addslashes($username), ['mail']);
|
||||
$entry = ldap_first_entry($server, $search);
|
||||
$email = @ldap_get_values($server, $entry, 'mail')[0] ?? platform_mail($username.uniqid());
|
||||
}
|
||||
make(UserQuery::class)->create(
|
||||
$email,
|
||||
$username,
|
||||
$password,
|
||||
0,
|
||||
1,
|
||||
(int) $this->getSetting('default_user_quota', -1)
|
||||
);
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!password_verify($password, $dbUser->password)) {
|
||||
make(UserQuery::class)->update(
|
||||
$dbUser->id,
|
||||
$dbUser->email,
|
||||
$username,
|
||||
$password,
|
||||
$dbUser->is_admin,
|
||||
$dbUser->active,
|
||||
$dbUser->max_disk_quota
|
||||
);
|
||||
}
|
||||
|
||||
return true;
|
||||
return $bindString;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,7 @@ class PasswordRecoveryController extends Controller
|
|||
return redirect($response, route('home'));
|
||||
}
|
||||
|
||||
$user = $this->database->query('SELECT `id`, `username` FROM `users` WHERE `email` = ? LIMIT 1', param($request, 'email'))->fetch();
|
||||
$user = $this->database->query('SELECT `id`, `username` FROM `users` WHERE `email` = ? AND NOT `ldap` LIMIT 1', param($request, 'email'))->fetch();
|
||||
|
||||
if (!isset($user->id)) {
|
||||
$this->session->alert(lang('recover_email_sent'), 'success');
|
||||
|
|
|
@ -167,4 +167,25 @@ abstract class Controller
|
|||
$this->session->alert($alerts[$rule], 'danger');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool|false|resource
|
||||
*/
|
||||
public function ldapConnect()
|
||||
{
|
||||
if (!extension_loaded('ldap')) {
|
||||
$this->logger->error('The LDAP extension is not loaded.');
|
||||
return false;
|
||||
}
|
||||
|
||||
$server = ldap_connect($this->config['ldap']['host'], $this->config['ldap']['port']);
|
||||
|
||||
if ($server) {
|
||||
ldap_set_option($server, LDAP_OPT_PROTOCOL_VERSION, 3);
|
||||
ldap_set_option($server, LDAP_OPT_REFERRALS, 0);
|
||||
ldap_set_option($server, LDAP_OPT_NETWORK_TIMEOUT, 10);
|
||||
}
|
||||
|
||||
return $server;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -79,9 +79,10 @@ class UserQuery
|
|||
* @param int $isActive
|
||||
* @param int $maxUserQuota
|
||||
* @param string|null $activateToken
|
||||
* @param int $ldap
|
||||
* @return bool|\PDOStatement|string
|
||||
*/
|
||||
public function create(string $email, string $username, string $password = null, int $isAdmin = 0, int $isActive = 0, int $maxUserQuota = -1, string $activateToken = null)
|
||||
public function create(string $email, string $username, string $password = null, int $isAdmin = 0, int $isActive = 0, int $maxUserQuota = -1, string $activateToken = null, int $ldap =0)
|
||||
{
|
||||
do {
|
||||
$userCode = humanRandomString(5);
|
||||
|
@ -89,7 +90,7 @@ class UserQuery
|
|||
|
||||
$token = $this->generateUserUploadToken();
|
||||
|
||||
return $this->database->query('INSERT INTO `users`(`email`, `username`, `password`, `is_admin`, `active`, `user_code`, `token`, `max_disk_quota`, `activate_token`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)', [
|
||||
return $this->database->query('INSERT INTO `users`(`email`, `username`, `password`, `is_admin`, `active`, `user_code`, `token`, `max_disk_quota`, `activate_token`, `ldap`) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?)', [
|
||||
$email,
|
||||
$username,
|
||||
$password !== null ? password_hash($password, PASSWORD_DEFAULT) : null,
|
||||
|
@ -99,6 +100,7 @@ class UserQuery
|
|||
$token,
|
||||
$maxUserQuota,
|
||||
$activateToken,
|
||||
$ldap
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -110,27 +112,30 @@ class UserQuery
|
|||
* @param int $isAdmin
|
||||
* @param int $isActive
|
||||
* @param int $maxUserQuota
|
||||
* @param int $ldap
|
||||
* @return bool|\PDOStatement|string
|
||||
*/
|
||||
public function update($id, string $email, string $username, string $password = null, int $isAdmin = 0, int $isActive = 0, int $maxUserQuota = -1)
|
||||
public function update($id, string $email, string $username, string $password = null, int $isAdmin = 0, int $isActive = 0, int $maxUserQuota = -1, int $ldap = 0)
|
||||
{
|
||||
if (!empty($password)) {
|
||||
return $this->database->query('UPDATE `users` SET `email`=?, `username`=?, `password`=?, `is_admin`=?, `active`=?, `max_disk_quota`=? WHERE `id` = ?', [
|
||||
return $this->database->query('UPDATE `users` SET `email`=?, `username`=?, `password`=?, `is_admin`=?, `active`=?, `max_disk_quota`=?, `ldap`=? WHERE `id` = ?', [
|
||||
$email,
|
||||
$username,
|
||||
password_hash($password, PASSWORD_DEFAULT),
|
||||
$isAdmin,
|
||||
$isActive,
|
||||
$maxUserQuota,
|
||||
$ldap,
|
||||
$id,
|
||||
]);
|
||||
} else {
|
||||
return $this->database->query('UPDATE `users` SET `email`=?, `username`=?, `is_admin`=?, `active`=?, `max_disk_quota`=? WHERE `id` = ?', [
|
||||
return $this->database->query('UPDATE `users` SET `email`=?, `username`=?, `is_admin`=?, `active`=?, `max_disk_quota`=?, `ldap`=? WHERE `id` = ?', [
|
||||
$email,
|
||||
$username,
|
||||
$isAdmin,
|
||||
$isActive,
|
||||
$maxUserQuota,
|
||||
$ldap,
|
||||
$id,
|
||||
]);
|
||||
}
|
||||
|
|
|
@ -34,7 +34,7 @@ if (isset($argv[1]) && $argv[1] === '--install') {
|
|||
}
|
||||
|
||||
if (file_exists(__DIR__.'/../install') && (!isset($config['debug']) || !$config['debug'])) {
|
||||
//removeDirectory(__DIR__.'/../install');
|
||||
removeDirectory(__DIR__.'/../install');
|
||||
}
|
||||
|
||||
echo 'If you are upgrading from a previous version, please run a "php bin\clean".'.PHP_EOL;
|
||||
|
|
1
resources/schemas/mysql/mysql.7.sql
Normal file
1
resources/schemas/mysql/mysql.7.sql
Normal file
|
@ -0,0 +1 @@
|
|||
ALTER TABLE `users` ADD COLUMN `ldap` BOOLEAN NOT NULL DEFAULT 0;
|
1
resources/schemas/sqlite/sqlite.7.sql
Normal file
1
resources/schemas/sqlite/sqlite.7.sql
Normal file
|
@ -0,0 +1 @@
|
|||
ALTER TABLE `users` ADD COLUMN `ldap` BOOLEAN NOT NULL DEFAULT 0;
|
Loading…
Add table
Reference in a new issue