Files
it.vidok.com/autoload/admin/factory/class.Users.php
2026-03-02 16:32:35 +01:00

307 lines
8.3 KiB
PHP
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
<?php
namespace admin\factory;
class Users
{
public static function user_delete($user_id)
{
global $mdb;
return $mdb->delete('pp_users', ['id' => (int)$user_id]);
}
public static function user_details($user_id)
{
global $mdb;
return $mdb->get('pp_users', '*', ['id' => (int)$user_id]);
}
public static function user_privileges($user_id)
{
global $mdb;
return $mdb->select('pp_users_privileges', '*', ['id_user' => (int)$user_id]);
}
public static function user_save($user_id, $login, $status, $active_to, $password, $password_re, $admin, $privileges, $twofa_enabled = 0, $twofa_email = '' )
{
global $mdb, $lang;
$mdb->delete('pp_users_privileges', ['id_user' => (int) $user_id]);
if (!$user_id)
{
if (strlen($password) < 5)
return $response = ['status' => 'error', 'msg' => 'Podane hasło jest zbyt krótkie.'];
if ($password != $password_re)
return $response = ['status' => 'error', 'msg' => 'Podane hasła są różne'];
if ($mdb->insert(
'pp_users',
[
'login' => $login,
'status' => $status == 'on' ? 1 : 0,
'active_to' => $active_to == '' ? NULL : $active_to,
'admin' => $admin,
'password' => md5($password),
'twofa_enabled' => $twofa_enabled == 'on' ? 1 : 0,
'twofa_email' => $twofa_email
]
))
$id_user = $mdb->get('pp_users', 'id', ['ORDER' => ['id' => 'DESC']]);
if (is_array($privileges))
{
foreach ($privileges as $pri)
{
$mdb->insert(
'pp_users_privileges',
[
'name' => $pri,
'id_user' => $id_user
]
);
}
}
else
{
$mdb->insert(
'pp_users_privileges',
[
'name' => $privileges,
'id_user' => $id_user
]
);
}
return $response = ['status' => 'ok', 'msg' => 'Użytkownik został zapisany.'];
}
else
{
if ($password and strlen($password) < 5)
return $response = ['status' => 'error', 'msg' => 'Podane hasło jest zbyt krótkie.'];
if ($password and $password != $password_re)
return $response = ['status' => 'error', 'msg' => 'Podane hasła są różne'];
if ($password)
$mdb->update('pp_users', [
'password' => md5($password)
], [
'id' => (int) $user_id
]);
$mdb->update('pp_users', [
'login' => $login,
'admin' => $admin,
'status' => $status == 'on' ? 1 : 0,
'active_to' => $active_to == '' ? NULL : $active_to,
'error_logged_count' => 0,
'twofa_enabled' => $twofa_enabled == 'on' ? 1 : 0,
'twofa_email' => $twofa_email
], [
'id' => (int) $user_id
]);
if (is_array($privileges))
{
foreach ($privileges as $pri)
{
$mdb->insert('pp_users_privileges', [
'name' => $pri,
'id_user' => $user_id
]);
}
}
else
{
$mdb->insert('pp_users_privileges', [
'name' => $privileges,
'id_user' => $user_id
]);
}
return $response = ['status' => 'ok', 'msg' => 'Uzytkownik został zapisany.'];
}
\S::delete_cache();
}
public static function check_login($login, $user_id)
{
global $mdb;
if ($mdb->get('pp_users', 'login', ['AND' => ['login' => $login, 'id[!]' => (int)$user_id]]))
return $response = ['status' => 'error', 'msg' => 'Podany login jest już zajęty.'];
return $response = ['status' => 'ok'];
}
public static function logon($login, $password)
{
global $mdb;
if (!$mdb->get('pp_users', '*', ['login' => $login]))
return 0;
if (!$mdb->get('pp_users', '*', ['AND' => ['login' => $login, 'status' => 1, 'error_logged_count[<]' => 5]]))
return -1;
if ($mdb->get('pp_users', '*', [
'AND' => [
'login' => $login,
'status' => 1,
'password' => md5($password),
'OR' => ['active_to[>=]' => date('Y-m-d'), 'active_to' => null]
]
]))
{
$mdb->update('pp_users', ['last_logged' => date('Y-m-d H:i:s'), 'error_logged_count' => 0], ['login' => $login]);
return 1;
}
else
{
$mdb->update('pp_users', ['last_error_logged' => date('Y-m-d H:i:s'), 'error_logged_count[+]' => 1], ['login' => $login]);
if ($mdb->get('pp_users', 'error_logged_count', ['login' => $login]) >= 5)
{
$mdb->update('pp_users', ['status' => 0], ['login' => $login]);
return -1;
}
}
return 0;
}
public static function details($login)
{
global $mdb;
return $mdb->get('pp_users', '*', ['login' => $login]);
}
public static function check_privileges($name, $user_id)
{
global $mdb;
if ($user_id == 1)
return true;
else
{
if (!$privilages = \Cache::fetch("check_privileges:$user_id:$name-tmp"))
{
$privilages = $mdb->count('pp_users_privileges', ['AND' => ['name' => $name, 'id_user' => (int)$user_id]]);
\Cache::store("check_privileges:$user_id:$name", $privilages);
}
return $privilages;
}
}
static public function get_by_id(int $userId): ?array
{
global $mdb;
return $mdb->get('pp_users', '*', ['id' => $userId]) ?: null;
}
static public function send_twofa_code(int $userId, bool $resend = false): bool
{
$user = self::get_by_id($userId);
if (!$user)
return false;
if ((int)$user['twofa_enabled'] !== 1)
{
return false;
}
$to = $user['twofa_email'] ?: $user['login'];
if (!filter_var($to, FILTER_VALIDATE_EMAIL))
{
return false;
}
if ($resend && !empty($user['twofa_sent_at']))
{
$last = strtotime($user['twofa_sent_at']);
if ($last && (time() - $last) < 30)
{
return false;
}
}
$code = random_int(100000, 999999);
$hash = password_hash((string)$code, PASSWORD_DEFAULT);
self::update_by_id($userId, [
'twofa_code_hash' => $hash,
'twofa_expires_at' => date('Y-m-d H:i:s', time() + 10 * 60), // 10 minut
'twofa_sent_at' => date('Y-m-d H:i:s'),
'twofa_failed_attempts' => 0,
]);
$subject = 'Twój kod logowania 2FA';
$body = "Twój kod logowania do panelu administratora: {$code}. Kod jest ważny przez 10 minut. Jeśli to nie Ty inicjowałeś logowanie zignoruj tę wiadomość i poinformuj administratora.";
$sent = \S::send_email($to, $subject, $body);
if (!$sent) {
$headers = "MIME-Version: 1.0\r\n";
$headers .= "Content-type: text/plain; charset=UTF-8\r\n";
$headers .= "From: no-reply@" . ($_SERVER['HTTP_HOST'] ?? 'localhost') . "\r\n";
$encodedSubject = mb_encode_mimeheader($subject, 'UTF-8');
$sent = mail($to, $encodedSubject, $body, $headers);
}
return $sent;
}
static public function update_by_id(int $userId, array $data): bool
{
global $mdb;
return (bool)$mdb->update('pp_users', $data, ['id' => $userId]);
}
static public function verify_twofa_code(int $userId, string $code): bool
{
$user = self::get_by_id( $userId );
if (!$user) return false;
if ((int)$user['twofa_failed_attempts'] >= 5)
{
return false; // zbyt wiele prób
}
// sprawdź ważność
if (empty($user['twofa_expires_at']) || time() > strtotime($user['twofa_expires_at']))
{
// wyczyść po wygaśnięciu
self::update_by_id($userId, [
'twofa_code_hash' => null,
'twofa_expires_at' => null,
]);
return false;
}
$ok = (!empty($user['twofa_code_hash']) && password_verify($code, $user['twofa_code_hash']));
if ($ok)
{
// sukces: czyścimy wszystko
self::update_by_id($userId, [
'twofa_code_hash' => null,
'twofa_expires_at' => null,
'twofa_sent_at' => null,
'twofa_failed_attempts' => 0,
'last_logged' => date('Y-m-d H:i:s'),
]);
return true;
}
// zła próba — inkrementacja
self::update_by_id($userId, [
'twofa_failed_attempts' => (int)$user['twofa_failed_attempts'] + 1,
'last_error_logged' => date('Y-m-d H:i:s'),
]);
return false;
}
}