User.php
См. документацию.
1 <?php
2 
3 /**
4  * @file
5  * @brief работа с данными пользователя
6  *
7  */
8 
9 namespace Wrong\Auth;
10 
12 use Wrong\Start\Env;
15 
16 /**
17  * @brief User отвечает за работу с данными пользователя
18  *
19  */
20 class User
21 {
22  /** User ID пользователя, уникальный идентификатор */
23  public $id;
24 
25  /** все активные группы в которых находится пользователь */
26  public $groups = [0];
27 
28  /** группа с максимальным весом в которой находится пользователь */
29  public $main_group_id = 0;
30 
31  /** все "подчинененные" по весу группы кроме гостей и системы */
32  public $subordinate_groups = [];
33 
34  /** вес пользователя, максимальный вес из групп в которых он находится */
35  public $weight = 0;
36 
37  /** максимальный подчиненный вес кроме собственного и системного */
38  public $weight_subordinate = 0;
39 
40  /** доступные каталоги для записи из групп(все подчиненные группы кроме гостей) */
41  public $writeble_paths = [];
42 
43  /** boolean - включена ли запись логов */
44  public $write_log_actions = false;
45 
46  /** boolean - пользователь авторизован по апи */
47  public $is_api = false;
48 
49 
50  /**
51  * конструктор для класса User
52  *
53  * @param int $id ID пользователя
54  */
55  public function __construct($id)
56  {
57  global $request;
58  if ($user = self::get($id)) {
59  if (!$user->act && !empty($_SESSION['user_id'])) {
60  $request = '/disabled';
61  return;
62  }
63  $this->groups = '[0]';
64  foreach ($user as $prop => $value) {
65  $this->$prop = $value;
66  }
67  $this->groups = array_filter(json_decode($this->groups, true), function ($id) {
68  return Group::is_active($id);
69  }) ?: [0];
70  $this->weight = Group::max_weight($this->groups);
71  $this->subordinate_groups = array_column(array_filter(Group::$groups_owners, function ($row) {
72  return ($row->weight < $this->weight || in_array($row->id, $this->groups)) && $row->id != 1;
73  }), 'id') ?: [];
74  $this->main_group_id = Group::max_weight_group($this->groups);
75  $this->writeble_paths = array_column(array_filter(Group::$groups_owners, function ($row) {
76  return ($row->weight < $this->weight || in_array($row->id, $this->groups));
77  }), 'path') ?: [];
78  $this->weight_subordinate = max(array_column(array_filter(Group::$groups_owners, function ($row) {
79  return $row->weight <= $this->weight && $row->id != 1;
80  }), 'weight')) - 1;
81  $this->write_log_actions = max(array_column(array_filter(Group::$groups_owners, function ($row) {
82  return in_array($row->id, $this->groups);
83  }), 'logs'));
84  }
85  }
86 
87 
88  /**
89  * берет текстовый пароль, хэширует его и обновляет пароль пользователя в базе данных.
90  *
91  * @param string $password Пароль для установки.
92  *
93  * @return int Количество строк, затронутых запросом.
94  */
95  public function set_password($password)
96  {
97  $dbh = Connect::getInstance()->dbh;
98  if (!$this->id) return;
99  $password = trim($password);
100  $sth = $dbh->prepare("UPDATE `users` SET `md5password` = :md5password WHERE `id` = :id");
101  $sth->bindValue(':md5password', md5($password));
102  $sth->bindValue(':id', $this->id);
103  $sth->execute();
104  $this->md5password = md5($password);
105  return $sth->rowCount();
106  }
107 
108  /**
109  * обновляет адрес электронной почты пользователя в базе данных.
110  *
111  * @param string $email Адрес электронной почты для установки.
112  *
113  * @return int Количество строк, затронутых запросом.
114  */
115  public function set_email($email)
116  {
117  $dbh = Connect::getInstance()->dbh;
118  if (!$this->id) return;
119  $email = mb_strtolower(trim($email), 'utf-8');
120  $sth = $dbh->prepare("UPDATE `users` SET `email` = ? WHERE `id` = ?");
121  $sth->bindValue(1, $email);
122  $sth->bindValue(2, $this->id);
123  $sth->execute();
124  $this->email = $email;
125  return $sth->rowCount();
126  }
127 
128  /**
129  * обновляет время онлайн пользователя и его текущий ip адрес
130  */
131  public function set_online()
132  {
133  $dbh = Connect::getInstance()->dbh;
134  if (!$this->id) {
136  return;
137  }
138  if (!empty($_COOKIE['FROM_UID'])) return;
139  $sth = $dbh->prepare("UPDATE `users` SET `date_online` = NOW(), `ip` = :ip WHERE `id` = :id AND `act` = 1");
140  $sth->bindValue(':ip', Env::$e->IP);
141  $sth->bindValue(':id', $this->id);
142  $sth->execute();
143  }
144 
145  /**
146  * записывает крайний запрос пользователя в поле
147  *
148  * @param string request
149  *
150  */
151  public function set_request($request)
152  {
153  $dbh = Connect::getInstance()->dbh;
154  if (!$this->id || in_array($request, ['/disabled', '/forbidden'])) {
155  return;
156  }
157  if (!empty($_COOKIE['FROM_UID'])) return;
158  $sth = $dbh->prepare("UPDATE `users` SET `request` = :request WHERE `id` = :id AND `act` = 1");
159  $sth->bindValue(':request', $request);
160  $sth->bindValue(':id', $this->id);
161  $sth->execute();
162  }
163 
164  /**
165  * принимает идентификатор и возвращает пользовательский объект
166  *
167  * @param int $id Идентификатор пользователя
168  *
169  * @return object строки из бд для пользователя.
170  */
171  public static function get($id)
172  {
173  $dbh = Connect::getInstance()->dbh;
174  if (!$id) return;
175  $sth = $dbh->prepare("SELECT * FROM `users` WHERE `id` = ?");
176  $sth->execute([$id]);
177  return $sth->fetch();
178  }
179 
180  /**
181  * сбрасывает сеанс авторизованного пользователя
182  *
183  */
184  public static function session_reset()
185  {
186  global $user;
187  if (!empty($_COOKIE['FROM_UID'])) {
188  setcookie('FROM_UID', 0, [
189  'expires' => time() - 31536000,
190  'path' => '/',
191  'domain' => $_SERVER['HTTP_HOST'],
192  'secure' => Env::$e->IS_SECURE,
193  'httponly' => false,
194  'samesite' => Env::$e->IS_SECURE ? 'None' : 'Lax'
195  ]) or setcookie('FROM_UID', 0, time() - 31536000, '/', $_SERVER['HTTP_HOST'], Env::$e->IS_SECURE);
196  $_COOKIE['FROM_UID'] = 0;
197  if (!empty($_SESSION['user_id'])) {
198  $user = new User($_SESSION['user_id']);
199  }
200  return;
201  }
202  setcookie('UID', 0, [
203  'expires' => time() - 31536000,
204  'path' => '/',
205  'domain' => $_SERVER['HTTP_HOST'],
206  'secure' => Env::$e->IS_SECURE,
207  'httponly' => false,
208  'samesite' => Env::$e->IS_SECURE ? 'None' : 'Lax'
209  ]) or setcookie('UID', 0, time() - 31536000, '/', $_SERVER['HTTP_HOST'], Env::$e->IS_SECURE);
210  $_COOKIE['UID'] = 0;
211  $_SESSION['user_id'] = 0;
212  $user = new User(0);
213  }
214 
215  /**
216  * устанавливает переменную сессии пользователя из инициализирующего id, либо устанавливает сессию по cookie UID - зашифрованный идентификатор, либо сбрасывает сессию
217  *
218  * @param int $init_id инициализирующий идентификатор пользователя, для которого устанавливается сеанс.
219  *
220  * @return int $id Идентификатор пользователя.
221  */
222  public static function session($init_id = 0)
223  {
224  if (!empty($_COOKIE['FROM_UID']) && ($id = Crypt::idDecrypt($_COOKIE['FROM_UID']))) {
225  return $id;
226  }
227  if ($init_id) {
228  $_SESSION['user_id'] = $init_id;
229  }
230  if (!empty($_SESSION['user_id'])) {
231  $id = $_SESSION['user_id'];
232  if (empty($_COOKIE['UID'])) {
234  setcookie('UID', $uid, [
235  'expires' => time() + 31536000,
236  'path' => '/',
237  'domain' => $_SERVER['HTTP_HOST'],
238  'secure' => Env::$e->IS_SECURE,
239  'httponly' => false,
240  'samesite' => Env::$e->IS_SECURE ? 'None' : 'Lax'
241  ]) or setcookie('UID', $uid, time() + 31536000, '/', $_SERVER['HTTP_HOST'], Env::$e->IS_SECURE);
242  $_COOKIE['UID'] = $uid;
243  }
244  } elseif (!empty($_COOKIE['UID'])) {
245  $id = Crypt::idDecrypt($_COOKIE['UID']);
246  $_SESSION['user_id'] = (int) $id;
247  } else {
249  $id = 0;
250  }
251  return $id;
252  }
253 
254 
255  /**
256  * принимает адрес электронной почты в качестве аргумента и возвращает объект пользователя, если адрес электронной почты найден в базе данных.
257  *
258  * @param string $email Адрес электронной почты для соответствия.
259  *
260  * @return object объект пользователя из бд совпадающий с данной почтой.
261  */
262  public static function match($email)
263  {
264  $dbh = Connect::getInstance()->dbh;
265  $email = trim($email);
266  if (empty($email)) {
267  return;
268  }
269  $sth = $dbh->prepare("SELECT * FROM `users` WHERE `email` = ?");
270  $sth->execute([$email]);
271  return $sth->fetch();
272  }
273 
274  /**
275  * Если пользователь существует и хэш md5 адреса электронной почты и пароля совпадает с переданным хэшем md5, вернуть объект пользователя. Используется при восстановлении пароля пользователя
276  *
277  * @param int $id Идентификатор пользователя
278  * @param string $md5 Хэш md5 электронной почты и пароля пользователя.
279  *
280  * @return object|null Пользовательский объект
281  */
282  public static function is_remind($id, $md5)
283  {
284  if (($user = self::get($id)) && $md5 == md5($user->email . $user->md5password)) {
285  return $user;
286  }
287  return;
288  }
289 
290  /**
291  * Если пользователь существует и хэш md5 адреса электронной почты и пароля совпадает с переданным хэшем md5, вернуть объект пользователя. Используется при подтверждении email пользователя
292  *
293  * @param int $id Идентификатор пользователя
294  * @param string $md5 Хэш md5 электронной почты и пароля пользователя.
295  *
296  * @return object|null Пользовательский объект в случае успешной проверки
297  */
298  public static function is_confirm($id, $md5)
299  {
300  if (($user = self::get($id)) && $md5 == md5($user->email . $user->md5password)) {
301  return $user;
302  }
303  return;
304  }
305 
306  /**
307  * устанавливает для поля email_confirmed в таблице пользователей значение 1. Подтверждение почты.
308  *
309  * @param int $email_confirmed 1 = подтверждено, 0 = не подтверждено
310  */
311  public function set_confirm($email_confirmed = 1)
312  {
313  $dbh = Connect::getInstance()->dbh;
314  $dbh->query("UPDATE `users` SET `email_confirmed` = $email_confirmed WHERE `id` = $this->id");
315  $this->email_confirmed = $email_confirmed;
316  }
317 
318 
319  /**
320  * Проверяет права доступа к модели для пользователя, ниже аргументы для методов проверок класса Access
321  *
322  * @param object $row объект строки модели из бд
323  * @param string $request строка запроса к модели
324  * @param int $id идентификатор модели
325  *
326  * $user->access()->read($row); - проверка прав доступа на чтение по объекту строки модели
327  *
328  * $user->access()->write($row); - проверка прав доступа на запись(изменение) по объекту строки модели
329  *
330  * $user->access()->write($row, true); - расширенная проверка прав доступа на запись(изменение) по объекту строки модели, включает системные модели
331  *
332  * $user->access()->is_system($row); - проверяет является ли владельцем данной модели группа система
333  *
334  * $user->access()->page($request); - проверка прав доступа на чтение по request запросу модели страницы (доступен ли такой request)
335  *
336  * $user->access()->page($id); - проверка прав доступа на чтение по id модели страницы (доступна ли модель с таким id)
337  *
338  * $user->access()->modal($request); - проверка прав доступа на чтение по request запросу модели модального окна (доступен ли такой request)
339  *
340  * $user->access()->modal($id); - проверка прав доступа на чтение по id модели модального окна (доступна ли модель с таким id)
341  *
342  * $user->access()->action($request); - проверка прав доступа на чтение по request запросу модели действия (доступен ли такой request)
343  *
344  * $user->access()->action($id); - проверка прав доступа на чтение по id модели действия (доступна ли модель с таким id)
345  *
346  * $user->access()->select($request); - проверка прав доступа на чтение по request запросу модели выборки (доступен ли такой request)
347  *
348  * $user->access()->select($id); - проверка прав доступа на чтение по id модели выборки (доступна ли модель с таким id)
349  *
350  * $user->access()->template($id); - проверка прав доступа на чтение по id модели шаблона (доступна ли модель с таким id)
351  *
352  * @return object объект Access класса с методами проверок
353  */
354  public function access()
355  {
356  return new Access($this);
357  }
358 
359 }
if(!($row=Wrong\Models\Crontabs::find($_POST['id']))) if(! $user->access() ->write($row)) $sth
Definition: edit-cli.php:20
$_SESSION['filter']
Definition: filter.php:22
static idDecrypt($hash)
Definition: Crypt.php:45
static idEncrypt($id)
Definition: Crypt.php:28
User отвечает за работу с данными пользователя
Definition: User.php:21
$subordinate_groups
Definition: User.php:32
static session($init_id=0)
Definition: User.php:222
set_email($email)
Definition: User.php:115
static match($email)
Definition: User.php:262
static is_remind($id, $md5)
Definition: User.php:282
set_password($password)
Definition: User.php:95
set_confirm($email_confirmed=1)
Definition: User.php:311
static is_confirm($id, $md5)
Definition: User.php:298
$weight_subordinate
Definition: User.php:38
$write_log_actions
Definition: User.php:44
set_request($request)
Definition: User.php:151
static session_reset()
Definition: User.php:184
__construct($id)
Definition: User.php:55
Connect создает подключение к базе данных
Definition: Connect.php:19
static getInstance($ignore_error=false)
Definition: Connect.php:50
Access класс, проверки прав доступов
Definition: Access.php:22
Group класс, содержащий статические методы, используемые для управления группами пользователей.
Definition: Group.php:25
static max_weight_group($arr)
Definition: Group.php:87
static max_weight($arr)
Definition: Group.php:69
static $groups_owners
Definition: Group.php:39
static is_active($id)
Definition: Group.php:222
Env класс управляющий, добавляющий или записывающий переменные среды
Definition: Env.php:17
static $e
Definition: Env.php:22
setcookie('FROM_UID', $uid, [ 'expires'=> time()+31536000, 'path'=> '/', 'domain'=> $_SERVER['HTTP_HOST'], 'secure'=> Wrong\Start\Env::$e->IS_SECURE, 'httponly'=> false, 'samesite'=> Wrong\Start\Env::$e->IS_SECURE ? 'None' :'Lax']) or setcookie('FROM_UID' time()+31536000
Definition: from-user.php:36
setcookie('FROM_UID', $uid, [ 'expires'=> time()+31536000, 'path'=> '/', 'domain'=> $_SERVER['HTTP_HOST'], 'secure'=> Wrong\Start\Env::$e->IS_SECURE, 'httponly'=> false, 'samesite'=> Wrong\Start\Env::$e->IS_SECURE ? 'None' :'Lax']) or setcookie('FROM_UID' Wrong Start Env::$e IS_SECURE
Definition: from-user.php:36
$user
Definition: from-user.php:38
if(!($row=Wrong\Models\Users::find($_POST['id']))) if($row->id==$user->id) if(! $user->access() ->write($row)) $uid
Definition: from-user.php:28
setcookie('FROM_UID', $uid, [ 'expires'=> time()+31536000, 'path'=> '/', 'domain'=> $_SERVER['HTTP_HOST'], 'secure'=> Wrong\Start\Env::$e->IS_SECURE, 'httponly'=> false, 'samesite'=> Wrong\Start\Env::$e->IS_SECURE ? 'None' :'Lax']) or setcookie('FROM_UID' $_SERVER['HTTP_HOST']
Definition: from-user.php:36
catch(\Throwable $th) $request
Definition: session.php:28
$dbh
Definition: session.php:19