[SECURITY] Removed SQL Templates

* Remove the entire SQL template system
* Secuirty issues arose that can't easily be fixed in MPOS
* For the sake of site security, these have been completely removed

! Will require the `templates/cache/bootstrap` and `template/compile/bootstrap`
folders to be removed if custom SQL templates were used !

Will fix #2114 once merged.
This commit is contained in:
Sebastian Grewe 2014-04-16 19:02:28 +02:00
parent 6324471bdf
commit a5fe6236e1
7 changed files with 1 additions and 311 deletions

View File

@ -1,48 +0,0 @@
<?php
$defflip = (!cfip()) ? exit(header('HTTP/1.1 401 Unauthorized')) : 1;
// Check user to ensure they are admin
if (!$user->isAuthenticated() || !$user->isAdmin($_SESSION['USERDATA']['id'])) {
header("HTTP/1.1 404 Page not found");
die("404 Page not found");
}
$aThemes = $template->getThemes();
$aTemplates = $template->getTemplatesTree($aThemes);
$aActiveTemplates = $template->cachedGetActiveTemplates();
$aFlatTemplatesList = array();
foreach($aThemes as $sTheme) {
$templates = $template->getTemplateFiles($sTheme);
$aFlatTemplatesList = array_merge($aFlatTemplatesList, $templates);
}
//Fetch current slug and template
$sTemplate = @$_REQUEST['template'];
if(!in_array($sTemplate, $aFlatTemplatesList)) {
$sTemplate = $aFlatTemplatesList[0];
}
$sOriginalTemplate = $template->getTemplateContent($sTemplate);
if (@$_REQUEST['do'] == 'save') {
if ($template->updateEntry(@$_REQUEST['template'], @$_REQUEST['content'], @$_REQUEST['active'])) {
$_SESSION['POPUP'][] = array('CONTENT' => 'Page updated', 'TYPE' => 'alert alert-success');
} else {
$_SESSION['POPUP'][] = array('CONTENT' => 'Page update failed: ' . $template->getError(), 'TYPE' => 'alert alert-danger');
}
}
$oDatabaseTemplate = $template->getEntry($sTemplate);
if ( $oDatabaseTemplate === false ) {
$_SESSION['POPUP'][] = array('CONTENT' => 'Can\'t fetch template from Database. Have you created `templates` table? Run 005_create_templates_table.sql from sql folder', 'TYPE' => 'alert alert-danger');
}
$smarty->assign("TEMPLATES", $aTemplates);
$smarty->assign("ACTIVE_TEMPLATES", $aActiveTemplates);
$smarty->assign("CURRENT_TEMPLATE", $sTemplate);
$smarty->assign("ORIGINAL_TEMPLATE", $sOriginalTemplate);
$smarty->assign("DATABASE_TEMPLATE", $oDatabaseTemplate);
$smarty->assign("CONTENT", "default.tpl");
?>

View File

