$cfEmail, 'auth_method' => 'cloudflare_access', 'role' => getUserRole($cfEmail) ]; } // Fall back to session-based auth if (session_status() === PHP_SESSION_NONE) { session_start(); } if (!empty($_SESSION['authenticated']) && !empty($_SESSION['user'])) { return [ 'email' => $_SESSION['user'], 'auth_method' => 'session', 'role' => getUserRole($_SESSION['user']) ]; } return null; } /** * Get user role from database or default to staff * * @param string $email User email * @return string Role (admin or staff) */ function getUserRole($email) { if (empty($email)) { return ROLE_STAFF; } // Normalize email for comparison (lowercase, trimmed) $email = strtolower(trim($email)); // Try multiple ways to get ADMIN_EMAILS (different PHP configs handle env vars differently) $adminEmails = ''; // Method 1: getenv() if (empty($adminEmails)) { $adminEmails = getenv('ADMIN_EMAILS'); } // Method 2: $_ENV superglobal if (empty($adminEmails) && isset($_ENV['ADMIN_EMAILS'])) { $adminEmails = $_ENV['ADMIN_EMAILS']; } // Method 3: $_SERVER (some configs put env vars here) if (empty($adminEmails) && isset($_SERVER['ADMIN_EMAILS'])) { $adminEmails = $_SERVER['ADMIN_EMAILS']; } // Method 4: Defined constant from config.php if (empty($adminEmails) && defined('ADMIN_EMAILS')) { $adminEmails = ADMIN_EMAILS; } // Check if email is in admin list if (!empty($adminEmails)) { $adminList = array_map(function($e) { return strtolower(trim($e)); }, explode(',', $adminEmails)); if (in_array($email, $adminList)) { return ROLE_ADMIN; } } // Try database lookup if getDB function exists if (function_exists('getDB')) { try { $db = getDB(); $stmt = $db->prepare("SELECT role FROM users WHERE LOWER(email) = ? AND active = 1"); $stmt->execute([$email]); $result = $stmt->fetch(PDO::FETCH_ASSOC); if ($result && !empty($result['role'])) { return $result['role']; } } catch (Exception $e) { // Table might not exist yet, fall through to default } } // Default to staff if not found in env or database return ROLE_STAFF; } /** * Check if current user has a specific role * * @param string $requiredRole Role to check for * @return bool True if user has the role */ function hasRole($requiredRole) { $user = getCurrentUser(); if (!$user) { return false; } // Admin has access to everything if ($user['role'] === ROLE_ADMIN) { return true; } return $user['role'] === $requiredRole; } /** * Check if current user is an admin * * @return bool True if user is admin */ function isAdmin() { return hasRole(ROLE_ADMIN); } /** * Check if current user is staff (or admin) * * @return bool True if user is staff or admin */ function isStaff() { return hasRole(ROLE_STAFF) || hasRole(ROLE_ADMIN); } /** * Require a specific role to access a page * Redirects to appropriate page if not authorized * * @param string $requiredRole Role required * @param string $redirectUrl URL to redirect to if unauthorized */ function requireRole($requiredRole, $redirectUrl = '/') { if (!hasRole($requiredRole)) { header('HTTP/1.1 403 Forbidden'); header('Location: ' . $redirectUrl . '?error=unauthorized'); exit; } } /** * Require admin role to access a page */ function requireAdmin() { requireRole(ROLE_ADMIN, '/'); } /** * Get user identifier for audit logging * Returns email or 'anonymous' if not authenticated * * @return string User identifier */ function getAuditUser() { $user = getCurrentUser(); if ($user) { return $user['email']; } // Check legacy session if (session_status() === PHP_SESSION_NONE) { session_start(); } return $_SESSION['user'] ?? 'anonymous'; } /** * Get user display info for header * * @return array User display info */ function getUserDisplayInfo() { $user = getCurrentUser(); if (!$user) { return [ 'name' => 'Guest', 'email' => '', 'role' => '', 'initials' => 'G', 'auth_method' => 'none', 'is_admin' => false ]; } $email = $user['email']; $name = explode('@', $email)[0]; $initials = strtoupper(substr($name, 0, 2)); return [ 'name' => ucfirst($name), 'email' => $email, 'role' => $user['role'], 'initials' => $initials, 'auth_method' => $user['auth_method'], 'is_admin' => $user['role'] === ROLE_ADMIN ]; }