These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | /*************************************************************************** |
||
3 | * for license information see LICENSE.md |
||
4 | * This class provides access to the login user data. Informations are |
||
5 | * stored in a cookie. |
||
6 | * Methods: |
||
7 | * verify() validate the login-session (automatically invoked) |
||
8 | * try_login() try to login with the given user/password |
||
9 | * logout() logout the user |
||
10 | * Properties: |
||
11 | * userid Integer 0 if no login, userid otherwise |
||
12 | * username String username or '' |
||
13 | * !! See also lib/login.class.php. !! |
||
14 | ***************************************************************************/ |
||
15 | |||
16 | use OcLegacy\Util\PasswordCrypt; |
||
17 | |||
18 | define('LOGIN_UNKNOWN_ERROR', -1); // unknown error occurred |
||
19 | define('LOGIN_OK', 0); // login succeeded |
||
20 | define('LOGIN_BADUSERPW', 1); // bad username or password |
||
21 | define('LOGIN_TOOMUCHLOGINS', 2); // too many logins in short time |
||
22 | define('LOGIN_USERNOTACTIVE', 3); // the userAccount locked |
||
23 | define('LOGIN_EMPTY_USERPASSWORD', 4); // given username/password was empty |
||
24 | define('LOGIN_LOGOUT_OK', 5); // logout was successful |
||
25 | |||
26 | // login times in seconds |
||
27 | define('LOGIN_TIME', 60 * 60); |
||
28 | define('LOGIN_TIME_PERMANENT', 90 * 24 * 60 * 60); |
||
29 | |||
30 | $login = new login(); |
||
31 | |||
32 | class login |
||
0 ignored issues
–
show
Comprehensibility
Best Practice
introduced
by
The type
login has been defined more than once; this definition is ignored, only the first definition in htdocs/lib/login.class.php (L28-213) is considered.
This check looks for classes that have been defined more than once. If you can, we would recommend to use standard object-oriented programming techniques. For example, to avoid multiple types, it might make sense to create a common interface, and then multiple, different implementations for that interface. This also has the side-effect of providing you with better IDE auto-completion, static analysis and also better OPCode caching from PHP.
Loading history...
|
|||
33 | { |
||
34 | /** |
||
35 | * @var int |
||
36 | */ |
||
37 | public $userid = 0; |
||
38 | /** |
||
39 | * @var mixed|string |
||
40 | */ |
||
41 | public $username = ''; |
||
42 | /** |
||
43 | * @var string |
||
44 | */ |
||
45 | public $lastlogin = ''; |
||
46 | /** |
||
47 | * @var bool |
||
48 | */ |
||
49 | public $permanent = false; |
||
50 | /** |
||
51 | * @var mixed|string |
||
52 | */ |
||
53 | public $sessionid = ''; |
||
54 | /** |
||
55 | * @var bool |
||
56 | */ |
||
57 | public $verified = false; |
||
58 | /** |
||
59 | * @var int |
||
60 | */ |
||
61 | public $admin = 0; |
||
62 | |||
63 | /** |
||
64 | * login constructor. |
||
65 | */ |
||
66 | View Code Duplication | public function __construct() |
|
67 | { |
||
68 | global $cookie; |
||
69 | |||
70 | // TODO good input evaluation |
||
71 | if ($cookie->is_set('userid') && $cookie->is_set('username')) { |
||
72 | $this->userid = (int) $cookie->get('userid'); |
||
73 | $this->username = $cookie->get('username'); |
||
74 | $this->permanent = (($cookie->get('permanent') + 0) == 1); |
||
75 | $this->lastlogin = $cookie->get('lastlogin'); |
||
76 | $this->sessionid = $cookie->get('sessionid'); |
||
77 | // $this->admin = $cookie->get('admin')+0; nonsense |
||
78 | $this->verified = false; |
||
79 | |||
80 | $this->verify(); |
||
81 | } else { |
||
82 | $this->pClear(); |
||
83 | } |
||
84 | } |
||
85 | |||
86 | View Code Duplication | public function pClear() |
|
87 | { |
||
88 | // set to no valid login |
||
89 | $this->userid = 0; |
||
90 | $this->username = ''; |
||
91 | $this->permanent = false; |
||
92 | $this->lastlogin = ''; |
||
93 | $this->sessionid = ''; |
||
94 | $this->admin = 0; |
||
95 | $this->verified = true; |
||
96 | |||
97 | $this->pStoreCookie(); |
||
98 | } |
||
99 | |||
100 | View Code Duplication | public function pStoreCookie() |
|
101 | { |
||
102 | global $cookie; |
||
103 | $cookie->set('userid', (int) $this->userid); |
||
104 | $cookie->set('username', $this->username); |
||
105 | $cookie->set('permanent', ($this->permanent === true ? 1 : 0)); |
||
106 | $cookie->set('lastlogin', $this->lastlogin); |
||
107 | $cookie->set('sessionid', $this->sessionid); |
||
108 | } |
||
109 | |||
110 | /** |
||
111 | */ |
||
112 | public function verify() |
||
113 | { |
||
114 | global $opt; |
||
115 | |||
116 | if ($this->verified == true) { |
||
117 | return; |
||
118 | } |
||
119 | |||
120 | if ($this->userid == 0) { |
||
121 | $this->pClear(); |
||
122 | |||
123 | return; |
||
124 | } |
||
125 | |||
126 | if ($this->checkLoginsCount() === false) { |
||
127 | $this->pClear(); |
||
128 | |||
129 | return; |
||
130 | } |
||
131 | |||
132 | $min_lastlogin = date('Y-m-d H:i:s', time() - LOGIN_TIME); |
||
133 | $min_lastlogin_permanent = date('Y-m-d H:i:s', time() - LOGIN_TIME_PERMANENT); |
||
134 | |||
135 | $rs = sqlf( |
||
136 | " |
||
137 | SELECT |
||
138 | `sys_sessions`.`last_login`, |
||
139 | `user`.`admin`, |
||
140 | `user`.`username` |
||
141 | FROM &db.`sys_sessions`, &db.`user` |
||
142 | WHERE `sys_sessions`.`user_id`=`user`.`user_id` |
||
143 | AND `user`.`is_active_flag`= 1 |
||
144 | AND `sys_sessions`.`uuid`='&1' |
||
145 | AND `sys_sessions`.`user_id`='&2' |
||
146 | AND |
||
147 | ( |
||
148 | (`sys_sessions`.`permanent`=1 |
||
149 | AND `sys_sessions`.`last_login`>'&3') |
||
150 | OR |
||
151 | (`sys_sessions`.`permanent`=0 AND `sys_sessions`.`last_login`>'&4') |
||
152 | )", |
||
153 | $this->sessionid, |
||
154 | $this->userid, |
||
155 | $min_lastlogin_permanent, |
||
156 | $min_lastlogin |
||
157 | ); |
||
158 | |||
159 | // sys_session.last_login controls the automatic logout of users at the OC website. |
||
160 | // user.last_login gives the overall last login date, including OKAPI logins. |
||
161 | |||
162 | if ($rUser = sql_fetch_assoc($rs)) { |
||
163 | View Code Duplication | if ((($this->permanent == true) && (strtotime($rUser['last_login']) + LOGIN_TIME_PERMANENT / 2 < time())) || |
|
164 | (($this->permanent == false) && (strtotime($rUser['last_login']) + LOGIN_TIME / 2 < time())) |
||
165 | ) { |
||
166 | sqlf( |
||
167 | "UPDATE `sys_sessions` SET `sys_sessions`.`last_login`=NOW() |
||
168 | WHERE `sys_sessions`.`uuid`='&1' AND `sys_sessions`.`user_id`='&2'", |
||
169 | $this->sessionid, |
||
170 | $this->userid |
||
171 | ); |
||
172 | $rUser['last_login'] = date('Y-m-d H:i:s'); |
||
173 | } |
||
174 | |||
175 | if (isset($opt['template']['locale'])) { |
||
176 | sqlf( |
||
177 | "UPDATE `user` SET `last_login`=NOW(), `language`='&2', `language_guessed`=0, `domain`='&3' |
||
178 | WHERE `user_id`='&1'", |
||
179 | $this->userid, |
||
180 | $opt['template']['locale'], |
||
181 | $opt['page']['domain'] |
||
182 | ); |
||
183 | } else { |
||
184 | sqlf("UPDATE `user` SET `last_login`=NOW() WHERE `user_id`='&1'", $this->userid); |
||
185 | } |
||
186 | |||
187 | $this->lastlogin = $rUser['last_login']; |
||
188 | $this->username = $rUser['username']; |
||
189 | $this->admin = $rUser['admin']; |
||
190 | $this->verified = true; |
||
191 | } else { |
||
192 | // prevent brute force |
||
193 | sql("INSERT INTO `sys_logins` (`remote_addr`, `success`) VALUES ('&1', 0)", $_SERVER['REMOTE_ADDR']); |
||
194 | |||
195 | $this->pClear(); |
||
196 | } |
||
197 | sql_free_result($rs); |
||
198 | |||
199 | $this->pStoreCookie(); |
||
200 | } |
||
201 | |||
202 | /** |
||
203 | * @param $user |
||
204 | * @param $password |
||
205 | * @param $permanent |
||
206 | * @return int |
||
207 | */ |
||
208 | public function try_login($user, $password, $permanent) |
||
209 | { |
||
210 | if ($password == '') { |
||
211 | return LOGIN_EMPTY_USERPASSWORD; |
||
212 | } |
||
213 | |||
214 | $encryptedPassword = PasswordCrypt::encryptPassword($password); |
||
215 | |||
216 | return $this->try_login_encrypted($user, $encryptedPassword, $permanent); |
||
217 | } |
||
218 | |||
219 | /** |
||
220 | * @return bool |
||
221 | */ |
||
222 | public function checkLoginsCount() |
||
223 | { |
||
224 | global $opt; |
||
225 | |||
226 | // cleanup old entries |
||
227 | // (execute only every 50 search calls) |
||
228 | View Code Duplication | if (mt_rand(1, 50) === 1) { |
|
229 | sqlf("DELETE FROM `sys_logins` WHERE `date_created`<'&1'", date('Y-m-d H:i:s', time() - 3600)); |
||
230 | } |
||
231 | |||
232 | // check the number of logins in the last hour ... |
||
233 | $loginAttemptsCount = sqlf_value( |
||
234 | " |
||
235 | SELECT COUNT(*) `count` |
||
236 | FROM `sys_logins` |
||
237 | WHERE `remote_addr`='&1' |
||
238 | AND `date_created`>'&2'", |
||
239 | 0, |
||
240 | $_SERVER['REMOTE_ADDR'], |
||
241 | date('Y-m-d H:i:s', time() - 3600) |
||
242 | ); |
||
243 | |||
244 | return !($loginAttemptsCount > $opt['page']['max_logins_per_hour']); |
||
245 | } |
||
246 | |||
247 | /** |
||
248 | * @param $user |
||
249 | * @param $encryptedPassword |
||
250 | * @param $permanent |
||
251 | * @return int |
||
252 | */ |
||
253 | public function try_login_encrypted($user, $encryptedPassword, $permanent) |
||
254 | { |
||
255 | $this->pClear(); |
||
256 | |||
257 | if ($user == '' || $encryptedPassword == '') { |
||
258 | return LOGIN_EMPTY_USERPASSWORD; |
||
259 | } |
||
260 | |||
261 | if ($this->checkLoginsCount() == false) { |
||
262 | return LOGIN_TOOMUCHLOGINS; |
||
263 | } |
||
264 | |||
265 | // delete old sessions |
||
266 | $min_lastlogin_permanent = date('Y-m-d H:i:s', time() - LOGIN_TIME_PERMANENT); |
||
267 | sqlf("DELETE FROM `sys_sessions` WHERE `last_login`<'&1'", $min_lastlogin_permanent); |
||
268 | |||
269 | // compare $user with email and username, if both matches use email |
||
270 | $rsUser = sqlf( |
||
271 | "SELECT `user_id`, `username`, 2 AS `prio`, `is_active_flag`, `permanent_login_flag`, `admin` |
||
272 | FROM `user` WHERE `username`='&1' AND `password`='&2' |
||
273 | UNION |
||
274 | SELECT `user_id`, `username`, 1 AS `prio`, `is_active_flag`, `permanent_login_flag`, `admin` |
||
275 | FROM `user`WHERE `email`='&1' AND `password`='&2' ORDER BY `prio` ASC LIMIT 1", |
||
276 | $user, |
||
277 | $encryptedPassword |
||
278 | ); |
||
279 | $rUser = sql_fetch_assoc($rsUser); |
||
280 | sql_free_result($rsUser); |
||
281 | |||
282 | if ($permanent == null) { |
||
283 | $permanent = ($rUser['permanent_login_flag'] == 1); |
||
284 | } |
||
285 | |||
286 | if ($rUser) { |
||
287 | // ok, there is a valid login |
||
288 | if ($rUser['is_active_flag'] != 0) { |
||
289 | // begin session |
||
290 | $uuid = self::create_sessionid(); |
||
291 | sqlf( |
||
292 | "INSERT INTO `sys_sessions` (`uuid`, `user_id`, `permanent`) |
||
293 | VALUES ('&1', '&2', '&3')", |
||
294 | $uuid, |
||
295 | $rUser['user_id'], |
||
296 | ($permanent != false ? 1 : 0) |
||
297 | ); |
||
298 | $this->userid = (int) $rUser['user_id']; |
||
299 | $this->username = $rUser['username']; |
||
300 | $this->permanent = $permanent; |
||
301 | $this->lastlogin = date('Y-m-d H:i:s'); |
||
302 | $this->sessionid = $uuid; |
||
303 | $this->admin = $rUser['admin']; |
||
304 | $this->verified = true; |
||
305 | |||
306 | $retval = LOGIN_OK; |
||
307 | } else { |
||
308 | $retval = LOGIN_USERNOTACTIVE; |
||
309 | } |
||
310 | } else { |
||
311 | // sorry, bad login |
||
312 | $retval = LOGIN_BADUSERPW; |
||
313 | } |
||
314 | |||
315 | sqlf( |
||
316 | "INSERT INTO `sys_logins` (`remote_addr`, `success`) VALUES ('&1', '&2')", |
||
317 | $_SERVER['REMOTE_ADDR'], |
||
318 | ($rUser === false ? 0 : 1) |
||
319 | ); |
||
320 | |||
321 | // store to cookie |
||
322 | $this->pStoreCookie(); |
||
323 | |||
324 | return $retval; |
||
325 | } |
||
326 | |||
327 | /** |
||
328 | * login for cronjobs, command line tools ... |
||
329 | * |
||
330 | * @param $username |
||
331 | * @return bool |
||
332 | */ |
||
333 | public function system_login($username) |
||
334 | { |
||
335 | $this->pClear(); |
||
336 | if ($username != '') { |
||
337 | $rs = sql( |
||
338 | "SELECT `user_id`,`username`,`admin` FROM `user` |
||
339 | WHERE `username`='&1' AND `is_active_flag`", |
||
340 | $username |
||
341 | ); |
||
342 | if ($rUser = sql_fetch_assoc($rs)) { |
||
343 | $this->username = $rUser['username']; |
||
344 | $this->userid = (int) $rUser['user_id']; |
||
345 | $this->admin = $rUser['admin']; |
||
346 | $this->verified = true; |
||
347 | sqlf("UPDATE `user` SET `user`.`last_login`=NOW() WHERE `user`.`user_id`='&1'", $this->userid); |
||
348 | } |
||
349 | sql_free_result($rs); |
||
350 | } |
||
351 | |||
352 | return ($this->userid > 0); |
||
353 | } |
||
354 | |||
355 | /** |
||
356 | * @return string |
||
357 | */ |
||
358 | private static function create_sessionid() |
||
359 | { |
||
360 | return sprintf( |
||
361 | '%04x%04x-%04x-%04x-%04x-%04x%04x%04x', |
||
362 | mt_rand(0, 0xffff), |
||
363 | mt_rand(0, 0xffff), |
||
364 | mt_rand(0, 0xffff), |
||
365 | mt_rand(0, 0xffff), |
||
366 | mt_rand(0, 0xffff), |
||
367 | mt_rand(0, 0xffff), |
||
368 | mt_rand(0, 0xffff), |
||
369 | mt_rand(0, 0xffff) |
||
370 | ); |
||
371 | } |
||
372 | |||
373 | /** |
||
374 | * @return mixed|string |
||
375 | */ |
||
376 | public function getUserCountry() |
||
377 | { |
||
378 | global $opt, $cookie; |
||
379 | |||
380 | // language specified in cookie? |
||
381 | View Code Duplication | if ($cookie->is_set('usercountry')) { |
|
382 | $sCountry = $cookie->get('usercountry', null); |
||
383 | if ($sCountry != null) { |
||
384 | return $sCountry; |
||
385 | } |
||
386 | } |
||
387 | |||
388 | |||
389 | |||
390 | // user specified a country? |
||
391 | if ($this->userid != 0) { |
||
392 | $sCountry = sql_value("SELECT `country` FROM `user` WHERE `user_id`='&1'", null, $this->userid); |
||
393 | if ($sCountry != null) { |
||
394 | return $sCountry; |
||
395 | } |
||
396 | } |
||
397 | |||
398 | // default country of this language |
||
399 | // |
||
400 | // disabled: produces unexpected results on multi-domains without translation, |
||
401 | // and will confusingly switch country when switching language -- following 3.9.2015 |
||
402 | // |
||
403 | // if (isset($opt['locale'][$opt['template']['locale']]['country'])) |
||
404 | // return $opt['locale'][$opt['template']['locale']]['country']; |
||
405 | |||
406 | // default country of installation (or domain) |
||
407 | return $opt['template']['default']['country']; |
||
408 | } |
||
409 | |||
410 | public function logout() |
||
411 | { |
||
412 | if ($this->userid != 0) { |
||
413 | sqlf("DELETE FROM `sys_sessions` WHERE `uuid`='&1' AND `user_id`='&2'", $this->sessionid, $this->userid); |
||
414 | } |
||
415 | |||
416 | $this->pClear(); |
||
417 | } |
||
418 | |||
419 | /** |
||
420 | * @param int|bool $privilege |
||
421 | * @return bool |
||
422 | */ |
||
423 | View Code Duplication | public function hasAdminPriv($privilege = false) |
|
424 | { |
||
425 | if ($privilege === false) { |
||
426 | return $this->admin != 0; |
||
427 | } |
||
428 | |||
429 | return ($this->admin & $privilege) == $privilege; |
||
430 | } |
||
431 | |||
432 | /** |
||
433 | * @return bool |
||
434 | */ |
||
435 | public function listingAdmin() |
||
436 | { |
||
437 | global $opt; |
||
438 | |||
439 | return $this->hasAdminPriv(ADMIN_LISTING) && $opt['logic']['admin']['enable_listing_admins']; |
||
440 | } |
||
441 | |||
442 | /** |
||
443 | * @return bool |
||
444 | */ |
||
445 | public function logged_in() |
||
446 | { |
||
447 | return $this->userid > 0; |
||
448 | } |
||
449 | } |
||
450 |
You can fix this by adding a namespace to your class:
When choosing a vendor namespace, try to pick something that is not too generic to avoid conflicts with other libraries.