@ -7,145 +7,6 @@ define('SMARTY_DIR', INCLUDE_DIR . '/smarty/libs/');
// Include the actual smarty class file
include(SMARTY_DIR . 'Smarty.class.php');
/**
* Custom Smarty Template Resource for Pages
* Get templates from Database
* Allow admin to manage his templates from Backoffice
*/
class Smarty_Resource_Database extends Smarty_Resource_Custom {
protected $template;
public function __construct($template) {
$this->template = $template;
}
/**
* Fetch a template and its modification time from database
*
* @param string $name template name
* @param string $source template source
* @param integer $mtime template modification timestamp (epoch)
* @return void
*/
protected function fetch($name, &$source, &$mtime) {
$oTemplate = $this->template->getEntry($this->fullTemplateName($name));
if ( $oTemplate && $oTemplate['active'] ) {
$source = $oTemplate['content'];
$mtime = strtotime($oTemplate['modified_at']);
} else {
$source = null;
$mtime = null;
}
}
/**
* Fetch a template's modification time from database
*
* @note implementing this method is optional. Only implement it if modification times can be accessed faster than loading the comple template source.
* @param string $name template name
* @return integer timestamp (epoch) the template was modified
*/
protected function fetchTimestamp($name) {
$templates = $this->template->cachedGetActiveTemplates();
$mtime = @$templates[$this->fullTemplateName($name)];
return $mtime ? $mtime : false;
}
/**
* Prepend THEME name to template name to get valid DB primary key
*
* @param string $name template name
*/
protected function fullTemplateName($name) {
return $this->normalisePath(THEME . "/" . $name);
}
/**
* Normalise a file path string so that it can be checked safely.
*
* Attempt to avoid invalid encoding bugs by transcoding the path. Then
* remove any unnecessary path components including '.', '..' and ''.
*
* @param $path string
* The path to normalise.
* @return string
* The path, normalised.
* @see https://gist.github.com/thsutton/772287
*/
protected function normalisePath($path) {
// Process the components
$parts = explode('/', $path);
$safe = array();
foreach ($parts as $idx => $part) {
if (empty($part) || ('.' == $part)) {
continue;
} elseif ('..' == $part) {
array_pop($safe);
continue;
} else {
$safe[] = $part;
}
}
// Return the "clean" path
$path = implode(DIRECTORY_SEPARATOR, $safe);
return $path;
}
}
class Smarty_Resource_Hybrid extends Smarty_Resource {
protected $databaseResource;
protected $fileResource;
public function __construct($dbResource, $fileResource) {
$this->databaseResource = $dbResource;
$this->fileResource = $fileResource;
}
/**
* populate Source Object with meta data from Resource
*
* @param Smarty_Template_Source $source source object
* @param Smarty_Internal_Template $_template template object
*/
public function populate(Smarty_Template_Source $source, Smarty_Internal_Template $_template=null) {
if ( !@$_REQUEST['disable_template_override'] ) {
$this->databaseResource->populate($source, $_template);
if( $source->exists )
return;
}
$source->type = 'file';
return $this->fileResource->populate($source, $_template);
}
/**
* Load template's source into current template object
*
* @param Smarty_Template_Source $source source object
* @return string template source
* @throws SmartyException if source cannot be loaded
*/
public function getContent(Smarty_Template_Source $source) {
try {
return $this->databaseResource->getContent($source);
} catch(SmartyException $e) {
return $this->fileResource->getContent($source);
}
}
/**
* Determine basename for compiled filename
*
* @param Smarty_Template_Source $source source object
* @return string resource's basename
*/
public function getBasename(Smarty_Template_Source $source) {
return $this->fileResource->getBasename($source);
}
}
// We initialize smarty here
$debug->append('Instantiating Smarty Object', 3);
$smarty = new Smarty;
@ -154,11 +15,6 @@ $smarty = new Smarty;
$debug->append('Define Smarty Paths', 3);
$smarty->template_dir = BASEPATH . 'templates/' . THEME . '/';
$smarty->compile_dir = BASEPATH . 'templates/compile/' . THEME . '/';
$smarty->registerResource('hybrid', new Smarty_Resource_Hybrid(
new Smarty_Resource_Database($template),
new Smarty_Internal_Resource_File()
));
$smarty->default_resource_type = "hybrid";
$smarty_cache_key = md5(serialize($_REQUEST) . serialize(@$_SESSION['USERDATA']['id']));
// Optional smarty caching, check Smarty documentation for details

View File

@ -1,48 +0,0 @@
<div class="col-lg-3">
<div class="panel panel-info">
<div class="panel-heading">
Select Page
</div>
<div class="panel-content templates-tree" id="templates-tree">
{include file="admin/templates/tree.tpl" files=$TEMPLATES prefix=""}
</div>
<link rel='stylesheet' type='text/css' href='{$PATH}/js/dynatree/skin/ui.dynatree.css'>
<script type="text/javascript" src="{$PATH}/js/jquery.cookie.js"></script>
<script type="text/javascript" src="{$PATH}/js/jquery-ui.custom.min.js"></script>
<script type="text/javascript" src="{$PATH}/js/dynatree/jquery.dynatree.min.js"></script>
<script>
$(function() {
$("#templates-tree").each(function() {
$(this).find("li").each(function() {
if($(this).find("li.dynatree-activated").length) {
$(this).attr("data", "addClass:'dynatree-has-activated'");
}
});
}).dynatree({
minExpandLevel: 2,
clickFolderMode: 2,
selectMode: 1,
persist: true,
//To show the active template onLoad
onPostInit: function(isReloading, isError) {
this.reactivate();
},
onActivate: function(node) {
if( node.tree.isUserEvent() && node.data.href )
location.href = node.data.href;
}
});
});
</script>
<style>
.templates-tree .dynatree-container { border: none; }
.templates-tree span.dynatree-folder a { font-weight: normal; }
.templates-tree span.dynatree-active a,
.templates-tree span.dynatree-has-activated a,
.templates-tree span.dynatree-activated a { font-weight: bold; }
</style>
<div class="panel-footer">
<h6><ul><li>Bold templates are activated</li></ul></h6>
</div>
</div>
</div>

