Completed
Push — work-fleets ( 2bd11a...17dd3b )
by SuperNova.WS
06:36
created

includes/classes/auth_local.php (3 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
/**
4
 * Class auth_local
5
 */
6
// Расширяет sn_module, потому что его потомки так же являются модулями
7
class auth_local extends auth_abstract {
8
  public $manifest = array(
9
    'package' => 'auth',
10
    'name' => 'local',
11
    'version' => '0a0',
12
    'copyright' => 'Project "SuperNova.WS" #41a50.104# copyright © 2009-2015 Gorlum',
13
14
    'root_relative' => '',
15
16
    'load_order' => 2,
17
18
    'installed' => true,
19
    'active' => true,
20
21
    'config_path' => SN_ROOT_PHYSICAL,
22
  );
23
24
  public $provider_id = ACCOUNT_PROVIDER_LOCAL;
25
26
  /**
27
   * Флаг входа в игру
28
   *
29
   * @var bool
30
   */
31
  protected $is_login = false;
32
  /**
33
   * Флаг регистрации
34
   *
35
   * @var bool
36
   */
37
  protected $is_register = false;
38
  /**
39
   * Флаг запроса кода на сброс пароля
40
   *
41
   * @var bool
42
   */
43
  protected $is_password_reset = false;
44
  /**
45
   * Флаг запроса на сброс пароля по коду
46
   *
47
   * @var bool
48
   */
49
  protected $is_password_reset_confirm = false;
50
  /**
51
   * Нужно ли запоминать креденшиался при выходе из браузера
52
   *
53
   * @var bool
54
   */
55
  protected $remember_me = 1;
56
57
  /**
58
   * @var Confirmation
59
   */
60
  protected $confirmation = null;
61
62
63
  protected $features = array(
64
    AUTH_FEATURE_EMAIL_CHANGE => AUTH_FEATURE_EMAIL_CHANGE,
65
    AUTH_FEATURE_PASSWORD_RESET => AUTH_FEATURE_PASSWORD_RESET,
66
    AUTH_FEATURE_PASSWORD_CHANGE => AUTH_FEATURE_PASSWORD_CHANGE,
67
    AUTH_FEATURE_HAS_PASSWORD => AUTH_FEATURE_HAS_PASSWORD,
68
  );
69
70
  /**
71
   * @var string $input_login_unsafe
72
   */
73
  protected $input_login_unsafe = '';
74
  protected $input_login_password_raw = '';
75
  protected $input_login_password_raw_repeat = '';
76
  protected $input_email_unsafe = '';
77
  protected $input_language_unsafe = '';
78
  protected $input_language_safe = '';
79
80
  protected $domain = null;
81
  protected $sn_root_path = null;
82
  protected $cookie_name = SN_COOKIE;
83
  protected $cookie_name_impersonate = SN_COOKIE_I;
84
  protected $secret_word = '';
85
86
  /**
87
   * @param string $filename
88
   */
89
  // OK v4.5
90
  public function __construct($filename = __FILE__) {
91
    parent::__construct($filename);
92
93
    $this->prepare();
94
95
    $this->manifest['active'] = false;
96
    if(!empty($this->config) && is_array($this->config['db'])) {
97
      // БД, отличная от стандартной
98
      $this->db = new db_mysql();
0 ignored issues
show
The call to db_mysql::__construct() misses a required argument $gc.

This check looks for function calls that miss required arguments.

Loading history...
99
100
      $this->db->sn_db_connect($this->config['db']);
101
      if($this->manifest['active'] = $this->db->connected) {
102
        $this->provider_id = ACCOUNT_PROVIDER_CENTRAL;
103
104
        $this->domain = $this->config['domain'];
105
        $this->sn_root_path = $this->config['sn_root_path'];
106
        $this->cookie_name = $this->config['cookie_name'];
107
        $this->secret_word = $this->config['secretword'];
108
        // TODO Проверить наличие всех нужных таблиц
109
      } else {
110
        unset($this->db);
111
      }
112
    }
113
114
    // Fallback to local DB
115
    if(!$this->manifest['active']) {
116
      $this->db = classSupernova::$db;
117
118
      $this->provider_id = ACCOUNT_PROVIDER_LOCAL;
119
120
      $this->domain = null;
121
      $this->sn_root_path = SN_ROOT_RELATIVE;
122
      $this->cookie_name = SN_COOKIE;
123
      $this->secret_word = classSupernova::$sn_secret_word;
124
125
      $this->manifest['active'] = true;
126
    }
127
128
    $this->cookie_name_impersonate = $this->cookie_name . AUTH_COOKIE_IMPERSONATE_SUFFIX;
129
130
    $this->account = new Account($this->db);
131
    $this->confirmation = new Confirmation($this->db);
132
  }
133
134
  /**
135
   * Попытка залогиниться с использованием метода $method
136
   *
137
   * @param string $method_name
0 ignored issues
show
There is no parameter named $method_name. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
138
   */
139
  public function login() {
140
    // TODO Проверяем поддерживаемость метода
141
    // TODO Пытаемся залогиниться
142
    $this->password_reset_send_code();
143
    $this->password_reset_confirm();
144
    $this->register();
145
    $this->login_username();
146
    $this->login_cookie();
147
148
    return $this->account_login_status;
149
  }
150
151
  public function logout() {
152
    $this->cookie_clear();
153
  }
154
155
  /**
156
   * Меняет пароль у аккаунта с проверкой старого пароля
157
   *
158
   * @param      $old_password_unsafe
159
   * @param      $new_password_unsafe
160
   * @param null $salt_unsafe
161
   *
162
   * @return array|bool|resource
163
   */
164
  // OK v4.5
165
  public function password_change($old_password_unsafe, $new_password_unsafe, $salt_unsafe = null) {
166
    $result = parent::password_change($old_password_unsafe, $new_password_unsafe, $salt_unsafe);
167
    if($result) {
168
      $this->cookie_set();
169
    }
170
171
    return $result;
172
  }
173
174
  public function impersonate($account_to_impersonate) {
175
    $this->cookie_set($account_to_impersonate);
176
  }
177
178
  /**
179
   * @param Account $account
180
   */
181
  public function login_with_account($account) {
182
    $this->account = $account;
183
    $this->cookie_set();
184
    return $this->login_cookie();
185
  }
186
187
188
  /**
189
   * Отсылает письмо с кодом подтверждения для сброса пароля
190
   *
191
   * @return int|string
192
   */
193
  // OK v4.6
194
  protected function password_reset_send_code() {
195
    if(!$this->is_password_reset) {
196
      return $this->account_login_status;
197
    }
198
199
    // Проверяем поддержку сброса пароля
200
    if(!$this->is_feature_supported(AUTH_FEATURE_PASSWORD_RESET)) {
201
      return $this->account_login_status;
202
    }
203
204
    try {
205
      $email_unsafe = $this->input_email_unsafe;
206
207
      unset($this->account);
208
      $this->account = new Account($this->db);
209
210
      if(!$this->account->db_get_by_email($email_unsafe)) {
211
        throw new Exception(PASSWORD_RESTORE_ERROR_EMAIL_NOT_EXISTS, ERR_ERROR);
212
        // return $this->account_login_status;
213
      }
214
215
      $account_translation = PlayerToAccountTranslate::db_translate_get_users_from_account_list($this->provider_id, $this->account->account_id); // OK 4.5
216
      $user_list = DBStaticUser::db_user_list_by_id(array_keys($account_translation));
217
218
      // TODO - Проверять уровень доступа аккаунта!
219
      // Аккаунты с АУТЛЕВЕЛ больше 0 - НЕ СБРАСЫВАЮТ ПАРОЛИ!
220
      foreach($user_list as $user_id => $user_data) {
221
        if($user_data['authlevel'] > AUTH_LEVEL_REGISTERED) {
222
          throw new Exception(PASSWORD_RESTORE_ERROR_ADMIN_ACCOUNT, ERR_ERROR);
223
        }
224
      }
225
226
      $confirmation = $this->confirmation->db_confirmation_get_latest_by_type_and_email(CONFIRM_PASSWORD_RESET, $email_unsafe); // OK 4.5
227
      if(isset($confirmation['create_time']) && SN_TIME_NOW - strtotime($confirmation['create_time']) < PERIOD_MINUTE_10) {
228
        throw new Exception(PASSWORD_RESTORE_ERROR_TOO_OFTEN, ERR_ERROR);
229
      }
230
231
      // Удаляем предыдущие записи продтверждения сброса пароля
232
      !empty($confirmation['id']) or $this->confirmation->db_confirmation_delete_by_type_and_email(CONFIRM_PASSWORD_RESET, $email_unsafe); // OK 4.5
233
234
      sn_db_transaction_start();
235
      $confirm_code_unsafe = $this->confirmation->db_confirmation_get_unique_code_by_type_and_email(CONFIRM_PASSWORD_RESET, $email_unsafe); // OK 4.5
236
      sn_db_transaction_commit();
237
238
      $result = mymail($email_unsafe,
239
        sprintf(classLocale::$lang['log_lost_email_title'], classSupernova::$config->game_name),
240
        sprintf(classLocale::$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), classSupernova::$config->game_name)
241
      );
242
243
      $result = $result ? PASSWORD_RESTORE_SUCCESS_CODE_SENT : PASSWORD_RESTORE_ERROR_SENDING;
244
    } catch(Exception $e) {
245
      sn_db_transaction_rollback();
246
      $result = $e->getMessage();
247
    }
248
249
    return $this->account_login_status = $result;
250
  }
251
  /**
252
   * Сброс пароля по введенному коду подтверждения
253
   *
254
   * @return int|string
255
   */
256
  protected function password_reset_confirm() {
257
    if(!$this->is_password_reset_confirm) {
258
      return $this->account_login_status;
259
    }
260
261
    if($this->account_login_status != LOGIN_UNDEFINED) {
262
      return $this->account_login_status;
263
    }
264
265
    // Проверяем поддержку сброса пароля
266
    if(!$this->is_feature_supported(AUTH_FEATURE_PASSWORD_RESET)) {
267
      return $this->account_login_status;
268
    }
269
270
    try {
271
      $code_unsafe = sys_get_param_str_unsafe('password_reset_code');
272
      if(empty($code_unsafe)) {
273
        throw new Exception(PASSWORD_RESTORE_ERROR_CODE_EMPTY, ERR_ERROR);
274
      }
275
276
      sn_db_transaction_start();
277
      $confirmation = $this->confirmation->db_confirmation_get_by_type_and_code(CONFIRM_PASSWORD_RESET, $code_unsafe); // OK 4.5
278
279
      if(empty($confirmation)) {
280
        throw new Exception(PASSWORD_RESTORE_ERROR_CODE_WRONG, ERR_ERROR);
281
      }
282
283
      if(SN_TIME_NOW - strtotime($confirmation['create_time']) > AUTH_PASSWORD_RESET_CONFIRMATION_EXPIRE) {
284
        throw new Exception(PASSWORD_RESTORE_ERROR_CODE_TOO_OLD, ERR_ERROR);
285
      }
286
287
      unset($this->account);
288
      $this->account = new Account($this->db);
289
290
      if(!$this->account->db_get_by_email($confirmation['email'])) {
291
        throw new Exception(PASSWORD_RESTORE_ERROR_CODE_OK_BUT_NO_ACCOUNT_FOR_EMAIL, ERR_ERROR);
292
      }
293
294
      $new_password_unsafe = $this->make_random_password();
295
      $salt_unsafe = $this->password_salt_generate();
296
      if(!$this->account->db_set_password($new_password_unsafe, $salt_unsafe)) {
297
        // Ошибка смены пароля
298
        throw new Exception(AUTH_ERROR_INTERNAL_PASSWORD_CHANGE_ON_RESTORE, ERR_ERROR);
299
      }
300
301
      $this->account_login_status = LOGIN_UNDEFINED;
302
      $this->remember_me = 1;
303
      $this->cookie_set();
304
      $this->login_cookie();
305
306
      if($this->account_login_status == LOGIN_SUCCESS) {
307
        // TODO - НЕ ОБЯЗАТЕЛЬНО ОТПРАВЛЯТЬ ЧЕРЕЗ ЕМЕЙЛ! ЕСЛИ ЭТО ФЕЙСБУЧЕК ИЛИ ВКШЕЧКА - МОЖНО ЧЕРЕЗ ЛС ПИСАТЬ!!
308
        $message_header = sprintf(classLocale::$lang['log_lost_email_title'], classSupernova::$config->game_name);
309
        $message = sprintf(classLocale::$lang['log_lost_email_pass'], classSupernova::$config->game_name, $this->account->account_name, $new_password_unsafe);
310
        // TODO - use $operation_result =
311
        mymail($confirmation['email'], $message_header, htmlspecialchars($message));
312
313
        $users_translated = PlayerToAccountTranslate::db_translate_get_users_from_account_list($this->provider_id, $this->account->account_id); // OK 4.5
314
        if(!empty($users_translated)) {
315
          // Отправляем в лички письмо о сбросе пароля
316
317
          // ПО ОПРЕДЕЛЕНИЮ в $users_translated только
318
          //    - аккаунты, поддерживающие сброс пароля
319
          //    - список аккаунтов, имеющих тот же емейл, что указан в Подтверждении
320
          //    - игроки, привязанные только к этим аккаунтам
321
          // Значит им всем сразу скопом можно отправлять сообщения
322
          $message = sprintf(classLocale::$lang['sys_password_reset_message_body'], $new_password_unsafe);
323
          $message = sys_bbcodeParse($message) . '<br><br>';
324
325
          foreach($users_translated as $user_id => $providers_list) {
326
            DBStaticMessages::msgSendFromAdmin($user_id, classLocale::$lang['sys_login_register_message_title'], $message);
327
          }
328
        } else {
329
          // Фигня - может быть и пустой, если у нас есть только аккаунт, но нет пользователей
330
          // throw new Exception(AUTH_PASSWORD_RESET_INSIDE_ERROR_NO_ACCOUNT_FOR_CONFIRMATION, ERR_ERROR);
331
        }
332
      }
333
334
      $this->confirmation->db_confirmation_delete_by_type_and_email(CONFIRM_PASSWORD_RESET, $confirmation['email']); // OK 4.5
335
336
      sn_db_transaction_commit();
337
338
      sys_redirect('overview.php');
339
    } catch (Exception $e) {
340
      sn_db_transaction_rollback();
341
      $this->account_login_status = $e->getMessage();
342
    }
343
344
    return $this->account_login_status;
345
  }
346
347
  /**
348
   * Функция инициализирует данные провайдера - разворачивает куки, берет данные итд
349
   */
350
  // OK v4.5
351
  protected function prepare() {
352
    $this->input_login_unsafe = sys_get_param_str_unsafe('username', sys_get_param_str_unsafe('email')); // TODO переделать эту порнографию
353
354
    $this->is_login = sys_get_param('login') ? true : false;
355
    $this->is_register = sys_get_param('register') ? true : false;
356
    $this->is_password_reset = sys_get_param('password_reset') ? true : false;
357
    $this->is_password_reset_confirm = sys_get_param('password_reset_confirm') ? true : false;
358
359
    $this->remember_me = intval(sys_get_param_int('rememberme') || $this->is_register);
360
    $this->input_login_password_raw = sys_get_param('password');
361
    $this->input_login_password_raw_repeat = sys_get_param('password_repeat');
362
    $this->input_email_unsafe = sys_get_param_str_unsafe('email');
363
    $this->input_language_unsafe = sys_get_param_str_unsafe('lang', DEFAULT_LANG);
364
    $this->input_language_safe = sys_get_param_str('lang', DEFAULT_LANG);
365
366
  }
367
368
  /**
369
   * Пытается зарегестрировать пользователя по введенным данным
370
   *
371
   * @return mixed
372
   */
373
  protected function register() {
374
    // TODO РЕГИСТРАЦИЯ ВСЕГДА ДОЛЖНА ЛОГИНИТЬ ПОЛЬЗОВАТЕЛЯ!
375
    $this->flog('Регистрация: начинаем. Провайдер ' . $this->provider_id);
376
377
    try {
378
      if(!$this->is_register) {
379
        $this->flog('Регистрация: не выставлен флаг регистрации - пропускаем');
380
        throw new Exception(LOGIN_UNDEFINED, ERR_ERROR);
381
      }
382
383
      $this->register_validate_input();
384
385
      sn_db_transaction_start();
386
387
      $this->account->db_get_by_name_or_email($this->input_login_unsafe, $this->input_email_unsafe);
388
      if($this->account->is_exists) {
389
        if($this->account->account_email == $this->input_email_unsafe) {
390
          throw new Exception(REGISTER_ERROR_EMAIL_EXISTS, ERR_ERROR);
391
        } else {
392
          throw new Exception(REGISTER_ERROR_ACCOUNT_NAME_EXISTS, ERR_ERROR);
393
        }
394
      }
395
396
      // Проблемы с созданием аккаунта - вызовут эксершн и обработается catch()
397
      $this->account->db_create(
398
        $this->input_login_unsafe,
399
        $this->input_login_password_raw,
400
        $this->input_email_unsafe,
401
        $this->input_language_unsafe
402
      );
403
404
      // Устанавливать не надо - мы дальше пойдем по workflow
405
      $this->account_login_status = LOGIN_SUCCESS;
406
      $this->cookie_set();
407
408
      // А вот это пока не нужно. Трансляцией аккаунтов в юзеров и созданием новых юзеров для новозашедших аккаунтов занимается Auth
409
      // $this->register_account();
410
      sn_db_transaction_commit();
411
    } catch(Exception $e) {
412
      sn_db_transaction_rollback();
413
      $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...
414
    }
415
416
    return $this->account_login_status;
417
  }
418
419
  /**
420
   * Пытается залогинить пользователя по куке
421
   *
422
   * @return int Результат попытки
423
   */
424
  protected function login_cookie() {
425
    if($this->account_login_status != LOGIN_UNDEFINED) {
426
      return $this->account_login_status;
427
    }
428
429
    // Пытаемся войти по куке
430
    if(!empty($_COOKIE[$this->cookie_name])) {
431
      if(count(explode("/%/", $_COOKIE[$this->cookie_name])) < 4) {
432
        list($account_id_unsafe, $cookie_password_hash_salted, $user_remember_me) = explode(AUTH_COOKIE_DELIMETER, $_COOKIE[$this->cookie_name]);
433
      } else {
434
        list($account_id_unsafe, $user_name, $cookie_password_hash_salted, $user_remember_me) = explode("/%/", $_COOKIE[$this->cookie_name]);
435
      }
436
437
      if(
438
        $this->account->db_get_by_id($account_id_unsafe)
439
        && ($this->password_encode_for_cookie($this->account->account_password) == $cookie_password_hash_salted)
440
      ) {
441
        $this->account_login_status = LOGIN_SUCCESS;
442
        $this->remember_me = intval($user_remember_me);
443
      }
444
    }
445
446
    if($this->account_login_status != LOGIN_SUCCESS) {
447
      // Невалидная кука - чистим
448
      $this->cookie_clear();
449
    }
450
451
    return $this->account_login_status;
452
  }
453
454
  /**
455
   * Пытается залогинить пользователя по имени аккаунта и паролю
456
   *
457
   * @return mixed
458
   */
459
  // OK v4.5
460
  protected function login_username() {
461
    // TODO - Логин по старым именам
462
    try {
463
      if(!$this->is_login) {
464
        $this->flog('Логин: не выставлен флаг входа в игру - это не логин');
465
        throw new Exception(LOGIN_UNDEFINED, ERR_ERROR);
466
      }
467
468
      // TODO Пустое имя аккаунта
469
      if(!$this->input_login_unsafe) {
470
        throw new Exception(LOGIN_UNDEFINED, ERR_ERROR);
471
      }
472
473
      $this->login_validate_input();
474
475
      if(!$this->account->db_get_by_name($this->input_login_unsafe) && !$this->account->db_get_by_email($this->input_login_unsafe)) {
476
        throw new Exception(LOGIN_ERROR_USERNAME, ERR_ERROR);
477
      }
478
479
      if(!$this->account->password_check($this->input_login_password_raw)) {
480
        throw new Exception(LOGIN_ERROR_PASSWORD, ERR_ERROR);
481
      }
482
483
      $this->cookie_set();
484
      $this->account_login_status = LOGIN_SUCCESS;
485
    } catch(Exception $e) {
486
      $this->account_login_status == LOGIN_UNDEFINED ? $this->account_login_status = $e->getMessage() : false;
487
    }
488
489
    return $this->account_login_status;
490
  }
491
492
  /**
493
   * Устанавливает куку аккаунта по данным $this->data[F_ACCOUNT]
494
   *
495
   * @param Account|null $account_to_impersonate
496
   *
497
   * @return bool
498
   * @throws Exception
499
   *
500
   */
501
  // OK v4.5
502
  // TODO - должен устанавливать куку исходя из пользователя, что бы пользователь мог логинится
503
  // TODO - или ставить мультикуку - хотя нахуя, спрашивается
504
  protected function cookie_set($account_to_impersonate = null) {
505
    $this_account = is_object($account_to_impersonate) ? $account_to_impersonate : $this->account;
506
507
    if(!is_object($this_account) || !$this_account->is_exists) {
508
      throw new Exception(LOGIN_ERROR_NO_ACCOUNT_FOR_COOKIE_SET, ERR_ERROR);
509
    }
510
511
    if(is_object($account_to_impersonate) && $account_to_impersonate->is_exists) {
512
      sn_setcookie($this->cookie_name_impersonate, $_COOKIE[$this->cookie_name], SN_TIME_NOW + PERIOD_YEAR, $this->sn_root_path, $this->domain);
513
    }
514
515
    $expire_time = $this->remember_me ? SN_TIME_NOW + PERIOD_YEAR : 0;
516
517
    $password_encoded = $this->password_encode_for_cookie($this_account->account_password);
518
    $cookie = $this_account->account_id . AUTH_COOKIE_DELIMETER . $password_encoded . AUTH_COOKIE_DELIMETER . $this->remember_me;
519
    $this->flog("cookie_set() - Устанавливаем куку {$cookie}");
520
    return sn_setcookie($this->cookie_name, $cookie, $expire_time, $this->sn_root_path, $this->domain);
521
  }
522
523
  /**
524
   * Очищает куку аккаунта - совсем или восстанавливая куку текущего имперсонатора
525
   */
526
  // OK v4.1
527
  protected function cookie_clear() {
528
    // Автоматически вообще-то - если установлена кука имперсонатора - то чистим обычную, а куку имперсонатора - копируем в неё
529
    if(!empty($_COOKIE[$this->cookie_name_impersonate])) {
530
      sn_setcookie($this->cookie_name, $_COOKIE[$this->cookie_name_impersonate], SN_TIME_NOW + PERIOD_YEAR, $this->sn_root_path, $this->domain);
531
      sn_setcookie($this->cookie_name_impersonate, '', SN_TIME_NOW - PERIOD_WEEK, $this->sn_root_path, $this->domain);
532
    } else {
533
      sn_setcookie($this->cookie_name, '', SN_TIME_NOW - PERIOD_WEEK, $this->sn_root_path, $this->domain);
534
    }
535
  }
536
537
538
  // ХЕЛПЕРЫ ===========================================================================================================
539
  /**
540
   * Проверяет введенные данные логина на корректность
541
   *
542
   * @throws Exception
543
   */
544
  // OK v4.1
545
  protected function login_validate_input() {
546
    // Проверяем, что бы в начале и конце не было пустых символов
547
    // TODO - при копировании Эксель -> Опера - в конце образуются пустые места. Это не должно быть проблемой! Вынести проверку пароля в регистрацию!
548
    if($this->input_login_password_raw != trim($this->input_login_password_raw)) {
549
      throw new Exception(LOGIN_ERROR_PASSWORD_TRIMMED, ERR_ERROR);
550
    }
551
    if(!$this->input_login_password_raw) {
552
      throw new Exception(LOGIN_ERROR_PASSWORD_EMPTY, ERR_ERROR);
553
    }
554
  }
555
556
  /**
557
   * Проверяет данные для регистрации на корректность
558
   *
559
   * @throws Exception
560
   */
561
  // OK v4.5
562
  protected function register_validate_input() {
563
    // То, что не подходит для логина - не подходит и для регистрации
564
    $this->login_validate_input();
565
566
    // Если нет имени пользователя - NO GO!
567
    if(!$this->input_login_unsafe) {
568
      throw new Exception(LOGIN_ERROR_USERNAME_EMPTY, ERR_ERROR);
569
    }
570
    // Если логин имеет запрещенные символы - NO GO!
571
    if(strpbrk($this->input_login_unsafe, LOGIN_REGISTER_CHARACTERS_PROHIBITED)) {
572
      throw new Exception(LOGIN_ERROR_USERNAME_RESTRICTED_CHARACTERS, ERR_ERROR);
573
    }
574
    // Если логин меньше минимальной длины - NO GO!
575
    if(strlen($this->input_login_unsafe) < LOGIN_LENGTH_MIN) {
576
      throw new Exception(REGISTER_ERROR_USERNAME_SHORT, ERR_ERROR);
577
    }
578
    // Если пароль меньше минимальной длины - NO GO!
579
    if(strlen($this->input_login_password_raw) < PASSWORD_LENGTH_MIN) {
580
      throw new Exception(REGISTER_ERROR_PASSWORD_INSECURE, ERR_ERROR);
581
    }
582
    // Если пароль имеет пробельные символы в начале или конце - NO GO!
583
    if($this->input_login_password_raw != trim($this->input_login_password_raw)) {
584
      throw new Exception(LOGIN_ERROR_PASSWORD_TRIMMED, ERR_ERROR);
585
    }
586
    // Если пароль не совпадает с подтверждением - NO GO! То, что у пароля нет пробельных символов в начале/конце - мы уже проверили выше
587
    //Если они есть у повтора - значит пароль и повтор не совпадут
588
    if($this->input_login_password_raw <> $this->input_login_password_raw_repeat) {
589
      throw new Exception(REGISTER_ERROR_PASSWORD_DIFFERENT, ERR_ERROR);
590
    }
591
    // Если нет емейла - NO GO!
592
    // TODO - регистрация без емейла
593
    if(!$this->input_email_unsafe) {
594
      throw new Exception(REGISTER_ERROR_EMAIL_EMPTY, ERR_ERROR);
595
    }
596
    // Если емейл не является емейлом - NO GO!
597
    if(!is_email($this->input_email_unsafe)) {
598
      throw new Exception(REGISTER_ERROR_EMAIL_WRONG, ERR_ERROR);
599
    }
600
  }
601
602
603
604
  // OK v4
605
  protected function password_encode_for_cookie($password) {
606
    return md5("{$password}--" . $this->secret_word);
607
  }
608
  // OK v4
609
  protected function password_encode($password, $salt) {
610
    return core_auth::password_encode($password, $salt);
611
  }
612
  // OK v4
613
  protected function password_salt_generate() {
614
    return core_auth::password_salt_generate();
615
  }
616
  /**
617
   * Генерирует случайный пароль
618
   *
619
   * @return string
620
   */
621
  // OK v4
622
  protected function make_random_password() {
623
    return core_auth::make_random_password();
624
  }
625 View Code Duplication
  protected function flog($message, $die = false) {
626
    if(!defined('DEBUG_AUTH') || !DEBUG_AUTH) {
627
      return;
628
    }
629
    list($called, $caller) = debug_backtrace(false);
630
631
    $caller_name =
632
      ((get_called_class()) ? get_called_class() : (!empty($caller['class']) ? $caller['class'] : '')) .
633
      (!empty($caller['type']) ? $caller['type'] : '') .
634
      (!empty($caller['function']) ? $caller['function'] : '') .
635
      (!empty($called['line']) ? ':' . $called['line'] : '');
636
637
    $_SERVER['SERVER_NAME'] == 'localhost' ? print("<div class='debug'>$message - $caller_name\r\n</div>") : false;
638
639
    classSupernova::log_file("$message - $caller_name");
640
    if($die) {
641
      $die && die("<div class='negative'>СТОП! Функция {$caller_name} при вызове в " . get_called_class() . " (располагается в " . get_class() . "). СООБЩИТЕ АДМИНИСТРАЦИИ!</div>");
642
    }
643
  }
644
645
}
646