Code Coverage |
||||||||||
Classes and Traits |
Functions and Methods |
Lines |
||||||||
Total | |
0.00% |
0 / 1 |
|
50.00% |
1 / 2 |
CRAP | |
44.79% |
43 / 96 |
db | |
0.00% |
0 / 1 |
|
50.00% |
1 / 2 |
159.93 | |
44.79% |
43 / 96 |
__construct | |
100.00% |
1 / 1 |
1 | |
100.00% |
9 / 9 |
|||
login | |
0.00% |
0 / 1 |
191.82 | |
39.08% |
34 / 87 |
<?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; | |
use phpbb\captcha\factory; | |
use phpbb\captcha\plugins\captcha_abstract; | |
use phpbb\config\config; | |
use phpbb\db\driver\driver_interface; | |
use phpbb\passwords\manager; | |
use phpbb\request\request_interface; | |
use phpbb\user; | |
/** | |
* Database authentication provider for phpBB3 | |
* This is for authentication via the integrated user table | |
*/ | |
class db extends base | |
{ | |
/** @var factory CAPTCHA factory */ | |
protected $captcha_factory; | |
/** @var config phpBB config */ | |
protected $config; | |
/** @var driver_interface DBAL driver instance */ | |
protected $db; | |
/** @var request_interface Request object */ | |
protected $request; | |
/** @var user User object */ | |
protected $user; | |
/** @var string phpBB root path */ | |
protected $phpbb_root_path; | |
/** @var string PHP file extension */ | |
protected $php_ext; | |
/** | |
* phpBB passwords manager | |
* | |
* @var manager | |
*/ | |
protected $passwords_manager; | |
/** | |
* Database Authentication Constructor | |
* | |
* @param factory $captcha_factory | |
* @param config $config | |
* @param driver_interface $db | |
* @param manager $passwords_manager | |
* @param request_interface $request | |
* @param user $user | |
* @param string $phpbb_root_path | |
* @param string $php_ext | |
*/ | |
public function __construct(factory $captcha_factory, config $config, driver_interface $db, manager $passwords_manager, request_interface $request, user $user, $phpbb_root_path, $php_ext) | |
{ | |
$this->captcha_factory = $captcha_factory; | |
$this->config = $config; | |
$this->db = $db; | |
$this->passwords_manager = $passwords_manager; | |
$this->request = $request; | |
$this->user = $user; | |
$this->phpbb_root_path = $phpbb_root_path; | |
$this->php_ext = $php_ext; | |
} | |
/** | |
* {@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; | |
} | |
$login_error_attempts = 'LOGIN_ERROR_ATTEMPTS'; | |
$user_login_attempts = (is_array($row) && $this->config['max_login_attempts'] && $row['user_login_attempts'] >= $this->config['max_login_attempts']); | |
$ip_login_attempts = ($this->config['ip_login_limit_max'] && $attempts >= $this->config['ip_login_limit_max']); | |
$show_captcha = $user_login_attempts || $ip_login_attempts; | |
if ($show_captcha) | |
{ | |
$captcha = $this->captcha_factory->get_instance($this->config['captcha_plugin']); | |
// Get custom message for login error when exceeding maximum number of attempts | |
if ($captcha instanceof captcha_abstract) | |
{ | |
$login_error_attempts = $captcha->get_login_error_attempts(); | |
} | |
} | |
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), | |
); | |
} | |
// 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->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, | |
); | |
} | |
} |