From 88a4c51ba7102f95290d6e6373065abd0826095e Mon Sep 17 00:00:00 2001 From: Florent Bruneau Date: Sat, 21 Jun 2008 22:00:48 +0200 Subject: [PATCH] Base for the PlSession object. Signed-off-by: Florent Bruneau --- classes/plsession.php | 170 ++++++++++++++++++++++++++++++++++++++++++++++++++ classes/s.php | 88 +++++++++++++++++++++++++- classes/session.php | 133 --------------------------------------- 3 files changed, 257 insertions(+), 134 deletions(-) create mode 100644 classes/plsession.php delete mode 100644 classes/session.php diff --git a/classes/plsession.php b/classes/plsession.php new file mode 100644 index 0000000..af3e883 --- /dev/null +++ b/classes/plsession.php @@ -0,0 +1,170 @@ +fillSession(); + } + + /** Build the session structure with system fields. + */ + private function fillSession() + { + S::bootstrap('user', null); + S::bootstrap('auth', AUTH_PUBLIC); + S::bootstrap('challenge', sha1(uniqid(rand(), true))); + S::bootstrap('xsrf_token', rand_url_id()); + S::bootstrap('perms', new PlFlagSet()); + } + + /** Write current session and close it. + */ + public function close() + { + session_write_close(); + } + + /** Kill the current session. + */ + public function destroy() + { + session_destroy(); + unset($_SESSION); + } + + /** Check if the user has at least the given authentication level. + */ + public function checkAuth($level) + { + return S::i('auth') >= $level; + } + + /** Check if the user has the given permissions. + */ + public function checkPerms($perms) + { + return S::v('perms')->hasFlagCombination($perms); + } + + /** Run authentication procedure to reach at least the given level. + */ + public function start($level) + { + if ($this->checkAuth($level)) { + return true; + } + $user = $this->doAuth($level); + if (is_null($user) || !$this->checkAuth($level)) { + return false; + } + if ($this->startSessionAs($user, $level)) { + if (is_null(S::v('user'))) { + S::set('user', $user); + } + return true; + } else { + $this->destroy(); + } + return false; + } + + + /*** Abstract methods ***/ + + /** Run the effectively authentication procedure to reach the given user. + * This method must return a user object (that will be used to fill the + * $_SESSION['user'] field). + * + * If auth failed, the function MUST return null. If auth succeed, the + * field $_SESSION['auth'] MUST be filled to the current effective level. + */ + abstract protected function doAuth($level); + + /** Set the session environment to the given user and authentication level. + * This function MUST return false if a session is already started and the + * user mismatch. + * + * On succes, this function MUST return true. + * If $level is set to -1, this means you are building a new SUID session. + */ + abstract protected function startSessionAs($user, $level); + + + /*** SUID management ***/ + + /** Start a new SUID session. + */ + public function startSUID($user) + { + if (isset($_SESSION['suid'])) { + return false; + } + $newsession = array(); + $backup =& $_SESSION; + $_SESSION =& $newsession; + $this->fillSession(); + S::set('suid', $backup); + if (!$this->startSessionAs($user, -1)) { + $this->stopSUID(); + return false; + } + return true; + } + + /** Stop a SUID session + */ + public function stopSUID() + { + if (!isset($_SESSION['suid'])) { + return false; + } + $_SESSION =& $_SESSION['suid']; + return true; + } + + + /*** Thresholds ***/ + + /** Minimum level of authentication that is considered as sure. + */ + abstract public function sureLevel(); +} + +// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: +?> diff --git a/classes/s.php b/classes/s.php index 338a437..bcb8975 100644 --- a/classes/s.php +++ b/classes/s.php @@ -19,7 +19,93 @@ * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * ***************************************************************************/ -class S extends Session { +class S +{ + /** Set a constructor because this is called prior to S::s(), so we can + * define S::s() for other usages. + */ + private function __construct() + { + assert(false); + } + + public static function has($key) + { + return isset($_SESSION[$key]); + } + + public static function kill($key) + { + unset($_SESSION[$key]); + } + + public static function v($key, $default = null) + { + return isset($_SESSION[$key]) ? $_SESSION[$key] : $default; + } + + public static function s($key, $default = '') + { + return (string)S::v($key, $default); + } + + public static function i($key, $default = 0) + { + $i = S::v($key, $default); + return is_numeric($i) ? intval($i) : $default; + } + + public static function l(array $keys) + { + return array_map(array('S', 'v'), $keys); + } + + public static function set($key, &$value) + { + $_SESSION[$key] =& $value; + } + + public static function bootstrap($key, &$value) + { + if (!S::has($key)) { + S::set($key, $value); + } + } + + public static function has_perms() + { + global $session; + return $session->checkPerms(PERMS_ADMIN); + } + + public static function logged() + { + return S::v('auth', AUTH_PUBLIC) > AUTH_PUBLIC; + } + + public static function identified() + { + global $session; + return S::v('auth', AUTH_PUBLIC) >= $session->sureLevel(); + } + + // Anti-XSRF protections. + public static function has_xsrf_token() + { + return S::has('xsrf_token') && S::v('xsrf_token') == Env::v('token'); + } + + public static function assert_xsrf_token() + { + if (!S::has_xsrf_token()) { + Platal::page()->kill('L\'opération n\'a pas pu aboutir, merci de réessayer.'); + } + } + + public static function rssActivated() + { + return S::has('core_rss_hash') && S::v('core_rss_hash'); + } } // vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: diff --git a/classes/session.php b/classes/session.php deleted file mode 100644 index b2874eb..0000000 --- a/classes/session.php +++ /dev/null @@ -1,133 +0,0 @@ -hasFlag(PERMS_ADMIN); - } - - public static function logged() - { - return Session::v('auth', AUTH_PUBLIC) >= AUTH_COOKIE; - } - - public static function identified() - { - return Session::v('auth', AUTH_PUBLIC) >= AUTH_MDP; - } - - // Anti-XSRF protections. - public static function has_xsrf_token() - { - return Session::has('xsrf_token') && Session::v('xsrf_token') == Env::v('token'); - } - - public static function assert_xsrf_token() - { - if (!Session::has_xsrf_token()) { - global $page; - if ($page instanceof PlPage) { - $page->kill("L'opération n'a pas pu aboutir, merci de réessayer."); - } - } - } - - public static function rssActivated() - { - return Session::has('core_rss_hash') && Session::v('core_rss_hash'); - } -} - -// {{{ function check_perms() - -/** verifie si un utilisateur a les droits pour voir une page - ** si ce n'est pas le cas, on affiche une erreur - * @return void - */ -function check_perms() -{ - global $page; - if (!S::has_perms()) { - if ($_SESSION['log']) { - $_SESSION['log']->log("noperms",$_SERVER['PHP_SELF']); - } - $page->kill("Tu n'as pas les permissions nécessaires pour accéder à cette page."); - } -} - -// }}} - -// vim:set et sw=4 sts=4 sws=4 foldmethod=marker enc=utf-8: -?> -- 2.1.4