Files
kobcrane-montaze.pl/autoload/admin/factory/class.Users.php
Jacek Pyziak c9ed7b5d5d Add author management functionality and update routing rules
- Updated .htaccess rules to allow trailing slashes for specific routes.
- Introduced a new .gitignore file to exclude the cache directory.
- Created project configuration file for Serena with language and tool settings.
- Implemented Authors class for managing author data, including methods for saving, deleting, and editing authors.
- Added factory class for Authors to handle database interactions related to authors.
- Developed Article class to manage article data and interactions, including fetching articles and updating views.
- Created Page class with a placeholder method for sorting pages.
- Added front factory class for fetching author details with caching.
2026-02-27 11:28:56 +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;
}
}