// Copyright (c) 2011, Outercurve Foundation. // All rights reserved. // // Redistribution and use in source and binary forms, with or without modification, // are permitted provided that the following conditions are met: // // - Redistributions of source code must retain the above copyright notice, this // list of conditions and the following disclaimer. // // - Redistributions in binary form must reproduce the above copyright notice, // this list of conditions and the following disclaimer in the documentation // and/or other materials provided with the distribution. // // - Neither the name of the Outercurve Foundation nor the names of its // contributors may be used to endorse or promote products derived from this // software without specific prior written permission. // // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND // ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED // WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE // DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR // ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES // (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; // LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS // SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. using System; using System.IO; using System.Collections.Generic; using System.Text; using System.Web; using System.Web.UI.WebControls; using WebsitePanel.Providers.OS; using Microsoft.Security.Application; namespace WebsitePanel.Portal { public partial class FileManager : WebsitePanelModuleBase { string ALLOWED_EDIT_EXTENSIONS = ".txt.htm.html.php.pl.sql.cs.vb.ascx.aspx.inc.asp.config.xml.xsl.xslt.xsd.Master.htaccess.htpasswd.cshtml.vbhtml"; protected void Page_Load(object sender, EventArgs e) { // Localization for JS RegisterJsLocalizedMessages(); // gvFilesID.Text = gvFiles.ClientID; string downloadFile = Request["DownloadFile"]; if (downloadFile != null) { // download file Response.Clear(); Response.AddHeader("Content-Disposition", "attachment; filename=" + Path.GetFileName(downloadFile)); Response.ContentType = "application/octet-stream"; int FILE_BUFFER_LENGTH = 5000000; byte[] buffer = null; int offset = 0; do { try { // read remote content buffer = ES.Services.Files.GetFileBinaryChunk(PanelSecurity.PackageId, downloadFile, offset, FILE_BUFFER_LENGTH); } catch (Exception ex) { messageBox.ShowErrorMessage("FILES_READ_FILE", ex); break; } // write to stream Response.BinaryWrite(buffer); offset += FILE_BUFFER_LENGTH; } while (buffer.Length == FILE_BUFFER_LENGTH); Response.End(); } // set display preferences gvFiles.PageSize = UsersHelper.GetDisplayItemsPerPage(); if (!IsPostBack) { BindPath(); BindEncodings(); } //Make sure text boxes in popup screens are focussed SetModalPopupFocus(); } void BindEncodings() { ddlFileEncodings.DataSource = Encoding.GetEncodings(); ddlFileEncodings.DataTextField = "DisplayName"; ddlFileEncodings.DataValueField = "Name"; ddlFileEncodings.DataBind(); ddlFileEncodings.SelectedValue = Encoding.UTF8.WebName; } void SetModalPopupFocus() { string setFocusJS = @"function modalPopupFocus() {{ var createFilePopup = $find('{0}'); createFilePopup.add_shown(SetCreateFileFocus); var createFolderPopup = $find('{2}'); createFolderPopup.add_shown(SetCreateFolderFocus); var createDbPopup = $find('{4}'); createDbPopup.add_shown(SetCreateDbFocus); var createZipPopup = $find('{6}'); createZipPopup.add_shown(SetCreateZipFocus); }} function SetCreateFileFocus() {{ $get('{1}').focus(); }} function SetCreateFolderFocus() {{ $get('{3}').focus(); }} function SetCreateDbFocus() {{ $get('{5}').focus(); }} function SetCreateZipFocus() {{ $get('{7}').focus(); }} "; Page.ClientScript.RegisterClientScriptBlock(this.GetType(), "setFocus", String.Format(setFocusJS, CreateFileModal.BehaviorID, CreateFilePanel.FindControl("txtFileName").FindControl("txtFileName").ClientID, CreateFolderModal.BehaviorID, CreateFolderPanel.FindControl("txtFolderName").FindControl("txtFileName").ClientID, CreateDatabaseModal.BehaviorID, CreateDatabasePanel.FindControl("txtDatabaseName").FindControl("txtFileName").ClientID, ZipFilesModal.BehaviorID, ZipFilesPanel.FindControl("txtZipName").FindControl("txtFileName").ClientID ), true); } public string GetDownloadLink(string fileName) { string path = GetFullRelativePath(fileName); return NavigateURL(PortalUtils.SPACE_ID_PARAM, PanelSecurity.PackageId.ToString(), "DownloadFile=" + Server.UrlEncode(path)); } public string GetFileIcon(object obj) { SystemFile item = (SystemFile)obj; string iconsPath = GetThemedImage("FileManager/"); string imagePath = ""; // folder icon if (item.IsDirectory) return iconsPath + "OpenFolder.gif"; else { string ext = Path.GetExtension(item.Name); ext = (ext.Length > 0) ? ext.Substring(1) : ext; imagePath = iconsPath + ext + ".png"; } // check icon existance if (!File.Exists(Server.MapPath(imagePath))) imagePath = iconsPath + "unknown.png"; return imagePath; } public string GetFileSize(long size) { if (size >= 0x400 && size < 0x100000) // kilobytes return Convert.ToString((int)Math.Round(((float)size / 1024))) + "K"; else if (size >= 0x100000 && size < 0x40000000) // megabytes return Convert.ToString((int)Math.Round(((float)size / 1024 / 1024))) + "M"; else if (size >= 0x40000000 && size < 0x10000000000) // gigabytes return Convert.ToString((int)Math.Round(((float)size / 1024 / 1024 / 1024))) + "G"; else return size.ToString(); } public bool IsFolder(object obj) { return ((SystemFile)obj).IsDirectory; } public bool IsEditable(object obj) { SystemFile file = (SystemFile)obj; if (file.IsDirectory) return false; string ext = Path.GetExtension(file.Name); //allow to edit Master pages if (ext == ".Master") return true; else return ALLOWED_EDIT_EXTENSIONS.IndexOf(ext.ToLower()) != -1; } #region Path methods private void BindPath() { List pathList = new List(); // add "Home" link SystemFile item = new SystemFile(GetLocalizedString("Home.Text"), "\\", false, 0, DateTime.Now, DateTime.Now); pathList.Add(item); string currPath = Server.HtmlDecode(litPath.Text).Substring(1); if (currPath != "") { string[] pathParts = currPath.Split(new char[] { '\\', '/' }); for (int i = 0; i < pathParts.Length; i++) { string subPath = "\\" + String.Join("\\", pathParts, 0, i + 1); item = new SystemFile(pathParts[i], subPath, false, 0, DateTime.Now, DateTime.Now); pathList.Add(item); } } path.DataSource = pathList; path.DataBind(); } protected void path_ItemCommand(object source, RepeaterCommandEventArgs e) { if (e.CommandName == "browse") { litPath.Text = HttpContext.Current.Server.HtmlEncode((string)e.CommandArgument); BindPath(); } } #endregion #region Upload protected void btnUpload_Click(object sender, EventArgs e) { // upload file this.UploadFile(fileUpload1.FileName, fileUpload1.FileContent); this.UploadFile(fileUpload2.FileName, fileUpload2.FileContent); this.UploadFile(fileUpload3.FileName, fileUpload3.FileContent); this.UploadFile(fileUpload4.FileName, fileUpload4.FileContent); this.UploadFile(fileUpload5.FileName, fileUpload5.FileContent); // hide form gvFiles.DataBind(); } private void UploadFile(string fileName, Stream stream) { // upload file if (!String.IsNullOrEmpty(fileName)) { string path = GetFullRelativePath(Path.GetFileName(fileName)); try { int result = ES.Services.Files.CreateFile(PanelSecurity.PackageId, path); if (result < 0) { messageBox.ShowResultMessage(result); return; } } catch (Exception ex) { messageBox.ShowErrorMessage("FILES_CREATE_FILE", ex); } int buffLength = 1000000; byte[] buffer = new byte[buffLength]; int readLength = 0; while (true) { readLength = stream.Read(buffer, 0, buffLength); if (readLength < buffLength) Array.Resize(ref buffer, readLength); try { int result = ES.Services.Files.AppendFileBinaryChunk(PanelSecurity.PackageId, path, buffer); if (result < 0) { messageBox.ShowResultMessage(result); return; } } catch (Exception ex) { messageBox.ShowErrorMessage("FILES_UPLOAD_FILE", ex); break; } if (readLength < buffLength) break; } } } #endregion #region Create File protected void btnCreateFile_Click(object sender, EventArgs e) { if (!Page.IsValid) { CreateFileModal.Show(); return; } // create file string path = GetFullRelativePath(txtFileName.Text.Trim()); try { int result = ES.Services.Files.CreateFile(PanelSecurity.PackageId, path); if (result < 0) { messageBox.ShowResultMessage(result); return; } // update content if (txtFileContent.Text != "") { byte[] content = Encoding.UTF8.GetBytes(txtFileContent.Text); result = ES.Services.Files.UpdateFileBinaryContent(PanelSecurity.PackageId, path, content); if (result < 0) { messageBox.ShowResultMessage(result); return; } } } catch (Exception ex) { messageBox.ShowErrorMessage("FILES_CREATE_FILE", ex); } // hide form gvFiles.DataBind(); } #endregion #region Create Folder protected void btnCreateFolder_Click(object sender, EventArgs e) { if (!Page.IsValid) { CreateFolderModal.Show(); return; } // create folder string path = GetFullRelativePath(txtFolderName.Text.Trim()); try { int result = ES.Services.Files.CreateFolder(PanelSecurity.PackageId, path); if (result < 0) { messageBox.ShowResultMessage(result); return; } } catch (Exception ex) { messageBox.ShowErrorMessage("FILES_CREATE_FOLDER", ex); } // hide form gvFiles.DataBind(); } #endregion #region Zip protected void btnZip_Click(object sender, EventArgs e) { if (!Page.IsValid) { ZipFilesModal.Show(); return; } // zip files string fileName = txtZipName.Text.Trim(); if (!fileName.ToLower().EndsWith(".zip")) fileName = fileName + ".zip"; string path = GetFullRelativePath(fileName); string[] files = GetSelectedFiles(); if (files.Length > 0) { try { int result = ES.Services.Files.ZipFiles(PanelSecurity.PackageId, files, path); if (result < 0) { messageBox.ShowResultMessage(result); return; } } catch (Exception ex) { messageBox.ShowErrorMessage("FILES_ZIP_FILES", ex); } // hide form gvFiles.DataBind(); } } #endregion #region Unzip protected void cmdUnzipFiles_Click(object sender, EventArgs e) { // unzip files string[] files = GetSelectedFiles(); if (files.Length > 0) { try { ES.Services.Files.UnzipFiles(PanelSecurity.PackageId, files); } catch (Exception ex) { messageBox.ShowErrorMessage("FILES_UNZIP_FILES", ex); } // refresh list gvFiles.DataBind(); } } #endregion #region Copy protected void btnCopy_Click(object sender, EventArgs e) { // copy files string path = copyDestination.SelectedFile; string[] files = GetSelectedFiles(); if (files.Length > 0) { try { int result = ES.Services.Files.CopyFiles(PanelSecurity.PackageId, files, path); if (result < 0) { messageBox.ShowResultMessage(result); return; } } catch (Exception ex) { messageBox.ShowErrorMessage("FILES_COPY_FILES", ex); } // hide form gvFiles.DataBind(); } } #endregion #region Move protected void btnMove_Click(object sender, EventArgs e) { // move files string path = moveDestination.SelectedFile; string[] files = GetSelectedFiles(); if (files.Length > 0) { try { int result = ES.Services.Files.MoveFiles(PanelSecurity.PackageId, files, path); if (result < 0) { messageBox.ShowResultMessage(result); return; } } catch (Exception ex) { messageBox.ShowErrorMessage("FILES_MOVE_FILES", ex); } // hide form gvFiles.DataBind(); } } #endregion #region Edit protected void btnSaveEditFile_Click(object sender, EventArgs e) { // create file path string path = (string)ViewState["EditFile"]; try { //update file int result = PutFileContents(path, ddlFileEncodings.SelectedValue, txtEditFileContent.Text); if (result < 0) { messageBox.ShowResultMessage(result); return; } } catch (Exception ex) { messageBox.ShowErrorMessage("FILES_UPDATE_FILE", ex); } // hide form EditFileModal.Hide(); gvFiles.DataBind(); } #endregion #region Rename protected void btnRename_Click(object sender, EventArgs e) { if (!Page.IsValid) { RenameFileModal.Show(); return; } // move files string oldPath = GetFullRelativePath((string)ViewState["RenameFile"]); string newPath = GetFullRelativePath(txtRenameFile.Text); try { int result = ES.Services.Files.RenameFile(PanelSecurity.PackageId, oldPath, newPath); if (result < 0) { messageBox.ShowResultMessage(result); return; } } catch (Exception ex) { messageBox.ShowErrorMessage("FILES_RENAME_FILE", ex); } // hide form RenameFileModal.Hide(); gvFiles.DataBind(); } #endregion #region Access Databases protected void btnCreateDatabase_Click(object sender, EventArgs e) { if (!Page.IsValid) { CreateDatabaseModal.Show(); return; } // create database string fileName = txtDatabaseName.Text.Trim(); if (!fileName.ToLower().EndsWith(".mdb")) fileName = fileName + ".mdb"; string path = GetFullRelativePath(fileName); try { int result = ES.Services.Files.CreateAccessDatabase(PanelSecurity.PackageId, path); if (result < 0) { messageBox.ShowResultMessage(result); return; } } catch (Exception ex) { messageBox.ShowErrorMessage("FILES_CREATE_DB", ex); } // hide form gvFiles.DataBind(); } #endregion #region Delete protected void btnDeleteFiles_Click(object sender, EventArgs e) { // delete files string[] files = GetSelectedFiles(); if (files.Length > 0) { try { int result = ES.Services.Files.DeleteFiles(PanelSecurity.PackageId, files); if (result < 0) { messageBox.ShowResultMessage(result); return; } } catch (Exception ex) { messageBox.ShowErrorMessage("FILES_DELETE_FILES", ex); } // refresh list gvFiles.DataBind(); } } #endregion #region Set Permissions protected void btnSetPermissions_Click(object sender, EventArgs e) { // create file string path = (string)ViewState["EditPermissions"]; try { // update permissions List users = new List(); foreach (GridViewRow row in gvFilePermissions.Rows) { Literal litAccountName = (Literal)row.FindControl("litAccountName"); CheckBox chkRead = (CheckBox)row.FindControl("chkRead"); CheckBox chkWrite = (CheckBox)row.FindControl("chkWrite"); if (litAccountName != null) { UserPermission user = new UserPermission(); user.AccountName = litAccountName.Text; user.Read = chkRead.Checked; user.Write = chkWrite.Checked; users.Add(user); } } int result = ES.Services.Files.SetFilePermissions(PanelSecurity.PackageId, path, users.ToArray(), chkReplaceChildPermissions.Checked); if (result < 0) { messageBox.ShowResultMessage(result); return; } } catch (Exception ex) { messageBox.ShowErrorMessage("FILES_UPDATE_PERMISSIONS", ex); } // hide form PermissionsFileModal.Hide(); } #endregion private string[] GetSelectedFiles() { List files = new List(); foreach (GridViewRow row in gvFiles.Rows) { CheckBox chkSelected = (CheckBox)row.FindControl("selected"); if (chkSelected != null && chkSelected.Checked) { string fileName = (string)gvFiles.DataKeys[row.RowIndex][0]; fileName = GetFullRelativePath(fileName); files.Add(fileName); } } return files.ToArray(); } private string GetFullRelativePath(string fileName) { return Server.HtmlDecode(litPath.Text) + ((Server.HtmlDecode(litPath.Text) != "\\") ? ("\\" + fileName) : fileName); } protected void gvFiles_RowCommand(object sender, GridViewCommandEventArgs e) { if (e.CommandName == "browse") { string fileName = (string)e.CommandArgument; litPath.Text += HttpContext.Current.Server.HtmlEncode((litPath.Text != "\\") ? ("\\" + fileName) : fileName); BindPath(); } else if (e.CommandName == "download") { string path = GetFullRelativePath((string)e.CommandArgument); Response.Redirect(NavigateURL(PortalUtils.SPACE_ID_PARAM, PanelSecurity.PackageId.ToString(), "DownloadFile=" + Server.UrlEncode(path))); } else if (e.CommandName == "edit_file") { // read file content try { string path = GetFullRelativePath((string)e.CommandArgument); ViewState["EditFile"] = path; txtEditFileContent.Text = GetFileContent(path, ddlFileEncodings.SelectedValue); // show edit panel EditFileModal.Show(); } catch (Exception ex) { messageBox.ShowErrorMessage("FILES_READ_FILE", ex); } } else if (e.CommandName == "edit_permissions") { // read file content try { string path = GetFullRelativePath((string)e.CommandArgument); ViewState["EditPermissions"] = path; UserPermission[] users = ES.Services.Files.GetFilePermissions(PanelSecurity.PackageId, path); gvFilePermissions.DataSource = users; gvFilePermissions.DataBind(); // show permissions panel PermissionsFileModal.Show(); } catch (Exception ex) { messageBox.ShowErrorMessage("FILES_READ_PERMISSIONS", ex); } } else if (e.CommandName == "rename") { RenameFileModal.Show(); ViewState["RenameFile"] = (string)e.CommandArgument; txtRenameFile.Text = (string)e.CommandArgument; } } /// /// Returns string representing file contents. /// /// Path to the file. /// Encoding to use when reading file. Web Name of encoding must be specified. See for details. /// String representing file contents. private string GetFileContent(string path, string encoding) { Encoding currentEncoding = Encoding.GetEncoding(encoding); byte[] content = ES.Services.Files.GetFileBinaryContentUsingEncoding(PanelSecurity.PackageId, path, currentEncoding.WebName); return currentEncoding.GetString(content); } /// /// Saves file. /// /// Path to the file. /// Name of encoding that will be used to store file contents. /// String representing file contents. /// Error code or 0 if succeeded. private int PutFileContents(string path, string encoding, string fileContents) { return ES.Services.Files.UpdateFileBinaryContentUsingEncoding( PanelSecurity.PackageId , path , Encoding.GetEncoding(encoding).GetBytes(fileContents).Clone() as byte[] , encoding ); } protected void ddlFileEncodings_SelectedIndexChanged(object sender, EventArgs e) { try { string path = (string)ViewState["EditFile"]; txtEditFileContent.Text = GetFileContent(path, ddlFileEncodings.SelectedValue); EditFileModal.Show(); } catch (Exception ex) { messageBox.ShowErrorMessage("FILES_READ_FILE", ex); } } protected void odsFilesPaged_Selected(object sender, ObjectDataSourceStatusEventArgs e) { if (e.Exception != null) { if (PanelSecurity.SelectedUser.Role == WebsitePanel.EnterpriseServer.UserRole.Administrator) messageBox.ShowWarningMessage("FILES_GET_LIST"); else messageBox.ShowErrorMessage("FILES_GET_LIST", e.Exception); //mnuOperations.Enabled = false; btnRecalcDiskspace.Enabled = false; e.ExceptionHandled = true; } } protected void odsFilesPaged_Selecting(object sender, ObjectDataSourceSelectingEventArgs e) { if (e.InputParameters == null) return; // Decode path parameter to pass it to the server as is if (e.InputParameters.Contains("path") == true) { e.InputParameters["path"] = Server.HtmlDecode((String)e.InputParameters["path"]); } } protected void btnRecalcDiskspace_Click(object sender, EventArgs e) { int result = ES.Services.Files.CalculatePackageDiskspace(PanelSecurity.PackageId); if (result < 0) { messageBox.ShowResultMessage(result); return; } } protected void btnCancelRename_Click(object sender, EventArgs e) { RenameFileModal.Hide(); } protected void btnCancelEditFile_Click(object sender, EventArgs e) { EditFileModal.Hide(); } protected void btnCancelPermissions_Click(object sender, EventArgs e) { PermissionsFileModal.Hide(); } private void RegisterJsLocalizedMessages() { if (!Page.ClientScript.IsClientScriptBlockRegistered("FM_UNZIP_FILES_MESSAGE")) { Page.ClientScript.RegisterClientScriptBlock(GetType(), "FM_UNZIP_FILES_MESSAGE", String.Format("FM_UNZIP_FILES_MESSAGE = \"{0}\";", GetLocalResourceObject("FM_UNZIP_FILES_MESSAGE")), true); } } } }