From 1833951ffc37b2b8043d089960dd7fb5b70d09a0 Mon Sep 17 00:00:00 2001 From: Olav Morken <olav.morken@uninett.no> Date: Mon, 13 Jul 2009 06:16:58 +0000 Subject: [PATCH] Auth_State: Add support for exception handling. This patch introduces infrastructure for throwing exceptions within authentication modules and processing filters, and later catching them in the application which uses the filters. git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@1568 44740490-163a-0410-bde0-09ae8108e29a --- lib/SimpleSAML/Auth/State.php | 93 +++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) diff --git a/lib/SimpleSAML/Auth/State.php b/lib/SimpleSAML/Auth/State.php index 8c16bc5ea..f890c00cd 100644 --- a/lib/SimpleSAML/Auth/State.php +++ b/lib/SimpleSAML/Auth/State.php @@ -18,6 +18,12 @@ * The $stage parameter must be a unique string. To maintain uniqueness, it must be on the form * "<classname>.<identifier>" or "<module>:<identifier>". * + * There is also support for passing exceptions through the state. + * By defining an exception handler when creating the state array, users of the state + * array can call throwException with the state and the exception. This exception will + * be passed to the handler defined by the EXCEPTION_HANDLER_URL or EXCEPTION_HANDLER_FUNC + * elements of the state array. + * * @author Olav Morken, UNINETT AS. * @package simpleSAMLphp * @version $Id$ @@ -43,6 +49,36 @@ class SimpleSAML_Auth_State { const RESTART = 'SimpleSAML_Auth_State.restartURL'; + /** + * The index in the state array which contains the exception handler URL. + */ + const EXCEPTION_HANDLER_URL = 'SimpleSAML_Auth_State.exceptionURL'; + + + /** + * The index in the state array which contains the exception handler function. + */ + const EXCEPTION_HANDLER_FUNC = 'SimpleSAML_Auth_State.exceptionFunc'; + + + /** + * The index in the state array which contains the exception data. + */ + const EXCEPTION_DATA = 'SimpleSAML_Auth_State.exceptionData'; + + + /** + * The stage of a state with an exception. + */ + const EXCEPTION_STAGE = 'SimpleSAML_Auth_State.exceptionStage'; + + + /** + * The URL parameter which contains the exception state id. + */ + const EXCEPTION_PARAM = 'SimpleSAML_Auth_State_exceptionId'; + + /** * Save the state. * @@ -166,6 +202,63 @@ class SimpleSAML_Auth_State { $session->deleteData('SimpleSAML_Auth_State', $state[self::ID]); } + + /** + * Throw exception to the state exception handler. + * + * @param array $state The state array. + * @param SimpleSAML_Error_Exception $exception The exception. + */ + public static function throwException($state, SimpleSAML_Error_Exception $exception) { + assert('is_array($state)'); + + if (array_key_exists(self::EXCEPTION_HANDLER_URL, $state)) { + + /* Save the exception. */ + $state[self::EXCEPTION_DATA] = $exception; + $id = self::saveState($state, self::EXCEPTION_STAGE); + + /* Redirect to the exception handler. */ + SimpleSAML_Utilities::redirect($state[self::EXCEPTION_HANDLER_URL], array(self::EXCEPTION_PARAM => $id)); + + } elseif (array_key_exists(self::EXCEPTION_HANDLER_FUNC, $state)) { + /* Call the exception handler. */ + $func = $state[self::EXCEPTION_HANDLER_FUNC]; + assert('is_callable($func)'); + + call_user_func($func, $exception, $state); + assert(FALSE); + + } else { + /* + * No exception handler is defined for the current state. + */ + throw $exception; + } + + } + + + /** + * Retrieve an exception state. + * + * @param string|NULL $id The exception id. Can be NULL, in which case it will be retrieved from the request. + * @return array The state array with the exception. + */ + public static function loadExceptionState($id = NULL) { + assert('is_string($id) || is_null($id)'); + + if ($id === NULL) { + assert('array_key_exists(self::EXCEPTION_PARAM, $_REQUEST)'); + $id = $_REQUEST[self::EXCEPTION_PARAM]; + } + + $state = self::loadState($id, self::EXCEPTION_STAGE); + assert('array_key_exists(self::EXCEPTION_DATA, $state)'); + + return $state; + } + } ?> \ No newline at end of file -- GitLab