From 20d3be8927b84dc5ea8355f6a8ad09934ec76618 Mon Sep 17 00:00:00 2001
From: Olav Morken <olav.morken@uninett.no>
Date: Tue, 3 Aug 2010 09:36:50 +0000
Subject: [PATCH] New error page when missing state information.

git-svn-id: https://simplesamlphp.googlecode.com/svn/trunk@2472 44740490-163a-0410-bde0-09ae8108e29a
---
 lib/SimpleSAML/Auth/State.php                 |  2 +-
 lib/SimpleSAML/Error/NoState.php              | 73 +++++++++++++++++++
 .../dictionaries/no_state.definition.json     | 35 +++++++++
 .../dictionaries/no_state.translation.json    | 46 ++++++++++++
 modules/core/templates/no_state.tpl.php       | 43 +++++++++++
 5 files changed, 198 insertions(+), 1 deletion(-)
 create mode 100644 lib/SimpleSAML/Error/NoState.php
 create mode 100644 modules/core/dictionaries/no_state.definition.json
 create mode 100644 modules/core/dictionaries/no_state.translation.json
 create mode 100644 modules/core/templates/no_state.tpl.php

diff --git a/lib/SimpleSAML/Auth/State.php b/lib/SimpleSAML/Auth/State.php
index 922c0c514..681c973d7 100644
--- a/lib/SimpleSAML/Auth/State.php
+++ b/lib/SimpleSAML/Auth/State.php
@@ -155,7 +155,7 @@ class SimpleSAML_Auth_State {
 			/* Could not find saved data. Attempt to restart. */
 
 			if ($restartURL === NULL) {
-				throw new Exception('State information lost, and no way to restart the request.');
+				throw new SimpleSAML_Error_NoState();
 			}
 
 			SimpleSAML_Utilities::redirect($restartURL);
diff --git a/lib/SimpleSAML/Error/NoState.php b/lib/SimpleSAML/Error/NoState.php
new file mode 100644
index 000000000..5cbf047c3
--- /dev/null
+++ b/lib/SimpleSAML/Error/NoState.php
@@ -0,0 +1,73 @@
+<?php
+
+/**
+ * Exception which will show a page telling the user
+ * that we don't know what to do.
+ *
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+class SimpleSAML_Error_NoState extends SimpleSAML_Error_Error {
+
+
+	/**
+	 * Create the error
+	 *
+	 * @param string $reason  Optional description of why the given page could not be found.
+	 */
+	public function __construct() {
+		parent::__construct('State information lost, and no way to restart the request.');
+	}
+
+
+	/**
+	 * Show the error to the user.
+	 *
+	 * This function does not return.
+	 */
+	public function show() {
+
+		header('HTTP/1.0 500 Internal Server Error');
+
+		$globalConfig = SimpleSAML_Configuration::getInstance();
+
+		$reportId = SimpleSAML_Utilities::stringToHex(SimpleSAML_Utilities::generateRandomBytes(4));
+		SimpleSAML_Logger::error('Error report with id ' . $reportId . ' generated.');
+
+		$session = SimpleSAML_Session::getInstance();
+
+		$errorData = array(
+			'exceptionMsg' => $this->getMessage(),
+			'exceptionTrace' => implode("\n", $this->format()),
+			'reportId' => $reportId,
+			'trackId' => $session->getTrackID(),
+			'url' => SimpleSAML_Utilities::selfURLNoQuery(),
+			'version' => $globalConfig->getVersion(),
+		);
+		$session->setData('core:errorreport', $reportId, $errorData);
+
+
+		$attributes = $session->getAttributes();
+		if (isset($attributes['mail'][0])) {
+			$email = $attributes['mail'][0];
+		} else {
+			$email = '';
+		}
+
+
+		$t = new SimpleSAML_XHTML_Template($globalConfig, 'core:no_state.tpl.php');
+
+		/* Enable error reporting if we have a valid technical contact email. */
+		if($globalConfig->getString('technicalcontact_email', 'na@example.org') !== 'na@example.org') {
+			/* Enable error reporting. */
+			$baseurl = SimpleSAML_Utilities::getBaseURL();
+			$t->data['errorReportAddress'] = $baseurl . 'errorreport.php';
+			$t->data['reportId'] = $reportId;
+			$t->data['email'] = $email;
+		}
+
+		$t->show();
+		exit();
+	}
+
+}
diff --git a/modules/core/dictionaries/no_state.definition.json b/modules/core/dictionaries/no_state.definition.json
new file mode 100644
index 000000000..9ce452a0c
--- /dev/null
+++ b/modules/core/dictionaries/no_state.definition.json
@@ -0,0 +1,35 @@
+{
+	"header": {
+		"en": "State information lost"
+	},
+	"description": {
+		"en": "We were unable to locate the state information for the current request."
+	},
+	"suggestions": {
+		"en": "Suggestions for resolving this problem:"
+	},
+	"suggestion_goback": {
+		"en": "Go back to the previous page and try again."
+	},
+	"suggestion_closebrowser": {
+		"en": "Close the web browser, and try again."
+	},
+	"causes": {
+		"en": "This error may be caused by:"
+	},
+	"cause_backforward": {
+		"en": "Using the back and forward buttons in the web browser."
+	},
+	"cause_openbrowser": {
+		"en": "Opened the web browser with tabs saved from the previous session."
+	},
+	"cause_nocookie": {
+		"en": "Cookies may be disabled in the web browser."
+	},
+	"report_header": {
+		"en": "Report this error"
+	},
+	"report_text": {
+		"en": "If this problem persists, you can report it to the system administrators."
+	}
+}
diff --git a/modules/core/dictionaries/no_state.translation.json b/modules/core/dictionaries/no_state.translation.json
new file mode 100644
index 000000000..986ecdede
--- /dev/null
+++ b/modules/core/dictionaries/no_state.translation.json
@@ -0,0 +1,46 @@
+{
+	"header": {
+		"no": "Tilstandsinformasjon tapt",
+		"nn": "Tilstandsinformasjon tapt"
+	},
+	"description": {
+		"no": "Vi kunne ikke finne tilstandsinformasjonen for denne foresp\u00f8rselen.",
+		"nn": "Vi kunne ikkje finne tilstandsinformasjonen for denne foresp\u00f8rselen."
+	},
+	"suggestions": {
+		"no": "Forslag for \u00e5 l\u00f8se dette problemet:",
+		"nn": "Forslag for \u00e5 l\u00f8yse dette problemet:"
+	},
+	"suggestion_goback": {
+		"no": "G\u00e5 tilbake til forrige side og pr\u00f8v p\u00e5 nytt.",
+		"nn": "G\u00e5 tilbake til forrige side og pr\u00f8v p\u00e5 nytt."
+	},
+	"suggestion_closebrowser": {
+		"no": "Lukk nettleseren, og pr\u00f8v p\u00e5 nytt.",
+		"nn": "Lukk nettlesaren, og pr\u00f8v p\u00e5 nytt."
+	},
+	"causes": {
+		"no": "Denne feilen kan v\u00e6re for\u00e5rsaket av:",
+		"nn": "Denne feilen kan v\u00e6re for\u00e5rsaket av:"
+	},
+	"cause_backforward": {
+		"no": "Bruk av \"frem\"- og \"tilbake\"-knappene i nettleseren.",
+		"nn": "Bruk av \"fram\"- og \"attende\"-knappane i nettlesaren."
+	},
+	"cause_openbrowser": {
+		"no": "Starte nettleseren med faner lagret fra forrige gang.",
+		"nn": "Starte nettlesaren med faner lagret fra forrige gong."
+	},
+	"cause_nocookie": {
+		"no": "At informasjonskapsler ikke er aktivert i nettleseren.",
+		"nn": "At informasjonskapsler ikkje er aktivert i nettlesaren."
+	},
+	"report_header": {
+		"no": "Rapporter denne feilen",
+		"nn": "Rapporter denne feilen"
+	},
+	"report_text": {
+		"no": "Hvis problemet vedvarer, kan du rapportere det til systemadministratorene.",
+		"nn": "Om problemet vedvarar, kan du rapportere det til systemadministratorane."
+	}
+}
diff --git a/modules/core/templates/no_state.tpl.php b/modules/core/templates/no_state.tpl.php
new file mode 100644
index 000000000..8cf07f793
--- /dev/null
+++ b/modules/core/templates/no_state.tpl.php
@@ -0,0 +1,43 @@
+<?php
+
+$this->data['header'] = $this->t('{core:no_state:header}');
+$this->includeAtTemplateBase('includes/header.php');
+
+echo('<h2>' . $this->t('{core:no_state:header}') . '</h2>');
+echo('<p>' . $this->t('{core:no_state:description}') . '</p>');
+
+echo('<h3>' . $this->t('{core:no_state:suggestions}') . '</h3>');
+echo('<ul>');
+echo('<li>' . $this->t('{core:no_state:suggestion_goback}') . '</li>');
+echo('<li>' . $this->t('{core:no_state:suggestion_closebrowser}') . '</li>');
+echo('</ul>');
+
+echo('<h3>' . $this->t('{core:no_state:causes}') . '</h3>');
+echo('<ul>');
+echo('<li>' . $this->t('{core:no_state:cause_backforward}') . '</li>');
+echo('<li>' . $this->t('{core:no_state:cause_openbrowser}') . '</li>');
+echo('<li>' . $this->t('{core:no_state:cause_nocookie}') . '</li>');
+echo('</ul>');
+
+
+/* Add error report submit section if we have a valid technical contact. */
+if (isset($this->data['errorReportAddress'])) {
+
+	echo('<h2>' . $this->t('{core:no_state:report_header}') . '</h2>');
+
+	echo('<form action="' . htmlspecialchars($this->data['errorReportAddress']) . '" method="post">');
+
+	echo('<p>' . $this->t('{core:no_state:report_text}') . '</p>');
+	echo('<p>' . $this->t('{errors:report_email}') . '<input type="text" size="25" name="email" value="' . htmlspecialchars($this->data['email']) . '"/></p>');
+
+	echo('<p>');
+	echo('<textarea style="width: 300px; height: 100px" name="text">' . $this->t('{errors:report_explain}') . '</textarea>');
+	echo('</p>');
+	echo('<p>');
+	echo('<input type="hidden" name="reportId" value="' . $this->data['reportId'] . '" />');
+	echo('<input type="submit" name="send" value="' . $this->t('{errors:report_submit}') . '" />');
+	echo('</p>');
+	echo('</form>');
+}
+
+$this->includeAtTemplateBase('includes/footer.php');
-- 
GitLab