View File

@ -1,4 +0,0 @@
<div class="row">
{include file="admin/templates/browser.tpl"}
{include file="admin/templates/editor.tpl"}
</div>

View File

@ -1,38 +0,0 @@
<form class="col-lg-9" method="POST" action="{$smarty.server.SCRIPT_NAME}">
<input type="hidden" name="page" value="{$smarty.request.page}">
<input type="hidden" name="action" value="{$smarty.request.action}">
<input type="hidden" name="template" value="{$CURRENT_TEMPLATE}">
<input type="hidden" name="do" value="save">
<input type="hidden" name="ctoken" value="{$CTOKEN|escape|default:""}" />
<div class="panel panel-info">
<div class="panel-heading">
<i class="fa fa-pencil fa-fw"></i> Edit template '{$CURRENT_TEMPLATE}'
</div>
<div class="panel-body no-padding">
<table class="table table-striped table-bordered table-hover">
<tr>
<td><label>Active</label></td>
<td>
<input type="hidden" name="active" value="0" />
<input type="checkbox" data-size="small" class="switch" name="active" value="1" id="active" {nocache}{if $DATABASE_TEMPLATE.active}checked{/if}{/nocache} />
</td>
</tr>
<tr>
<td><label>Content</label></td>
<td>
<textarea name="content" rows="15" type="text" class="form-control" required>{nocache}{$DATABASE_TEMPLATE.content nofilter}{/nocache}</textarea>
</td>
</tr>
<tr>
<td><label>Original Template Content</label></td>
<td>
<textarea readonly rows="15" type="text" class="form-control">{nocache}{$ORIGINAL_TEMPLATE nofilter}{/nocache}</textarea>
</td>
</tr>
</table>
</div>
<div class="panel-footer">
<input type="submit" value="Save" class="btn btn-success btn-sm">
</div>
</div>
</form>

View File

@ -1,27 +0,0 @@
<ul>
{foreach from=$files item="value" key="file"}
{if $file != 'master.tpl'}
{if is_array($value)}
<li class="folder">
{$file}
{assign var="new_prefix" value="$prefix$file/"}
{include file="admin/templates/tree.tpl" files=$value prefix=$new_prefix}
</li>
{else}
{assign var="path" value="$prefix$file"}
{assign var="classes" value=array()}
{if array_key_exists($path, $ACTIVE_TEMPLATES)}
{assign var="tmp" value=array_push($classes,"dynatree-activated")}
{/if}
{if $CURRENT_TEMPLATE eq $path}
{assign var="tmp" value=array_push($classes,"dynatree-active")}
{/if}
{assign var="classes" value=join(" ", $classes)}
<li{if $classes} class="{$classes}" data="addClass:'{$classes}'{if strpos("dynatree-active", $classes) !== false}, activate: true{/if}"{/if}>
<a href="{$smarty.server.SCRIPT_NAME}?page={$smarty.request.page}&action={$smarty.request.action}&template={$prefix}{$file}">{$file}</a>
</li>
{/if}
{/if}
{/foreach}
</ul>

View File

@ -8,7 +8,7 @@
<li>
<a href="{$smarty.server.SCRIPT_NAME}?page=dashboard"><i class="fa fa-dashboard fa-fw"></i> Dashboard</a>
</li>
<li {if $smarty.get.page|default:"0" eq "account"}class="active"{/if}>
<a href="#"><i class="fa fa-user-md fa-fw"></i> My Account<span class="fa arrow"></span></a>
<ul class="nav nav-second-level">
@ -39,7 +39,6 @@
<li><a href="{$smarty.server.SCRIPT_NAME}?page=admin&action=registrations"><i class="fa fa-pencil-square-o fa-fw"></i> Registrations</a></li>
<li><a href="{$smarty.server.SCRIPT_NAME}?page=admin&action=invitations"><i class="fa fa-users fa-fw"></i> Invitations</a></li>
<li><a href="{$smarty.server.SCRIPT_NAME}?page=admin&action=poolworkers"><i class="fa fa-desktop fa-fw"></i> Pool Workers</a></li>
<li><a href="{$smarty.server.SCRIPT_NAME}?page=admin&action=templates"><i class="fa fa-files-o fa-fw"></i> Templates</a></li>
</ul>
<!-- /.nav-second-level -->
</li>