Init Git Prod Mars 2026
This commit is contained in:
commit
d81efe93b1
362 files changed
+86627
No files matched your search
@@ -0,0 +1,179 @@
|
||||
<?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_user_id' => $_SESSION['user_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['user_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['user_id'] = (int)$user['id'];
|
||||
$_SESSION['role'] = $role;
|
||||
$_SESSION['reference_id'] = (int)($user['reference_id'] ?? 0);
|
||||
|
||||
// Redirection selon le rôle
|
||||
if ($role === 'praticien') {
|
||||
header('Location: /public/espace_praticien/index.php');
|
||||
} elseif ($role === 'client') {
|
||||
header('Location: /public/espace_client/index.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"><?= e($translations['admin_impersonate_title'] ?? 'Подключиться как пользователь') ?></h2>
|
||||
|
||||
<?php if ($isImpersonating): ?>
|
||||
<div class="alert alert-warning">
|
||||
<?= 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;">
|
||||
<?= e($translations['admin_impersonate_btn_back_admin'] ?? 'Вернуться в режим администратора') ?>
|
||||
</a>
|
||||
</div>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ($flash): ?>
|
||||
<div class="alert alert-<?= e($flash['type'] ?? 'info') ?>"><?= e($flash['msg'] ?? '') ?></div>
|
||||
<?php endif; ?>
|
||||
|
||||
<form method="post" class="mb-4">
|
||||
<input type="hidden" name="csrf" value="<?= e($CSRF) ?>">
|
||||
<input type="hidden" name="do" value="impersonate">
|
||||
|
||||
<div class="mb-3">
|
||||
<label class="form-label"><?= e($translations['admin_impersonate_label_email'] ?? 'E-mail практикующего или клиента') ?></label>
|
||||
<input type="email" name="email" class="form-control" required
|
||||
placeholder="<?= e($translations['admin_impersonate_ph_email'] ?? 'example@domaine.fr') ?>">
|
||||
<div class="form-text">
|
||||
<?= e($translations['admin_impersonate_help'] ?? 'Администратор будет авторизован под этим пользователем без ввода пароля.') ?>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<button type="submit" class="btn btn-danger" style="border-radius:999px;">
|
||||
<?= e($translations['admin_impersonate_btn_submit'] ?? 'Подключиться под этим пользователем') ?>
|
||||
</button>
|
||||
</form>
|
||||
|
||||
<hr>
|
||||
|
||||
<p class="text-muted mb-0">
|
||||
<?= e($translations['admin_impersonate_footer'] ?? 'Все действия должны соответствовать политике конфиденциальности. Доступ к этой функции есть только у супер-администратора.') ?>
|
||||
</p>
|
||||
</div>
|
||||
Reference in new issue
Block a user