[pLog-svn] r5895 - in plog/trunk: class/action/admin js/ui/pages templates/admin
oscar at devel.lifetype.net
oscar at devel.lifetype.net
Mon Sep 3 16:44:57 EDT 2007
Author: oscar
Date: 2007-09-03 16:44:57 -0400 (Mon, 03 Sep 2007)
New Revision: 5895
Added:
plog/trunk/class/action/admin/admincopyblogtemplatefileaction.class.php
Modified:
plog/trunk/class/action/admin/admincopytemplatefileaction.class.php
plog/trunk/js/ui/pages/templateeditor.js
plog/trunk/templates/admin/edittemplate_table.template
Log:
Inpmlemented the copy of blog template files, and closed another potential issue, where a user could copy for example an .template file into an .html or .js one bypassing all security checks if .html and .js files are not allowed.
Added: plog/trunk/class/action/admin/admincopyblogtemplatefileaction.class.php
===================================================================
--- plog/trunk/class/action/admin/admincopyblogtemplatefileaction.class.php (rev 0)
+++ plog/trunk/class/action/admin/admincopyblogtemplatefileaction.class.php 2007-09-03 20:44:57 UTC (rev 5895)
@@ -0,0 +1,94 @@
+<?php
+
+ lt_include( PLOG_CLASS_PATH."class/action/admin/adminbasetemplateeditoraction.class.php" );
+ lt_include( PLOG_CLASS_PATH."class/data/validator/templatenamevalidator.class.php" );
+ lt_include( PLOG_CLASS_PATH."class/data/validator/stringvalidator.class.php" );
+ lt_include( PLOG_CLASS_PATH."class/data/filter/regexpfilter.class.php" );
+ lt_include( PLOG_CLASS_PATH."class/template/templatesets/templatesets.class.php" );
+ lt_include( PLOG_CLASS_PATH."class/template/editor/templatetools.class.php" );
+ lt_include( PLOG_CLASS_PATH."class/view/admin/adminsitetemplateslistview.class.php" );
+ lt_include( PLOG_CLASS_PATH."class/view/admin/adminerrordialogview.class.php" );
+
+ class AdminCopyBlogTemplateFileAction extends AdminBaseTemplateEditorAction
+ {
+ protected $_template;
+ protected $_path;
+ private $_message;
+
+ function __construct( $actionInfo, $request )
+ {
+ $this->AdminBaseTemplateEditorAction( $actionInfo, $request );
+
+ $this->registerFieldValidator( "templateId", new TemplateNameValidator(), false);
+ $this->registerFieldValidator( "path", new StringValidator(), true );
+ $this->registerFieldValidator( "sourceFileName", new StringValidator(), true );
+ $this->registerFieldValidator( "destFileName", new StringValidator(), true );
+ $view = new AdminSiteTemplatesListView( $this->_blogInfo );
+ $view->setErrorMessage( $this->_locale->tr( "error_loading_template_file" ));
+ $this->setValidationErrorView( $view );
+
+ $this->blogId = $this->_blogInfo->getId();
+
+ $this->requireAdminPermission( "edit_global_templates" );
+ }
+
+ function validate()
+ {
+ return( parent::validate( Array( "templateId", "path" )));
+ }
+
+ function copyFile()
+ {
+ $sourceFileName = $this->_request->getFilteredValue( "sourceFileName", TemplateTools::getTemplateFileNameFilter());
+ $destFileName = $this->_request->getFilteredValue( "destFileName", TemplateTools::getTemplateFileNameFilter());
+
+ // clean up all ".." and just leave ".", to avoid potential relative path attacks
+ $sourceFileName = preg_replace( "/\.+/", ".", $sourceFileName );
+ $destFileName = preg_replace( "/\.+/", ".", $destFileName );
+
+ // and make sure that we're not copying an editable file into a non-editable one (i.e. copy a .template file into a .js one
+ // or .html one with undesired content)
+
+ // see if the destination file is one of the allowed/editable extensions
+ $config =& Config::getConfig();
+ $editableFiles = $config->getValue( 'template_editor_editable_extensions', '');
+ $ok = false;
+ foreach( explode( ' ', $editableFiles ) as $pattern ) {
+ if( Glob::fnmatch( $pattern, $destFileName ))
+ $ok = true;
+ }
+
+ // if the destination file is not one of the allowed ones, then return an error
+ if( !$ok ) {
+ $this->_message = $this->_locale->tr( "error_cannot_copy_to_noneditable_file" );
+ return false;
+ }
+
+ // otherwise proceed with the copy
+ $path = TemplateSetStorage::getTemplateFolder( $this->_templateId, $this->_blogInfo->getId()) . "/" . $this->_path . "/";
+ $result = File::copy( $path.$sourceFileName, $path.$destFileName );
+
+ if( $result )
+ $this->_message = $this->_locale->tr( "template_file_copied_ok" );
+ else
+ $this->_message = $this->_locale->tr( "error_copying_template_file" );
+ }
+
+ function performAjax()
+ {
+ $result = $this->copyFile();
+
+ lt_include( PLOG_CLASS_PATH."class/view/admin/ajax/adminajaxview.class.php" );
+ $this->_view = new AdminAjaxView( $this->_blogInfo );
+
+ $this->_view->setSuccess( $result );
+ if( $result )
+ $this->_view->setSuccessMessage( $this->_message );
+ else
+ $this->_view->setErrorMessage( $this->_message );
+
+ return( true );
+ }
+ }
+
+?>
\ No newline at end of file
Modified: plog/trunk/class/action/admin/admincopytemplatefileaction.class.php
===================================================================
--- plog/trunk/class/action/admin/admincopytemplatefileaction.class.php 2007-09-03 20:04:34 UTC (rev 5894)
+++ plog/trunk/class/action/admin/admincopytemplatefileaction.class.php 2007-09-03 20:44:57 UTC (rev 5895)
@@ -23,7 +23,7 @@
$this->registerFieldValidator( "sourceFileName", new StringValidator(), true );
$this->registerFieldValidator( "destFileName", new StringValidator(), true );
$view = new AdminSiteTemplatesListView( $this->_blogInfo );
- $view->setErrorMessage( $this->_locale->tr( "error_loading_template" ));
+ $view->setErrorMessage( $this->_locale->tr( "error_loading_template_file" ));
$this->setValidationErrorView( $view );
$this->requireAdminPermission( "edit_global_templates" );
@@ -34,34 +34,55 @@
return( parent::validate( Array( "templateId", "path" )));
}
- function createFolder()
+ function copyFile()
{
- $sourceFileName = $this->_request->getFilteredValue( "sourceFileName", TemplateTools::getTemplatePathFilter());
+ $sourceFileName = $this->_request->getFilteredValue( "sourceFileName", TemplateTools::getTemplateFileNameFilter());
$destFileName = $this->_request->getFilteredValue( "destFileName", TemplateTools::getTemplateFileNameFilter());
// clean up all ".." and just leave ".", to avoid potential relative path attacks
$sourceFileName = preg_replace( "/\.+/", ".", $sourceFileName );
- $destFileName = preg_replace( "/\.+/", ".", $destFileName );
+ $destFileName = preg_replace( "/\.+/", ".", $destFileName );
- $path = TemplateSetStorage::getTemplateFolder( $this->_templateId) . "/" . $this->_path . "/";
+ // and make sure that we're not copying an editable file into a non-editable one (i.e. copy a .template file into a .js one
+ // or .html one with undesired content)
- return(
- File::copy( $path.$sourceFileName, $path.$destFileName )
- );
+ // see if the destination file is one of the allowed/editable extensions
+ $config =& Config::getConfig();
+ $editableFiles = $config->getValue( 'template_editor_editable_extensions', '');
+ $ok = false;
+ foreach( explode( ' ', $editableFiles ) as $pattern ) {
+ if( Glob::fnmatch( $pattern, $destFileName ))
+ $ok = true;
+ }
+
+ // if the destination file is not one of the allowed ones, then return an error
+ if( !$ok ) {
+ $this->_message = $this->_locale->tr( "error_cannot_copy_to_noneditable_file" );
+ return false;
+ }
+
+ // otherwise proceed with the copy
+ $path = TemplateSetStorage::getTemplateFolder( $this->_templateId ) . "/" . $this->_path . "/";
+ $result = File::copy( $path.$sourceFileName, $path.$destFileName );
+
+ if( $result )
+ $this->_message = $this->_locale->tr( "template_file_copied_ok" );
+ else
+ $this->_message = $this->_locale->tr( "error_copying_template_file" );
}
function performAjax()
{
- $result = $this->createFolder();
+ $result = $this->copyFile();
lt_include( PLOG_CLASS_PATH."class/view/admin/ajax/adminajaxview.class.php" );
$this->_view = new AdminAjaxView( $this->_blogInfo );
$this->_view->setSuccess( $result );
if( $result )
- $this->_view->setSuccessMessage( $this->_locale->tr( "template_file_copied_ok" ));
+ $this->_view->setSuccessMessage( $this->_message );
else
- $this->_view->setErrorMessage( $this->_locale->tr( "error_copying_template_file" ));
+ $this->_view->setErrorMessage( $this->_message );
return( true );
}
Modified: plog/trunk/js/ui/pages/templateeditor.js
===================================================================
--- plog/trunk/js/ui/pages/templateeditor.js 2007-09-03 20:04:34 UTC (rev 5894)
+++ plog/trunk/js/ui/pages/templateeditor.js 2007-09-03 20:44:57 UTC (rev 5895)
@@ -51,6 +51,19 @@
}
}
+Lifetype.UI.Pages.TemplateEditor.handleCopyBlogFileOk = function( value )
+{
+ if( value != "" ) {
+ var url = '?op=copyBlogTemplateFile&templateId=' + Lifetype.Dom.$( 'templateId' ).value +
+ '&path=' + Lifetype.Dom.$( 'currentPath' ).value +
+ '&sourceFileName=' + Lifetype.UI.Pages.TemplateEditor.copySourceFile +
+ '&destFileName=' + value;
+ Lifetype.Forms.performUrl( url );
+ }
+
+ Lifetype.UI.Pages.TemplateEditor.copySourceFile = null;
+}
+
Lifetype.UI.Pages.TemplateEditor.handleCopyFileOk = function( value )
{
if( value != "" ) {
@@ -64,10 +77,17 @@
Lifetype.UI.Pages.TemplateEditor.copySourceFile = null;
}
-Lifetype.UI.Pages.TemplateEditor.copyTemplateFileTo = function( sourceFile )
+Lifetype.UI.Pages.TemplateEditor.copyTemplateFileTo = function( sourceFile, mode )
{
Lifetype.UI.Pages.TemplateEditor.copySourceFile = sourceFile;
- var v = Lifetype.UI.Prompt.OkCancelPrompt.show( tr('enter_new_template_file_name'), { handleOk:Lifetype.UI.Pages.TemplateEditor.handleCopyFileOk });
+
+ var okCallback;
+ if( mode == "blog" )
+ okCallback = Lifetype.UI.Pages.TemplateEditor.handleCopyBlogFileOk;
+ else
+ okCallback = Lifetype.UI.Pages.TemplateEditor.handleCopyFileOk;
+
+ var v = Lifetype.UI.Prompt.OkCancelPrompt.show( tr('enter_new_template_file_name'), { handleOk:okCallback });
}
/**
Modified: plog/trunk/templates/admin/edittemplate_table.template
===================================================================
--- plog/trunk/templates/admin/edittemplate_table.template 2007-09-03 20:04:34 UTC (rev 5894)
+++ plog/trunk/templates/admin/edittemplate_table.template 2007-09-03 20:44:57 UTC (rev 5895)
@@ -79,7 +79,7 @@
<img src="imgs/admin/icon_empty-16.png" />
{/if}
{if $file.isReadable && !$file.isFolder}
- <a href="#" id="{$file.name}" onClick="Lifetype.UI.Pages.TemplateEditor.copyTemplateFileTo('{$file.name}');return(false);" >
+ <a href="#" id="{$file.name}" onClick="Lifetype.UI.Pages.TemplateEditor.copyTemplateFileTo('{$file.name}','{$mode}');return(false);" >
<img src="imgs/admin/icon_copy-16.png" alt="{$locale->tr("copy")}" />
</a>
{else}
More information about the pLog-svn
mailing list