mirror of
https://github.com/YunoHost-Apps/phpbb_ynh.git
synced 2024-09-03 19:56:36 +02:00
239 lines
6.8 KiB
PHP
239 lines
6.8 KiB
PHP
<?php
|
|
/**
|
|
*
|
|
* This file is part of the phpBB Forum Software package.
|
|
*
|
|
* @copyright (c) phpBB Limited <https://www.phpbb.com>
|
|
* @license GNU General Public License, version 2 (GPL-2.0)
|
|
*
|
|
* For full copyright and license information, please see
|
|
* the docs/CREDITS.txt file.
|
|
*
|
|
*/
|
|
|
|
namespace phpbb\auth\provider;
|
|
|
|
/**
|
|
* Database authentication provider for phpBB3
|
|
* This is for authentication via the integrated user table
|
|
*/
|
|
class db extends \phpbb\auth\provider\base
|
|
{
|
|
/**
|
|
* phpBB passwords manager
|
|
*
|
|
* @var \phpbb\passwords\manager
|
|
*/
|
|
protected $passwords_manager;
|
|
|
|
/**
|
|
* DI container
|
|
*
|
|
* @var \Symfony\Component\DependencyInjection\ContainerInterface
|
|
*/
|
|
protected $phpbb_container;
|
|
|
|
/**
|
|
* Database Authentication Constructor
|
|
*
|
|
* @param \phpbb\db\driver\driver_interface $db
|
|
* @param \phpbb\config\config $config
|
|
* @param \phpbb\passwords\manager $passwords_manager
|
|
* @param \phpbb\request\request $request
|
|
* @param \phpbb\user $user
|
|
* @param \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container DI container
|
|
* @param string $phpbb_root_path
|
|
* @param string $php_ext
|
|
*/
|
|
public function __construct(\phpbb\db\driver\driver_interface $db, \phpbb\config\config $config, \phpbb\passwords\manager $passwords_manager, \phpbb\request\request $request, \phpbb\user $user, \Symfony\Component\DependencyInjection\ContainerInterface $phpbb_container, $phpbb_root_path, $php_ext)
|
|
{
|
|
$this->db = $db;
|
|
$this->config = $config;
|
|
$this->passwords_manager = $passwords_manager;
|
|
$this->request = $request;
|
|
$this->user = $user;
|
|
$this->phpbb_root_path = $phpbb_root_path;
|
|
$this->php_ext = $php_ext;
|
|
$this->phpbb_container = $phpbb_container;
|
|
}
|
|
|
|
/**
|
|
* {@inheritdoc}
|
|
*/
|
|
public function login($username, $password)
|
|
{
|
|
// Auth plugins get the password untrimmed.
|
|
// For compatibility we trim() here.
|
|
$password = trim($password);
|
|
|
|
// do not allow empty password
|
|
if (!$password)
|
|
{
|
|
return array(
|
|
'status' => LOGIN_ERROR_PASSWORD,
|
|
'error_msg' => 'NO_PASSWORD_SUPPLIED',
|
|
'user_row' => array('user_id' => ANONYMOUS),
|
|
);
|
|
}
|
|
|
|
if (!$username)
|
|
{
|
|
return array(
|
|
'status' => LOGIN_ERROR_USERNAME,
|
|
'error_msg' => 'LOGIN_ERROR_USERNAME',
|
|
'user_row' => array('user_id' => ANONYMOUS),
|
|
);
|
|
}
|
|
|
|
$username_clean = utf8_clean_string($username);
|
|
|
|
$sql = 'SELECT *
|
|
FROM ' . USERS_TABLE . "
|
|
WHERE username_clean = '" . $this->db->sql_escape($username_clean) . "'";
|
|
$result = $this->db->sql_query($sql);
|
|
$row = $this->db->sql_fetchrow($result);
|
|
$this->db->sql_freeresult($result);
|
|
|
|
if (($this->user->ip && !$this->config['ip_login_limit_use_forwarded']) ||
|
|
($this->user->forwarded_for && $this->config['ip_login_limit_use_forwarded']))
|
|
{
|
|
$sql = 'SELECT COUNT(*) AS attempts
|
|
FROM ' . LOGIN_ATTEMPT_TABLE . '
|
|
WHERE attempt_time > ' . (time() - (int) $this->config['ip_login_limit_time']);
|
|
if ($this->config['ip_login_limit_use_forwarded'])
|
|
{
|
|
$sql .= " AND attempt_forwarded_for = '" . $this->db->sql_escape($this->user->forwarded_for) . "'";
|
|
}
|
|
else
|
|
{
|
|
$sql .= " AND attempt_ip = '" . $this->db->sql_escape($this->user->ip) . "' ";
|
|
}
|
|
|
|
$result = $this->db->sql_query($sql);
|
|
$attempts = (int) $this->db->sql_fetchfield('attempts');
|
|
$this->db->sql_freeresult($result);
|
|
|
|
$attempt_data = array(
|
|
'attempt_ip' => $this->user->ip,
|
|
'attempt_browser' => trim(substr($this->user->browser, 0, 149)),
|
|
'attempt_forwarded_for' => $this->user->forwarded_for,
|
|
'attempt_time' => time(),
|
|
'user_id' => ($row) ? (int) $row['user_id'] : 0,
|
|
'username' => $username,
|
|
'username_clean' => $username_clean,
|
|
);
|
|
$sql = 'INSERT INTO ' . LOGIN_ATTEMPT_TABLE . $this->db->sql_build_array('INSERT', $attempt_data);
|
|
$this->db->sql_query($sql);
|
|
}
|
|
else
|
|
{
|
|
$attempts = 0;
|
|
}
|
|
|
|
if (!$row)
|
|
{
|
|
if ($this->config['ip_login_limit_max'] && $attempts >= $this->config['ip_login_limit_max'])
|
|
{
|
|
return array(
|
|
'status' => LOGIN_ERROR_ATTEMPTS,
|
|
'error_msg' => 'LOGIN_ERROR_ATTEMPTS',
|
|
'user_row' => array('user_id' => ANONYMOUS),
|
|
);
|
|
}
|
|
|
|
return array(
|
|
'status' => LOGIN_ERROR_USERNAME,
|
|
'error_msg' => 'LOGIN_ERROR_USERNAME',
|
|
'user_row' => array('user_id' => ANONYMOUS),
|
|
);
|
|
}
|
|
|
|
$show_captcha = ($this->config['max_login_attempts'] && $row['user_login_attempts'] >= $this->config['max_login_attempts']) ||
|
|
($this->config['ip_login_limit_max'] && $attempts >= $this->config['ip_login_limit_max']);
|
|
|
|
// If there are too many login attempts, we need to check for a confirm image
|
|
// Every auth module is able to define what to do by itself...
|
|
if ($show_captcha)
|
|
{
|
|
$captcha_factory = $this->phpbb_container->get('captcha.factory');
|
|
$captcha = $captcha_factory->get_instance($this->config['captcha_plugin']);
|
|
$captcha->init(CONFIRM_LOGIN);
|
|
$vc_response = $captcha->validate($row);
|
|
if ($vc_response)
|
|
{
|
|
return array(
|
|
'status' => LOGIN_ERROR_ATTEMPTS,
|
|
'error_msg' => 'LOGIN_ERROR_ATTEMPTS',
|
|
'user_row' => $row,
|
|
);
|
|
}
|
|
else
|
|
{
|
|
$captcha->reset();
|
|
}
|
|
|
|
}
|
|
|
|
// Check password ...
|
|
if ($this->passwords_manager->check($password, $row['user_password'], $row))
|
|
{
|
|
// Check for old password hash...
|
|
if ($this->passwords_manager->convert_flag || strlen($row['user_password']) == 32)
|
|
{
|
|
$hash = $this->passwords_manager->hash($password);
|
|
|
|
// Update the password in the users table to the new format
|
|
$sql = 'UPDATE ' . USERS_TABLE . "
|
|
SET user_password = '" . $this->db->sql_escape($hash) . "'
|
|
WHERE user_id = {$row['user_id']}";
|
|
$this->db->sql_query($sql);
|
|
|
|
$row['user_password'] = $hash;
|
|
}
|
|
|
|
$sql = 'DELETE FROM ' . LOGIN_ATTEMPT_TABLE . '
|
|
WHERE user_id = ' . $row['user_id'];
|
|
$this->db->sql_query($sql);
|
|
|
|
if ($row['user_login_attempts'] != 0)
|
|
{
|
|
// Successful, reset login attempts (the user passed all stages)
|
|
$sql = 'UPDATE ' . USERS_TABLE . '
|
|
SET user_login_attempts = 0
|
|
WHERE user_id = ' . $row['user_id'];
|
|
$this->db->sql_query($sql);
|
|
}
|
|
|
|
// User inactive...
|
|
if ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE)
|
|
{
|
|
return array(
|
|
'status' => LOGIN_ERROR_ACTIVE,
|
|
'error_msg' => 'ACTIVE_ERROR',
|
|
'user_row' => $row,
|
|
);
|
|
}
|
|
|
|
// Successful login... set user_login_attempts to zero...
|
|
return array(
|
|
'status' => LOGIN_SUCCESS,
|
|
'error_msg' => false,
|
|
'user_row' => $row,
|
|
);
|
|
}
|
|
|
|
// Password incorrect - increase login attempts
|
|
$sql = 'UPDATE ' . USERS_TABLE . '
|
|
SET user_login_attempts = user_login_attempts + 1
|
|
WHERE user_id = ' . (int) $row['user_id'] . '
|
|
AND user_login_attempts < ' . LOGIN_ATTEMPTS_MAX;
|
|
$this->db->sql_query($sql);
|
|
|
|
// Give status about wrong password...
|
|
return array(
|
|
'status' => ($show_captcha) ? LOGIN_ERROR_ATTEMPTS : LOGIN_ERROR_PASSWORD,
|
|
'error_msg' => 'LOGIN_ERROR_PASSWORD',
|
|
'user_row' => $row,
|
|
);
|
|
}
|
|
}
|