| Server IP : 193.86.120.172 / Your IP : 216.73.216.67 Web Server : Apache/2.4.63 (Unix) System : Linux JServices 3.10.108 #86003 SMP Wed Oct 22 13:20:46 CST 2025 x86_64 User : kubec ( 1026) PHP Version : 8.2.28 Disable Function : NONE MySQL : OFF | cURL : ON | WGET : ON | Perl : ON | Python : OFF | Sudo : ON | Pkexec : OFF Directory : /volume1/web/hotellesnizatisi_cz/new/includes/ |
Upload File : |
<?php
// ============================================================
// Autentizace a session — pracuje s tabulkami uzivatele / uzivatel_session
// ============================================================
require_once __DIR__ . '/db.php';
if (session_status() === PHP_SESSION_NONE) {
session_start();
}
// Sekce, ke kterým lze zaměstnanci individuálně udělit přístup.
// Nastavení a Uživatelé záměrně NEJSOU delegovatelné — vždy jen admin/manažer.
const DELEGOVATELNE_SEKCE = ['obsah', 'doplnky', 'okoli', 'cenik', 'fotky'];
const SEKCE_URL = [
'obsah' => 'obsah.php',
'doplnky' => 'doplnky.php',
'okoli' => 'okoli.php',
'cenik' => 'cenik.php',
'fotky' => 'fotky.php',
];
const SEKCE_NAZEV = [
'obsah' => 'Texty sekcí',
'doplnky' => 'Doplňky',
'okoli' => 'V okolí',
'cenik' => 'Ceník a storno',
'fotky' => 'Fotky',
];
/**
* Pokusí se přihlásit uživatele podle e-mailu a hesla.
* Při úspěchu založí záznam v uzivatel_session a uloží token do PHP session.
*/
function auth_login(string $username, string $password): bool
{
$stmt = db()->prepare('SELECT * FROM uzivatele WHERE uzivatelske_jmeno = ? AND aktivni = 1');
$stmt->execute([$username]);
$user = $stmt->fetch();
if (!$user || !password_verify($password, $user['heslo_hash'])) {
return false;
}
$token = bin2hex(random_bytes(32));
$platnost = date('Y-m-d H:i:s', strtotime('+' . SESSION_LIFETIME_HOURS . ' hours'));
db()->prepare('INSERT INTO uzivatel_session (token, uzivatel_id, platnost_do) VALUES (?, ?, ?)')
->execute([$token, $user['id'], $platnost]);
db()->prepare('UPDATE uzivatele SET posledni_prihlaseni = NOW() WHERE id = ?')
->execute([$user['id']]);
$_SESSION['token'] = $token;
return true;
}
/**
* Vrátí aktuálně přihlášeného uživatele (pole z tabulky uzivatele), nebo null.
*/
function auth_user(): ?array
{
if (empty($_SESSION['token'])) {
return null;
}
$stmt = db()->prepare('
SELECT u.*
FROM uzivatel_session s
JOIN uzivatele u ON u.id = s.uzivatel_id
WHERE s.token = ? AND s.platnost_do > NOW() AND u.aktivni = 1
');
$stmt->execute([$_SESSION['token']]);
$user = $stmt->fetch();
return $user ?: null;
}
/**
* Odhlásí uživatele — smaže session záznam v DB i v PHP session.
*/
function auth_logout(): void
{
if (!empty($_SESSION['token'])) {
db()->prepare('DELETE FROM uzivatel_session WHERE token = ?')
->execute([$_SESSION['token']]);
}
$_SESSION = [];
session_destroy();
}
/**
* Vyžaduje přihlášení. Pokud uživatel není přihlášen, přesměruje na login.php.
* Pokud má nastavený příznak vyzaduje_zmenu_hesla, přesměruje na zmenit-heslo.php
* (kromě situace, kdy už na té stránce je — aby nevznikla smyčka).
* Vrací pole přihlášeného uživatele.
*/
function require_login(): array
{
$user = auth_user();
if (!$user) {
header('Location: login.php');
exit;
}
$current = basename($_SERVER['SCRIPT_NAME']);
if ((int) $user['vyzaduje_zmenu_hesla'] === 1 && !in_array($current, ['zmenit-heslo.php', 'logout.php'], true)) {
header('Location: zmenit-heslo.php');
exit;
}
return $user;
}
/**
* Vyžaduje přihlášení A konkrétní roli (např. ['admin'] nebo ['admin','manazer']).
* Při nedostatečném oprávnění vrátí 403. Používá se pro Nastavení a Uživatelé —
* sekce, které NEJSOU individuálně delegovatelné na zaměstnance.
*/
function require_role(array $allowedRoles): array
{
$user = require_login();
if (!in_array($user['role'], $allowedRoles, true)) {
http_response_code(403);
die('Nemáte oprávnění k této stránce.');
}
return $user;
}
/**
* Vrátí seznam sekcí (klíčů z DELEGOVATELNE_SEKCE), ke kterým má daný
* zaměstnanec individuálně udělený přístup. Pro admin/manažera nevolat —
* ti mají vždy přístup ke všem sekcím bez ohledu na tuto tabulku.
*/
function ziskej_opravneni_zamestnance(int $uzivatelId): array
{
$stmt = db()->prepare('SELECT sekce FROM uzivatele_opravneni WHERE uzivatel_id = ?');
$stmt->execute([$uzivatelId]);
return $stmt->fetchAll(PDO::FETCH_COLUMN);
}
/**
* Zjistí, jestli má daný uživatel (pole z tabulky uzivatele) přístup
* na danou sekci. Admin a manažer mají vždy přístup ke všem sekcím
* (Nastavení a Uživatelé navíc kontroluje samostatně require_role()).
* Zaměstnanec jen k sekcím, které mu byly individuálně přidělené.
*/
function user_can(array $user, string $sekce): bool
{
if (in_array($user['role'], ['admin', 'manazer'], true)) {
return true;
}
if ($user['role'] === 'zamestnanec') {
return in_array($sekce, ziskej_opravneni_zamestnance((int) $user['id']), true);
}
return false;
}
/**
* Vyžaduje přihlášení A přístup ke konkrétní obsahové sekci (viz
* DELEGOVATELNE_SEKCE). Admin/manažer projdou vždy, zaměstnanec jen
* pokud má sekci individuálně přidělenou. Vrací pole uživatele.
*/
function require_section(string $sekce): array
{
$user = require_login();
if (!user_can($user, $sekce)) {
http_response_code(403);
die('Nemáte oprávnění k této sekci. O přístup požádejte svého manažera nebo admina.');
}
return $user;
}
/**
* Vrátí cestu k "domovské" stránce administrace pro daného uživatele.
* Admin/manažer vždy Texty sekcí. Zaměstnanec první sekci, ke které má
* přístup, nebo bez-pristupu.php, pokud nemá přidělenou žádnou.
*/
function home_url_for_user(array $user): string
{
if (in_array($user['role'], ['admin', 'manazer'], true)) {
return 'obsah.php';
}
foreach (DELEGOVATELNE_SEKCE as $sekce) {
if (user_can($user, $sekce)) {
return SEKCE_URL[$sekce];
}
}
return 'bez-pristupu.php';
}
/**
* Vygeneruje náhodné dočasné heslo (12 znaků, vždy obsahuje velké/malé písmeno,
* číslici i speciální znak). Vynechává znaky snadno zaměnitelné (I, l, O, 0, 1).
*/
function generate_temp_password(): string
{
$upper = 'ABCDEFGHJKLMNPQRSTUVWXYZ';
$lower = 'abcdefghijkmnopqrstuvwxyz';
$digits = '23456789';
$special = '!@#$%&*';
$all = $upper . $lower . $digits . $special;
$password = $upper[random_int(0, strlen($upper) - 1)]
. $lower[random_int(0, strlen($lower) - 1)]
. $digits[random_int(0, strlen($digits) - 1)]
. $special[random_int(0, strlen($special) - 1)];
for ($i = 0; $i < 8; $i++) {
$password .= $all[random_int(0, strlen($all) - 1)];
}
return str_shuffle($password);
}