From 8284c0d9af71cd18532834dfa1cfd03afa4c8d8f Mon Sep 17 00:00:00 2001 From: flashwave Date: Sun, 18 Oct 2015 03:50:50 +0200 Subject: [PATCH] r20151018 Signed-off-by: Flashwave --- _sakura/components/Forum.php | 20 ----- _sakura/components/Main.php | 3 - _sakura/components/Session.php | 135 +++++++++++++++++++++++++++- _sakura/components/Sessions.php | 152 -------------------------------- _sakura/components/User.php | 6 +- _sakura/components/Users.php | 36 ++++---- _sakura/sakura.php | 17 ++-- integrations/SockChat.php | 2 +- public/manage.php | 2 +- public/settings.php | 18 ++-- public/support.php | 10 +-- 11 files changed, 182 insertions(+), 219 deletions(-) delete mode 100755 _sakura/components/Sessions.php diff --git a/_sakura/components/Forum.php b/_sakura/components/Forum.php index 8d594ad..c57fc36 100755 --- a/_sakura/components/Forum.php +++ b/_sakura/components/Forum.php @@ -349,25 +349,5 @@ class Forum public static function createPost($subject, $text, $enableMD, $enableSig, $forum, $type = 0, $status = 0, $topic = 0) { - // Check if this post is OP - if (!$topic) { - // If so create a new topic - Database::insert('topics', [ - 'forum_id' => $forum, - 'topic_hidden' => 0, - 'topic_title' => $subject, - 'topic_time' => time(), - 'topic_time_limit' => 0, - 'topic_last_reply' => 0, - 'topic_views' => 0, - 'topic_replies' => 0, - 'topic_status' => $status, - 'topic_status_change' => 0, - 'topic_type' => $type, - 'topic_first_post_id' => 0, - 'topic_first_poster_id' => Session::$userId, - ]); - } - } } diff --git a/_sakura/components/Main.php b/_sakura/components/Main.php index d583a58..39cf952 100755 --- a/_sakura/components/Main.php +++ b/_sakura/components/Main.php @@ -23,9 +23,6 @@ class Main // "Dynamic" Configuration Configuration::initDB(); - // Create new session - Session::init(); - } // Parse markdown diff --git a/_sakura/components/Session.php b/_sakura/components/Session.php index 1acecc0..79786d7 100755 --- a/_sakura/components/Session.php +++ b/_sakura/components/Session.php @@ -8,17 +8,146 @@ namespace Sakura; class Session { // Current user data - public $userId; - public $sessionId; + public $userId = 0; + public $sessionId = ""; // Initialise new session - public function __construct() + public function __construct($userId, $sessionId = null) { + // Set the supposed session data + $this->userId = $userId; + $this->sessionId = $sessionId; + // Check if a PHP session was already started and if not start one if (session_status() != PHP_SESSION_ACTIVE) { session_start(); } } + + // Destroy this session + public function destroy() + { + + // Invalidate the session key + Database::delete('sessions', [ + 'session_key' => [$this->sessionId, '='], + 'user_id' => [$this->userId, '='], + ]); + + // Unset userId and sessionId + unset($this->userId); + unset($this->sessionId); + + // Destroy the session + if (session_status() == PHP_SESSION_ACTIVE) { + session_destroy(); + } + + } + + // Create a new session + public function create($permanent) + { + + // Generate session key + $session = hash('sha256', $this->userId . base64_encode('sakura' . mt_rand(0, 99999999)) . time()); + + // Insert the session into the database + Database::insert('sessions', [ + 'user_id' => $this->userId, + 'user_ip' => Main::getRemoteIP(), + 'user_agent' => Main::cleanString(isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'No user agent header.'), + 'session_key' => $session, + 'session_start' => time(), + 'session_expire' => time() + 604800, + 'session_remember' => $permanent ? '1' : '0', + ]); + + // Return the session key + return $session; + + } + + // Validate an apparently existing session + public function validate() + { + + // Get session from database + $session = Database::fetch('sessions', false, [ + 'user_id' => [$this->userId, '='], + 'session_key' => [$this->sessionId, '='], + ]); + + // Check if we actually got something in return + if (!$session) { + return 0; + } + + // Check if the session expired + if ($session['session_expire'] < time()) { + // ...and return false + return 0; + } + + // Origin checking + if ($ipCheck = Configuration::getConfig('session_check')) { + // Split both IPs up + $sessionIP = explode('.', $session['user_ip']); + $userIP = explode('.', Main::getRemoteIP()); + + // Take 1 off the ipCheck variable so it's equal to the array keys + $ipCheck = $ipCheck - 1; + + // Check if the user's IP is similar to the session's registered IP + switch ($ipCheck) { + // 000.xxx.xxx.xxx + case 3: + if ($userIP[3] !== $sessionIP[3]) { + return 0; + } + + // xxx.000.xxx.xxx + case 2: + case 3: + if ($userIP[2] !== $sessionIP[2]) { + return 0; + } + + // xxx.xxx.000.xxx + case 1: + case 2: + case 3: + if ($userIP[1] !== $sessionIP[1]) { + return 0; + } + + // xxx.xxx.xxx.000 + case 0: + case 1: + case 2: + case 3: + if ($userIP[0] !== $sessionIP[0]) { + return 0; + } + } + } + + // If the remember flag is set extend the session time + if ($session['session_remember']) { + Database::update('sessions', [ + [ + 'session_expire' => time() + 604800, + ], + [ + 'session_id' => [$session['session_id'], '='], + ], + ]); + } + + // Return 2 if the remember flag is set and return 1 if not + return $session['session_remember'] ? 2 : 1; + + } } diff --git a/_sakura/components/Sessions.php b/_sakura/components/Sessions.php deleted file mode 100755 index 35e193f..0000000 --- a/_sakura/components/Sessions.php +++ /dev/null @@ -1,152 +0,0 @@ - $userId, - 'user_ip' => Main::getRemoteIP(), - 'user_agent' => Main::cleanString($_SERVER['HTTP_USER_AGENT']), - 'session_key' => $session, - 'session_start' => time(), - 'session_expire' => time() + 604800, - 'session_remember' => $remember ? '1' : '0', - ]); - - // Return the session key - return $session; - - } - - // Check session data (expiry, etc.) - public static function checkSession($userId, $sessionId) - { - - // Get session from database - $session = Database::fetch('sessions', true, ['user_id' => [$userId, '='], 'session_key' => [$sessionId, '=']]); - - // Check if we actually got something in return - if (!count($session)) { - return 0; - } - - $session = $session[0]; - - // Check if the session expired - if ($session['session_expire'] < time()) { - // If it is delete the session... - self::deleteSession($session['session_id']); - - // ...and return false - return 0; - } - - // Origin checking - if ($ipCheck = Configuration::getConfig('session_check')) { - // Split both IPs up - $sessionIP = explode('.', $session['user_ip']); - $userIP = explode('.', Main::getRemoteIP()); - - // Take 1 off the ipCheck variable so it's equal to the array keys - $ipCheck = $ipCheck - 1; - - // Check if the user's IP is similar to the session's registered IP - switch ($ipCheck) { - // 000.xxx.xxx.xxx - case 3: - if ($userIP[3] !== $sessionIP[3]) { - return 0; - } - - // xxx.000.xxx.xxx - case 2: - case 3: - if ($userIP[2] !== $sessionIP[2]) { - return 0; - } - - // xxx.xxx.000.xxx - case 1: - case 2: - case 3: - if ($userIP[1] !== $sessionIP[1]) { - return 0; - } - - // xxx.xxx.xxx.000 - case 0: - case 1: - case 2: - case 3: - if ($userIP[0] !== $sessionIP[0]) { - return 0; - } - } - } - - // If the remember flag is set extend the session time - if ($session['session_remember']) { - Database::update('sessions', [['session_expire' => time() + 604800], ['session_id' => [$session['session_id'], '=']]]); - } - - // Return 2 if the remember flag is set and return 1 if not - return $session['session_remember'] ? 2 : 1; - - } - - // Delete a session - public static function deleteSession($sessionId, $key = false) - { - - // Check if the session exists - if (!Database::fetch('sessions', [($key ? 'session_key' : 'session_id'), true, [$sessionId, '=']])) { - return false; - } - - // Run the query - Database::delete('sessions', [($key ? 'session_key' : 'session_id') => [$sessionId, '=']]); - - // Return true if key was found and deleted - return true; - - } -} diff --git a/_sakura/components/User.php b/_sakura/components/User.php index f9fd7fd..d52475c 100755 --- a/_sakura/components/User.php +++ b/_sakura/components/User.php @@ -148,7 +148,7 @@ class User // Add friend Database::insert('friends', [ - 'user_id' => Session::$userId, + 'user_id' => $this->data['user_id'], 'friend_id' => $uid, 'friend_timestamp' => time(), ]); @@ -177,14 +177,14 @@ class User // Remove friend Database::delete('friends', [ - 'user_id' => [Session::$userId, '='], + 'user_id' => [$this->data['user_id'], '='], 'friend_id' => [$uid, '='], ]); // Attempt to remove the request if ($deleteRequest) { Database::delete('friends', [ - 'friend_id' => [Session::$userId, '='], + 'friend_id' => [$this->data['user_id'], '='], 'user_id' => [$uid, '='], ]); } diff --git a/_sakura/components/Users.php b/_sakura/components/Users.php index 1e3a464..9ffc4d0 100755 --- a/_sakura/components/Users.php +++ b/_sakura/components/Users.php @@ -57,10 +57,13 @@ class Users : 0); // Get session - $session = Session::checkSession($uid, $sid); + $session = new Session($uid, $sid); + + // Validate the session + $sessionValid = $session->validate(); // Check if the session exists and check if the user is activated - if ($session == 0 || Permissions::check('SITE', 'DEACTIVATED', $uid, 1)) { + if ($sessionValid == 0 || Permissions::check('SITE', 'DEACTIVATED', $uid, 1)) { // Unset User ID setcookie( Configuration::getConfig('cookie_prefix') . 'id', @@ -83,7 +86,7 @@ class Users } // Extend the cookie times if the remember flag is set - if ($session == 2) { + if ($sessionValid == 2) { // User ID cookie setcookie( Configuration::getConfig('cookie_prefix') . 'id', @@ -117,7 +120,7 @@ class Users self::updatePremiumMeta($uid); // If everything went through return true - return true; + return [$uid, $sid]; } @@ -163,7 +166,10 @@ class Users } // Create a new session - $sessionKey = Session::newSession($user['user_id'], $remember); + $session = new Session($user['user_id']); + + // Generate a session key + $sessionKey = $session->create($remember); // Set cookies if ($cookies) { @@ -201,7 +207,7 @@ class Users } // Remove the active session from the database - if (!Session::deleteSession(Session::$sessionId, true)) { + if (!(new Session)->destroy()) { return false; } @@ -665,7 +671,7 @@ class Users } // Create new registration code - public static function createRegistrationCode() + public static function createRegistrationCode($userId) { // Check if we're logged in @@ -677,18 +683,18 @@ class Users if (Database::count( 'regcodes', true, - ['uid' => [Session::$userId, '=']] + ['uid' => [$userId, '=']] )[0] >= Configuration::getConfig('max_reg_keys')) { return false; } // Generate a code by MD5'ing some random bullshit - $code = md5('SAKURA' . rand(0, 99999999) . Session::$userId . 'NOOKLSISGOD'); + $code = md5('SAKURA' . rand(0, 99999999) . $userId . 'NOOKLSISGOD'); // Insert the key into the database Database::insert('regcodes', [ 'code' => $code, - 'created_by' => Session::$userId, + 'created_by' => $userId, 'used_by' => 0, 'key_used' => 0, ]); @@ -867,7 +873,7 @@ class Users // Iterate over the fields and clean them up foreach ($optionFields as $field) { - if (!Permissions::check('SITE', $field['option_permission'], Session::$userId, 1)) { + if (!Permissions::check('SITE', $field['option_permission'], self::checkLogin()[0], 1)) { continue; } @@ -1241,7 +1247,7 @@ class Users // Prepare conditions $conditions = array(); - $conditions['user_id'] = [($uid ? $uid : Session::$userId), '=']; + $conditions['user_id'] = [($uid ? $uid : self::checkLogin()[0]), '=']; if ($timediff) { $conditions['alert_timestamp'] = [time() - $timediff, '>']; @@ -1317,7 +1323,7 @@ class Users // Get all messages from the database $messages = Database::fetch('messages', true, [ - ($from ? 'from_user' : 'to_user') => [Session::$userId, '='], + ($from ? 'from_user' : 'to_user') => [self::checkLogin()[0], '='], ]); // Prepare a storage array @@ -1346,7 +1352,7 @@ class Users // Assign $uid if (!$uid) { - $uid = Session::$userId; + $uid = Users::checkLogin()[0]; } // Get all friends @@ -1389,7 +1395,7 @@ class Users // Assign $of automatically if it's not set if (!$uid) { - $uid = Session::$userId; + $uid = self::checkLogin()[0]; } // Get all friend entries from other people involved the current user diff --git a/_sakura/sakura.php b/_sakura/sakura.php index 26a7fb5..5a80c16 100755 --- a/_sakura/sakura.php +++ b/_sakura/sakura.php @@ -8,7 +8,7 @@ namespace Sakura; // Define Sakura version -define('SAKURA_VERSION', '20151017'); +define('SAKURA_VERSION', '20151018'); define('SAKURA_VLABEL', 'Eminence'); define('SAKURA_COLOUR', '#6C3082'); define('SAKURA_STABLE', false); @@ -36,7 +36,7 @@ require_once ROOT . '_sakura/components/Database.php'; require_once ROOT . '_sakura/components/Urls.php'; require_once ROOT . '_sakura/components/Templates.php'; require_once ROOT . '_sakura/components/Permissions.php'; -require_once ROOT . '_sakura/components/Sessions.php'; +require_once ROOT . '_sakura/components/Session.php'; require_once ROOT . '_sakura/components/User.php'; require_once ROOT . '_sakura/components/Rank.php'; require_once ROOT . '_sakura/components/Users.php'; @@ -94,8 +94,11 @@ if (Configuration::getConfig('no_cron_service')) { // Start output buffering ob_start(Configuration::getConfig('use_gzip') ? 'ob_gzhandler' : null); +// Auth check +$authCheck = Users::checkLogin(); + // Create a user object for the current logged in user -$currentUser = new User(Session::$userId); +$currentUser = new User($authCheck[0]); // Create the Urls object $urls = new Urls(); @@ -186,9 +189,9 @@ if (!defined('SAKURA_NO_TPL')) { 'session' => [ - 'checkLogin' => Users::checkLogin(), - 'sessionId' => Session::$sessionId, - 'userId' => Session::$userId, + 'checkLogin' => $authCheck, + 'sessionId' => $authCheck[1], + 'userId' => $authCheck[0], ], @@ -213,7 +216,7 @@ if (!defined('SAKURA_NO_TPL')) { } // Ban checking - if (Users::checkLogin() && $ban = Bans::checkBan(Session::$userId)) { + if ($authCheck && $ban = Bans::checkBan($currentUser->data['user_id'])) { // Additional render data $renderData = array_merge($renderData, [ diff --git a/integrations/SockChat.php b/integrations/SockChat.php index d30db1d..dd88dba 100755 --- a/integrations/SockChat.php +++ b/integrations/SockChat.php @@ -40,7 +40,7 @@ if (Auth::getPageType() == AUTH_FETCH) { $sid = $_REQUEST['arg2']; // Check if session is active else deny - if (Session::checkSession($uid, $sid)) { + if (new Session($uid, $sid)) { // Check if they can access the chat if (Permissions::check('SITE', 'DEACTIVATED', $uid, 1) || Permissions::check('SITE', 'RESTRICTED', $uid, 1)) { Auth::Deny(); diff --git a/public/manage.php b/public/manage.php index 7e63aa4..559666a 100755 --- a/public/manage.php +++ b/public/manage.php @@ -13,7 +13,7 @@ define('SAKURA_MANAGE', true); require_once str_replace(basename(__DIR__), '', dirname(__FILE__)) . '_sakura/sakura.php'; // Make sure user has the permissions to view this -if (!Permissions::check('MANAGE', 'USE_MANAGE', Session::$userId, 1)) { +if (!Permissions::check('MANAGE', 'USE_MANAGE', $currentUser->data['user_id'], 1)) { header('Location: /'); exit; } diff --git a/public/settings.php b/public/settings.php index da529c0..cf6395f 100755 --- a/public/settings.php +++ b/public/settings.php @@ -258,7 +258,7 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification } // Compare time and session so we know the link isn't forged - if ($continue && $_REQUEST[(isset($_REQUEST['add']) ? 'add' : 'remove')] == Session::$userId) { + if ($continue && $_REQUEST[(isset($_REQUEST['add']) ? 'add' : 'remove')] == $currentUser->data['user_id']) { $renderData['page'] = [ 'redirect' => $redirect, @@ -339,7 +339,7 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification // Create a notification if (array_key_exists($action[1], $notifStrings)) { // Get the current user's profile data - $user = new User(Session::$userId); + $user = new User($currentUser->data['user_id']); Users::createNotification( $_REQUEST[(isset($_REQUEST['add']) ? 'add' : 'remove')], @@ -442,7 +442,7 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification // Set path variables $filepath = ROOT . Configuration::getConfig('user_uploads') . '/'; - $filename = $filepath . $mode . '_' . Session::$userId; + $filename = $filepath . $mode . '_' . $currentUser->data['user_id']; $currfile = isset($currentUser->data['user_data'][$userDataKey]) && !empty($_OLDFILE = $currentUser->data['user_data'][$userDataKey]) ? $_OLDFILE : null; @@ -602,7 +602,7 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification } // Update database - Users::updateUserDataField(Session::$userId, $updated); + Users::updateUserDataField($currentUser->data['user_id'], $updated); // Set render data $renderData['page'] = [ @@ -641,7 +641,7 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification } // Update database - Users::updateUserDataField(Session::$userId, ['profileFields' => $store]); + Users::updateUserDataField($currentUser->data['user_id'], ['profileFields' => $store]); // Set render data $renderData['page'] = [ @@ -707,7 +707,7 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification 'user_birthday' => $birthdate, ], [ - 'user_id' => [Session::$userId, '='], + 'user_id' => [$currentUser->data['user_id'], '='], ], ]); @@ -735,7 +735,7 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification } // Update database - Users::updateUserDataField(Session::$userId, ['userOptions' => $store]); + Users::updateUserDataField($currentUser->data['user_id'], ['userOptions' => $store]); // Set render data $renderData['page'] = [ @@ -781,7 +781,7 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification 'user_title' => (isset($_POST['usertitle']) ? $_POST['usertitle'] : null), ], [ - 'user_id' => [Session::$userId, '='], + 'user_id' => [$currentUser->data['user_id'], '='], ], ] ); @@ -936,7 +936,7 @@ if (isset($_REQUEST['request-notifications']) && $_REQUEST['request-notification $userPage = base64_encode($_POST['userpage']); // Update database - Users::updateUserDataField(Session::$userId, ['userPage' => $userPage]); + Users::updateUserDataField($currentUser->data['user_id'], ['userPage' => $userPage]); // Set render data $renderData['page'] = [ diff --git a/public/support.php b/public/support.php index 3cda7f7..ceb1bae 100755 --- a/public/support.php +++ b/public/support.php @@ -12,7 +12,7 @@ require_once str_replace(basename(__DIR__), '', dirname(__FILE__)) . '_sakura/sa // Switch between modes (we only allow this to be used by logged in user) if (isset($_REQUEST['mode']) && Users::checkLogin() - && Permissions::check('SITE', 'OBTAIN_PREMIUM', Session::$userId, 1)) { + && Permissions::check('SITE', 'OBTAIN_PREMIUM', $currentUser->data['user_id'], 1)) { // Initialise Payments class if (!Payments::init()) { header('Location: ' . $urls->format('SITE_PREMIUM') . '?fail=true'); @@ -89,10 +89,10 @@ if (isset($_REQUEST['mode']) // Attempt to complete the transaction if ($finalise) { // Make the user premium - $expiration = Users::addUserPremium(Session::$userId, (2628000 * $_SESSION['premiumMonths'])); - Users::updatePremiumMeta(Session::$userId); + $expiration = Users::addUserPremium($currentUser->data['user_id'], (2628000 * $_SESSION['premiumMonths'])); + Users::updatePremiumMeta($currentUser->data['user_id']); Main::updatePremiumTracker( - Session::$userId, + $currentUser->data['user_id'], ((float) Configuration::getConfig('premium_price_per_month') * $_SESSION['premiumMonths']), $currentUser->data['username'] . ' bought premium for ' @@ -116,7 +116,7 @@ if (isset($_REQUEST['mode']) 'page' => [ - 'expiration' => ($prem = Users::checkUserPremium(Session::$userId)[2]) !== null ? $prem : 0, + 'expiration' => ($prem = Users::checkUserPremium($currentUser->data['user_id'])[2]) !== null ? $prem : 0, ],