Files
maria_uslugi/admin/tools/connecter_en_admin.php

212 lines
8.6 KiB
PHP
Raw Permalink 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
// admin/tools/connecter_en_admin.php
require_once __DIR__ . '/../../public/includes/init_admin.php';
const ADMIN_PRACTICIEN_ID = 88888888;
$me = (int) ($_SESSION['reference_id'] ?? 0);
if ($me !== ADMIN_PRACTICIEN_ID) {
http_response_code(403);
echo '<div class="container py-5"><div class="alert alert-danger">' . htmlspecialchars(($translations['access_denied'] ?? 'Доступ запрещён.'), ENT_QUOTES, 'UTF-8') . '</div></div>';
exit;
}
// reauth (10 min)
$mustReauth = function (int $ttl = 600) {$t = (int) ($_SESSION['admin_reauth_at'] ?? 0);return ($t === 0 || (time() - $t) > $ttl);};
if ($mustReauth()) {
$qs = http_build_query(['page' => 'reauth', 'redir' => ($_SERVER['REQUEST_URI'] ?? 'index.php?page=maintenance')]);
header('Location:?' . $qs);
exit;
}
// CSRF
if (! isset($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = bin2hex(random_bytes(32));
}
$CSRF = $_SESSION['csrf_token'];
function e($s)
{return htmlspecialchars((string) $s, ENT_QUOTES, 'UTF-8');}
// Helpers DB : test existence de la table de log
function tableExists(PDO $pdo, string $table): bool
{
$sql = "SELECT 1 FROM information_schema.TABLES
WHERE TABLE_SCHEMA = DATABASE() AND TABLE_NAME = ? LIMIT 1";
$st = $pdo->prepare($sql);
$st->execute([$table]);
return (bool) $st->fetchColumn();
}
// ------------ Traitement POST ------------
$flash = null;
if (($_POST['do'] ?? '') === 'impersonate') {
try {
if (! hash_equals($_SESSION['csrf_token'] ?? '', $_POST['csrf'] ?? '')) {
throw new Exception('CSRF');
}
$email = trim((string) ($_POST['email'] ?? ''));
if ($email === '') {
throw new Exception('NO_EMAIL');
}
// On cherche dans la table compte (à adapter si le nom diffère)
$sql = "SELECT id, email, role, reference_id
FROM compte
WHERE email = ?
LIMIT 1";
$st = $pdo->prepare($sql);
$st->execute([$email]);
$user = $st->fetch(PDO::FETCH_ASSOC);
if (! $user) {
throw new Exception('NOT_FOUND');
}
$role = (string) ($user['role'] ?? '');
// On autorise seulement certains rôles à être "impersonnés"
$allowedRoles = ['praticien', 'client'];
if (! in_array($role, $allowedRoles, true)) {
throw new Exception('ROLE_FORBIDDEN');
}
// Sauvegarder l’admin actuel si ce n’est pas déjà fait
if (empty($_SESSION['admin_impersonate']) || ! is_array($_SESSION['admin_impersonate'])) {
$_SESSION['admin_impersonate'] = [
'admin_compte_id' => $_SESSION['compte_id'] ?? null,
'admin_reference_id' => $_SESSION['reference_id'] ?? null,
'admin_role' => $_SESSION['role'] ?? null,
'started_at' => time(),
];
}
// Log de l’action si la table existe
if (tableExists($pdo, 'admin_impersonation_log')) {
$ip = $_SERVER['REMOTE_ADDR'] ?? null;
$ua = $_SERVER['HTTP_USER_AGENT'] ?? null;
$adminUid = (int) ($_SESSION['compte_id'] ?? 0);
$adminRef = (int) ($_SESSION['reference_id'] ?? 0);
$targetUid = (int) ($user['id'] ?? 0);
$targetRef = (int) ($user['reference_id'] ?? 0);
$emailLog = (string) ($user['email'] ?? '');
$logSql = "INSERT INTO admin_impersonation_log
(admin_user_id, admin_reference_id, target_user_id, target_reference_id, target_role, email, ip, user_agent)
VALUES (?,?,?,?,?,?,?,?)";
$pdo->prepare($logSql)->execute([
$adminUid,
$adminRef,
$targetUid,
$targetRef,
$role,
$emailLog,
$ip,
$ua,
]);
}
// Basculer la session sur l’utilisateur cible
session_regenerate_id(true);
unset(
$_SESSION['client_id'],
$_SESSION['praticien_id'],
$_SESSION['secretaire_id'],
$_SESSION['admin_id'],
$_SESSION['compte_id'],
$_SESSION['reference_id'],
$_SESSION['role']
);
$_SESSION['compte_id'] = (int) $user['id'];
$_SESSION['role'] = $role;
$_SESSION['reference_id'] = (int) ($user['reference_id'] ?? 0);
$_SESSION['last_activity'] = time();
if ($role === 'praticien') {
$_SESSION['praticien_id'] = (int) $user['reference_id'];
} elseif ($role === 'client') {
$_SESSION['client_id'] = (int) $user['reference_id'];
}
// Redirection selon le rôle
if ($role === 'praticien') {
header('Location: /public/praticien/agenda.php');
} elseif ($role === 'client') {
header('Location: /public/client/mes_rendez_vous.php');
} else {
// fallback
header('Location: /');
}
exit;
} catch (Throwable $e) {
$code = $e->getMessage();
$msg = ($translations['admin_impersonate_err_default'] ?? 'Ошибка при подключении.');
if ($code === 'CSRF') {
$msg = ($translations['admin_impersonate_err_csrf'] ?? 'Ошибка безопасности. Обновите страницу.');
}
if ($code === 'NO_EMAIL') {
$msg = ($translations['admin_impersonate_err_no_email'] ?? 'Укажите e-mail практикующего или клиента.');
}
if ($code === 'NOT_FOUND') {
$msg = ($translations['admin_impersonate_err_not_found'] ?? 'Пользователь с таким e-mail не найден.');
}
if ($code === 'ROLE_FORBIDDEN') {
$msg = ($translations['admin_impersonate_err_role_forbidden'] ?? 'Невозможно подключиться под этим типом пользователя.');
}
$flash = ['type' => 'danger', 'msg' => $msg];
}
}
// Indicateur si on est déjà en mode impersonation (admin_impersonate présent)
$isImpersonating = ! empty($_SESSION['admin_impersonate']) && is_array($_SESSION['admin_impersonate']);
?>
<div class="shadow p-4 rounded bg-light">
<h2 class="mb-3"><?php echo e($translations['admin_impersonate_title'] ?? 'Подключиться как пользователь') ?></h2>
<?php if ($isImpersonating): ?>
<div class="alert alert-warning">
<?php echo e($translations['admin_impersonate_warn_active'] ?? 'Внимание: сейчас вы авторизованы как другой пользователь.') ?>
<a href="/admin/index.php?page=retour_admin" class="btn btn-sm btn-outline-danger ms-2" style="border-radius:999px;">
<?php echo e($translations['admin_impersonate_btn_back_admin'] ?? 'Вернуться в режим администратора') ?>
</a>
</div>
<?php endif; ?>
<?php if ($flash): ?>
<div class="alert alert-<?php echo e($flash['type'] ?? 'info') ?>"><?php echo e($flash['msg'] ?? '') ?></div>
<?php endif; ?>
<form method="post" class="mb-4">
<input type="hidden" name="csrf" value="<?php echo e($CSRF) ?>">
<input type="hidden" name="do" value="impersonate">
<div class="mb-3">
<label class="form-label"><?php echo e($translations['admin_impersonate_label_email'] ?? 'E-mail практикующего или клиента') ?></label>
<input type="email" name="email" class="form-control" required
placeholder="<?php echo e($translations['admin_impersonate_ph_email'] ?? 'example@domaine.fr') ?>">
<div class="form-text">
<?php echo e($translations['admin_impersonate_help'] ?? 'Администратор будет авторизован под этим пользователем без ввода пароля.') ?>
</div>
</div>
<button type="submit" class="btn btn-danger" style="border-radius:999px;">
<?php echo e($translations['admin_impersonate_btn_submit'] ?? 'Подключиться под этим пользователем') ?>
</button>
</form>
<hr>
<p class="text-muted mb-0">
<?php echo e($translations['admin_impersonate_footer'] ?? 'Все действия должны соответствовать политике конфиденциальности. Доступ к этой функции есть только у супер-администратора.') ?>
</p>
</div>