[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