diff --git a/fav.php b/fav.php index 1a091ff..cb89ef1 100644 --- a/fav.php +++ b/fav.php @@ -6,28 +6,18 @@ require_once('includes/functions.php'); // UTF-8 header('Content-Type: text/html; charset=utf-8'); -$date = date('jS F Y'); -$ip = $_SERVER['REMOTE_ADDR']; - -if (isset($_POST['fid']) && isset($_SESSION['token'])) { - $f_user = htmlspecialchars($_SESSION['username']); - $f_pasteid = Trim(htmlspecialchars($_POST['fid'])); - $f_pasteid = preg_replace('/[^0-9]/', '', $f_pasteid); - $f_pasteid = (int)filter_var($f_pasteid, FILTER_SANITIZE_NUMBER_INT); - $f_time = gmmktime(date("H"), date("i"), date("s"), date("n"), date("j"), date("Y")); - - - $query = $conn->prepare('SELECT 1 FROM pins WHERE f_paste = ? AND m_fav = ?'); - $query->execute([$f_pasteid, $f_user]); +if ($current_user && !empty($_POST['fid'])) { + $paste_id = intval($_POST['fid']); + $query = $conn->prepare('SELECT 1 FROM pins WHERE paste_id = ? AND user_id = ?'); + $query->execute([$paste_id, $current_user->user_id]); if ($query->fetch()) { /* Already favorited */ - $query = $conn->prepare('DELETE FROM pins WHERE f_paste = ? AND m_fav = ?'); + $query = $conn->prepare('DELETE FROM pins WHERE paste_id = ? AND user_id = ?'); } else { - $query = $conn->prepare('INSERT INTO pins (m_fav, f_paste, f_time) VALUES (?, ?, NOW())'); + $query = $conn->prepare('INSERT INTO pins (paste_id, user_id, f_time) VALUES (?, ?, NOW())'); } - $query->execute([$f_pasteid, $f_user]); - + $query->execute([$paste_id, $current_user->user_id]); $error = 'Paste has been favorited.'; } diff --git a/includes/DatabaseHandle.class.php b/includes/DatabaseHandle.class.php new file mode 100644 index 0000000..f100b7f --- /dev/null +++ b/includes/DatabaseHandle.class.php @@ -0,0 +1,32 @@ +conn = new PDO($conString, $username, $password, [ + PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, + PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, + PDO::ATTR_EMULATE_PREPARES => false + ]); + } + + public function query(string $query, array $params = null) : PDOStatement { + if (empty($params)) { + return $this->conn->query($query); + } + + $stmt = $this->conn->prepare($query); + $stmt->execute($params); + + return $stmt; + } + + public static function get() { + if (DatabaseHandle::$instance === null) { + DatabaseHandle::$instance = new DatabaseHandle(); + } + + return DatabaseHandle::$instance; + } +} diff --git a/includes/User.class.php b/includes/User.class.php new file mode 100644 index 0000000..c7e486f --- /dev/null +++ b/includes/User.class.php @@ -0,0 +1,54 @@ +user_id = intval($row['user_id']); + $this->username = $row['username']; + } + + public static function current(DatabaseHandle $conn) : User | null { + $session_user = User::createFromPhpSession($conn); + + if ($session_user !== null) { + return $session_user; + } + + if (!empty($_COOKIE['_ponepaste_token']) && + ($token_user = User::createFromRememberToken($conn, $_COOKIE['_ponepaste_token']))) { + $_SESSION['user_id'] = $token_user->user_id; + return $token_user; + } + + return null; + } + + public static function createFromRememberToken(DatabaseHandle $conn, string $remember_token) : User | null { + $result = $conn->query( + 'SELECT users.id AS id, users.username AS username + FROM user_sessions + INNER JOIN users ON users.id = user_sessions.user_id + WHERE user_sessions.token = ?', [$remember_token] + ); + + if ($row = $result->fetch()) { + return new User($row); + } + + return null; + } + + public static function createFromPhpSession(DatabaseHandle $conn) : User | null { + if (empty($_SESSION['user_id'])) { + return null; + } + + $user_id = intval($_SESSION['user_id']); + + $row = $conn->query('SELECT id, username FROM users WHERE id = ?', [$user_id])->fetch(); + + return $row ? new User($row) : null; + } +} diff --git a/includes/common.php b/includes/common.php index ae0d86a..ee54fc3 100644 --- a/includes/common.php +++ b/includes/common.php @@ -5,6 +5,8 @@ if (!defined('IN_PONEPASTE')) { require_once(__DIR__ . '/config.php'); require_once(__DIR__ . '/functions.php'); +require_once(__DIR__ . '/DatabaseHandle.class.php'); +require_once(__DIR__ . '/User.class.php'); /* View functions */ function urlForPaste($paste_id) : string { @@ -47,18 +49,6 @@ function getSiteTotal_unique_views(PDO $conn) : int { return intval($conn->query('SELECT tvisit FROM page_view ORDER BY id DESC LIMIT 1')->fetch(PDO::FETCH_NUM)[0]); } -function getCurrentUser(PDO $conn) : array | null { - if (empty($_SESSION['username'])) { - return null; - } - - $query = $conn->prepare('SELECT * FROM users WHERE username = ?'); - $query->execute([$_SESSION['username']]); - - return $query->fetch(); -} - - /** * Specialization of `htmlentities()` that avoids double escaping and uses UTF-8. * @@ -115,6 +105,8 @@ $conn = new PDO( $db_opts ); +$new_conn = new DatabaseHandle("mysql:host=$db_host;dbname=$db_schema;charset=utf8", $db_user, $db_pass); + // Setup site info $site_info = getSiteInfo(); $row = $site_info['site_info']; @@ -147,9 +139,7 @@ if ($site_permissions) { $privatesite = $siteprivate; $noguests = $disableguest; -if (isset($_SESSION['username'])) { - $noguests = "off"; -} + // Prevent a potential LFI (you never know :p) $lang_file = "${default_lang}.php"; @@ -164,8 +154,7 @@ if (is_banned($conn, $ip)) die($lang['banned']); // "You have been banned from " // Logout if (isset($_GET['logout'])) { header('Location: ' . $_SERVER['HTTP_REFERER']); - unset($_SESSION['token']); - unset($_SESSION['username']); + unset($_SESSION['user_id']); unset($_SESSION['pic']); session_destroy(); } @@ -175,4 +164,9 @@ $total_pastes = getSiteTotalPastes($conn); $total_page_views = getSiteTotalviews($conn); $total_unique_views = getSiteTotal_unique_views($conn); -$current_user = getCurrentUser($conn); +$current_user = User::current($new_conn); +//$current_user = getCurrentUser($conn); + +if ($current_user) { + $noguests = "off"; +} diff --git a/index.php b/index.php index 0ced6e9..bf4935a 100644 --- a/index.php +++ b/index.php @@ -31,8 +31,9 @@ function verifyCaptcha() : string|bool { global $mode; global $recaptcha_secretkey; global $lang; + global $current_user; - if ($cap_e == "on" && !isset($_SESSION['username'])) { + if ($cap_e == "on" && !$current_user) { if ($mode == "reCAPTCHA") { $response = file_get_contents("https://www.google.com/recaptcha/api/siteverify?secret=" . $recaptcha_secretkey . "&response=" . $_POST['g-recaptcha-response']); $response = json_decode($response, true); @@ -104,8 +105,6 @@ header('Content-Type: text/html; charset=utf-8'); $date = date('jS F Y'); $ip = $_SERVER['REMOTE_ADDR']; -$current_user = getCurrentUser($conn); - // Sitemap $site_sitemap_rows = $conn->query('SELECT * FROM sitemap_options LIMIT 1'); if ($row = $site_sitemap_rows->fetch()) { diff --git a/login.php b/login.php index faf2e71..624d853 100644 --- a/login.php +++ b/login.php @@ -26,8 +26,9 @@ $ip = $_SERVER['REMOTE_ADDR']; // Check if already logged in -if (isset($_SESSION['token'])) { +if ($current_user !== null) { header("Location: ./"); + die(); } // Page title @@ -84,8 +85,7 @@ if (isset($_POST['forgot'])) { $error = $lang['banned']; } else { // Login successful - $_SESSION['token'] = md5($db_id . $username); - $_SESSION['username'] = $username; + $_SESSION['user_id'] = $row['id']; header('Location: ' . $_SERVER['HTTP_REFERER']); exit(); diff --git a/profile.php b/profile.php index 130efe2..5e077e9 100644 --- a/profile.php +++ b/profile.php @@ -28,10 +28,12 @@ $p_title = $lang['myprofile']; //"My Profile"; // Check if already logged in -if (!isset($_SESSION['token'])) { +if ($current_user === null) { header("Location: ./login.php"); + die(); } -$user_username = htmlentities(trim($_SESSION['username'])); + +$user_username = $current_user->username; $query = $conn->prepare('SELECT * FROM users WHERE username = ?'); $query->execute([$user_username]); diff --git a/report.php b/report.php index e715288..0225bdb 100644 --- a/report.php +++ b/report.php @@ -6,21 +6,15 @@ require_once('includes/functions.php'); // UTF-8 header('Content-Type: text/html; charset=utf-8'); -$date = date('jS F Y'); $ip = $_SERVER['REMOTE_ADDR']; //Report paste $p_reasonrep = Trim(htmlspecialchars($_POST['reasonrep'])); -if (isset($_SESSION['token'])) { - $p_memreport = htmlspecialchars($_SESSION['username']); -} else { - $p_memreport = "Guest"; -} -$p_pastereport = Trim(htmlspecialchars($_POST['reppasteid'])); -$p_reporttime = gmmktime(date("H"), date("i"), date("s"), date("n"), date("j"), date("Y")); +$p_memreport = $current_user ? $current_user ->username : 'Guest'; +$p_pastereport = $_POST['reppasteid']; $p_reasonrep = preg_replace("/[^0-9]/", "", $p_reasonrep); -$conn->prepare('INSERT INTO user_reports (m_report, p_report, t_report, rep_reason) VALUES (?, ?, ?, ?)') - ->execute([$p_memreport, $p_pastereport, $p_reporttime, $p_reasonrep]); +$conn->prepare('INSERT INTO user_reports (m_report, p_report, t_report, rep_reason) VALUES (?, ?, NOW(), ?)') + ->execute([$p_memreport, $p_pastereport, $p_reasonrep]); $repmes = "Paste has been reported."; diff --git a/theme/bulma/header.php b/theme/bulma/header.php index 0873133..05802ae 100644 --- a/theme/bulma/header.php +++ b/theme/bulma/header.php @@ -76,9 +76,8 @@ $start = $time;