/
delphin
/
CatRW
Обзор
Документация
Войти
/
delphin
/
CatRW
Код
Запросы
0
Задачи
Вики
Пакеты
0
Релизы
0
CI/CD
Аналитика
Безопасность
master
api/Auth.php
341 строка
12 KB
delphin
start project
02 мар 2026, 09:14
Верифицирован
02 мар 2026, 09:14
4b0ee03
Код
Авторство
О чём код?
<?php // /api/Auth.php - ПЕРЕПИСАННЫЙ, ЧИСТЫЙ И ПОНЯТНЫЙ class Auth { // === КОНФИГУРАЦИЯ === private static $roleHierarchy = [ 'guest' => 0, // Неавторизованные 'editor' => 1, // Может добавлять/редактировать своё 'admin' => 2, // Может всё кроме управления пользователями 'root' => 3 // Полный доступ ]; // === ОСНОВНЫЕ МЕТОДЫ === /** * Авторизация пользователя */ public static function login($username, $password) { // Находим пользователя $sql = "SELECT * FROM users WHERE username = ? OR email = ?"; $user = Database::selectOne($sql, [$username, $username]); if (!$user) { return ['success' => false, 'error' => 'Пользователь не найден']; } // Проверяем пароль if (!password_verify($password, $user['password_hash'])) { return ['success' => false, 'error' => 'Неверный пароль']; } // Проверяем статус аккаунта if (!$user['is_active']) { return ['success' => false, 'error' => 'Аккаунт деактивирован']; } if ($user['is_banned']) { return ['success' => false, 'error' => 'Аккаунт заблокирован']; } // Обновляем время входа Database::query("UPDATE users SET last_login = NOW() WHERE id = ?", [$user['id']]); // Устанавливаем сессию self::setSession($user); return ['success' => true, 'user' => self::getSafeUserData($user)]; } /** * Выход из системы */ public static function logout() { session_destroy(); if (isset($_COOKIE[session_name()])) { setcookie(session_name(), '', time() - 3600, '/'); } } /** * Проверка авторизации */ public static function check() { return isset($_SESSION['user_id']); } // === ПОЛУЧЕНИЕ ДАННЫХ ПОЛЬЗОВАТЕЛЯ === /** * Получить данные текущего пользователя */ public static function user() { if (!self::check()) { return null; } return [ 'id' => $_SESSION['user_id'], 'username' => $_SESSION['username'], 'role' => $_SESSION['user_role'], 'email' => $_SESSION['email'], 'full_name' => $_SESSION['full_name'] ]; } /** * Получить ID текущего пользователя */ public static function id() { return $_SESSION['user_id'] ?? null; } /** * Получить имя пользователя */ public static function username() { return $_SESSION['username'] ?? 'Гость'; } /** * Получить роль пользователя */ public static function role() { return $_SESSION['user_role'] ?? 'guest'; } // === ПРОВЕРКИ ПРАВ === /** * Проверка на наличие роли (с иерархией) */ public static function hasRole($requiredRole) { $userRole = self::role(); // Гость имеет только права гостя if ($userRole === 'guest') { return $requiredRole === 'guest'; } // Проверяем по иерархии $requiredLevel = self::$roleHierarchy[$requiredRole] ?? 0; $userLevel = self::$roleHierarchy[$userRole] ?? 0; return $userLevel >= $requiredLevel; } /** * Проверка и редирект если нет прав */ public static function requireRole($role) { if (!self::check()) { $redirect = urlencode($_SERVER['REQUEST_URI'] ?? '/'); header("Location: /login?redirect=$redirect"); exit; } if (!self::hasRole($role)) { http_response_code(403); // Красивая страница 403 для пользователей if (strpos($_SERVER['HTTP_ACCEPT'] ?? '', 'application/json') !== false) { header('Content-Type: application/json'); echo json_encode([ 'success' => false, 'error' => 'Доступ запрещён. Недостаточно прав.', 'required_role' => $role, 'your_role' => self::role() ]); } else { echo ' <!DOCTYPE html> <html> <head> <title>Доступ запрещён</title> <style> body { font-family: Arial, sans-serif; text-align: center; padding: 50px; } h1 { color: #e74c3c; } .info { background: #f8f9fa; padding: 20px; border-radius: 5px; margin: 20px auto; max-width: 500px; } </style> </head> <body> <h1>🚫 Доступ запрещён</h1> <div class="info"> <p><strong>Требуется роль:</strong> ' . htmlspecialchars($role) . '</p> <p><strong>Ваша роль:</strong> ' . htmlspecialchars(self::role()) . '</p> </div> <p><a href="/">На главную</a> | <a href="/logout">Выйти и зайти под другим пользователем</a></p> </body> </html>'; } exit; } } // === СПЕЦИАЛЬНЫЕ ПРОВЕРКИ (ДЛЯ УДОБСТВА) === /** * Только для админ-панели (admin и root) */ public static function requireAdminPanel() { self::requireRole('admin'); // editor не достаточно } /** * Только для управления пользователями (только root) */ public static function requireRootAccess() { self::requireRole('root'); } /** * Только для редакторов и выше */ public static function requireEditorAccess() { self::requireRole('editor'); } /** * Проверка является ли root */ public static function isRoot() { return self::role() === 'root'; } /** * Проверка является ли admin (или root) */ public static function isAdmin() { return self::hasRole('admin'); } /** * Проверка является ли editor (или выше) */ public static function isEditor() { return self::hasRole('editor'); } /** * Проверка авторизован ли вообще */ public static function loggedIn() { return self::check(); } /** * Проверка является ли гостем */ public static function isGuest() { return !self::check(); } // === ВСПОМОГАТЕЛЬНЫЕ МЕТОДЫ === /** * Установить сессию */ private static function setSession($user) { $_SESSION['user_id'] = $user['id']; $_SESSION['username'] = $user['username']; $_SESSION['user_role'] = $user['role']; $_SESSION['email'] = $user['email']; $_SESSION['full_name'] = $user['full_name']; $_SESSION['language'] = $user['language'] ?? 'ru'; $_SESSION['login_time'] = time(); } /** * Безопасные данные пользователя (без пароля) */ private static function getSafeUserData($user) { return [ 'id' => $user['id'], 'username' => $user['username'], 'email' => $user['email'], 'role' => $user['role'], 'full_name' => $user['full_name'], 'language' => $user['language'] ?? 'ru', 'created_at' => $user['created_at'] ]; } /** * Валидация URL для редиректа (защита от открытого редиректа) */ public static function validateRedirect($url) { $url = urldecode($url); $parsed = parse_url($url); // Если нет хоста - считаем относительным URL if (!isset($parsed['host'])) { // Проверяем, что путь начинается с / if (isset($parsed['path']) && strpos($parsed['path'], '/') === 0) { return $url; } return '/'; // Фолбек на главную } // Проверяем, что редирект на тот же домен if ($parsed['host'] === $_SERVER['HTTP_HOST']) { return $url; } // Если внешний домен - фолбек return '/'; } /** * Проверка может ли пользователь редактировать запись * (позже можно расширить для проверки авторства) */ public static function canEdit($entityType, $entityId = null) { if (!self::check()) { return false; } $role = self::role(); // Root и admin могут всё if (in_array($role, ['root', 'admin'])) { return true; } // Editor может редактировать только своё if ($role === 'editor') { // Здесь позже добавим проверку авторства // Например: return self::isOwner($entityType, $entityId); return true; // Временно разрешаем всё } return false; } /** * Получить список доступных ролей (для форм) */ public static function availableRoles($currentUserRole = null) { $currentRole = $currentUserRole ?? self::role(); $roles = []; foreach (self::$roleHierarchy as $role => $level) { // Пропускаем guest (это не роль пользователя) if ($role === 'guest') continue; // Root может назначать любые роли if ($currentRole === 'root') { $roles[$role] = $role; } // Admin может назначать editor и admin (но не root) elseif ($currentRole === 'admin' && $role !== 'root') { $roles[$role] = $role; } // Editor не может назначать роли } return $roles; } } ?>