Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
| Total | |
0.00% |
0 / 1 |
|
50.00% |
1 / 2 |
CRAP | |
43.59% |
51 / 117 |
| db | |
0.00% |
0 / 1 |
|
50.00% |
1 / 2 |
137.19 | |
43.59% |
51 / 117 |
| __construct | |
100.00% |
1 / 1 |
1 | |
100.00% |
9 / 9 |
|||
| login | |
0.00% |
0 / 1 |
155.46 | |
38.89% |
42 / 108 |
|||
| <?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) | |
| { | |
| /* @var $captcha_factory \phpbb\captcha\factory */ | |
| $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, | |
| ); | |
| } | |
| } |