diff --git a/config-templates/config.php b/config-templates/config.php index d0f3dc454801432495c2be706d9992edba5311f6..0d38221529575047afc4dff1b445a2031200aca5 100644 --- a/config-templates/config.php +++ b/config-templates/config.php @@ -381,16 +381,16 @@ $config = array ( /* - * This configuration option allows you to select which session handler - * SimpleSAMLPHP should use to store the session information. Currently - * we have two session handlers: - * - 'phpsession': The default PHP session handler. - * - 'memcache': Stores the session information in one or more - * memcache servers by using the MemcacheStore class. + * Configure the datastore for simpleSAMLphp. * - * The default session handler is 'phpsession'. + * - 'phpsession': Limited datastore, which uses the PHP session. + * - 'memcache': Key-value datastore, based on memcache. + * + * The default datastore is 'phpsession'. + * + * (This option replaces the old 'session.handler'-option.) */ - 'session.handler' => 'phpsession', + 'store.type' => 'phpsession', /* diff --git a/lib/SimpleSAML/SessionHandler.php b/lib/SimpleSAML/SessionHandler.php index b3dbfceb33fb1b39a6de94a2d092eb30198aa1ea..90eb511625e94aec180748d58996e548aaac18c6 100644 --- a/lib/SimpleSAML/SessionHandler.php +++ b/lib/SimpleSAML/SessionHandler.php @@ -81,28 +81,12 @@ abstract class SimpleSAML_SessionHandler { */ private static function createSessionHandler() { - /* Get the configuration. */ - $config = SimpleSAML_Configuration::getInstance(); - assert($config instanceof SimpleSAML_Configuration); - - /* Get the session handler option from the configuration. */ - $handler = $config->getString('session.handler', 'phpsession'); - $handler = strtolower($handler); - - switch ($handler) { - case 'phpsession': - $sh = new SimpleSAML_SessionHandlerPHP(); - break; - case 'memcache': - $sh = new SimpleSAML_SessionHandlerMemcache(); - break; - default: - throw new SimpleSAML_Error_Exception( - 'Invalid session handler specified in the \'session.handler\'-option.'); + $store = SimpleSAML_Store::getInstance(); + if ($store === FALSE) { + self::$sessionHandler = new SimpleSAML_SessionHandlerPHP(); + } else { + self::$sessionHandler = new SimpleSAML_SessionHandlerStore($store); } - - /* Set the session handler. */ - self::$sessionHandler = $sh; } diff --git a/lib/SimpleSAML/SessionHandlerMemcache.php b/lib/SimpleSAML/SessionHandlerMemcache.php deleted file mode 100644 index 48a562267c3235f24aae5c822d6b8325f8d167cf..0000000000000000000000000000000000000000 --- a/lib/SimpleSAML/SessionHandlerMemcache.php +++ /dev/null @@ -1,73 +0,0 @@ -<?php - -/** - * This file is part of SimpleSAMLphp. See the file COPYING in the - * root of the distribution for licence information. - * - * This file defines a session handler which uses the MemcacheStore - * class to store data in memcache servers. - * - * @author Olav Morken, UNINETT AS. <andreas.solberg@uninett.no> - * @package simpleSAMLphp - * @version $Id$ - */ -class SimpleSAML_SessionHandlerMemcache -extends SimpleSAML_SessionHandlerCookie { - - /* Initialize the memcache session handling. This constructor is - * protected because it should only be called from - * SimpleSAML_SessionHandler::createSessionHandler(...). - */ - protected function __construct() { - - /* Call parent constructor to allow it to configure the session - * id. - */ - parent::__construct(); - } - - - /** - * Save the current session to memcache. - * - * @param SimpleSAML_Session $session The session object we should save. - */ - public function saveSession(SimpleSAML_Session $session) { - - SimpleSAML_Memcache::set('simpleSAMLphp.session.' . $this->session_id, $session); - } - - - /** - * Load the session from memcache. - * - * @return SimpleSAML_Session|NULL The session object, or NULL if it doesn't exist. - */ - public function loadSession() { - - $session = SimpleSAML_Memcache::get('simpleSAMLphp.session.' . $this->session_id); - if ($session !== NULL) { - assert('$session instanceof SimpleSAML_Session'); - return $session; - } - - /* For backwards compatibility, check the MemcacheStore object. */ - $store = SimpleSAML_MemcacheStore::find($this->session_id); - if ($store === NULL) { - return NULL; - } - - $session = $store->get('SimpleSAMLphp_SESSION'); - if ($session === NULL) { - return NULL; - } - - assert('is_string($session)'); - - $session = unserialize($session); - assert('$session instanceof SimpleSAML_Session'); - - return $session; - } - -} diff --git a/lib/SimpleSAML/SessionHandlerStore.php b/lib/SimpleSAML/SessionHandlerStore.php new file mode 100644 index 0000000000000000000000000000000000000000..d17b25be58d369af134984aa8aca0616cfef4b8b --- /dev/null +++ b/lib/SimpleSAML/SessionHandlerStore.php @@ -0,0 +1,77 @@ +<?php + +/** + * Session storage in the datastore. + * + * @package simpleSAMLphp + * @version $Id$ + */ +class SimpleSAML_SessionHandlerStore extends SimpleSAML_SessionHandlerCookie { + + /** + * The datastore we save the session to. + */ + private $store; + + /** + * Initialize the session handlerstore. + */ + protected function __construct(SimpleSAML_Store $store) { + parent::__construct(); + + $this->store = $store; + } + + + /** + * Load the session from the datastore. + * + * @return SimpleSAML_Session|NULL The session object, or NULL if it doesn't exist. + */ + public function loadSession() { + + $session = $this->store->get('session', $this->session_id); + if ($session !== NULL) { + assert('$session instanceof SimpleSAML_Session'); + return $session; + } + + if (!($this->store instanceof SimpleSAML_Store_Memcache)) { + return NULL; + } + + /* For backwards compatibility, check the MemcacheStore object. */ + $store = SimpleSAML_MemcacheStore::find($this->session_id); + if ($store === NULL) { + return NULL; + } + + $session = $store->get('SimpleSAMLphp_SESSION'); + if ($session === NULL) { + return NULL; + } + + assert('is_string($session)'); + + $session = unserialize($session); + assert('$session instanceof SimpleSAML_Session'); + + return $session; + } + + + /** + * Save the current session to the datastore. + * + * @param SimpleSAML_Session $session The session object we should save. + */ + public function saveSession(SimpleSAML_Session $session) { + + $config = SimpleSAML_Configuration::getInstance(); + $sessionDuration = $config->getInteger('session.duration', 8*60*60); + $expire = time() + $sessionDuration; + + $this->store->set('session', $this->session_id, $session, $expire); + } + +} diff --git a/lib/SimpleSAML/Store.php b/lib/SimpleSAML/Store.php new file mode 100644 index 0000000000000000000000000000000000000000..db204655177dfc248b461f229b152702554d843d --- /dev/null +++ b/lib/SimpleSAML/Store.php @@ -0,0 +1,84 @@ +<?php + +/** + * Base class for datastores. + * + * @package simpleSAMLphp + * @version $Id$ + */ +abstract class SimpleSAML_Store { + + /** + * Our singleton instance. + * + * This is FALSE if the datastore isn't enabled, and NULL + * if we haven't attempted to initialize it. + * + * @var SimpleSAML_Store|FALSE|NULL + */ + private static $instance; + + + /** + * Retrieve our singleton instance. + * + * @return SimpleSAML_Store|FALSE The datastore, or FALSE if it isn't enabled. + */ + public static function getInstance() { + + if (self::$instance !== NULL) { + return self::$instance; + } + + $config = SimpleSAML_Configuration::getInstance(); + $storeType = $config->getString('store.type', NULL); + if ($storeType === NULL) { + $storeType = $config->getString('session.handler', 'phpsession'); + } + + switch ($storeType) { + case 'phpsession': + /* We cannot support advanced features with the PHP session store. */ + self::$instance = FALSE; + break; + case 'memcache': + self::$instance = new SimpleSAML_Store_Memcache(); + break; + default: + throw new SimpleSAML_Error_Exception('Unknown datastore type: ' . var_export($storeType, TRUE)); + } + + return self::$instance; + } + + + /** + * Retrieve a value from the datastore. + * + * @param string $type The datatype. + * @param string $key The key. + * @return mixed|NULL The value. + */ + abstract public function get($type, $key); + + + /** + * Save a value to the datastore. + * + * @param string $type The datatype. + * @param string $key The key. + * @param mixed $value The value. + * @param int|NULL $expire The expiration time (unix timestamp), or NULL if it never expires. + */ + abstract public function set($type, $key, $value, $expire = NULL); + + + /** + * Delete a value from the datastore. + * + * @param string $type The datatype. + * @param string $key The key. + */ + abstract public function delete($type, $key); + +} diff --git a/lib/SimpleSAML/Store/Memcache.php b/lib/SimpleSAML/Store/Memcache.php new file mode 100644 index 0000000000000000000000000000000000000000..b7a0181ea3e5e49023fb6d83d322cacc011923fa --- /dev/null +++ b/lib/SimpleSAML/Store/Memcache.php @@ -0,0 +1,63 @@ +<?php + +/** + * A memcache based datastore. + * + * @package simpleSAMLphp + * @version $Id$ + */ +class SimpleSAML_Store_Memcache extends SimpleSAML_Store { + + /** + * Initialize the memcache datastore. + */ + protected function __construct() { + } + + + /** + * Retrieve a value from the datastore. + * + * @param string $type The datatype. + * @param string $key The key. + * @return mixed|NULL The value. + */ + public function get($type, $key) { + assert('is_string($type)'); + assert('is_string($key)'); + + return SimpleSAML_Memcache::get('simpleSAMLphp.' . $type . '.' . $key); + } + + + /** + * Save a value to the datastore. + * + * @param string $type The datatype. + * @param string $key The key. + * @param mixed $value The value. + * @param int|NULL $expire The expiration time (unix timestamp), or NULL if it never expires. + */ + public function set($type, $key, $value, $expire = NULL) { + assert('is_string($type)'); + assert('is_string($key)'); + assert('is_null($expire) || (is_int($expire) && $expire > 2592000)'); + + SimpleSAML_Memcache::set('simpleSAMLphp.' . $type . '.' . $key, $value, $expire); + } + + + /** + * Delete a value from the datastore. + * + * @param string $type The datatype. + * @param string $key The key. + */ + public function delete($type, $key) { + assert('is_string($type)'); + assert('is_string($key)'); + + SimpleSAML_Memcache::delete('simpleSAMLphp.' . $type . '.' . $key, $value, $expire); + } + +}