Issues (1369)

classes/auth_local.php (11 issues)

1
<?php
2
3
use DBAL\db_mysql;
4
5
/**
6
 * Class auth_local
7
 */
8
// Расширяет Modules\sn_module, потому что его потомки так же являются модулями
9
class auth_local extends auth_abstract {
10
  public $versionCommitted = '#46a151#';
11
12
  public $manifest = [
13
    'package'   => 'auth',
14
    'name'      => 'local',
15
    'version'   => '0a0',
16
    'copyright' => 'Project "SuperNova.WS" #46a151# copyright © 2009-2015 Gorlum',
17
18
    self::M_LOAD_ORDER => MODULE_LOAD_ORDER_AUTH_LOCAL,
19
20
    'config_path' => SN_ROOT_PHYSICAL,
21
  ];
22
23
  public $provider_id = ACCOUNT_PROVIDER_LOCAL;
24
25
  /**
26
   * Флаг входа в игру
27
   *
28
   * @var bool
29
   */
30
  protected $is_login = false;
31
  /**
32
   * Флаг регистрации
33
   *
34
   * @var bool
35
   */
36
  protected $is_register = false;
37
  /**
38
   * Флаг запроса кода на сброс пароля
39
   *
40
   * @var bool
41
   */
42
  protected $is_password_reset = false;
43
  /**
44
   * Флаг запроса на сброс пароля по коду
45
   *
46
   * @var bool
47
   */
48
  protected $is_password_reset_confirm = false;
49
  /**
50
   * Нужно ли запоминать креденшиался при выходе из браузера
51
   *
52
   * @var bool
53
   */
54
  protected $remember_me = 1;
55
56
  /**
57
   * @var Confirmation
58
   */
59
  protected $confirmation = null;
60
61
62
  protected $features = array(
63
    AUTH_FEATURE_EMAIL_CHANGE    => AUTH_FEATURE_EMAIL_CHANGE,
64
    AUTH_FEATURE_PASSWORD_RESET  => AUTH_FEATURE_PASSWORD_RESET,
65
    AUTH_FEATURE_PASSWORD_CHANGE => AUTH_FEATURE_PASSWORD_CHANGE,
66
    AUTH_FEATURE_HAS_PASSWORD    => AUTH_FEATURE_HAS_PASSWORD,
67
  );
68
69
  /**
70
   * @var string $input_login_unsafe
71
   */
72
  protected $input_login_unsafe = '';
73
  protected $input_login_password_raw = '';
74
  protected $input_login_password_raw_repeat = '';
75
  protected $input_email_unsafe = '';
76
  protected $input_language_unsafe = '';
77
  protected $input_language_safe = '';
78
79
  protected $domain = null;
80
  protected $sn_root_path = SN_ROOT_RELATIVE;
81
  protected $cookie_name = SN_COOKIE;
82
  protected $cookie_name_impersonate = SN_COOKIE_I;
83
  protected $secret_word = '';
84
85
  /**
86
   * @param string $filename
87
   */
88
  public function __construct($filename = __FILE__) {
89
    parent::__construct($filename);
90
91
    $this->prepare();
92
93
    $this->active = false;
94
    if (!empty($this->config) && is_array($this->config['db'])) {
95
      // БД, отличная от стандартной
96
      $this->db = new db_mysql();
97
98
      $this->db->sn_db_connect($this->config['db']);
99
      if ($this->active = $this->db->connected) {
100
        $this->provider_id = ACCOUNT_PROVIDER_CENTRAL;
101
102
        $this->domain       = $this->config['domain'];
103
        $this->sn_root_path = $this->config['sn_root_path'];
104
        $this->cookie_name  = $this->config['cookie_name'];
105
        $this->secret_word  = $this->config['secretword'];
106
        // TODO Проверить наличие всех нужных таблиц
107
      } else {
108
        unset($this->db);
109
      }
110
    }
111
112
    // Fallback to local DB
113
    if (!$this->active) {
114
      $this->db = SN::$db;
115
116
      $this->provider_id = ACCOUNT_PROVIDER_LOCAL;
117
118
      $this->domain       = null;
119
      $this->sn_root_path = SN_ROOT_RELATIVE;
120
      $this->cookie_name  = SN_COOKIE;
121
      $this->secret_word  = SN::$sn_secret_word;
122
123
      $this->active = true;
124
    }
125
126
    $this->cookie_name_impersonate = $this->cookie_name . AUTH_COOKIE_IMPERSONATE_SUFFIX;
127
128
    $this->account      = new Account($this->db);
129
    $this->confirmation = new Confirmation($this->db);
130
  }
131
132
  /**
133
   * Попытка залогиниться с использованием метода $method
134
   *
135
   * @param string $method_name
136
   *
137
   * @version 4.5
138
   *
139
   */
140
  public function login() {
141
    // TODO Проверяем поддерживаемость метода
142
    // TODO Пытаемся залогиниться
143
    $this->password_reset_send_code();
144
    $this->password_reset_confirm();
145
    $this->register();
146
    $this->login_username();
147
    $this->login_cookie();
148
149
    // $this->is_impersonating = $this->account_login_status == LOGIN_SUCCESS && !empty($_COOKIE[$this->cookie_name_impersonate]);
150
151
    return $this->account_login_status;
152
  }
153
154
  public function logout() {
155
    $this->cookie_clear();
156
  }
157
158
  /**
159
   * Меняет пароль у аккаунта с проверкой старого пароля
160
   *
161
   * @param      $old_password_unsafe
162
   * @param      $new_password_unsafe
163
   * @param null $salt_unsafe
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $salt_unsafe is correct as it would always require null to be passed?
Loading history...
164
   *
165
   * @return array|bool|resource
166
   * @throws Exception
167
   */
168
  public function password_change($old_password_unsafe, $new_password_unsafe, $salt_unsafe = null) {
169
    $result = parent::password_change($old_password_unsafe, $new_password_unsafe, $salt_unsafe);
170
    if ($result) {
171
      $this->cookie_set();
172
    }
173
174
    return $result;
175
  }
176
177
  public function impersonate($account_to_impersonate) {
178
    $this->cookie_set($account_to_impersonate);
179
  }
180
181
  /**
182
   * @param Account $account
183
   */
184
  public function login_with_account($account) {
185
    $this->account = $account;
186
    $this->cookie_set();
187
188
    return $this->login_cookie();
189
  }
190
191
192
  /**
193
   * Отсылает письмо с кодом подтверждения для сброса пароля
194
   *
195
   * @return int|string
196
   */
197
  protected function password_reset_send_code() {
198
    global $lang, $config;
199
200
    if (!$this->is_password_reset) {
201
      return $this->account_login_status;
202
    }
203
204
    // Проверяем поддержку сброса пароля
205
    if (!$this->is_feature_supported(AUTH_FEATURE_PASSWORD_RESET)) {
206
      return $this->account_login_status;
207
    }
208
209
    try {
210
      $email_unsafe = $this->input_email_unsafe;
211
212
      unset($this->account);
213
      $this->account = new Account($this->db);
214
215
      if (!$this->account->db_get_by_email($email_unsafe)) {
216
        throw new Exception(PASSWORD_RESTORE_ERROR_EMAIL_NOT_EXISTS, ERR_ERROR);
217
        // return $this->account_login_status;
218
      }
219
220
      $account_translation = PlayerToAccountTranslate::db_translate_get_users_from_account_list($this->provider_id, $this->account->account_id); // OK 4.5
221
      $user_list           = db_user_list_by_id(array_keys($account_translation));
222
223
      // TODO - Проверять уровень доступа аккаунта!
224
      // Аккаунты с АУТЛЕВЕЛ больше 0 - НЕ СБРАСЫВАЮТ ПАРОЛИ!
225
      foreach ($user_list as $user_id => $user_data) {
226
        if ($user_data['authlevel'] > AUTH_LEVEL_REGISTERED) {
227
          throw new Exception(PASSWORD_RESTORE_ERROR_ADMIN_ACCOUNT, ERR_ERROR);
228
        }
229
      }
230
231
      $confirmation = $this->confirmation->db_confirmation_get_latest_by_type_and_email(CONFIRM_PASSWORD_RESET, $email_unsafe); // OK 4.5
232
      if (isset($confirmation['create_time']) && SN_TIME_NOW - strtotime($confirmation['create_time']) < PERIOD_MINUTE_10) {
233
        throw new Exception(PASSWORD_RESTORE_ERROR_TOO_OFTEN, ERR_ERROR);
234
      }
235
236
      // Удаляем предыдущие записи продтверждения сброса пароля
237
      !empty($confirmation['id']) or $this->confirmation->db_confirmation_delete_by_type_and_email(CONFIRM_PASSWORD_RESET, $email_unsafe); // OK 4.5
238
239
      db_mysql::db_transaction_start();
240
      $confirm_code_unsafe = $this->confirmation->db_confirmation_get_unique_code_by_type_and_email(CONFIRM_PASSWORD_RESET, $email_unsafe); // OK 4.5
241
      db_mysql::db_transaction_commit();
242
243
      if (!is_email($email_unsafe)) {
244
        SN::$debug->error("Email is invalid: '{$email_unsafe}'", 'Invalid email for password restoration');
245
      }
246
247
      @$result = mymail($email_unsafe,
248
        sprintf($lang['log_lost_email_title'], $config->game_name),
249
        sprintf($lang['log_lost_email_code'], SN_ROOT_VIRTUAL . 'login.php', $confirm_code_unsafe, date(FMT_DATE_TIME, SN_TIME_NOW + AUTH_PASSWORD_RESET_CONFIRMATION_EXPIRE), $config->game_name)
250
      );
251
252
      $result = $result ? PASSWORD_RESTORE_SUCCESS_CODE_SENT : PASSWORD_RESTORE_ERROR_SENDING;
253
    } catch (Exception $e) {
254
      db_mysql::db_transaction_rollback();
255
      $result = $e->getMessage();
256
    }
257
258
    return $this->account_login_status = $result;
0 ignored issues
show
Documentation Bug introduced by
The property $account_login_status was declared of type integer, but $result is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
259
  }
260
261
  /**
262
   * Сброс пароля по введенному коду подтверждения
263
   *
264
   * @return int|string
265
   */
266
  protected function password_reset_confirm() {
267
    global $lang, $config;
268
269
    if (!$this->is_password_reset_confirm) {
270
      return $this->account_login_status;
271
    }
272
273
    if ($this->account_login_status != LOGIN_UNDEFINED) {
274
      return $this->account_login_status;
275
    }
276
277
    // Проверяем поддержку сброса пароля
278
    if (!$this->is_feature_supported(AUTH_FEATURE_PASSWORD_RESET)) {
279
      return $this->account_login_status;
280
    }
281
282
    try {
283
      $code_unsafe = sys_get_param_str_unsafe('password_reset_code');
284
      if (empty($code_unsafe)) {
285
        throw new Exception(PASSWORD_RESTORE_ERROR_CODE_EMPTY, ERR_ERROR);
286
      }
287
288
      db_mysql::db_transaction_start();
289
      $confirmation = $this->confirmation->db_confirmation_get_by_type_and_code(CONFIRM_PASSWORD_RESET, $code_unsafe); // OK 4.5
290
291
      if (empty($confirmation)) {
292
        throw new Exception(PASSWORD_RESTORE_ERROR_CODE_WRONG, ERR_ERROR);
293
      }
294
295
      if (SN_TIME_NOW - strtotime($confirmation['create_time']) > AUTH_PASSWORD_RESET_CONFIRMATION_EXPIRE) {
296
        throw new Exception(PASSWORD_RESTORE_ERROR_CODE_TOO_OLD, ERR_ERROR);
297
      }
298
299
      unset($this->account);
300
      $this->account = new Account($this->db);
301
302
      if (!$this->account->db_get_by_email($confirmation['email'])) {
303
        throw new Exception(PASSWORD_RESTORE_ERROR_CODE_OK_BUT_NO_ACCOUNT_FOR_EMAIL, ERR_ERROR);
304
      }
305
306
      $new_password_unsafe = $this->make_random_password();
307
      $salt_unsafe         = $this->password_salt_generate();
308
      if (!$this->account->db_set_password($new_password_unsafe, $salt_unsafe)) {
309
        // Ошибка смены пароля
310
        throw new Exception(AUTH_ERROR_INTERNAL_PASSWORD_CHANGE_ON_RESTORE, ERR_ERROR);
311
      }
312
313
      $this->account_login_status = LOGIN_UNDEFINED;
314
      $this->remember_me          = 1;
315
      $this->cookie_set();
316
      $this->login_cookie();
317
318
      if ($this->account_login_status == LOGIN_SUCCESS) {
319
        // TODO - НЕ ОБЯЗАТЕЛЬНО ОТПРАВЛЯТЬ ЧЕРЕЗ ЕМЕЙЛ! ЕСЛИ ЭТО ФЕЙСБУЧЕК ИЛИ ВКШЕЧКА - МОЖНО ЧЕРЕЗ ЛС ПИСАТЬ!!
320
        $message_header = sprintf($lang['log_lost_email_title'], $config->game_name);
321
        $message        = sprintf($lang['log_lost_email_pass'], $config->game_name, $this->account->account_name, $new_password_unsafe);
322
        @$operation_result = mymail($confirmation['email'], $message_header, htmlspecialchars($message));
0 ignored issues
show
The assignment to $operation_result is dead and can be removed.
Loading history...
323
324
        $users_translated = PlayerToAccountTranslate::db_translate_get_users_from_account_list($this->provider_id, $this->account->account_id); // OK 4.5
325
        if (!empty($users_translated)) {
326
          // Отправляем в лички письмо о сбросе пароля
327
328
          // ПО ОПРЕДЕЛЕНИЮ в $users_translated только
329
          //    - аккаунты, поддерживающие сброс пароля
330
          //    - список аккаунтов, имеющих тот же емейл, что указан в Подтверждении
331
          //    - игроки, привязанные только к этим аккаунтам
332
          // Значит им всем сразу скопом можно отправлять сообщения
333
          $message = sprintf($lang['sys_password_reset_message_body'], $new_password_unsafe);
334
          $message = HelperString::nl2br($message) . '<br><br>';
335
          // msg_send_simple_message($found_provider->data[F_USER_ID], 0, SN_TIME_NOW, MSG_TYPE_ADMIN, $lang['sys_administration'], $lang['sys_login_register_message_title'], $message);
336
337
          foreach ($users_translated as $user_id => $providers_list) {
338
            msg_send_simple_message($user_id, 0, SN_TIME_NOW, MSG_TYPE_ADMIN, $lang['sys_administration'], $lang['sys_login_register_message_title'], $message);
339
          }
340
        } else {
341
          // Фигня - может быть и пустой, если у нас есть только аккаунт, но нет пользователей
342
          // throw new Exception(AUTH_PASSWORD_RESET_INSIDE_ERROR_NO_ACCOUNT_FOR_CONFIRMATION, ERR_ERROR);
343
        }
344
      }
345
346
      $this->confirmation->db_confirmation_delete_by_type_and_email(CONFIRM_PASSWORD_RESET, $confirmation['email']); // OK 4.5
347
348
      db_mysql::db_transaction_commit();
349
350
      sys_redirect('overview.php');
351
    } catch (Exception $e) {
352
      db_mysql::db_transaction_rollback();
353
      $this->account_login_status = $e->getMessage();
0 ignored issues
show
Documentation Bug introduced by
The property $account_login_status was declared of type integer, but $e->getMessage() is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
354
    }
355
356
    return $this->account_login_status;
357
  }
358
359
  /**
360
   * Функция инициализирует данные провайдера - разворачивает куки, берет данные итд
361
   */
362
  protected function prepare() {
363
    $this->input_login_unsafe = sys_get_param_str_unsafe('username', sys_get_param_str_unsafe('email')); // TODO переделать эту порнографию
364
365
    $this->is_login                  = sys_get_param('login') ? true : false;
366
    $this->is_register               = sys_get_param('register') ? true : false;
367
    $this->is_password_reset         = sys_get_param('password_reset') ? true : false;
368
    $this->is_password_reset_confirm = sys_get_param('password_reset_confirm') ? true : false;
369
370
    $this->remember_me                     = intval(sys_get_param_int('rememberme') || $this->is_register);
0 ignored issues
show
Documentation Bug introduced by
The property $remember_me was declared of type boolean, but intval(sys_get_param_int... || $this->is_register) is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
371
    $this->input_login_password_raw        = sys_get_param('password');
372
    $this->input_login_password_raw_repeat = sys_get_param('password_repeat');
373
    $this->input_email_unsafe              = sys_get_param_str_unsafe('email');
374
    $this->input_language_unsafe           = sys_get_param_str_unsafe('lang', DEFAULT_LANG);
375
    $this->input_language_safe             = sys_get_param_str('lang', DEFAULT_LANG);
376
377
  }
378
379
  /**
380
   * Пытается зарегестрировать пользователя по введенным данным
381
   * @return mixed
382
   * @version 4.5
383
   *
384
   */
385
  protected function register() {
386
    // TODO РЕГИСТРАЦИЯ ВСЕГДА ДОЛЖНА ЛОГИНИТЬ ПОЛЬЗОВАТЕЛЯ!
387
    $this->flog('Регистрация: начинаем. Провайдер ' . $this->provider_id);
388
389
    if (!$this->is_register) {
390
      $this->flog('Регистрация: не выставлен флаг регистрации - пропускаем');
391
    } else {
392
      try {
393
394
        $this->register_validate_input();
395
396
        db_mysql::db_transaction_start();
397
        $this->account->db_get_by_name_or_email($this->input_login_unsafe, $this->input_email_unsafe);
398
        if ($this->account->is_exists) {
399
          if ($this->account->account_email == $this->input_email_unsafe) {
400
            throw new Exception(REGISTER_ERROR_EMAIL_EXISTS, ERR_ERROR);
401
          } else {
402
            throw new Exception(REGISTER_ERROR_ACCOUNT_NAME_EXISTS, ERR_ERROR);
403
          }
404
        }
405
406
        // Проблемы с созданием аккаунта - вызовут эксершн и обработается catch()
407
        $this->account->db_create(
408
          $this->input_login_unsafe,
409
          $this->input_login_password_raw,
410
          $this->input_email_unsafe,
411
          $this->input_language_unsafe
412
        );
413
414
        // Устанавливать не надо - мы дальше пойдем по workflow
415
        $this->account_login_status = LOGIN_SUCCESS;
416
        $this->cookie_set();
417
418
        // А вот это пока не нужно. Трансляцией аккаунтов в юзеров и созданием новых юзеров для новозашедших аккаунтов занимается Auth
419
        // $this->register_account();
420
        db_mysql::db_transaction_commit();
421
      } catch (Exception $e) {
422
        db_mysql::db_transaction_rollback();
423
        $this->account_login_status == LOGIN_UNDEFINED ? $this->account_login_status = $e->getMessage() : false;
0 ignored issues
show
Documentation Bug introduced by
The property $account_login_status was declared of type integer, but $e->getMessage() is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
424
      }
425
    }
426
427
    return $this->account_login_status;
428
  }
429
430
  /**
431
   * Пытается залогинить пользователя по куке
432
   * @return int Результат попытки
433
   * @version 4.5
434
   *
435
   */
436
  protected function login_cookie() {
437
    if ($this->account_login_status != LOGIN_UNDEFINED) {
438
      return $this->account_login_status;
439
    }
440
441
    if ($this->account->cookieLogin($rememberMe)) {
442
      $this->account_login_status = LOGIN_SUCCESS;
443
      $this->remember_me          = intval($rememberMe);
0 ignored issues
show
Documentation Bug introduced by
The property $remember_me was declared of type boolean, but intval($rememberMe) is of type integer. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
444
    }
445
446
    return $this->account_login_status;
447
  }
448
449
  /**
450
   * Пытается залогинить пользователя по имени аккаунта и паролю
451
   * @return mixed
452
   * @version 4.5
453
   *
454
   */
455
  protected function login_username() {
456
    // TODO - Логин по старым именам
457
    try {
458
      if (!$this->is_login) {
459
        $this->flog('Логин: не выставлен флаг входа в игру - это не логин');
460
        throw new Exception(LOGIN_UNDEFINED, ERR_ERROR);
461
      }
462
463
      // TODO Пустое имя аккаунта
464
      if (!$this->input_login_unsafe) {
465
        throw new Exception(LOGIN_UNDEFINED, ERR_ERROR);
466
      }
467
468
      $this->login_validate_input();
469
470
      if (!$this->account->db_get_by_name($this->input_login_unsafe) && !$this->account->db_get_by_email($this->input_login_unsafe)) {
471
        throw new Exception(LOGIN_ERROR_USERNAME, ERR_ERROR);
472
      }
473
474
      if (!$this->account->password_check($this->input_login_password_raw)) {
475
        throw new Exception(LOGIN_ERROR_PASSWORD, ERR_ERROR);
476
      }
477
478
      $this->cookie_set();
479
      $this->account_login_status = LOGIN_SUCCESS;
480
    } catch (Exception $e) {
481
      $this->account_login_status == LOGIN_UNDEFINED ? $this->account_login_status = $e->getMessage() : false;
0 ignored issues
show
Documentation Bug introduced by
The property $account_login_status was declared of type integer, but $e->getMessage() is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
482
    }
483
484
    return $this->account_login_status;
485
  }
486
487
  /**
488
   * Устанавливает куку аккаунта по данным $this->data[F_ACCOUNT]
489
   *
490
   * @param Account|null $account_to_impersonate
491
   *
492
   * @return bool
493
   * @throws Exception
494
   *
495
   */
496
  // TODO - должен устанавливать куку исходя из пользователя, что бы пользователь мог логинится
497
  // TODO - или ставить мультикуку - хотя нахуя, спрашивается
498
  protected function cookie_set($account_to_impersonate = null) {
499
    $this_account = is_object($account_to_impersonate) ? $account_to_impersonate : $this->account;
500
501
    if (!is_object($this_account) || !$this_account->is_exists) {
502
      throw new Exception(LOGIN_ERROR_NO_ACCOUNT_FOR_COOKIE_SET, ERR_ERROR);
503
    }
504
505
    if (is_object($account_to_impersonate) && $account_to_impersonate->is_exists) {
506
      sn_setcookie($this->cookie_name_impersonate, $_COOKIE[$this->cookie_name], SN_TIME_NOW + PERIOD_YEAR, $this->sn_root_path, $this->domain);
507
    }
508
509
    $this->flog("cookie_set() - Устанавливаем куку");
510
511
    return $this_account->cookieSet($this->remember_me, $this->domain);
512
  }
513
514
  /**
515
   * Очищает куку аккаунта - совсем или восстанавливая куку текущего имперсонатора
516
   */
517
  protected function cookie_clear() {
518
    $this->account->cookieClear($this->domain);
519
  }
520
521
522
  // ХЕЛПЕРЫ ===========================================================================================================
523
524
  /**
525
   * Проверяет введенные данные логина на корректность
526
   *
527
   * @throws Exception
528
   */
529
  protected function login_validate_input() {
530
    // Проверяем, что бы в начале и конце не было пустых символов
531
    // TODO - при копировании Эксель -> Опера - в конце образуются пустые места. Это не должно быть проблемой! Вынести проверку пароля в регистрацию!
532
    if ($this->input_login_password_raw != trim($this->input_login_password_raw)) {
533
      throw new Exception(LOGIN_ERROR_PASSWORD_TRIMMED, ERR_ERROR);
534
    }
535
    if (!$this->input_login_password_raw) {
536
      throw new Exception(LOGIN_ERROR_PASSWORD_EMPTY, ERR_ERROR);
537
    }
538
  }
539
540
  /**
541
   * Проверяет данные для регистрации на корректность
542
   *
543
   * @throws Exception
544
   */
545
  protected function register_validate_input() {
546
    // То, что не подходит для логина - не подходит и для регистрации
547
    $this->login_validate_input();
548
549
    // Если нет имени пользователя - NO GO!
550
    if (!$this->input_login_unsafe) {
551
      throw new Exception(LOGIN_ERROR_USERNAME_EMPTY, ERR_ERROR);
552
    }
553
    // Если логин имеет запрещенные символы - NO GO!
554
    if (strpbrk($this->input_login_unsafe, LOGIN_REGISTER_CHARACTERS_PROHIBITED)) {
555
      throw new Exception(LOGIN_ERROR_USERNAME_RESTRICTED_CHARACTERS, ERR_ERROR);
556
    }
557
    // Если логин меньше минимальной длины - NO GO!
558
    if (strlen($this->input_login_unsafe) < LOGIN_LENGTH_MIN) {
559
      throw new Exception(REGISTER_ERROR_USERNAME_SHORT, ERR_ERROR);
560
    }
561
    // Если пароль меньше минимальной длины - NO GO!
562
    if (strlen($this->input_login_password_raw) < PASSWORD_LENGTH_MIN) {
563
      throw new Exception(REGISTER_ERROR_PASSWORD_INSECURE, ERR_ERROR);
564
    }
565
    // Если пароль имеет пробельные символы в начале или конце - NO GO!
566
    if ($this->input_login_password_raw != trim($this->input_login_password_raw)) {
567
      throw new Exception(LOGIN_ERROR_PASSWORD_TRIMMED, ERR_ERROR);
568
    }
569
    // Если пароль не совпадает с подтверждением - NO GO! То, что у пароля нет пробельных символов в начале/конце - мы уже проверили выше
570
    //Если они есть у повтора - значит пароль и повтор не совпадут
571
    if ($this->input_login_password_raw <> $this->input_login_password_raw_repeat) {
572
      throw new Exception(REGISTER_ERROR_PASSWORD_DIFFERENT, ERR_ERROR);
573
    }
574
    // Если нет емейла - NO GO!
575
    // TODO - регистрация без емейла
576
    if (!$this->input_email_unsafe) {
577
      throw new Exception(REGISTER_ERROR_EMAIL_EMPTY, ERR_ERROR);
578
    }
579
    // Если емейл не является емейлом - NO GO!
580
    if (!is_email($this->input_email_unsafe)) {
581
      throw new Exception(REGISTER_ERROR_EMAIL_WRONG, ERR_ERROR);
582
    }
583
  }
584
585
586
  protected function password_encode($password, $salt) {
587
    return core_auth::password_encode($password, $salt);
588
  }
589
590
  protected function password_salt_generate() {
591
    return core_auth::password_salt_generate();
592
  }
593
594
  /**
595
   * Генерирует случайный пароль
596
   *
597
   * @return string
598
   */
599
  protected function make_random_password() {
600
    return core_auth::make_random_password();
601
  }
602
603
  protected function flog($message, $die = false) {
604
    if (!defined('DEBUG_AUTH') || !DEBUG_AUTH) {
0 ignored issues
show
The constant DEBUG_AUTH was not found. Maybe you did not declare it correctly or list all dependencies?
Loading history...
605
      return;
606
    }
607
    list($called, $caller) = debug_backtrace(false);
0 ignored issues
show
false of type false is incompatible with the type integer expected by parameter $options of debug_backtrace(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

607
    list($called, $caller) = debug_backtrace(/** @scrutinizer ignore-type */ false);
Loading history...
608
609
    $caller_name =
610
      ((get_called_class()) ? get_called_class() : (!empty($caller['class']) ? $caller['class'] : '')) .
611
      (!empty($caller['type']) ? $caller['type'] : '') .
612
      (!empty($caller['function']) ? $caller['function'] : '') .
613
      (!empty($called['line']) ? ':' . $called['line'] : '');
614
615
    $_SERVER['SERVER_NAME'] == 'localhost' ? print("<div class='debug'>$message - $caller_name\r\n</div>") : false;
616
617
    SN::log_file("$message - $caller_name");
618
    if ($die) {
619
      $die && die("<div class='negative'>СТОП! Функция {$caller_name} при вызове в " . get_called_class() . " (располагается в " . get_class() . "). СООБЩИТЕ АДМИНИСТРАЦИИ!</div>");
0 ignored issues
show
Using exit here is not recommended.

In general, usage of exit should be done with care and only when running in a scripting context like a CLI script.

Loading history...
620
    }
621
  }
622
623
}
624