|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
// define("DEBUG_AUTH", true); |
|
|
|
|
|
|
4
|
|
|
|
|
5
|
|
|
/** |
|
6
|
|
|
* Статический над-класс, который обеспечивает интерфейс авторизации для остального кода |
|
7
|
|
|
* |
|
8
|
|
|
* User: Gorlum |
|
9
|
|
|
* Date: 21.04.2015 |
|
10
|
|
|
* Time: 3:51 |
|
11
|
|
|
* |
|
12
|
|
|
* version #41a7.59# |
|
13
|
|
|
*/ |
|
14
|
|
|
class core_auth extends sn_module { |
|
15
|
|
|
public $manifest = array( |
|
16
|
|
|
'package' => 'core', |
|
17
|
|
|
'name' => 'auth', |
|
18
|
|
|
'version' => '0a0', |
|
19
|
|
|
'copyright' => 'Project "SuperNova.WS" #41a7.59# copyright © 2009-2015 Gorlum', |
|
20
|
|
|
|
|
21
|
|
|
// 'require' => null, |
|
|
|
|
|
|
22
|
|
|
'root_relative' => '', |
|
23
|
|
|
|
|
24
|
|
|
'load_order' => 1, |
|
25
|
|
|
|
|
26
|
|
|
'installed' => true, |
|
27
|
|
|
'active' => true, |
|
28
|
|
|
|
|
29
|
|
|
'mvc' => array( |
|
30
|
|
|
'model' => array( |
|
31
|
|
|
'player_register' => array( |
|
32
|
|
|
'callable' => 'player_register_model', |
|
33
|
|
|
), |
|
34
|
|
|
), |
|
35
|
|
|
|
|
36
|
|
|
'view' => array( |
|
37
|
|
|
'player_register' => array( |
|
38
|
|
|
'callable' => 'player_register_view', |
|
39
|
|
|
), |
|
40
|
|
|
), |
|
41
|
|
|
), |
|
42
|
|
|
); |
|
43
|
|
|
|
|
44
|
|
|
/** |
|
45
|
|
|
* БД из которой читать данные |
|
46
|
|
|
* |
|
47
|
|
|
* @var db_mysql $db |
|
48
|
|
|
*/ |
|
49
|
|
|
public static $db; |
|
50
|
|
|
/** |
|
51
|
|
|
* Информация об устройстве |
|
52
|
|
|
* |
|
53
|
|
|
* @var RequestInfo |
|
54
|
|
|
*/ |
|
55
|
|
|
public static $device; |
|
56
|
|
|
/** |
|
57
|
|
|
* Аккаунт ???? |
|
58
|
|
|
* |
|
59
|
|
|
* @var Account |
|
60
|
|
|
*/ |
|
61
|
|
|
public $account = null; |
|
62
|
|
|
/** |
|
63
|
|
|
* Запись текущего игрока из `users` |
|
64
|
|
|
* |
|
65
|
|
|
* @var array|bool|null |
|
66
|
|
|
*/ |
|
67
|
|
|
public static $user = null; |
|
68
|
|
|
|
|
69
|
|
|
/** |
|
70
|
|
|
* Основной провайдер |
|
71
|
|
|
* |
|
72
|
|
|
* @var auth_local |
|
73
|
|
|
*/ |
|
74
|
|
|
public static $main_provider = null; |
|
75
|
|
|
|
|
76
|
|
|
/** |
|
77
|
|
|
* Статус инициализации |
|
78
|
|
|
* |
|
79
|
|
|
* @var bool |
|
80
|
|
|
*/ |
|
81
|
|
|
// protected static $is_init = false; |
|
|
|
|
|
|
82
|
|
|
/** |
|
83
|
|
|
* Список провайдеров |
|
84
|
|
|
* |
|
85
|
|
|
* @var auth_local[] |
|
86
|
|
|
*/ |
|
87
|
|
|
protected $providers = array(); |
|
88
|
|
|
|
|
89
|
|
|
/** |
|
90
|
|
|
* Глобальный статус входа в игру |
|
91
|
|
|
* |
|
92
|
|
|
* @var int |
|
93
|
|
|
*/ |
|
94
|
|
|
public static $login_status = LOGIN_UNDEFINED; |
|
95
|
|
|
/** |
|
96
|
|
|
* Имя, предлагаемое пользователю в качестве имени игрока |
|
97
|
|
|
* |
|
98
|
|
|
* @var string |
|
99
|
|
|
*/ |
|
100
|
|
|
protected $player_suggested_name = ''; |
|
101
|
|
|
|
|
102
|
|
|
/** |
|
103
|
|
|
* Список полностью авторизированных аккаунтов с LOGIN_SUCCESS |
|
104
|
|
|
* |
|
105
|
|
|
* @var auth_local[] |
|
106
|
|
|
*/ |
|
107
|
|
|
protected $providers_authorised = array(); |
|
108
|
|
|
/** |
|
109
|
|
|
* Статусы всех провайдеров |
|
110
|
|
|
* |
|
111
|
|
|
* @var auth_local[] |
|
112
|
|
|
*/ |
|
113
|
|
|
protected $provider_error_list = array(); |
|
114
|
|
|
/** |
|
115
|
|
|
* Список юзеров (user_row - записей из `user`), доступных всем авторизированным аккаунтам |
|
116
|
|
|
* |
|
117
|
|
|
* @var array |
|
118
|
|
|
*/ |
|
119
|
|
|
protected $accessible_user_row_list = array(); |
|
120
|
|
|
|
|
121
|
|
|
protected $user_id_to_provider = array(); |
|
122
|
|
|
|
|
123
|
|
|
/** |
|
124
|
|
|
* Флаг имперсонации |
|
125
|
|
|
* |
|
126
|
|
|
* @var bool |
|
127
|
|
|
*/ |
|
128
|
|
|
protected $is_impersonating = false; |
|
129
|
|
|
protected $impersonator_username = ''; |
|
130
|
|
|
|
|
131
|
|
|
/** |
|
132
|
|
|
* Флаг регистрации пользователя |
|
133
|
|
|
* |
|
134
|
|
|
* @var bool |
|
135
|
|
|
*/ |
|
136
|
|
|
protected $is_player_register = false; |
|
137
|
|
|
/** |
|
138
|
|
|
* @var int |
|
139
|
|
|
*/ |
|
140
|
|
|
protected $register_status = LOGIN_UNDEFINED; |
|
141
|
|
|
|
|
142
|
|
|
/** |
|
143
|
|
|
* Максимальный локальный уровень авторизации игрока |
|
144
|
|
|
* |
|
145
|
|
|
* @var int |
|
146
|
|
|
*/ |
|
147
|
|
|
public $auth_level_max_local = AUTH_LEVEL_ANONYMOUS; |
|
148
|
|
|
|
|
149
|
|
|
/** |
|
150
|
|
|
* @var int |
|
151
|
|
|
*/ |
|
152
|
|
|
public $partner_id = 0; |
|
153
|
|
|
|
|
154
|
|
|
/** |
|
155
|
|
|
* @var string |
|
156
|
|
|
*/ |
|
157
|
|
|
protected $server_name = ''; |
|
158
|
|
|
|
|
159
|
|
|
/** |
|
160
|
|
|
* Присвоение переменных, которые нуждаются в позднем связывании - например, используют константы из манифеста |
|
161
|
|
|
* или еще не обрабатываются стандартной процедурой инициализациии модуля |
|
162
|
|
|
* |
|
163
|
|
|
* @return array |
|
164
|
|
|
*/ |
|
165
|
|
|
// OK 4.7 |
|
166
|
|
|
public function __assign_vars() { |
|
167
|
|
|
return array( |
|
168
|
|
|
'sn_data[pages]' => array( |
|
169
|
|
|
'player_register' => 'includes/classes/core_auth', |
|
170
|
|
|
), |
|
171
|
|
|
); |
|
172
|
|
|
} |
|
173
|
|
|
|
|
174
|
|
|
/** |
|
175
|
|
|
* @param string $filename |
|
176
|
|
|
*/ |
|
177
|
|
|
// TODO - OK 4.7 |
|
178
|
|
|
public function __construct($filename = __FILE__) { |
|
179
|
|
|
parent::__construct($filename); |
|
180
|
|
|
|
|
181
|
|
|
self::$main_provider = new auth_local(); |
|
182
|
|
|
|
|
183
|
|
|
// В этой точке все модули уже прогружены и инициализированы по 1 экземпляру |
|
184
|
|
|
// self::$db = !is_object($db) ? classSupernova::$db : $db; |
|
|
|
|
|
|
185
|
|
|
self::$db = classSupernova::$db; |
|
186
|
|
|
|
|
187
|
|
|
self::$device = new RequestInfo(); |
|
188
|
|
|
$this->is_player_register = sys_get_param('player_register') ? true : false; |
|
189
|
|
|
$this->partner_id = sys_get_param_int('id_ref', sys_get_param_int('partner_id')); |
|
190
|
|
|
$this->server_name = sys_get_param_str_unsafe('server_name', SN_ROOT_VIRTUAL); |
|
191
|
|
|
} |
|
192
|
|
|
|
|
193
|
|
|
// TODO - OK v4.7 |
|
194
|
|
|
public function player_register_model() { |
|
195
|
|
|
// TODO ВСЕГДА ПРЕДЛАГАТЬ РЕГАТЬ ИГРОКА ИЛИ ПОДКЛЮЧИТЬ ИМЕЮЩЕГОСЯ! |
|
196
|
|
|
|
|
197
|
|
|
// TODO в auth_local делать проверку БД на существование имени игрока в локальной БД - что бы избежать лишнего шага (см.выше) |
|
198
|
|
|
// TODO Хотя тут может получится вечный цикл - ПОДУМАТЬ |
|
199
|
|
|
// TODO Тут же можно пробовать провести попытку слияния аккаунтов - хотя это и очень небезопасно |
|
200
|
|
|
|
|
201
|
|
|
if (sys_get_param('login_player_register_logout')) { |
|
202
|
|
|
$this->logout(); |
|
203
|
|
|
} |
|
204
|
|
|
|
|
205
|
|
|
$original_suggest = ''; |
|
206
|
|
|
// Смотрим - есть ли у нас данные от пользователя |
|
207
|
|
|
if (($player_name_submitted = sys_get_param('submit_player_name'))) { |
|
208
|
|
|
// Попытка регистрации нового игрока из данных, введенных пользователем |
|
209
|
|
|
$this->player_suggested_name = sys_get_param_str_unsafe('player_suggested_name'); |
|
210
|
|
|
} else { |
|
211
|
|
|
foreach ($this->providers_authorised as $provider) { |
|
212
|
|
|
if ($this->player_suggested_name = $provider->player_name_suggest()) { // OK 4.5 |
|
213
|
|
|
$original_suggest = $provider->player_name_suggest(); |
|
214
|
|
|
break; |
|
215
|
|
|
} |
|
216
|
|
|
} |
|
217
|
|
|
} |
|
218
|
|
|
|
|
219
|
|
|
// Если у нас провайдеры не дают имени и пользователь не дал свой вариант - это у нас первый логин в игру |
|
220
|
|
|
if (!$this->player_suggested_name) { |
|
221
|
|
|
$max_user_id = DBStaticUser::getMaxId(); // 4.5 |
|
222
|
|
|
// TODO - предлагать имя игрока по локали |
|
223
|
|
|
|
|
224
|
|
|
// Проверить наличие такого имени в истории имён |
|
225
|
|
|
do { |
|
226
|
|
|
sn_db_transaction_rollback(); |
|
227
|
|
|
$this->player_suggested_name = 'Emperor ' . mt_rand($max_user_id + 1, $max_user_id + 1000); |
|
228
|
|
|
sn_db_transaction_start(); |
|
229
|
|
|
} while (db_player_name_exists($this->player_suggested_name)); |
|
230
|
|
|
|
|
231
|
|
|
} |
|
232
|
|
|
|
|
233
|
|
|
if ($player_name_submitted) { |
|
234
|
|
|
$this->register_player_db_create($this->player_suggested_name); // OK 4.5 |
|
235
|
|
|
if ($this->register_status == LOGIN_SUCCESS) { |
|
236
|
|
|
sys_redirect(SN_ROOT_VIRTUAL . 'overview.php'); |
|
237
|
|
|
} elseif ($this->register_status == REGISTER_ERROR_PLAYER_NAME_EXISTS && $original_suggest == $this->player_suggested_name) { |
|
|
|
|
|
|
238
|
|
|
// self::$player_suggested_name .= ' ' . $this->account->account_id; |
|
|
|
|
|
|
239
|
|
|
} |
|
240
|
|
|
// if(self::$login_status != LOGIN_SUCCESS) { |
|
|
|
|
|
|
241
|
|
|
// // TODO Ошибка при регистрации нового игрока под текущим именем |
|
242
|
|
|
// } |
|
243
|
|
|
} |
|
244
|
|
|
|
|
245
|
|
|
} |
|
246
|
|
|
|
|
247
|
|
|
// TODO - OK v4.7 |
|
248
|
|
|
public function player_register_view($template = null) { |
|
249
|
|
|
global $template_result; |
|
250
|
|
|
|
|
251
|
|
|
define('LOGIN_LOGOUT', true); |
|
252
|
|
|
|
|
253
|
|
|
$template_result[F_PLAYER_REGISTER_MESSAGE] = |
|
254
|
|
|
isset($template_result[F_PLAYER_REGISTER_MESSAGE]) && $template_result[F_PLAYER_REGISTER_MESSAGE] |
|
255
|
|
|
? $template_result[F_PLAYER_REGISTER_MESSAGE] |
|
256
|
|
|
: ($this->register_status != LOGIN_UNDEFINED |
|
257
|
|
|
? classLocale::$lang['sys_login_messages'][$this->register_status] |
|
258
|
|
|
: false |
|
259
|
|
|
); |
|
260
|
|
|
|
|
261
|
|
View Code Duplication |
if ($this->register_status == LOGIN_ERROR_USERNAME_RESTRICTED_CHARACTERS) { |
|
|
|
|
|
|
262
|
|
|
$prohibited_characters = array_map(function ($value) { |
|
263
|
|
|
return "'" . htmlentities($value, ENT_QUOTES, 'UTF-8') . "'"; |
|
264
|
|
|
}, str_split(LOGIN_REGISTER_CHARACTERS_PROHIBITED)); |
|
265
|
|
|
$template_result[F_PLAYER_REGISTER_MESSAGE] .= implode(', ', $prohibited_characters); |
|
266
|
|
|
} |
|
267
|
|
|
|
|
268
|
|
|
// pdump('view'); |
|
|
|
|
|
|
269
|
|
|
// die('view'); |
|
270
|
|
|
$template_result = array_merge($template_result, array( |
|
271
|
|
|
'NAVBAR' => false, |
|
272
|
|
|
'PLAYER_SUGGESTED_NAME' => sys_safe_output($this->player_suggested_name), |
|
273
|
|
|
'PARTNER_ID' => sys_safe_output($this->partner_id), |
|
274
|
|
|
'SERVER_NAME' => sys_safe_output($this->server_name), |
|
275
|
|
|
'PLAYER_REGISTER_STATUS' => $this->register_status, |
|
276
|
|
|
'PLAYER_REGISTER_MESSAGE' => $template_result[F_PLAYER_REGISTER_MESSAGE], |
|
277
|
|
|
'LOGIN_UNDEFINED' => LOGIN_UNDEFINED, |
|
278
|
|
|
)); |
|
279
|
|
|
|
|
280
|
|
|
$template = gettemplate('login_player_register', $template); |
|
281
|
|
|
|
|
282
|
|
|
return $template; |
|
283
|
|
|
} |
|
284
|
|
|
|
|
285
|
|
|
/** |
|
286
|
|
|
* Функция пытается залогиниться по всем известным провайдерам |
|
287
|
|
|
* |
|
288
|
|
|
* @param null $result |
|
|
|
|
|
|
289
|
|
|
*/ |
|
290
|
|
|
public function login() { |
|
291
|
|
|
if (empty(sn_module::$sn_module_list['auth'])) { |
|
292
|
|
|
die('{Не обнаружено ни одного провайдера авторизации в core_auth::login()!}'); |
|
293
|
|
|
} |
|
294
|
|
|
|
|
295
|
|
|
!empty($_POST) ? self::flog(dump($_POST, '$_POST')) : false; |
|
296
|
|
|
!empty($_GET) ? self::flog(dump($_GET, '$_GET')) : false; |
|
297
|
|
|
!empty($_COOKIE) ? self::flog(dump($_COOKIE, '$_COOKIE')) : false; |
|
298
|
|
|
|
|
299
|
|
|
$this->auth_reset(); // OK v4.5 |
|
300
|
|
|
|
|
301
|
|
|
$this->providers = array(); |
|
302
|
|
|
foreach (sn_module::$sn_module_list['auth'] as $module_name => $module) { |
|
303
|
|
|
$this->providers[$module->provider_id] = $module; |
|
304
|
|
|
} |
|
305
|
|
|
|
|
306
|
|
|
// $this->providers = array_reverse($this->providers, true); // НИНАДА! СН-аккаунт должен всегда авторизироваться первым! |
|
|
|
|
|
|
307
|
|
|
|
|
308
|
|
|
foreach ($this->providers as $provider_id => $provider) { |
|
309
|
|
|
$login_status = $provider->login(); // OK v4.5 |
|
310
|
|
|
self::flog(($provider->manifest['name'] . '->' . 'login_try - ') . (empty($provider->account->account_id) ? classLocale::$lang['sys_login_messages'][$provider->account_login_status] : dump($provider))); |
|
311
|
|
|
if ($login_status == LOGIN_SUCCESS && is_object($provider->account) && $provider->account instanceof Account && $provider->account->account_id) { |
|
312
|
|
|
$this->providers_authorised[$provider_id] = &$this->providers[$provider_id]; |
|
313
|
|
|
|
|
314
|
|
|
$this->user_id_to_provider = array_replace_recursive( |
|
315
|
|
|
$this->user_id_to_provider, |
|
316
|
|
|
// static::db_translate_get_users_from_account_list($provider_id, $provider->account->account_id) // OK 4.5 |
|
|
|
|
|
|
317
|
|
|
PlayerToAccountTranslate::db_translate_get_users_from_account_list($provider_id, $provider->account->account_id) // OK 4.5 |
|
318
|
|
|
); |
|
319
|
|
|
} elseif ($login_status != LOGIN_UNDEFINED) { |
|
320
|
|
|
$this->provider_error_list[$provider_id] = $login_status; |
|
321
|
|
|
} |
|
322
|
|
|
} |
|
323
|
|
|
|
|
324
|
|
|
if (empty($this->providers_authorised)) { |
|
325
|
|
|
// Ни один аккаунт не авторизирован |
|
326
|
|
|
// Проверяем - есть ли у нас ошибки в аккаунтах? |
|
327
|
|
|
if (!empty($this->provider_error_list)) { |
|
328
|
|
|
// Если есть - выводим их |
|
329
|
|
|
self::$login_status = reset($this->provider_error_list); |
|
330
|
|
|
} |
|
331
|
|
|
// Иначе - это первый запуск страницы. ИЛИ СПЕЦИАЛЬНОЕ ДЕЙСТВИЕ! |
|
332
|
|
|
// ...которые по факты должны обрабатываться в рамках provider->login() |
|
333
|
|
|
} else { |
|
334
|
|
|
// Есть хотя бы один авторизированный аккаунт |
|
335
|
|
|
$temp = reset($this->providers_authorised); |
|
336
|
|
|
$this->account = $temp->account; |
|
337
|
|
|
|
|
338
|
|
|
$this->get_accessible_user_list(); |
|
339
|
|
|
// В self::$accessible_user_row_list - список доступных игроков для данных аккаунтов с соответствующими записями из таблицы `users` |
|
340
|
|
|
|
|
341
|
|
|
// Остались ли у нас в списке доступные игроки? |
|
342
|
|
|
if (empty($this->accessible_user_row_list)) { |
|
343
|
|
|
// Нет ни одного игрока ни на одном авторизированном аккаунте |
|
344
|
|
|
// Надо регать нового игрока |
|
345
|
|
|
|
|
346
|
|
|
// Сейчас происходит процесс регистрации игрока? |
|
347
|
|
|
if (!$this->is_player_register) { |
|
348
|
|
|
// Нет - отправляем на процесс регистрации |
|
349
|
|
|
$partner_id = sys_get_param_int('id_ref', sys_get_param_int('partner_id')); |
|
350
|
|
|
sys_redirect(SN_ROOT_VIRTUAL . 'index.php?page=player_register&player_register=1' . ($partner_id ? '&id_ref=' . $partner_id : '')); |
|
351
|
|
|
} |
|
352
|
|
|
} else { |
|
353
|
|
|
// Да, есть доступные игроки, которые так же прописаны в базе |
|
354
|
|
|
$this->get_active_user(); // 4.5 |
|
355
|
|
|
|
|
356
|
|
|
if ($this->is_impersonating = !empty($_COOKIE[SN_COOKIE_U_I]) ? $_COOKIE[SN_COOKIE_U_I] : 0) { |
|
357
|
|
|
$a_user = DBStaticUser::db_user_by_id($this->is_impersonating); |
|
358
|
|
|
$this->impersonator_username = $a_user['username']; |
|
359
|
|
|
} |
|
360
|
|
|
|
|
361
|
|
|
|
|
362
|
|
|
//Прописываем текущего игрока на все авторизированные аккаунты |
|
363
|
|
|
// TODO - ИЛИ ВСЕХ ИГРОКОВ?? |
|
364
|
|
|
if (empty($this->is_impersonating)) { |
|
365
|
|
|
foreach ($this->providers_authorised as $provider_id => $provider) { |
|
366
|
|
|
if (empty($this->user_id_to_provider[self::$user['id']][$provider_id])) { |
|
367
|
|
|
// self::db_translate_register_user($provider_id, $provider->account->account_id, self::$user['id']); |
|
|
|
|
|
|
368
|
|
|
PlayerToAccountTranslate::db_translate_register_user($provider_id, $provider->account->account_id, self::$user['id']); |
|
369
|
|
|
$this->user_id_to_provider[self::$user['id']][$provider_id][$provider->account->account_id] = true; |
|
370
|
|
|
} |
|
371
|
|
|
} |
|
372
|
|
|
} |
|
373
|
|
|
} |
|
374
|
|
|
} |
|
375
|
|
|
|
|
376
|
|
|
if (empty(self::$user['id'])) { |
|
377
|
|
|
self::cookie_set(''); // OK 4.5 |
|
378
|
|
|
} elseif (self::$user['id'] != $_COOKIE[SN_COOKIE_U]) { |
|
379
|
|
|
self::cookie_set(self::$user['id']); // OK 4.5 |
|
380
|
|
|
} |
|
381
|
|
|
|
|
382
|
|
|
return $this->make_return_array(); |
|
383
|
|
|
} |
|
384
|
|
|
|
|
385
|
|
|
/** |
|
386
|
|
|
* Логаут игрока и всех аккаунтов |
|
387
|
|
|
* |
|
388
|
|
|
* @param bool|string $redirect нужно ли сделать перенаправление после логаута |
|
389
|
|
|
* <p><b>false</b> - не перенаправлять</p> |
|
390
|
|
|
* <p><i><b>true</b></i> - перенаправить на главную страницу</p> |
|
391
|
|
|
* <p><b>string</b> - перенаправить на указанный URL</p> |
|
392
|
|
|
* |
|
393
|
|
|
* @param bool $only_impersonator Если установлен - то логаут происходит только при имперсонации |
|
394
|
|
|
*/ |
|
395
|
|
|
// OK v4.7 |
|
396
|
|
|
public function logout($redirect = true) { |
|
397
|
|
|
if (!empty($_COOKIE[SN_COOKIE_U_I])) { |
|
398
|
|
|
self::cookie_set($_COOKIE[SN_COOKIE_U_I]); |
|
399
|
|
|
self::cookie_set(0, true); |
|
400
|
|
|
self::$main_provider->logout(); |
|
401
|
|
|
} else { |
|
402
|
|
|
foreach ($this->providers as $provider_name => $provider) { |
|
403
|
|
|
$provider->logout(); |
|
404
|
|
|
} |
|
405
|
|
|
|
|
406
|
|
|
self::cookie_set(0); |
|
407
|
|
|
} |
|
408
|
|
|
|
|
409
|
|
|
if ($redirect === true) { |
|
410
|
|
|
sys_redirect(SN_ROOT_RELATIVE . (empty($_COOKIE[SN_COOKIE_U]) ? 'login.php' : 'admin/overview.php')); |
|
411
|
|
|
} elseif ($redirect !== false) { |
|
412
|
|
|
sys_redirect($redirect); |
|
413
|
|
|
} |
|
414
|
|
|
} |
|
415
|
|
|
|
|
416
|
|
|
/** |
|
417
|
|
|
* Имперсонация |
|
418
|
|
|
* |
|
419
|
|
|
* @param $user_selected |
|
420
|
|
|
*/ |
|
421
|
|
|
public function impersonate($user_selected) { |
|
422
|
|
|
if ($_COOKIE[SN_COOKIE_U_I]) { |
|
423
|
|
|
die('You already impersonating someone. Go back to living other\'s life! Or clear your cookies and try again'); // TODO: Log it |
|
424
|
|
|
} |
|
425
|
|
|
|
|
426
|
|
|
if ($this->auth_level_max_local < AUTH_LEVEL_ADMINISTRATOR) { |
|
427
|
|
|
die('You can\'t impersonate - too low level'); // TODO: Log it |
|
428
|
|
|
} |
|
429
|
|
|
|
|
430
|
|
|
if ($this->auth_level_max_local <= $user_selected['authlevel']) { |
|
431
|
|
|
die('You can\'t impersonate this account - level is greater or equal to yours'); // TODO: Log it |
|
432
|
|
|
} |
|
433
|
|
|
|
|
434
|
|
|
$account_translate = PlayerToAccountTranslate::db_translate_get_account_by_user_id($user_selected['id'], self::$main_provider->provider_id); |
|
435
|
|
|
$account_translate = reset($account_translate[$user_selected['id']][self::$main_provider->provider_id]); |
|
436
|
|
|
$account_to_impersonate = new Account(self::$main_provider->db); |
|
437
|
|
|
$account_to_impersonate->db_get_by_id($account_translate['provider_account_id']); |
|
438
|
|
|
if (!$account_to_impersonate->is_exists) { |
|
439
|
|
|
die('Какая-то ошибка - не могу найти аккаунт для имперсонации'); // TODO: Log it |
|
440
|
|
|
} |
|
441
|
|
|
self::$main_provider->impersonate($account_to_impersonate); |
|
442
|
|
|
|
|
443
|
|
|
self::cookie_set($_COOKIE[SN_COOKIE_U], true, 0); |
|
444
|
|
|
|
|
445
|
|
|
// TODO - Имперсонейт - только на одну сессию |
|
446
|
|
|
self::cookie_set($user_selected['id']); |
|
447
|
|
|
|
|
448
|
|
|
// sec_set_cookie_by_user($user_selected, 0); |
|
|
|
|
|
|
449
|
|
|
sys_redirect(SN_ROOT_RELATIVE); |
|
450
|
|
|
} |
|
451
|
|
|
|
|
452
|
|
|
/** |
|
453
|
|
|
* Проверяет пароль на совпадение с текущими паролями |
|
454
|
|
|
* |
|
455
|
|
|
* @param $password_unsafe |
|
456
|
|
|
* |
|
457
|
|
|
* @return bool |
|
458
|
|
|
*/ |
|
459
|
|
|
// OK v4.6 |
|
460
|
|
|
// TODO - ПЕРЕДЕЛАТЬ! |
|
461
|
|
|
public function password_check($password_unsafe) { |
|
462
|
|
|
$result = false; |
|
463
|
|
|
|
|
464
|
|
|
if (empty($this->providers_authorised)) { |
|
465
|
|
|
// TODO - такого быть не может! |
|
466
|
|
|
self::flog("password_check: Не найдено ни одного авторизированного провайдера в self::\$providers_authorised", true); |
|
467
|
|
|
} else { |
|
468
|
|
|
foreach ($this->providers_authorised as $provider_id => $provider) { |
|
469
|
|
|
if ($provider->is_feature_supported(AUTH_FEATURE_HAS_PASSWORD)) { |
|
470
|
|
|
$result = $result || $provider->password_check($password_unsafe); |
|
471
|
|
|
} |
|
472
|
|
|
} |
|
473
|
|
|
} |
|
474
|
|
|
|
|
475
|
|
|
return $result; |
|
476
|
|
|
} |
|
477
|
|
|
|
|
478
|
|
|
/** |
|
479
|
|
|
* Меняет старый пароль на новый |
|
480
|
|
|
* |
|
481
|
|
|
* @param $old_password_unsafe |
|
482
|
|
|
* @param $new_password_unsafe |
|
483
|
|
|
* |
|
484
|
|
|
* @return bool |
|
485
|
|
|
*/ |
|
486
|
|
|
// OK v4.6 |
|
487
|
|
|
public function password_change($old_password_unsafe, $new_password_unsafe) { |
|
488
|
|
|
if (empty($this->providers_authorised)) { |
|
489
|
|
|
// TODO - такого быть не может! |
|
490
|
|
|
self::flog("Не найдено ни одного авторизированного провайдера в self::\$providers_authorised", true); |
|
491
|
|
|
|
|
492
|
|
|
return false; |
|
493
|
|
|
} |
|
494
|
|
|
|
|
495
|
|
|
// TODO - Проверять пароль на корректность |
|
496
|
|
|
|
|
497
|
|
|
// TODO - Не менять (?) пароль у аккаунтов, к которым пристёгнут хоть один игрок с AUTH_LEVEL > 0 |
|
498
|
|
|
|
|
499
|
|
|
$salt_unsafe = self::password_salt_generate(); |
|
500
|
|
|
|
|
501
|
|
|
$providers_changed_password = array(); |
|
502
|
|
|
foreach ($this->providers_authorised as $provider_id => $provider) { |
|
503
|
|
|
if ( |
|
504
|
|
|
!$provider->is_feature_supported(AUTH_FEATURE_PASSWORD_CHANGE) |
|
505
|
|
|
|| !$provider->password_change($old_password_unsafe, $new_password_unsafe, $salt_unsafe) |
|
506
|
|
|
) { |
|
507
|
|
|
continue; |
|
508
|
|
|
} |
|
509
|
|
|
|
|
510
|
|
|
// Узнаем список игроков, которые прикреплены к этому аккаунту |
|
511
|
|
|
// $account_translation = self::db_translate_get_users_from_account_list($provider_id, $provider->account->account_id); |
|
|
|
|
|
|
512
|
|
|
$account_translation = PlayerToAccountTranslate::db_translate_get_users_from_account_list($provider_id, $provider->account->account_id); |
|
513
|
|
|
|
|
514
|
|
|
// Рассылаем уведомления о смене пароля в ЛС |
|
515
|
|
|
foreach ($account_translation as $user_id => $provider_info) { |
|
516
|
|
|
// TODO - УКазывать тип аккаунта, на котором сменён пароль |
|
517
|
|
|
$message = sprintf(classLocale::$lang['sys_login_register_message_body'], $provider->account->account_name, $new_password_unsafe); |
|
518
|
|
|
DBStaticMessages::msgSendFromAdmin($user_id, classLocale::$lang['sys_login_register_message_title'], $message); |
|
519
|
|
|
} |
|
520
|
|
|
$providers_changed_password[$provider_id] = $provider; |
|
521
|
|
|
} |
|
522
|
|
|
|
|
523
|
|
|
// TODO - отсылать уведомление на емейл |
|
524
|
|
|
|
|
525
|
|
|
return !empty($providers_changed_password); |
|
526
|
|
|
} |
|
527
|
|
|
|
|
528
|
|
|
|
|
529
|
|
|
|
|
530
|
|
|
|
|
531
|
|
|
/** |
|
532
|
|
|
* Сбрасывает значения полей |
|
533
|
|
|
*/ |
|
534
|
|
|
// OK v4.5 |
|
535
|
|
|
protected function auth_reset() { |
|
536
|
|
|
self::$login_status = LOGIN_UNDEFINED; |
|
537
|
|
|
$this->player_suggested_name = ''; |
|
538
|
|
|
$this->account = null; |
|
539
|
|
|
self::$user = null; |
|
540
|
|
|
$this->providers_authorised = array(); // Все аккаунты, которые успешно залогинились |
|
541
|
|
|
$this->provider_error_list = array(); // Статусы всех аккаунтов |
|
542
|
|
|
$this->accessible_user_row_list = array(); |
|
543
|
|
|
$this->user_id_to_provider = array(); |
|
544
|
|
|
} |
|
545
|
|
|
|
|
546
|
|
|
/** |
|
547
|
|
|
* Функция пытается создать игрока в БД, делая все нужные проверки |
|
548
|
|
|
* |
|
549
|
|
|
* @param $player_name_unsafe |
|
550
|
|
|
*/ |
|
551
|
|
|
// OK v4 |
|
552
|
|
|
protected function register_player_db_create($player_name_unsafe) { |
|
553
|
|
|
try { |
|
554
|
|
|
// Проверить корректность имени |
|
555
|
|
|
$this->register_player_name_validate($player_name_unsafe); |
|
556
|
|
|
|
|
557
|
|
|
sn_db_transaction_start(); |
|
558
|
|
|
// Проверить наличие такого имени в истории имён |
|
559
|
|
|
|
|
560
|
|
|
if (db_player_name_exists($player_name_unsafe)) { |
|
561
|
|
|
throw new Exception(REGISTER_ERROR_PLAYER_NAME_EXISTS, ERR_ERROR); |
|
562
|
|
|
} |
|
563
|
|
|
|
|
564
|
|
|
// Узнаем язык и емейл игрока |
|
565
|
|
|
$player_language = ''; |
|
566
|
|
|
$player_email = ''; |
|
567
|
|
|
// TODO - порнография - работа должна происходить над списком аккаунтов, а не только на одном аккаунте... |
|
568
|
|
|
foreach ($this->providers_authorised as $provider) { |
|
569
|
|
|
if (!$player_language && $provider->account->account_language) { |
|
570
|
|
|
$player_language = $provider->account->account_language; |
|
571
|
|
|
} |
|
572
|
|
|
if (!$player_email && $provider->account->account_email) { |
|
573
|
|
|
$player_email = $provider->account->account_email; |
|
574
|
|
|
} |
|
575
|
|
|
} |
|
576
|
|
|
$player_language = sys_get_param_str('lang') ? sys_get_param_str('lang') : $player_language; |
|
577
|
|
|
$player_language = $player_language ? $player_language : DEFAULT_LANG; |
|
578
|
|
|
|
|
579
|
|
|
// TODO - дописать эксепшнов в процедуре создания игрока |
|
580
|
|
|
self::$user = player_create($player_name_unsafe, $player_email, array( |
|
581
|
|
|
'partner_id' => $partner_id = sys_get_param_int('id_ref', sys_get_param_int('partner_id')), |
|
582
|
|
|
'language_iso' => static::$db->db_escape($player_language), |
|
583
|
|
|
// 'password_encoded_unsafe' => $this->data[F_ACCOUNT]['account_password'], |
|
|
|
|
|
|
584
|
|
|
// 'salt' => $this->data[F_ACCOUNT]['account_salt'], |
|
|
|
|
|
|
585
|
|
|
)); |
|
586
|
|
|
// Зарегестрировать на него аккаунты из self::$accounts_authorised |
|
587
|
|
|
$a_user = self::$user; |
|
588
|
|
|
foreach ($this->providers_authorised as $provider) { |
|
589
|
|
|
// TODO - порнография. Должен быть отдельный класс трансляторов - в т.ч. и кэширующий транслятор |
|
590
|
|
|
// TODO - ну и работа должна происходить над списком аккаунтов, а не только на одном аккаунте... |
|
591
|
|
|
// self::db_translate_register_user($provider->provider_id, $provider->account->account_id, $a_user['id']); |
|
|
|
|
|
|
592
|
|
|
PlayerToAccountTranslate::db_translate_register_user($provider->provider_id, $provider->account->account_id, $a_user['id']); |
|
593
|
|
|
|
|
594
|
|
|
} |
|
595
|
|
|
// Установить куку игрока |
|
596
|
|
|
self::cookie_set(self::$user['id']); |
|
597
|
|
|
|
|
598
|
|
|
sn_db_transaction_commit(); |
|
599
|
|
|
$this->register_status = LOGIN_SUCCESS; |
|
600
|
|
|
} catch (Exception $e) { |
|
601
|
|
|
sn_db_transaction_rollback(); |
|
602
|
|
|
|
|
603
|
|
|
// Если старое имя занято |
|
604
|
|
|
self::$user = null; |
|
605
|
|
|
$this->register_status == LOGIN_UNDEFINED ? $this->register_status = $e->getMessage() : false; |
|
|
|
|
|
|
606
|
|
|
} |
|
607
|
|
|
} |
|
608
|
|
|
|
|
609
|
|
|
|
|
610
|
|
|
/** |
|
611
|
|
|
* Проверяет доступ авторизированных аккаунтов к заявленным в трансляции юзерам |
|
612
|
|
|
* @version 4.5 |
|
613
|
|
|
*/ |
|
614
|
|
|
// OK v4.5 |
|
615
|
|
|
protected function get_accessible_user_list() { |
|
616
|
|
|
// Пробиваем все ИД игроков по базе - есть ли вообще такие записи |
|
617
|
|
|
// Вообще-то это не особо нужно - у нас по определению стоят констраинты |
|
618
|
|
|
// Зато так мы узнаем максимальный authlevel, проверим права имперсонейта и вытащим все записи юзеров |
|
619
|
|
|
foreach ($this->user_id_to_provider as $user_id => $cork) { |
|
620
|
|
|
$user = DBStaticUser::db_user_by_id($user_id); |
|
621
|
|
|
// Если записи игрока в БД не существует? |
|
622
|
|
|
if (empty($user['id'])) { |
|
623
|
|
|
// Удаляем этого и переходим к следующему |
|
624
|
|
|
unset($this->user_id_to_provider[$user_id]); |
|
625
|
|
|
// Де-регистрируем игрока из таблицы трансляции игроков |
|
626
|
|
|
PlayerToAccountTranslate::db_translate_unregister_user($user_id); |
|
627
|
|
|
} else { |
|
628
|
|
|
$this->accessible_user_row_list[$user['id']] = $user; |
|
629
|
|
|
$this->auth_level_max_local = max($this->auth_level_max_local, $user['authlevel']); |
|
630
|
|
|
} |
|
631
|
|
|
unset($user); |
|
632
|
|
|
} |
|
633
|
|
|
} |
|
634
|
|
|
|
|
635
|
|
|
/** |
|
636
|
|
|
* Выбирает активного игрока из куки или из списка доступных игроков |
|
637
|
|
|
* |
|
638
|
|
|
* @version 4.5 |
|
639
|
|
|
*/ |
|
640
|
|
|
// OK v4.5 |
|
641
|
|
|
protected function get_active_user() { |
|
642
|
|
|
// Проверяем куку "текущего игрока" из браузера |
|
643
|
|
|
if ( |
|
644
|
|
|
// Кука не пустая |
|
645
|
|
|
($_COOKIE[SN_COOKIE_U] = trim($_COOKIE[SN_COOKIE_U])) && !empty($_COOKIE[SN_COOKIE_U]) |
|
646
|
|
|
// И в куке находится ID |
|
647
|
|
|
&& is_id($_COOKIE[SN_COOKIE_U]) |
|
648
|
|
|
// И у аккаунтов есть права на данного игрока |
|
649
|
|
|
&& ( |
|
650
|
|
|
// Есть прямые права из `account_translate` |
|
651
|
|
|
!empty($this->accessible_user_row_list[$_COOKIE[SN_COOKIE_U]]) |
|
652
|
|
|
// Или есть доступ через имперсонейт |
|
653
|
|
|
|| ( |
|
654
|
|
|
// Максимальные права всех доступных записей игроков - не ниже администраторских |
|
655
|
|
|
$this->auth_level_max_local >= AUTH_LEVEL_ADMINISTRATOR |
|
656
|
|
|
// И права игрока, в которого пытаются зайти - меньше текущих максимальных прав |
|
657
|
|
|
&& $this->accessible_user_row_list[$_COOKIE[SN_COOKIE_U]]['authlevel'] < $this->auth_level_max_local |
|
658
|
|
|
) |
|
659
|
|
|
) |
|
660
|
|
|
) { |
|
661
|
|
|
// Берем текущим юзером юзера с ИД из куки |
|
|
|
|
|
|
662
|
|
|
// $this->is_impersonating = empty($this->accessible_user_row_list[$_COOKIE[SN_COOKIE_U]]); |
|
663
|
|
|
// self::$user = self::$accessible_user_row_list[$_COOKIE[SN_COOKIE_U]]; |
|
|
|
|
|
|
664
|
|
|
self::$user = DBStaticUser::db_user_by_id($_COOKIE[SN_COOKIE_U]); |
|
665
|
|
|
} |
|
666
|
|
|
|
|
667
|
|
|
// В куке нет валидного ИД записи игрока, доступной с текущих аккаунтов |
|
668
|
|
|
if (empty(self::$user['id'])) { |
|
669
|
|
|
// Берем первого из доступных |
|
670
|
|
|
// TODO - default_user |
|
671
|
|
|
self::$user = reset($this->accessible_user_row_list); |
|
672
|
|
|
} |
|
673
|
|
|
} |
|
674
|
|
|
|
|
675
|
|
|
|
|
676
|
|
|
|
|
677
|
|
|
/** |
|
678
|
|
|
* Генерирует набор даннх для возврата в основной код |
|
679
|
|
|
*/ |
|
680
|
|
|
// OK v4.5 |
|
681
|
|
|
protected function make_return_array() { |
|
682
|
|
|
$user_id = !empty(self::$user['id']) ? self::$user['id'] : 0; |
|
683
|
|
|
// if(!empty($user_id) && !$user_impersonator) { |
|
|
|
|
|
|
684
|
|
|
// $user_id не может быть пустым из-за констраинтов в таблице SPE |
|
685
|
|
|
// self::db_security_entry_insert(); |
|
|
|
|
|
|
686
|
|
|
self::$device->db_security_entry_insert($user_id); |
|
687
|
|
|
|
|
688
|
|
|
$result = array(); |
|
689
|
|
|
|
|
690
|
|
|
if ($user_id && empty($this->is_impersonating)) { |
|
691
|
|
|
// self::db_counter_insert(); |
|
|
|
|
|
|
692
|
|
|
self::$device->db_counter_insert($user_id); |
|
693
|
|
|
|
|
694
|
|
|
$user = &self::$user; |
|
695
|
|
|
|
|
696
|
|
|
sys_user_options_unpack($user); |
|
697
|
|
|
|
|
698
|
|
|
if ($user['banaday'] && $user['banaday'] <= SN_TIME_NOW) { |
|
699
|
|
|
$user['banaday'] = 0; |
|
700
|
|
|
$user['vacation'] = SN_TIME_NOW; |
|
701
|
|
|
} |
|
702
|
|
|
|
|
703
|
|
|
$user['user_lastip'] = self::$device->ip_v4_string;// $ip['ip']; |
|
|
|
|
|
|
704
|
|
|
$user['user_proxy'] = self::$device->ip_v4_proxy_chain; //$ip['proxy_chain']; |
|
705
|
|
|
|
|
706
|
|
|
$result[F_BANNED_STATUS] = $user['banaday']; |
|
707
|
|
|
$result[F_VACATION_STATUS] = $user['vacation']; |
|
708
|
|
|
|
|
709
|
|
|
$proxy_safe = static::$db->db_escape(self::$device->ip_v4_proxy_chain); |
|
710
|
|
|
|
|
711
|
|
|
DBStaticUser::db_user_set_by_id($user['id'], "`onlinetime` = " . SN_TIME_NOW . ", |
|
712
|
|
|
`banaday` = " . static::$db->db_escape($user['banaday']) . ", `vacation` = " . static::$db->db_escape($user['vacation']) . ", |
|
713
|
|
|
`user_lastip` = '" . static::$db->db_escape($user['user_lastip']) . "', `user_last_proxy` = '{$proxy_safe}', `user_last_browser_id` = " . self::$device->browser_id |
|
714
|
|
|
); |
|
715
|
|
|
} |
|
716
|
|
|
|
|
717
|
|
|
if ($extra = classSupernova::$config->security_ban_extra) { |
|
718
|
|
|
$extra = explode(',', $extra); |
|
719
|
|
|
array_walk($extra, 'trim'); |
|
720
|
|
|
in_array(self::$device->device_id, $extra) and die(); |
|
721
|
|
|
} |
|
722
|
|
|
|
|
723
|
|
|
$result[F_LOGIN_STATUS] = self::$login_status = empty($this->providers_authorised) ? self::$login_status : LOGIN_SUCCESS; |
|
724
|
|
|
$result[F_PLAYER_REGISTER_STATUS] = $this->register_status; |
|
725
|
|
|
$result[F_USER] = self::$user; |
|
726
|
|
|
|
|
727
|
|
|
// $result[AUTH_LEVEL] = isset(self::$user['authlevel']) ? self::$user['authlevel'] : AUTH_LEVEL_ANONYMOUS; |
|
|
|
|
|
|
728
|
|
|
$result[AUTH_LEVEL] = $this->auth_level_max_local; |
|
729
|
|
|
|
|
730
|
|
|
$result[F_IMPERSONATE_STATUS] = $this->is_impersonating; |
|
731
|
|
|
$result[F_IMPERSONATE_OPERATOR] = $this->impersonator_username; |
|
732
|
|
|
// TODO |
|
|
|
|
|
|
733
|
|
|
// self::$hidden[F_IMPERSONATE_OPERATOR] = $found_provider->data[F_IMPERSONATE_OPERATOR]; |
|
734
|
|
|
|
|
735
|
|
|
//TODO Сол и Парол тоже вкинуть в хидден |
|
736
|
|
|
$result[F_ACCOUNTS_AUTHORISED] = $this->providers_authorised; |
|
737
|
|
|
|
|
738
|
|
|
return $result; |
|
739
|
|
|
} |
|
740
|
|
|
|
|
741
|
|
|
|
|
742
|
|
|
// ХЕЛПЕРЫ =========================================================================================================== |
|
743
|
|
|
/** |
|
744
|
|
|
* Функция проверяет корректность имени игрока при регистрации |
|
745
|
|
|
* |
|
746
|
|
|
* @param $player_name_unsafe |
|
747
|
|
|
* |
|
748
|
|
|
* @throws Exception |
|
749
|
|
|
*/ |
|
750
|
|
|
// OK v4 |
|
751
|
|
|
// TODO - вынести в отдельный хелпер |
|
752
|
|
|
protected function register_player_name_validate($player_name_unsafe) { |
|
753
|
|
|
// TODO - переделать под RAW-строки |
|
754
|
|
|
// Если имя игрока пустое - NO GO! |
|
755
|
|
|
if (trim($player_name_unsafe) == '') { |
|
756
|
|
|
throw new Exception(REGISTER_ERROR_PLAYER_NAME_EMPTY, ERR_ERROR); |
|
757
|
|
|
} |
|
758
|
|
|
// Проверяем, что бы в начале и конце не было пустых символов |
|
759
|
|
|
if ($player_name_unsafe != trim($player_name_unsafe)) { |
|
760
|
|
|
throw new Exception(REGISTER_ERROR_PLAYER_NAME_TRIMMED, ERR_ERROR); |
|
761
|
|
|
} |
|
762
|
|
|
// Если логин имеет запрещенные символы - NO GO! |
|
763
|
|
|
if (strpbrk($player_name_unsafe, LOGIN_REGISTER_CHARACTERS_PROHIBITED)) { |
|
764
|
|
|
// TODO - выдавать в сообщение об ошибке список запрещенных символов |
|
765
|
|
|
// TODO - заранее извещать игрока, какие символы являются запрещенными |
|
766
|
|
|
throw new Exception(REGISTER_ERROR_PLAYER_NAME_RESTRICTED_CHARACTERS, ERR_ERROR); |
|
767
|
|
|
} |
|
768
|
|
|
// Если логин меньше минимальной длины - NO GO! |
|
769
|
|
|
if (strlen($player_name_unsafe) < LOGIN_LENGTH_MIN) { |
|
770
|
|
|
// TODO - выдавать в сообщение об ошибке минимальную длину имени игрока |
|
771
|
|
|
// TODO - заранее извещать игрока, какая минимальная и максимальная длина имени |
|
772
|
|
|
throw new Exception(REGISTER_ERROR_PLAYER_NAME_SHORT, ERR_ERROR); |
|
773
|
|
|
} |
|
774
|
|
|
|
|
775
|
|
|
// TODO проверка на максимальную длину имени игрока |
|
776
|
|
|
} |
|
777
|
|
|
|
|
778
|
|
|
/** |
|
779
|
|
|
* Генерирует случайный код для сброса пароля |
|
780
|
|
|
* |
|
781
|
|
|
* @return string |
|
782
|
|
|
*/ |
|
783
|
|
|
// OK v4 |
|
784
|
|
|
public static function make_password_reset_code() { |
|
785
|
|
|
return sys_random_string(LOGIN_PASSWORD_RESET_CONFIRMATION_LENGTH, SN_SYS_SEC_CHARS_CONFIRMATION); |
|
786
|
|
|
} |
|
787
|
|
|
/** |
|
788
|
|
|
* Генерирует случайный пароль |
|
789
|
|
|
* |
|
790
|
|
|
* @return string |
|
791
|
|
|
*/ |
|
792
|
|
|
// OK v4 |
|
793
|
|
|
public static function make_random_password() { |
|
794
|
|
|
return sys_random_string(LOGIN_PASSWORD_RESET_CONFIRMATION_LENGTH, SN_SYS_SEC_CHARS_CONFIRMATION); |
|
795
|
|
|
} |
|
796
|
|
|
/** |
|
797
|
|
|
* Просаливает пароль |
|
798
|
|
|
* |
|
799
|
|
|
* @param $password |
|
800
|
|
|
* @param $salt |
|
801
|
|
|
* |
|
802
|
|
|
* @return string |
|
803
|
|
|
*/ |
|
804
|
|
|
// OK v4 |
|
805
|
|
|
public static function password_encode($password, $salt) { |
|
806
|
|
|
return md5($password . $salt); |
|
807
|
|
|
} |
|
808
|
|
|
/** |
|
809
|
|
|
* Генерирует соль |
|
810
|
|
|
* |
|
811
|
|
|
* @return string |
|
812
|
|
|
*/ |
|
813
|
|
|
// OK v4 |
|
814
|
|
|
public static function password_salt_generate() { |
|
815
|
|
|
// НЕ ПЕРЕКРЫВАТЬ |
|
816
|
|
|
// TODO ВКЛЮЧИТЬ ГЕНЕРАЦИЮ СОЛИ !!! |
|
817
|
|
|
return ''; // sys_random_string(16); |
|
|
|
|
|
|
818
|
|
|
} |
|
819
|
|
|
|
|
820
|
|
|
// OK v4.5 |
|
821
|
|
|
// TODO - REMEMBER_ME |
|
822
|
|
|
protected static function cookie_set($value, $impersonate = false, $period = null) { |
|
823
|
|
|
sn_setcookie($impersonate ? SN_COOKIE_U_I : SN_COOKIE_U, $value, $period === null ? SN_TIME_NOW + PERIOD_YEAR : $period, SN_ROOT_RELATIVE); |
|
824
|
|
|
} |
|
825
|
|
|
|
|
826
|
|
View Code Duplication |
protected static function flog($message, $die = false) { |
|
|
|
|
|
|
827
|
|
|
if (!defined('DEBUG_AUTH') || !DEBUG_AUTH) { |
|
828
|
|
|
return; |
|
829
|
|
|
} |
|
830
|
|
|
list($called, $caller) = debug_backtrace(false); |
|
831
|
|
|
$caller_name = |
|
832
|
|
|
(!empty($caller['class']) ? $caller['class'] : '') . |
|
833
|
|
|
(!empty($caller['type']) ? $caller['type'] : '') . |
|
834
|
|
|
(!empty($caller['function']) ? $caller['function'] : '') . |
|
835
|
|
|
(!empty($called['line']) ? ':' . $called['line'] : ''); |
|
836
|
|
|
|
|
837
|
|
|
$_SERVER['SERVER_NAME'] == 'localhost' ? print("<div class='debug'>$message - $caller_name\r\n</div>") : false; |
|
838
|
|
|
|
|
839
|
|
|
classSupernova::log_file("$message - $caller_name"); |
|
840
|
|
|
if ($die) { |
|
841
|
|
|
// pdump($caller); |
|
|
|
|
|
|
842
|
|
|
// pdump(debug_backtrace(false)); |
|
|
|
|
|
|
843
|
|
|
$die && die("<div class='negative'>СТОП! Функция {$caller_name} при вызове в " . get_called_class() . " (располагается в " . get_class() . "). СООБЩИТЕ АДМИНИСТРАЦИИ!</div>"); |
|
844
|
|
|
} |
|
845
|
|
|
} |
|
846
|
|
|
|
|
847
|
|
|
} |
|
848
|
|
|
|
Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.
The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.
This check looks for comments that seem to be mostly valid code and reports them.