/** * Set a cookie with the appropriate application cookie prefix and other cookie information. * * @param string $Name The name of the cookie without a prefix. * @param string $Value The value of the cookie. * @param int $Expire When the cookie should expire. * @param bool $Force Whether or not to set the cookie even if already exists. */ function setAppCookie($Name, $Value, $Expire = 0, $Force = false) { $Px = c('Garden.Cookie.Name'); $Key = "{$Px}-{$Name}"; // Check to see if the cookie is already set before setting it again. if (!$Force && isset($_COOKIE[$Key]) && $_COOKIE[$Key] == $Value) { return; } $Domain = c('Garden.Cookie.Domain', ''); // If the domain being set is completely incompatible with the current domain then make the domain work. $CurrentHost = Gdn::Request()->Host(); if (!StringEndsWith($CurrentHost, trim($Domain, '.'))) { $Domain = ''; } // Create the cookie. safeCookie($Key, $Value, $Expire, '/', $Domain, null, true); $_COOKIE[$Key] = $Value; }
/** * Used by $this->Stash() to create & manage sessions for users & guests. * * This is a stop-gap solution until full session management for users & * guests can be imlemented. */ private function _getStashSession($ValueToStash) { $CookieName = c('Garden.Cookie.Name', 'Vanilla'); $Name = $CookieName . '-sid'; // Grab the entire session record $SessionID = val($Name, $_COOKIE, ''); // If there is no session, and no value for saving, return; if ($SessionID == '' && $ValueToStash == '') { return false; } $Session = Gdn::SQL()->select()->from('Session')->where('SessionID', $SessionID)->get()->firstRow(); if (!$Session) { $SessionID = betterRandomString(32); $TransientKey = substr(md5(mt_rand()), 0, 11) . '!'; // Save the session information to the database. Gdn::SQL()->insert('Session', array('SessionID' => $SessionID, 'UserID' => Gdn::session()->UserID, 'TransientKey' => $TransientKey, 'DateInserted' => Gdn_Format::toDateTime(), 'DateUpdated' => Gdn_Format::toDateTime())); Trace("Inserting session stash {$SessionID}"); $Session = Gdn::SQL()->select()->from('Session')->where('SessionID', $SessionID)->get()->firstRow(); // Save a session cookie $Path = c('Garden.Cookie.Path', '/'); $Domain = c('Garden.Cookie.Domain', ''); $Expire = 0; // If the domain being set is completely incompatible with the current domain then make the domain work. $CurrentHost = Gdn::request()->host(); if (!stringEndsWith($CurrentHost, trim($Domain, '.'))) { $Domain = ''; } safeCookie($Name, $SessionID, $Expire, $Path, $Domain); $_COOKIE[$Name] = $SessionID; } $Session->Attributes = @unserialize($Session->Attributes); if (!$Session->Attributes) { $Session->Attributes = array(); } return $Session; }
/** * Set 'NoMobile' cookie for current user to prevent use of mobile theme. * * @param string $type The type of mobile device. This can be one of the following: * - desktop: Force the desktop theme. * - mobile: Force the mobile theme. * - tablet: Force the tablet theme (desktop). * - app: Force the app theme (app). * - 1: Unset the force cookie and use the user agent to determine the theme. */ public function noMobile($type = 'desktop') { $type = strtolower($type); if ($type == '1') { Gdn_CookieIdentity::deleteCookie('X-UA-Device-Force'); redirect("/", 302); } if (in_array($type, array('mobile', 'desktop', 'tablet', 'app'))) { $type = $type; } else { $type = 'desktop'; } if ($type == '1') { // Allow mobile again Gdn_CookieIdentity::deleteCookie('VanillaNoMobile'); } else { // Set 48-hour "no mobile" cookie $Expiration = time() + 172800; $Path = c('Garden.Cookie.Path'); $Domain = c('Garden.Cookie.Domain'); safeCookie('X-UA-Device-Force', $type, $Expiration, $Path, $Domain); } redirect("/", 302); }
/** * Fingerprint the user. * * @param Gdn_Controller $sender */ public function base_render_before($sender) { // Don't do anything if the user isn't signed in. if (!Gdn::session()->isValid()) { return; } $cookieFingerprint = val('__vnf', $_COOKIE, null); $databaseFingerprint = val('Fingerprint', Gdn::session()->User, null); $expires = time() + 60 * 60 * 24 * 256; // Expire one year from now // Cookie and user record both empty, assign both if (empty($cookieFingerprint) && empty($databaseFingerprint)) { $databaseFingerprint = uniqid(); Gdn::sql()->update('User', ['Fingerprint' => $databaseFingerprint], ['UserID' => Gdn::session()->UserID])->put(); safeCookie('__vnf', $databaseFingerprint, $expires); return; } // If the cookie exists... if (!empty($cookieFingerprint)) { // If the cookie disagrees with the database, update the database if ($databaseFingerprint != $cookieFingerprint) { Gdn::sql()->update('User', ['Fingerprint' => $cookieFingerprint], ['UserID' => Gdn::session()->UserID])->put(); } // If only the user record exists, propagate it to the cookie } else { if (!empty($databaseFingerprint)) { // Propagate it to the cookie safeCookie('__vnf', $databaseFingerprint, $expires); } } }
/** * Remove a cookie. * * @param $CookieName * @param null $Path * @param null $Domain */ public static function deleteCookie($CookieName, $Path = null, $Domain = null) { if (is_null($Path)) { $Path = Gdn::config('Garden.Cookie.Path'); } if (is_null($Domain)) { $Domain = Gdn::config('Garden.Cookie.Domain'); } $CurrentHost = Gdn::request()->host(); if (!StringEndsWith($CurrentHost, trim($Domain, '.'))) { $Domain = ''; } $Expiry = time() - 60 * 60; safeCookie($CookieName, "", $Expiry, $Path, $Domain); $_COOKIE[$CookieName] = null; }
/** * Used by $this->stash() to create & manage sessions for users & guests. * * This is a stop-gap solution until full session management for users & * guests can be implemented. * * @param Gdn_SQLDriver $sql Local clone of the sql driver. * @param string $valueToStash The value of the stash to set. * * @return bool|Gdn_DataSet Current session. */ private function getStashSession($sql, $valueToStash) { $cookieName = c('Garden.Cookie.Name', 'Vanilla'); $name = $cookieName . '-sid'; // Grab the entire session record. $sessionID = val($name, $_COOKIE, ''); // If there is no session, and no value for saving, return. if ($sessionID == '' && $valueToStash == '') { return false; } $session = $sql->select()->from('Session')->where('SessionID', $sessionID)->get()->firstRow(); if (!$session) { $sessionID = betterRandomString(32); $transientKey = substr(md5(mt_rand()), 0, 11) . '!'; // Save the session information to the database. $sql->insert('Session', ['SessionID' => $sessionID, 'UserID' => Gdn::session()->UserID, 'TransientKey' => $transientKey, 'DateInserted' => Gdn_Format::toDateTime(), 'DateUpdated' => Gdn_Format::toDateTime()]); trace("Inserting session stash {$sessionID}"); $session = $sql->select()->from('Session')->where('SessionID', $sessionID)->get()->firstRow(); // Save a session cookie. $path = c('Garden.Cookie.Path', '/'); $domain = c('Garden.Cookie.Domain', ''); $expire = 0; // If the domain being set is completely incompatible with the // current domain then make the domain work. $currentHost = Gdn::request()->host(); if (!stringEndsWith($currentHost, trim($domain, '.'))) { $domain = ''; } safeCookie($name, $sessionID, $expire, $path, $domain); $_COOKIE[$name] = $sessionID; } $session->Attributes = dbdecode($session->Attributes); if (!$session->Attributes) { $session->Attributes = []; } return $session; }