Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
| Total | |
39.66% |
46 / 116 |
|
16.67% |
1 / 6 |
CRAP | |
0.00% |
0 / 1 |
| apache | |
39.66% |
46 / 116 |
|
16.67% |
1 / 6 |
227.77 | |
0.00% |
0 / 1 |
| __construct | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
| init | |
66.67% |
2 / 3 |
|
0.00% |
0 / 1 |
3.33 | |||
| login | |
36.36% |
20 / 55 |
|
0.00% |
0 / 1 |
35.77 | |||
| autologin | |
51.85% |
14 / 27 |
|
0.00% |
0 / 1 |
18.04 | |||
| user_row | |
0.00% |
0 / 18 |
|
0.00% |
0 / 1 |
12 | |||
| validate_session | |
50.00% |
3 / 6 |
|
0.00% |
0 / 1 |
6.00 | |||
| 1 | <?php |
| 2 | /** |
| 3 | * |
| 4 | * This file is part of the phpBB Forum Software package. |
| 5 | * |
| 6 | * @copyright (c) phpBB Limited <https://www.phpbb.com> |
| 7 | * @license GNU General Public License, version 2 (GPL-2.0) |
| 8 | * |
| 9 | * For full copyright and license information, please see |
| 10 | * the docs/CREDITS.txt file. |
| 11 | * |
| 12 | */ |
| 13 | |
| 14 | namespace phpbb\auth\provider; |
| 15 | |
| 16 | use phpbb\config\config; |
| 17 | use phpbb\db\driver\driver_interface; |
| 18 | use phpbb\language\language; |
| 19 | use phpbb\request\request_interface; |
| 20 | use phpbb\request\type_cast_helper; |
| 21 | use phpbb\user; |
| 22 | |
| 23 | /** |
| 24 | * Apache authentication provider for phpBB |
| 25 | */ |
| 26 | class apache extends base |
| 27 | { |
| 28 | /** @var config phpBB config */ |
| 29 | protected $config; |
| 30 | |
| 31 | /** @var driver_interface Database object */ |
| 32 | protected $db; |
| 33 | |
| 34 | /** @var language Language object */ |
| 35 | protected $language; |
| 36 | |
| 37 | /** @var request_interface Request object */ |
| 38 | protected $request; |
| 39 | |
| 40 | /** @var user User object */ |
| 41 | protected $user; |
| 42 | |
| 43 | /** @var string Relative path to phpBB root */ |
| 44 | protected $phpbb_root_path; |
| 45 | |
| 46 | /** @var string PHP file extension */ |
| 47 | protected $php_ext; |
| 48 | |
| 49 | /** |
| 50 | * Apache Authentication Constructor |
| 51 | * |
| 52 | * @param config $config Config object |
| 53 | * @param driver_interface $db Database object |
| 54 | * @param language $language Language object |
| 55 | * @param request_interface $request Request object |
| 56 | * @param user $user User object |
| 57 | * @param string $phpbb_root_path Relative path to phpBB root |
| 58 | * @param string $php_ext PHP file extension |
| 59 | */ |
| 60 | public function __construct(config $config, driver_interface $db, language $language, request_interface $request, user $user, $phpbb_root_path, $php_ext) |
| 61 | { |
| 62 | $this->config = $config; |
| 63 | $this->db = $db; |
| 64 | $this->language = $language; |
| 65 | $this->request = $request; |
| 66 | $this->user = $user; |
| 67 | $this->phpbb_root_path = $phpbb_root_path; |
| 68 | $this->php_ext = $php_ext; |
| 69 | } |
| 70 | |
| 71 | /** |
| 72 | * {@inheritdoc} |
| 73 | */ |
| 74 | public function init() |
| 75 | { |
| 76 | if (!$this->request->is_set('PHP_AUTH_USER', request_interface::SERVER) || $this->user->data['username'] !== html_entity_decode($this->request->server('PHP_AUTH_USER'), ENT_COMPAT)) |
| 77 | { |
| 78 | return $this->language->lang('APACHE_SETUP_BEFORE_USE'); |
| 79 | } |
| 80 | return false; |
| 81 | } |
| 82 | |
| 83 | /** |
| 84 | * {@inheritdoc} |
| 85 | */ |
| 86 | public function login($username, $password) |
| 87 | { |
| 88 | // do not allow empty password |
| 89 | if (!$password) |
| 90 | { |
| 91 | return array( |
| 92 | 'status' => LOGIN_ERROR_PASSWORD, |
| 93 | 'error_msg' => 'NO_PASSWORD_SUPPLIED', |
| 94 | 'user_row' => array('user_id' => ANONYMOUS), |
| 95 | ); |
| 96 | } |
| 97 | |
| 98 | if (!$username) |
| 99 | { |
| 100 | return array( |
| 101 | 'status' => LOGIN_ERROR_USERNAME, |
| 102 | 'error_msg' => 'LOGIN_ERROR_USERNAME', |
| 103 | 'user_row' => array('user_id' => ANONYMOUS), |
| 104 | ); |
| 105 | } |
| 106 | |
| 107 | if (!$this->request->is_set('PHP_AUTH_USER', request_interface::SERVER)) |
| 108 | { |
| 109 | return array( |
| 110 | 'status' => LOGIN_ERROR_EXTERNAL_AUTH, |
| 111 | 'error_msg' => 'LOGIN_ERROR_EXTERNAL_AUTH_APACHE', |
| 112 | 'user_row' => array('user_id' => ANONYMOUS), |
| 113 | ); |
| 114 | } |
| 115 | |
| 116 | $php_auth_user = html_entity_decode($this->request->server('PHP_AUTH_USER'), ENT_COMPAT); |
| 117 | $php_auth_pw = html_entity_decode($this->request->server('PHP_AUTH_PW'), ENT_COMPAT); |
| 118 | |
| 119 | if (!empty($php_auth_user) && !empty($php_auth_pw)) |
| 120 | { |
| 121 | if ($php_auth_user !== $username) |
| 122 | { |
| 123 | return array( |
| 124 | 'status' => LOGIN_ERROR_USERNAME, |
| 125 | 'error_msg' => 'LOGIN_ERROR_USERNAME', |
| 126 | 'user_row' => array('user_id' => ANONYMOUS), |
| 127 | ); |
| 128 | } |
| 129 | |
| 130 | $sql = 'SELECT user_id, username, user_password, user_passchg, user_email, user_type |
| 131 | FROM ' . USERS_TABLE . " |
| 132 | WHERE username = '" . $this->db->sql_escape($php_auth_user) . "'"; |
| 133 | $result = $this->db->sql_query($sql); |
| 134 | $row = $this->db->sql_fetchrow($result); |
| 135 | $this->db->sql_freeresult($result); |
| 136 | |
| 137 | if ($row) |
| 138 | { |
| 139 | // User inactive... |
| 140 | if ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE) |
| 141 | { |
| 142 | return array( |
| 143 | 'status' => LOGIN_ERROR_ACTIVE, |
| 144 | 'error_msg' => 'ACTIVE_ERROR', |
| 145 | 'user_row' => $row, |
| 146 | ); |
| 147 | } |
| 148 | |
| 149 | // Successful login... |
| 150 | return array( |
| 151 | 'status' => LOGIN_SUCCESS, |
| 152 | 'error_msg' => false, |
| 153 | 'user_row' => $row, |
| 154 | ); |
| 155 | } |
| 156 | |
| 157 | // this is the user's first login so create an empty profile |
| 158 | return array( |
| 159 | 'status' => LOGIN_SUCCESS_CREATE_PROFILE, |
| 160 | 'error_msg' => false, |
| 161 | 'user_row' => $this->user_row($php_auth_user), |
| 162 | ); |
| 163 | } |
| 164 | |
| 165 | // Not logged into apache |
| 166 | return array( |
| 167 | 'status' => LOGIN_ERROR_EXTERNAL_AUTH, |
| 168 | 'error_msg' => 'LOGIN_ERROR_EXTERNAL_AUTH_APACHE', |
| 169 | 'user_row' => array('user_id' => ANONYMOUS), |
| 170 | ); |
| 171 | } |
| 172 | |
| 173 | /** |
| 174 | * {@inheritdoc} |
| 175 | */ |
| 176 | public function autologin() |
| 177 | { |
| 178 | if (!$this->request->is_set('PHP_AUTH_USER', request_interface::SERVER)) |
| 179 | { |
| 180 | return array(); |
| 181 | } |
| 182 | |
| 183 | $php_auth_user = html_entity_decode($this->request->server('PHP_AUTH_USER'), ENT_COMPAT); |
| 184 | $php_auth_pw = html_entity_decode($this->request->server('PHP_AUTH_PW'), ENT_COMPAT); |
| 185 | |
| 186 | if (!empty($php_auth_user) && !empty($php_auth_pw)) |
| 187 | { |
| 188 | $type_cast_helper = new type_cast_helper(); |
| 189 | $type_cast_helper->set_var($php_auth_user, $php_auth_user, 'string', true); |
| 190 | |
| 191 | $sql = 'SELECT * |
| 192 | FROM ' . USERS_TABLE . " |
| 193 | WHERE username = '" . $this->db->sql_escape($php_auth_user) . "'"; |
| 194 | $result = $this->db->sql_query($sql); |
| 195 | $row = $this->db->sql_fetchrow($result); |
| 196 | $this->db->sql_freeresult($result); |
| 197 | |
| 198 | if ($row) |
| 199 | { |
| 200 | return ($row['user_type'] == USER_INACTIVE || $row['user_type'] == USER_IGNORE) ? array() : $row; |
| 201 | } |
| 202 | |
| 203 | if (!function_exists('user_add')) |
| 204 | { |
| 205 | include($this->phpbb_root_path . 'includes/functions_user.' . $this->php_ext); |
| 206 | } |
| 207 | |
| 208 | // create the user if he does not exist yet |
| 209 | user_add($this->user_row($php_auth_user)); |
| 210 | |
| 211 | $sql = 'SELECT * |
| 212 | FROM ' . USERS_TABLE . " |
| 213 | WHERE username_clean = '" . $this->db->sql_escape(utf8_clean_string($php_auth_user)) . "'"; |
| 214 | $result = $this->db->sql_query($sql); |
| 215 | $row = $this->db->sql_fetchrow($result); |
| 216 | $this->db->sql_freeresult($result); |
| 217 | |
| 218 | if ($row) |
| 219 | { |
| 220 | return $row; |
| 221 | } |
| 222 | } |
| 223 | |
| 224 | return array(); |
| 225 | } |
| 226 | |
| 227 | /** |
| 228 | * This function generates an array which can be passed to the user_add |
| 229 | * function in order to create a user |
| 230 | * |
| 231 | * @param string $username The username of the new user. |
| 232 | * |
| 233 | * @return array Contains data that can be passed directly to |
| 234 | * the user_add function. |
| 235 | */ |
| 236 | private function user_row($username) |
| 237 | { |
| 238 | // first retrieve default group id |
| 239 | $sql = 'SELECT group_id |
| 240 | FROM ' . GROUPS_TABLE . " |
| 241 | WHERE group_name = '" . $this->db->sql_escape('REGISTERED') . "' |
| 242 | AND group_type = " . GROUP_SPECIAL; |
| 243 | $result = $this->db->sql_query($sql); |
| 244 | $row = $this->db->sql_fetchrow($result); |
| 245 | $this->db->sql_freeresult($result); |
| 246 | |
| 247 | if (!$row) |
| 248 | { |
| 249 | trigger_error('NO_GROUP'); |
| 250 | } |
| 251 | |
| 252 | // generate user account data |
| 253 | return array( |
| 254 | 'username' => $username, |
| 255 | 'user_password' => '', |
| 256 | 'user_email' => '', |
| 257 | 'group_id' => (int) $row['group_id'], |
| 258 | 'user_type' => USER_NORMAL, |
| 259 | 'user_ip' => $this->user->ip, |
| 260 | 'user_new' => ($this->config['new_member_post_limit']) ? 1 : 0, |
| 261 | ); |
| 262 | } |
| 263 | |
| 264 | /** |
| 265 | * {@inheritdoc} |
| 266 | */ |
| 267 | public function validate_session($user) |
| 268 | { |
| 269 | // Check if PHP_AUTH_USER is set and handle this case |
| 270 | if ($this->request->is_set('PHP_AUTH_USER', request_interface::SERVER)) |
| 271 | { |
| 272 | $php_auth_user = $this->request->server('PHP_AUTH_USER'); |
| 273 | |
| 274 | return ($php_auth_user === $user['username']) ? true : false; |
| 275 | } |
| 276 | |
| 277 | // PHP_AUTH_USER is not set. A valid session is now determined by the user type (anonymous/bot or not) |
| 278 | if ($user['user_type'] == USER_IGNORE) |
| 279 | { |
| 280 | return true; |
| 281 | } |
| 282 | |
| 283 | return false; |
| 284 | } |
| 285 | } |