summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lib/SimpleSAML/Module.php17
-rw-r--r--lib/SimpleSAML/XHTML/Template.php141
-rw-r--r--www/module.php146
3 files changed, 265 insertions, 39 deletions
diff --git a/lib/SimpleSAML/Module.php b/lib/SimpleSAML/Module.php
index 5ac8c46..18a332b 100644
--- a/lib/SimpleSAML/Module.php
+++ b/lib/SimpleSAML/Module.php
@@ -129,6 +129,23 @@ class SimpleSAML_Module {
return $className;
}
+
+ /**
+ * Get absolute URL to a specified module resource.
+ *
+ * This function creates an absolute URL to a resource stored under ".../modules/<module>/www/".
+ *
+ * @param string $resource Resource path, on the form "<module name>/<resource>"
+ * @return string The absolute URL to the given resource.
+ */
+ public static function getModuleURL($resource) {
+ assert('is_string($resource)');
+ assert('$resource[0] !== "/"');
+
+ $config = SimpleSAML_Configuration::getInstance();
+ return SimpleSAML_Utilities::selfURLhost() . '/' . $config->getBaseURL() . 'module.php/' . $resource;
+ }
+
}
?> \ No newline at end of file
diff --git a/lib/SimpleSAML/XHTML/Template.php b/lib/SimpleSAML/XHTML/Template.php
index e32086e..d87c62a 100644
--- a/lib/SimpleSAML/XHTML/Template.php
+++ b/lib/SimpleSAML/XHTML/Template.php
@@ -190,21 +190,8 @@ class SimpleSAML_XHTML_Template {
*/
private function includeAtTemplateBase($file) {
$data = $this->data;
- $filename = $this->configuration->getPathValue('templatedir') . $this->configuration->getValue('theme.use') . '/' . $file;
- if (!file_exists($filename)) {
-
- SimpleSAML_Logger::error($_SERVER['PHP_SELF'].' - Template: Could not find template file [' . $file .
- '] at [' . $filename . '] - Now trying at base');
-
- $filename = $this->configuration->getPathValue('templatedir') . $this->configuration->getValue('theme.base') . '/' . $file;
- if (!file_exists($filename)) {
- SimpleSAML_Logger::error($_SERVER['PHP_SELF'].' - Template: Could not find template file [' . $file .
- '] at [' . $filename . ']');
- throw new Exception('Could not load template file [' . $file . ']');
- }
-
- }
+ $filename = $this->findTemplatePath($file);
include($filename);
}
@@ -223,8 +210,16 @@ class SimpleSAML_XHTML_Template {
assert('is_string($name)');
if(!array_key_exists($name, $this->dictionaries)) {
- $dictDir = $this->configuration->getPathValue('dictionarydir');
- $this->dictionaries[$name] = $this->readDictionaryFile($dictDir . $name . '.php');
+ $sepPos = strpos($name, ':');
+ if($sepPos !== FALSE) {
+ $module = substr($name, 0, $sepPos);
+ $fileName = substr($name, $sepPos + 1);
+ $dictDir = SimpleSAML_Module::getModuleDir($module) . '/dictionaries/';
+ } else {
+ $dictDir = $this->configuration->getPathValue('dictionarydir');
+ $fileName = $name;
+ }
+ $this->dictionaries[$name] = $this->readDictionaryFile($dictDir . $fileName . '.php');
}
return $this->dictionaries[$name];
@@ -249,7 +244,7 @@ class SimpleSAML_XHTML_Template {
}
/* Check whether we should use the default dictionary or a dictionary specified in the tag. */
- if(substr($tag, 0, 1) === '{' && preg_match('/^{(\w+?):(.*)}$/', $tag, $matches)) {
+ if(substr($tag, 0, 1) === '{' && preg_match('/^{((?:\w+:)?\w+?):(.*)}$/', $tag, $matches)) {
$dictionary = $matches[1];
$tag = $matches[2];
} else {
@@ -460,31 +455,99 @@ class SimpleSAML_XHTML_Template {
* Show the template to the user.
*/
public function show() {
-
- $filename = $this->configuration->getPathValue('templatedir') .
- $this->configuration->getValue('theme.use') . '/' . $this->template;
-
- if (!file_exists($filename)) {
- SimpleSAML_Logger::warning($_SERVER['PHP_SELF'].' - Template: Could not find template file [' . $this->template . '] at [' . $filename . '] - now trying the base template');
-
-
- $filename = $this->configuration->getPathValue('templatedir') .
- $this->configuration->getValue('theme.base') . '/' . $this->template;
-
-
- if (!file_exists($filename)) {
- SimpleSAML_Logger::critical($_SERVER['PHP_SELF'].' - Template: Could not find template file [' . $this->template . '] at [' . $filename . ']');
-
- echo 'Fatal error: Could not find template file [' . $this->template . '] at [' . $filename . ']';
- exit(0);
- }
- }
-
+ $filename = $this->findTemplatePath($this->template);
require_once($filename);
}
-
-
+
+
+ /**
+ * Find template path.
+ *
+ * This function locates the given template based on the template name.
+ * It will first search for the template in the current theme directory, and
+ * then the default theme.
+ *
+ * The template name may be on the form <module name>:<template path>, in which case
+ * it will search for the template file in the given module.
+ *
+ * An error will be thrown if the template file couldn't be found.
+ *
+ * @param string $template The relative path from the theme directory to the template file.
+ * @return string The absolute path to the template file.
+ */
+ private function findTemplatePath($template) {
+ assert('is_string($template)');
+
+ $tmp = explode(':', $template, 2);
+ if (count($tmp) === 2) {
+ $templateModule = $tmp[0];
+ $templateName = $tmp[1];
+ } else {
+ $templateModule = 'default';
+ $templateName = $tmp[0];
+ }
+
+ $tmp = explode(':', $this->configuration->getValue('theme.use'), 2);
+ if (count($tmp) === 2) {
+ $themeModule = $tmp[0];
+ $themeName = $tmp[1];
+ } else {
+ $themeModule = NULL;
+ $themeName = $tmp[0];
+ }
+
+
+ /* First check the current theme. */
+ if ($themeModule !== NULL) {
+ /* .../module/<themeModule>/themes/<themeName>/<templateModule>/<templateName> */
+
+ $filename = SimpleSAML_Module::getModuleDir($themeModule) . '/themes/' . $themeName . '/' .
+ $templateModule . '/' . $templateName;
+ } elseif ($templateModule !== 'default') {
+ /* .../module/<templateModule>/templates/<themeName>/<templateName> */
+ $filename = SimpleSAML_Module::getModuleDir($templateModule) . '/templates/' .
+ $themeName . '/' . $templateName;
+ } else {
+ /* .../templates/<theme>/<templateName> */
+ $filename = $this->configuration->getPathValue('templatedir') . $themeName . '/' .
+ $templateName;
+ }
+
+ if (file_exists($filename)) {
+ return $filename;
+ }
+
+
+ /* Not found in current theme. */
+ SimpleSAML_Logger::info($_SERVER['PHP_SELF'].' - Template: Could not find template file [' .
+ $template . '] at [' . $filename . '] - now trying the base template');
+
+
+ /* Try default theme. */
+ $baseTheme = $this->configuration->getValue('theme.base');
+ if ($templateModule !== 'default') {
+ /* .../module/<templateModule>/templates/<baseTheme>/<templateName> */
+ $filename = SimpleSAML_Module::getModuleDir($templateModule) . '/templates/' .
+ $baseTheme . '/' . $templateName;
+ } else {
+ /* .../templates/<baseTheme>/<templateName> */
+ $filename = $this->configuration->getPathValue('templatedir') . $baseTheme . '/' .
+ $templateName;
+ }
+
+ if (file_exists($filename)) {
+ return $filename;
+ }
+
+
+ /* Not found in default template - log error and throw exception. */
+ $error = 'Template: Could not find template file [' . $template . '] at [' . $filename . ']';
+ SimpleSAML_Logger::critical($_SERVER['PHP_SELF'] . ' - ' . $error);
+
+ throw new Exception($error);
+ }
+
}
?> \ No newline at end of file
diff --git a/www/module.php b/www/module.php
new file mode 100644
index 0000000..73c36b2
--- /dev/null
+++ b/www/module.php
@@ -0,0 +1,146 @@
+<?php
+/**
+ * Handler for module requests.
+ *
+ * This web page receives requests for web-pages hosted by modules, and directs them to
+ * the RequestHandler in the module.
+ *
+ * @author Olav Morken, UNINETT AS.
+ * @package simpleSAMLphp
+ * @version $Id$
+ */
+
+require_once('_include.php');
+
+SimpleSAML_Error_Assertion::installHandler();
+
+/* Index pages - filenames to attempt when accessing directories. */
+$indexFiles = array('index.php', 'index.html', 'index.htm', 'index.txt');
+
+/* MIME types - key is file extension, value is MIME type. */
+$mimeTypes = array(
+ 'bml' => 'image/x-ms-bmp',
+ 'css' => 'text/css',
+ 'gif' => 'image/gif',
+ 'htm' => 'text/html',
+ 'html' => 'text/html',
+ 'shtml' => 'text/html',
+ 'jpe' => 'image/jpeg',
+ 'jpeg' => 'image/jpeg',
+ 'jpg' => 'image/jpeg',
+ 'js' => 'text/javascript',
+ 'pdf' => 'application/pdf',
+ 'png' => 'image/png',
+ 'svg' => 'image/svg+xml',
+ 'svgz' => 'image/svg+xml',
+ 'swf' => 'application/x-shockwave-flash',
+ 'swfl' => 'application/x-shockwave-flash',
+ 'txt' => 'text/plain',
+ 'xht' => 'application/xhtml+xml',
+ 'xhtml' => 'application/xhtml+xml',
+ );
+
+try {
+
+ if (empty($_SERVER['PATH_INFO'])) {
+ throw new SimpleSAML_Error_NotFound('No PATH_INFO to module.php');
+ }
+
+ $url = $_SERVER['PATH_INFO'];
+ assert('substr($url, 0, 1) === "/"');
+
+ $modEnd = strpos($url, '/', 1);
+ if ($modEnd === FALSE) {
+ /* The path must always be on the form /module/. */
+ throw new SimpleSAML_Error_NotFound('The URL must at least contain a module name followed by a slash.');
+ }
+
+ $module = substr($url, 1, $modEnd - 1);
+ $url = substr($url, $modEnd + 1);
+ if ($url === FALSE) {
+ $url = '';
+ }
+
+ if (!SimpleSAML_Module::isModuleEnabled($module)) {
+ throw new SimpleSAML_Error_NotFound('The module \'' . $module .
+ '\' was either not found, or wasn\'t enabled.');
+ }
+
+ /* Make sure that the request isn't suspicious (contains references to current
+ * directory or parent directory or anything like that. Searching for './' in the
+ * URL will detect both '../' and './'. Searching for '\' will detect attempts to
+ * use Windows-style paths.
+ */
+ if (strpos($url, '\\')) {
+ throw new SimpleSAML_Error_BadRequest('Requested URL contained a backslash.');
+ } elseif (strpos($url, './')) {
+ throw new SimpleSAML_Error_BadRequest('Requested URL contained \'./\'.');
+ }
+
+ $path = SimpleSAML_Module::getModuleDir($module) . '/www/' . $url;
+
+ if ($path[strlen($path)-1] === '/') {
+ /* Path ends with a slash - directory reference. Attempt to find index file
+ * in directory.
+ */
+ foreach ($indexFiles as $if) {
+ if (file_exists($path . $if)) {
+ $path .= $if;
+ break;
+ }
+ }
+ }
+
+ if (is_dir($path)) {
+ /* Path is a directory - maybe no index file was found in the previous step, or
+ * maybe the path didn't end with a slash. Either way, we don't do directory
+ * listings.
+ */
+ throw new SimpleSAML_Error_NotFound('Directory listing not available.');
+ }
+
+ if (!file_exists($path)) {
+ /* File not found. */
+ SimpleSAML_Logger::info('Could not find file \'' . $path . '\'.');
+ throw new SimpleSAML_Error_NotFound('The URL wasn\'t found in the module.');
+ }
+
+ if (preg_match('#\.php$#', $path)) {
+ /* PHP file - attempt to run it. */
+ require($path);
+ exit();
+ }
+
+ /* Some other file type - attempt to serve it. */
+
+ /* Find MIME type for file, based on extension. */
+ if (preg_match('#\.([^/]+)$#', $path, $type)) {
+ $type = strtolower($type[1]);
+ if (array_key_exists($type, $mimeTypes)) {
+ $contentType = $mimeTypes[$type];
+ } else {
+ $contentType = mime_content_type($path);
+ }
+ } else {
+ $contentType = mime_content_type($path);
+ }
+
+ $contentLength = sprintf('%u', filesize($path)); /* Force filesize to an unsigned number. */
+
+ header('Content-Type: ' . $contentType);
+ header('Content-Length: ' . $contentLength);
+ readfile($path);
+ exit();
+
+} catch(SimpleSAML_Error_Error $e) {
+
+ $e->show();
+
+} catch(Exception $e) {
+
+ $e = new SimpleSAML_Error_Error('UNHANDLEDEXCEPTION', $e);
+ $e->show();
+
+}
+
+?> \ No newline at end of file