protected override void BuildXml()
{
if ( Request.Form["CKFinderCommand"] != "true" )
{
ConnectorException.Throw( Errors.InvalidRequest );
}
if ( !this.CurrentFolder.CheckAcl( AccessControlRules.FileRename | AccessControlRules.FileUpload | AccessControlRules.FileDelete ) )
{
ConnectorException.Throw( Errors.Unauthorized );
}
if ( Request.Form["files[0][type]"] == null )
{
ConnectorException.Throw( Errors.InvalidRequest );
}
int moved = 0;
int movedAll = 0;
if ( Request.Form["moved"] != null )
{
movedAll = Int32.Parse( Request.Form["moved"] );
}
Settings.ResourceType resourceType;
Hashtable resourceTypeConfig = new Hashtable();
Hashtable checkedPaths = new Hashtable();
int iFileNum = 0;
while ( Request.Form["files[" + iFileNum.ToString() + "][type]"] != null && Request.Form["files[" + iFileNum.ToString() + "][type]"].Length > 0 )
{
string name = Request.Form["files[" + iFileNum.ToString() + "][name]"];
string type = Request.Form["files[" + iFileNum.ToString() + "][type]"];
string path = Request.Form["files[" + iFileNum.ToString() + "][folder]"];
string options = "";
if ( name == null || name.Length < 1 || type == null || type.Length < 1 || path == null || path.Length < 1 )
{
ConnectorException.Throw( Errors.InvalidRequest );
return;
}
if ( Request.Form["files[" + iFileNum.ToString() + "][options]"] != null )
{
options = Request.Form["files[" + iFileNum.ToString() + "][options]"];
}
iFileNum++;
// check #1 (path)
if ( !Connector.CheckFileName( name ) || Regex.IsMatch( path, @"(/\.)|(\.\.)|(//)|([\\:\*\?""\<\>\|])" ) )
{
ConnectorException.Throw( Errors.InvalidRequest );
return;
}
// get resource type config for current file
if ( !resourceTypeConfig.ContainsKey( type ) )
{
resourceTypeConfig[type] = Config.Current.GetResourceTypeConfig( type );
}
// check #2 (resource type)
if ( resourceTypeConfig[type] == null )
{
ConnectorException.Throw( Errors.InvalidRequest );
return;
}
resourceType = (Settings.ResourceType)resourceTypeConfig[type];
FolderHandler folder = new FolderHandler( type, path );
string sourceFilePath = System.IO.Path.Combine( folder.ServerPath, name );
// check #3 (extension)
if ( !resourceType.CheckExtension( System.IO.Path.GetExtension( name ) ) )
{
this.appendErrorNode( Errors.InvalidExtension, name, type, path );
continue;
}
// check #4 (extension) - when moving to another resource type, double check extension
if ( this.CurrentFolder.ResourceTypeName != type )
{
if ( !this.CurrentFolder.ResourceTypeInfo.CheckExtension( System.IO.Path.GetExtension( name ) ) )
{
this.appendErrorNode( Errors.InvalidExtension, name, type, path );
continue;
}
}
// check #5 (hidden folders)
if ( !checkedPaths.ContainsKey( path ) )
{
checkedPaths[path] = true;
if ( Config.Current.CheckIsHidenPath( path ) )
{
ConnectorException.Throw( Errors.InvalidRequest );
return;
}
}
// check #6 (hidden file name)
if ( Config.Current.CheckIsHiddenFile( name ) )
{
ConnectorException.Throw( Errors.InvalidRequest );
return;
}
// check #7 (Access Control, need file view permission to source files)
if ( !folder.CheckAcl( AccessControlRules.FileView ) )
{
ConnectorException.Throw( Errors.Unauthorized );
return;
}
// check #8 (invalid file name)
if ( !Achilles.Acme.Storage.IO.File.Exists( sourceFilePath ) || Achilles.Acme.Storage.IO.Directory.Exists( sourceFilePath ) )
{
this.appendErrorNode( Errors.FileNotFound, name, type, path );
continue;
}
// check #9 (max size)
if ( this.CurrentFolder.ResourceTypeName != type )
{
Achilles.Acme.Storage.IO.FileInfo fileInfo = new Achilles.Acme.Storage.IO.FileInfo( sourceFilePath );
if ( this.CurrentFolder.ResourceTypeInfo.MaxSize > 0 && fileInfo.Length > this.CurrentFolder.ResourceTypeInfo.MaxSize )
{
this.appendErrorNode( Errors.UploadedTooBig, name, type, path );
continue;
}
}
string destinationFilePath = System.IO.Path.Combine( this.CurrentFolder.ServerPath, name );
// finally, no errors so far, we may attempt to copy a file
// protection against copying files to itself
if ( sourceFilePath == destinationFilePath )
{
this.appendErrorNode( Errors.SourceAndTargetPathEqual, name, type, path );
continue;
}
// check if file exists if we don't force overwriting
else if ( Achilles.Acme.Storage.IO.File.Exists( destinationFilePath ) )
{
if ( options.Contains( "overwrite" ) )
{
try
{
Achilles.Acme.Storage.IO.File.Delete( destinationFilePath );
}
catch ( Exception )
{
this.appendErrorNode( Errors.AccessDenied, name, type, path );
continue;
}
try
{
Achilles.Acme.Storage.IO.File.Move( sourceFilePath, destinationFilePath );
moved++;
}
catch ( Exception )
{
this.appendErrorNode( Errors.AccessDenied, name, type, path );
continue;
}
}
else if ( options.Contains( "autorename" ) )
{
int iCounter = 1;
string fileName;
string sFileNameNoExt = System.IO.Path.GetFileNameWithoutExtension( name );
while ( true )
{
fileName = sFileNameNoExt + "(" + iCounter.ToString() + ")" + System.IO.Path.GetExtension( name );
destinationFilePath = System.IO.Path.Combine( this.CurrentFolder.ServerPath, fileName );
if ( !Achilles.Acme.Storage.IO.File.Exists( destinationFilePath ) )
break;
else
iCounter++;
}
try
{
Achilles.Acme.Storage.IO.File.Move( sourceFilePath, destinationFilePath );
moved++;
}
catch ( ArgumentException )
{
this.appendErrorNode( Errors.InvalidName, name, type, path );
continue;
}
catch ( System.IO.PathTooLongException )
{
this.appendErrorNode( Errors.InvalidName, name, type, path );
continue;
}
catch ( Exception )
{
#if DEBUG
throw;
#else
this.appendErrorNode( Errors.AccessDenied, name, type, path );
continue;
#endif
}
}
else
{
this.appendErrorNode( Errors.AlreadyExist, name, type, path );
continue;
}
}
else
{
try
{
Achilles.Acme.Storage.IO.File.Move( sourceFilePath, destinationFilePath );
moved++;
}
catch ( ArgumentException )
{
this.appendErrorNode( Errors.InvalidName, name, type, path );
continue;
}
catch ( System.IO.PathTooLongException )
{
this.appendErrorNode( Errors.InvalidName, name, type, path );
continue;
}
catch ( Exception )
{
#if DEBUG
throw;
#else
this.appendErrorNode( Errors.AccessDenied, name, type, path );
continue;
#endif
}
}
}
XmlNode moveFilesNode = XmlUtil.AppendElement( this.ConnectorNode, "MoveFiles" );
XmlUtil.SetAttribute( moveFilesNode, "moved", moved.ToString() );
XmlUtil.SetAttribute( moveFilesNode, "movedTotal", ( movedAll + moved ).ToString() );
if ( this.ErrorsNode != null )
{
ConnectorException.Throw( Errors.MoveFailed );
return;
}
}