X-Git-Url: https://jasonwoof.com/gitweb/?p=wfpl.git;a=blobdiff_plain;f=session.php;h=75508c026be78ef4d20d83f4ac76b7ec16ffc6da;hp=7f5d52e828f21278db33d40a59022ad9cb6453a8;hb=HEAD;hpb=59c2d4dd864a724f0940405fed4d61bb8aa1864c diff --git a/session.php b/session.php index 7f5d52e..75508c0 100644 --- a/session.php +++ b/session.php @@ -1,126 +1,198 @@ $session_key, + 'idle_timeout' => $idle_timeout, + 'expires' => $now + $idle_timeout, + 'expires_max' => $now + $max_length, + 'value' => '' + ); + + db_insert_assoc('wfpl_sessions', $row); + $session_id = db_auto_id(); + $GLOBALS['wfpl_session'] = array( + 'exists' => true, + 'id' => $session_id, + 'key' => $session_key, + 'idle_timeout' => $idle_timeout, + 'expires' => $now + $idle_timeout, + 'expires_max' => $now + $max_length, + 'value' => array() + ); + session_set_cookie(); + return $session_key; } -# call to renew the timeout for the session. -# assumes there's a session. call session_init() if you'd like one auto-create one if not found. -function session_touch($length = false) { - if(!$length) { - $length = db_get_value('wfpl_sessions', 'length', 'where id=%i', $GLOBALS['session_id']); +function session_set_cookie() { + if (session_exists()) { + if (!isset($GLOBALS['wfpl_session']['cookie_set'])) { + $GLOBALS['wfpl_session']['cookie_set'] = true; + header('Set-Cookie: session_key=' . $GLOBALS['wfpl_session']['key'] . '; Path=/'); + } } - $expires = time() + $length; +} - header('Set-Cookie: session_key=' . $GLOBALS['session_key']); +# this is a helper function. See session_new() +function session_touch() { + if(!session_exists()) { + return; + } + # is the session extendable? + if ($GLOBALS['wfpl_session']['expires'] < $GLOBALS['wfpl_session']['expires_max']) { + # would this extend the session by at least 10%? + $now = time(); + $last_activity = $GLOBALS['wfpl_session']['expires'] - $GLOBALS['wfpl_session']['idle_timeout']; + # don't db_update if only a tiny fraction of the idle timeout has passed + $db_threshold = ceil(0.1 * $GLOBALS['wfpl_session']['idle_timeout']); + if ($now > $last_activity + $db_threshold) { + $expires = min( + $GLOBALS['wfpl_session']['expires_max'], + $now + $GLOBALS['wfpl_session']['idle_timeout'] + ); + db_update('wfpl_sessions', 'expires', $expires, 'where id=%i', $GLOBALS['wfpl_session']['id']); + $GLOBALS['wfpl_session']['expires'] = $expires; + } + } +} - db_update('wfpl_sessions', 'expires', $expires, 'where id=%i', $GLOBALS['session_id']); +# delete the current session +function kill_session() { + if(!session_exists()) { + return; + } + db_delete('wfpl_sessions', 'where id=%i', $GLOBALS['wfpl_session']['id']); + $GLOBALS['wfpl_session'] = array('exists' => false); } # delete expired sessions from database function session_purge_old() { - $now = time(); - $exired_sessions = db_get_column('wfpl_sessions', 'id', 'where expires < %i', $now); - db_delete('wfpl_sessions', 'where expires < %i', $now); - if($expired_sessions) { - foreach($expired_sessions as $expired_session) { - db_delete('wfpl_session_data', 'where session_id=%i', $expired_session); - } - } + db_delete('wfpl_sessions', 'where expires < %i', time()); } # return true if a session exists function session_exists() { - if(!isset($_REQUEST['session_key'])) { + if (isset($GLOBALS['wfpl_session'])) { + return $GLOBALS['wfpl_session']['exists']; + } + + $GLOBALS['wfpl_session'] = array('exists' => false); + + if(!isset($_COOKIE['session_key'])) { return false; } - $session_key = ereg_replace('[^a-zA-Z0-9]', '', $_REQUEST['session_key']); + $session_key = preg_replace('|[^a-z0-9]|i', '', $_COOKIE['session_key']); if(!strlen($session_key) == 16) { return false; } - $GLOBALS['session_key'] = $session_key; - - session_purge_old(); - $id = db_get_value('wfpl_sessions', 'id', 'where session_key=%"', $session_key); - if($id === false) { + $row = db_get_assoc('wfpl_sessions', 'id,idle_timeout,expires,expires_max,value', 'where session_key=%"', $session_key); + if($row === false) { + return false; + } + $now = time(); + if ($now >= (int) $row['expires']) { + session_purge_old(); return false; } - $GLOBALS['session_id'] = $id; + $GLOBALS['wfpl_session']['exists'] = true; + $GLOBALS['wfpl_session']['id'] = $row['id']; + $GLOBALS['wfpl_session']['idle_timeout'] = (int) $row['idle_timeout']; + $GLOBALS['wfpl_session']['expires'] = (int) $row['expires']; + $GLOBALS['wfpl_session']['expires_max'] = (int) $row['expires_max']; + $GLOBALS['wfpl_session']['key'] = $session_key; + + if (strlen($row['value']) && is_array($parsed = json_decode($row['value'], true))) { + $GLOBALS['wfpl_session']['value'] = $parsed; + } else { + $GLOBALS['wfpl_session']['value'] = array(); + } + + # mark session as not idle + session_touch(); + return true; } + +# generate a random password using only letters and numbers that look +# particularly unique +function new_readable_password($length = 8) { + $character_set = "ABCDEFHJKLMNPQRTUWXY34789"; + $code = ""; + + # PHP 4.2.0 and up seed the random number generator for you. + # Lets hope that it seeds with something harder to guess than the clock. + while($length--) { + $code .= $character_set{mt_rand(0, 24)}; # inclusive + } + + return $code; +} + +# depricated # return username if a session exists and is authenticated -function session_exists_and_authed() { +function logged_in() { if(!session_exists()) { return false; } @@ -129,31 +201,100 @@ function session_exists_and_authed() { } -# find existing session, or make one +# depricated +function session_exists_and_authed() { + return logged_in(); +} + + +# depricated +# return true if a session exists and is authenticated +function logged_in_as_admin() { + if(!session_exists()) { + return false; + } + + if(session_get('auth_admin')) { + return true; + } + return false; +} + + +# find existing session, or make one (name "session_init" was taken) function init_session() { if(!session_exists()) { session_new(); } } -# delete the current session -function kill_session() { - if(!session_exists()) { - return; +# internal use only (write session cache to db) +function _sync_session() { + if (count($GLOBALS['wfpl_session']['value']) > 0) { + $value = json_encode($GLOBALS['wfpl_session']['value']); + } else { + $value = ''; } - db_delete('wfpl_session_data', 'where session_id=%i', $GLOBALS['session_id']); - db_delete('wfpl_sessions', 'where id=%i', $GLOBALS['session_id']); + db_update('wfpl_sessions', 'value', $value, 'where id=%i', $GLOBALS['wfpl_session']['id']); } -# save a variable into the session +# save data into the session +# $value can be anything json_encode()able function session_set($name, $value) { - db_delete('wfpl_session_data', 'where session_id=%i && name=%"', $GLOBALS['session_id'], $name); - db_insert('wfpl_session_data', 'session_id,name,value', $GLOBALS['session_id'], $name, $value); + init_session(); + if (isset($GLOBALS['wfpl_session']['value'][$name])) { + if ($GLOBALS['wfpl_session']['value'][$name] === $value) { + return; + } + } + $GLOBALS['wfpl_session']['value'][$name] = $value; + _sync_session(); +} + +# save data into the session +# values can be anything json_encode()able +function session_sets($assoc) { + init_session(); + $dirty = false; + foreach ($assoc as $name => &$value) { + if (isset($GLOBALS['wfpl_session']['value'][$name])) { + if ($GLOBALS['wfpl_session']['value'][$name] === $value) { + continue; + } + } + $GLOBALS['wfpl_session']['value'][$name] = $value; + $dirty = true; + } + if ($dirty) { + _sync_session(); + } +} + +# remove variable from the session +# with no args: clear all +function session_clear($name = -1) { + if(!session_exists()) { + return; + } + if ($name === -1) { + if (count($GLOBALS['wfpl_session']['value']) > 0) { + $GLOBALS['wfpl_session']['value'] = array(); + _sync_session(); + } + } elseif (isset($GLOBALS['wfpl_session']['value'][$name])) { + unset($GLOBALS['wfpl_session']['value'][$name]); + _sync_session(); + } } # get a variable into the session function session_get($name) { - return db_get_value('wfpl_session_data', 'value', 'where session_id=%i && name=%"', $GLOBALS['session_id'], $name); + if(!session_exists()) { + return false; + } + if (isset($GLOBALS['wfpl_session']['value'][$name])) { + return $GLOBALS['wfpl_session']['value'][$name]; + } else { + return false; + } } - -?>