HEX
Server: Microsoft-IIS/8.5
System: Windows NT YDAWBH120 6.3 build 9600 (Windows Server 2012 R2 Standard Edition) AMD64
User: tentjecom_web (0)
PHP: 7.4.14
Disabled: NONE
Upload Files
File: D:/HostingSpaces/RMourik/bassol.nl/wwwroot/CMSModules/FileImport/Tools/ImportFromServer.aspx.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;
using System.Security.Principal;
using System.Text.RegularExpressions;
using System.Threading;
using System.Web;
using System.Web.UI.WebControls;

using CMS.Base;
using CMS.DataEngine;
using CMS.DocumentEngine;
using CMS.EventLog;
using CMS.ExtendedControls;
using CMS.ExtendedControls.ActionsConfig;
using CMS.FormEngine;
using CMS.Helpers;
using CMS.IO;
using CMS.LicenseProvider;
using CMS.Localization;
using CMS.Membership;
using CMS.SiteProvider;
using CMS.UIControls;

using TreeNode = CMS.DocumentEngine.TreeNode;

[Security(Resource = "CMS.FileImport", Permission = "ImportFiles", ResourceSite = true)]
[UIElement("CMS.FileImport", "ImportFromServer")]
public partial class CMSModules_FileImport_Tools_ImportFromServer : CMSDeskPage
{
    #region "Variables"

    private List<string> filesList = new List<string>();
    protected string targetAliasPath = "";
    protected long filesCount = 0;
    protected long allowedFilesCount = 0;
    protected string rootPath = "~/cmsimportfiles/";

    private static List<string[]> resultListValues = new List<string[]>();
    private static List<string> errorFiles = new List<string>();

    private static readonly Hashtable mErrors = new Hashtable();

    #endregion


    #region "Properties"

    /// <summary>
    /// Current log context.
    /// </summary>
    public LogContext CurrentLog
    {
        get
        {
            return EnsureLog();
        }
    }

    /// <summary>
    /// Current Error.
    /// </summary>
    private string CurrentError
    {
        get
        {
            return ValidationHelper.GetString(mErrors["FileImport_" + ctlAsyncLog.ProcessGUID], string.Empty);
        }
        set
        {
            mErrors["FileImport_" + ctlAsyncLog.ProcessGUID] = value;
        }
    }

    #endregion


    #region "Methods"

    protected void Page_Load(object sender, EventArgs e)
    {
        // Register the main CMS script
        ScriptHelper.RegisterCMS(Page);

        // Register script for pendingCallbacks repair
        ScriptHelper.FixPendingCallbacks(Page);
        ctlAsyncLog.OnFinished += ctlAsyncLog_OnFinished;
        ctlAsyncLog.OnError += ctlAsyncLog_OnError;
        ctlAsyncLog.OnRequestLog += ctlAsyncLog_OnRequestLog;
        ctlAsyncLog.OnCancel += ctlAsyncLog_OnCancel;

        CurrentMaster.HeaderActions.ActionPerformed += HeaderActions_ActionPerformed;

        ucFilter.Column = "FileName";
        btnFilter.Text = ResHelper.GetString("general.search");

        if (!RequestHelper.IsCallback())
        {
            string path = GetPath();
            if (StorageHelper.IsExternalStorage(path))
            {
                // Add action for prepare for import
                CurrentMaster.HeaderActions.AddAction(new HeaderAction
                {
                    Text = GetString("dialogs.mediaview.azureprepare"),
                    CommandName = "prepareforimport",
                    ButtonStyle = ButtonStyle.Default
                });
            }
            else
            {
                CurrentMaster.HeaderActionsPlaceHolder.Visible = false;
                if (!Directory.Exists(path))
                {
                    ShowError(String.Format(ResHelper.GetString("Tools.FileImport.DirectoryDoesNotExist"), rootPath));
                }
            }

            var user = MembershipContext.AuthenticatedUser;

            // Check permissions for CMS Desk -> Tools -> File Import
            if (!user.IsAuthorizedPerUIElement("CMS.FileImport", "FileImport"))
            {
                RedirectToUIElementAccessDenied("CMS.FileImport", "FileImport");
            }

            if (!user.IsAuthorizedPerResource("CMS.FileImport", "ImportFiles"))
            {
                RedirectToAccessDenied("CMS.FileImport", "ImportFiles");
            }

            // Set visibility of panels
            pnlContent.Visible = true;
            pnlLog.Visible = false;

            ScriptHelper.RegisterCMS(Page);

            // Initialize culture selector
            cultureSelector.SiteID = SiteContext.CurrentSiteID;
            pathElem.SiteID = SiteContext.CurrentSiteID;

            // Prepare unigrid
            gridImport.DataSource = GetFileSystemDataSource(ucFilter.WhereCondition);
            gridImport.OnExternalDataBound += gridImport_OnExternalDataBound;
            gridImport.SelectionJavascript = "UpdateCount";
            gridImport.ZeroRowsText = GetString("Tools.FileImport.NoFiles");
            gridImport.OnShowButtonClick += gridImport_OnShowButtonClick;

            // Prepare async panel
            ctlAsyncLog.TitleText = GetString("tools.fileimport.importing");

            lblTitle.Text = GetString("Tools.FileImport.ImportedFiles") + " " + rootPath + ": ";
            lblSelected.Text = string.Format(GetString("Tools.FileImport.SelectedCount"), filesCount);

            if (!RequestHelper.IsPostBack())
            {
                cultureSelector.Value = LocalizationContext.PreferredCultureCode;

                // Initialize temporary lists
                resultListValues.Clear();
                errorFiles.Clear();
            }

            ltlScript.Text += ScriptHelper.GetScript(@"
function UpdateCount(id, checked) {
    var hidden = document.getElementById('" + hdnSelected.ClientID + @"')
    var label =  document.getElementById('" + lblSelectedValue.ClientID + @"')
    if (hidden.value.indexOf('|' + id + '|') != -1) {
        if (checked == false) {
            hidden.value = hidden.value.replace('|' + id + '|', '');
        }
    } else {
        if (checked == true) {
            hidden.value = hidden.value + '|' + id + '|';
        }
    }
    label.innerHTML = (hidden.value.split('|').length - 1) / 2;
}");
        }
    }


    private void HeaderActions_ActionPerformed(object sender, CommandEventArgs e)
    {
        switch (e.CommandName.ToLowerCSafe())
        {
            case "prepareforimport":
                Directory.PrepareFilesForImport(rootPath);
                URLHelper.Redirect(RequestContext.CurrentURL);
                break;
        }
    }


    protected void gridImport_OnShowButtonClick(object sender, EventArgs e)
    {
        gridImport.ResetSelection();
        hdnSelected.Value = string.Empty;
    }


    protected override void OnPreRender(EventArgs e)
    {
        base.OnPreRender(e);
        if ((errorFiles != null) && (errorFiles.Count > 0))
        {
            gridImport.SelectedItems = errorFiles;
        }

        gridImport.ReloadData();

        // Disable controls if no files found
        if (DataHelper.DataSourceIsEmpty(gridImport.DataSource))
        {
            btnStartImport.Enabled = false;
            pathElem.Enabled = false;
            pnlImportControls.Enabled = false;
        }
        else
        {
            btnStartImport.Enabled = true;
            pathElem.Enabled = true;
            pnlImportControls.Enabled = true;
            filesCount = ((DataSet)gridImport.DataSource).Tables[0].Rows.Count;
        }

        // Set labels
        string count = gridImport.SelectedItems.Count.ToString();
        hdnValue.Value = count;
        lblSelectedValue.Text = count;
        lblTotal.Text = string.Format(GetString("Tools.FileImport.TotalCount"), filesCount);

        errorFiles.Clear();
    }


    /// <summary>
    /// Gets path from current application settings.
    /// </summary>
    private string GetPath()
    {
        // If import folder for current site is not specified in settings set its path as rootpath
        if (!String.IsNullOrEmpty(SiteContext.CurrentSiteName))
        {
            // Get import folder path from settings
            string path = SettingsKeyInfoProvider.GetValue(SiteContext.CurrentSiteName + ".CMSFileImportFolder").Trim();
            if (!string.IsNullOrEmpty(path))
            {
                rootPath = Path.EnsureBackslashes(path, true);
            }
        }

        // Path starting with local driver letter
        if ((char.IsLetter(rootPath.ToLowerCSafe(), 0)) && (rootPath[1] == ':'))
        {
            if (rootPath[2] != '\\')
            {
                rootPath = rootPath[0] + ":\\" + rootPath.Substring(2, rootPath.Length - 2);
            }
        }
        // Relative path
        else if (!((rootPath[0] == '\\') && (rootPath[1] == '\\')))
        {
            try
            {
                rootPath = HttpContext.Current.Server.MapPath(rootPath);
            }
            catch (Exception ex)
            {
                plcImportContent.Visible = false;
                btnStartImport.Enabled = false;
                ShowError(String.Format(GetString("Tools.FileImport.InvalidFolder"), rootPath), ex.Message, null);
                return null;
            }
        }

        if (!String.IsNullOrEmpty(rootPath))
        {
            rootPath = Path.EnsureEndBackslash(rootPath);
        }

        return rootPath;
    }


    /// <summary>
    /// Removes all N (at the beginning of expression) from where condition
    /// (e.g. "column LIKE N'word'" => "column LIKE 'word'").
    /// </summary>
    /// <param name="where">WHERE condition</param>
    private string RemoveNFromWhereCondition(string where)
    {
        if (!String.IsNullOrEmpty(where))
        {
            // Remove all N (at the beginning of expression) from where condition (e.g. "column LIKE N'word'" => "column LIKE 'word'")
            bool inString = false;
            char prev = ' ';
            for (int i = 0; i < where.Length; i++)
            {
                if (where[i] == '\'')
                {
                    if (!inString && (prev == 'N'))
                    {
                        where = where.Remove(i - 1, 1);
                        where = where.Insert(i - 1, " ");
                    }
                    inString = !inString;
                }
                prev = where[i];
            }
        }

        return where;
    }


    /// <summary>
    /// Renames columns in WHERE condition.
    /// </summary>
    /// <param name="where">WHERE condition</param>
    /// <param name="oldColName">Old col name</param>
    /// <param name="newColName">New col name</param>
    private string RenameColumn(string where, string oldColName, string newColName)
    {
        if (!String.IsNullOrEmpty(where))
        {
            string[] strs = where.Split('\'');
            bool inString = where.StartsWithCSafe("'");
            where = "";
            for (int i = 0; i < strs.Length; i++)
            {
                // Rename/replace column name (avoid string literals)
                if (!inString && !String.IsNullOrEmpty(strs[i]))
                {
                    strs[i] = strs[i].Replace(oldColName, newColName);
                }

                // Create new WHERE condition
                where += (inString ? "'" : "") + strs[i] + (inString ? "'" : "");

                inString = !inString;
            }
        }

        return where;
    }


    /// <summary>
    /// Returns set of files in the file system.
    /// </summary>
    private DataSet GetFileSystemDataSource(string where)
    {
        string whereCond = RemoveNFromWhereCondition(where);
        whereCond = RenameColumn(whereCond, "[FilePath]", "[FileName]");
        fileSystemDataSource.WhereCondition = whereCond;
        fileSystemDataSource.Path = rootPath;

        try
        {
            return (DataSet)fileSystemDataSource.DataSource;
        }
        catch (Exception e)
        {
            ShowError(e.Message);
            return null;
        }
    }


    /// <summary>
    /// File list external databound handler.
    /// </summary>
    protected object gridImport_OnExternalDataBound(object sender, string sourceName, object parameter)
    {
        string filePath = ValidationHelper.GetString(parameter, string.Empty);
        switch (sourceName.ToLowerCSafe())
        {
            case "filename":
                if (filePath.StartsWithCSafe(rootPath))
                {
                    return filePath.Substring(rootPath.Length);
                }
                break;

            case "result":
                string result = string.Empty;
                if ((resultListValues != null) && (resultListValues.Count > 0))
                {
                    string[] values = resultListValues.Find(delegate(string[] arr) { return ((arr != null) && (arr[0].EqualsCSafe(filePath, StringComparison.InvariantCultureIgnoreCase))); });
                    if (values != null)
                    {
                        if (ValidationHelper.GetBoolean(values[2], false))
                        {
                            result = UniGridFunctions.ColoredSpanMsg(GetString("Tools.FileImport.Imported"), true);
                        }
                        else
                        {
                            result = UniGridFunctions.ColoredSpanMsg(values[1], false);
                        }
                    }
                    else
                    {
                        result = GetString("Tools.FileImport.Skipped");
                    }
                }
                return result;
        }

        return (parameter != null) ? parameter.ToString() : null;
    }


    /// <summary>
    /// BtnStartImport click event handler.
    /// </summary>
    protected void btnStartImport_Click(Object sender, EventArgs e)
    {
        // Check license limitations
        if (!CheckFilesCount(gridImport.SelectedItems.Count))
        {
            ShowError(string.Format(GetString("Tools.FileImport.MaximumCountExceeded"), allowedFilesCount));
        }
        else
        {
            if (gridImport.SelectedItems.Count > 0)
            {
                string path = pathElem.Value.ToString().Trim();
                if (!String.IsNullOrEmpty(path))
                {
                    // Set visibility of panels
                    pnlLog.Visible = true;
                    pnlContent.Visible = false;

                    CurrentError = string.Empty;
                    CurrentLog.Close();
                    EnsureLog();

                    ctlAsyncLog.Parameter = new[] { gridImport.SelectedItems.ToArray(), path, cultureSelector.Value, MembershipContext.AuthenticatedUser };
                    ctlAsyncLog.RunAsync(Import, WindowsIdentity.GetCurrent());
                }
                else
                {
                    ShowError(GetString("Tools.FileImport.AliasPathNotFound"));
                }
            }
            else
            {
                ShowError(GetString("tools.fileimport.nofilesselected"));
            }
        }
    }


    /// <summary>
    /// Import files.
    /// </summary>
    private void Import(object parameter)
    {
        try
        {
            object[] parameters = (object[])parameter;
            string[] items = (string[])parameters[0];
            CurrentUserInfo currentUser = (CurrentUserInfo)parameters[3];

            if ((items.Length > 0) && (currentUser != null))
            {
                resultListValues.Clear();
                errorFiles.Clear();
                hdnValue.Value = null;
                hdnSelected.Value = null;
                string siteName = SiteContext.CurrentSiteName;
                string targetAliasPath = ValidationHelper.GetString(parameters[1], null);

                bool imported = false; // Flag - true if one file was imported at least
                bool importError = false; // Flag - true when import failed

                TreeProvider tree = new TreeProvider(currentUser);
                TreeNode tn = tree.SelectSingleNode(siteName, targetAliasPath, TreeProvider.ALL_CULTURES, true, null, false);
                if (tn != null)
                {
                    // Check if CMS.File document type exist and check if document contains required columns (FileName, FileAttachment)
                    DataClassInfo fileClassInfo = DataClassInfoProvider.GetDataClassInfo("CMS.File");
                    if (fileClassInfo == null)
                    {
                        AddError(GetString("newfile.classcmsfileismissing"));
                        return;
                    }
                    else
                    {
                        FormInfo fi = new FormInfo(fileClassInfo.ClassFormDefinition);
                        FormFieldInfo fileFfi = null;
                        FormFieldInfo attachFfi = null;
                        if (fi != null)
                        {
                            fileFfi = fi.GetFormField("FileName");
                            attachFfi = fi.GetFormField("FileAttachment");
                        }
                        if ((fi == null) || (fileFfi == null) || (attachFfi == null))
                        {
                            AddError(GetString("newfile.someofrequiredfieldsmissing"));
                            return;
                        }
                    }

                    DataClassInfo dci = DataClassInfoProvider.GetDataClassInfo(tn.NodeClassName);

                    if (dci != null)
                    {
                        // Check if "file" and "folder" are allowed as a child document under selected document type
                        bool fileAllowed = false;
                        bool folderAllowed = false;
                        DataClassInfo folderClassInfo = DataClassInfoProvider.GetDataClassInfo("CMS.Folder");
                        if ((fileClassInfo != null) || (folderClassInfo != null))
                        {
                            string[] paths;
                            foreach (string fullFileName in items)
                            {
                                // Check if the file is located under default root path
                                if (!fullFileName.StartsWithCSafe(rootPath, StringComparison.InvariantCultureIgnoreCase))
                                {
                                    AddError(GetString("Tools.FileImport.NotUnderRootPath"));
                                    return;
                                }

                                paths = fullFileName.Substring(rootPath.Length).Split('\\');
                                // Check file
                                if (paths.Length == 1)
                                {
                                    if (!fileAllowed && (fileClassInfo != null) && !DocumentHelper.IsDocumentTypeAllowed(tn, fileClassInfo.ClassID))
                                    {
                                        AddError(GetString("Tools.FileImport.NotAllowedChildClass"));
                                        return;
                                    }
                                    else
                                    {
                                        fileAllowed = true;
                                    }
                                }

                                // Check folder
                                if (paths.Length > 1)
                                {
                                    if (!folderAllowed && (folderClassInfo != null) && !DocumentHelper.IsDocumentTypeAllowed(tn, folderClassInfo.ClassID))
                                    {
                                        AddError(GetString("Tools.FileImport.FolderNotAllowedChildClass"));
                                        return;
                                    }
                                    else
                                    {
                                        folderAllowed = true;
                                    }
                                }

                                if (fileAllowed && folderAllowed)
                                {
                                    break;
                                }
                            }
                        }

                        // Check if user is allowed to create new file document
                        if (fileAllowed && !currentUser.IsAuthorizedToCreateNewDocument(tn, "CMS.File"))
                        {
                            AddError(GetString("accessdenied.notallowedtocreatedocument"));
                            return;
                        }

                        // Check if user is allowed to create new folder document
                        if (folderAllowed && !currentUser.IsAuthorizedToCreateNewDocument(tn, "CMS.Folder"))
                        {
                            AddError(GetString("accessdenied.notallowedtocreatedocument"));
                            return;
                        }
                    }

                    string cultureCode = ValidationHelper.GetString(parameters[2], "");
                    string[] fileList = new string[1];
                    string[] relativePathList = new string[1];

                    // Begin log
                    AddLog(GetString("tools.fileimport.importingprogress"));

                    string msgImported = GetString("Tools.FileImport.Imported");
                    string msgFailed = GetString("Tools.FileImport.Failed");

                    // Insert files selected in datagrid to list of files to import
                    foreach (string fullFileName in items)
                    {
                        // Import selected files only
                        fileList[0] = fullFileName;
                        relativePathList[0] = fullFileName.Substring(rootPath.Length);

                        // Remove extension if needed
                        if (!chkIncludeExtension.Checked)
                        {
                            relativePathList[0] = Regex.Replace(relativePathList[0], "(.*)\\..*", "$1");
                        }

                        try
                        {
                            FileImport.ImportFiles(siteName, targetAliasPath, cultureCode, fileList, relativePathList, currentUser.UserID, chkDeleteImported.Checked);

                            // Import of a file succeeded, fill the output lists
                            resultListValues.Add(new string[] { fullFileName, msgImported, true.ToString() });

                            imported = true; // One file was imported
                            AddLog(HTMLHelper.HTMLEncode(fullFileName));
                        }
                        catch (Exception ex)
                        {
                            // File import failed
                            errorFiles.Add(fullFileName);
                            importError = true;

                            // Fill the output lists
                            resultListValues.Add(new string[] { fullFileName, msgFailed + " (" + HTMLHelper.HTMLEncode(ex.Message) + ")", false.ToString() });

                            AddError(msgFailed + " (" + HTMLHelper.HTMLEncode(ex.Message) + ")");

                            // Abort importing the rest of files for serious exceptions
                            if (!(ex is UnauthorizedAccessException))
                            {
                                return;
                            }
                        }
                    }
                }
                // Specified alias path not found
                else
                {
                    AddError(GetString("Tools.FileImport.AliasPathNotFound"));
                    return;
                }

                if (filesList.Count > 0)
                {
                    if (!importError)
                    {
                        if (imported)
                        {
                            AddError(GetString("Tools.FileImport.FilesWereImported"));
                            return;
                        }
                    }
                    else
                    {
                        AddError(GetString("Tools.FileImport.FilesNotImported"));
                        return;
                    }
                }
            }
            // No items selected to import
            else
            {
                AddError(GetString("Tools.FileImport.FilesNotImported"));
                return;
            }
        }
        catch (ThreadAbortException ex)
        {
            string state = ValidationHelper.GetString(ex.ExceptionState, string.Empty);
            if (state == CMSThread.ABORT_REASON_STOP)
            {
                // When canceled
            }
            else
            {
                // Log error
                LogExceptionToEventLog(ex);
            }
        }
        catch (Exception ex)
        {
            // Log error
            LogExceptionToEventLog(ex);
        }
    }


    /// <summary>
    /// Checks the total count of files to not exceed the license limitations.
    /// </summary>
    /// <param name="selectedFilesCount">Selected files count</param>
    private bool CheckFilesCount(long selectedFilesCount)
    {
        long currentDocumentsCount = 0;
        DataSet dsDocuments = TreeHelper.GetDocuments(SiteContext.CurrentSiteName, "/%", TreeProvider.ALL_CULTURES, true, null, null, null, TreeProvider.ALL_LEVELS, false, -1, TreeProvider.SELECTNODES_REQUIRED_COLUMNS);
        if (!DataHelper.DataSourceIsEmpty(dsDocuments))
        {
            currentDocumentsCount += DataHelper.GetItemsCount(dsDocuments);
        }
        int versionLimitations = LicenseKeyInfoProvider.VersionLimitations(LicenseContext.CurrentLicenseInfo, FeatureEnum.Documents);
        allowedFilesCount = (versionLimitations - currentDocumentsCount);
        return !((versionLimitations != 0) && (versionLimitations < (currentDocumentsCount + selectedFilesCount)));
    }


    /// <summary>
    /// When exception occurs, log it to event log.
    /// </summary>
    /// <param name="ex">Exception to log</param>
    private void LogExceptionToEventLog(Exception ex)
    {
        EventLogProvider.LogEvent(EventType.ERROR, "Content", "IMPORTFILE", EventLogProvider.GetExceptionLogMessage(ex), RequestContext.RawURL, MembershipContext.AuthenticatedUser.UserID, MembershipContext.AuthenticatedUser.UserName, 0, null, RequestContext.UserHostAddress, SiteContext.CurrentSiteID);

        AddError(GetString("tools.fileimport.failed") + " (" + ex.Message + ")");
    }


    /// <summary>
    /// Adds the script to the output request window.
    /// </summary>
    /// <param name="script">Script to add</param>
    public override void AddScript(string script)
    {
        ltlScript.Text += ScriptHelper.GetScript(script);
    }

    #endregion


    #region "Handling async thread"

    private void ctlAsyncLog_OnCancel(object sender, EventArgs e)
    {
        ctlAsyncLog.Parameter = null;
        HandlePossibleErrors();
    }


    private void ctlAsyncLog_OnRequestLog(object sender, EventArgs e)
    {
        ctlAsyncLog.LogContext = CurrentLog;
    }


    private void ctlAsyncLog_OnError(object sender, EventArgs e)
    {
        HandlePossibleErrors();
    }


    private void ctlAsyncLog_OnFinished(object sender, EventArgs e)
    {
        HandlePossibleErrors();
    }


    /// <summary>
    /// Ensures the logging context.
    /// </summary>
    protected LogContext EnsureLog()
    {
        LogContext log = LogContext.EnsureLog(ctlAsyncLog.ProcessGUID);
        return log;
    }


    /// <summary>
    /// Adds the log information.
    /// </summary>
    /// <param name="newLog">New log information</param>
    protected void AddLog(string newLog)
    {
        EnsureLog();
        LogContext.AppendLine(newLog);
    }


    /// <summary>
    /// Adds the error to collection of errors.
    /// </summary>
    /// <param name="error">Error message</param>
    protected void AddError(string error)
    {
        AddLog(error);
        if (String.IsNullOrEmpty(CurrentError))
        {
            CurrentError = error;
        }
        else
        {
            CurrentError += "<br />" + error;
        }
    }


    private void HandlePossibleErrors()
    {
        CurrentLog.Close();
        ScriptHelper.RegisterClientScriptBlock(this, typeof(string), "terminatePendingCallbacks", ScriptHelper.GetScript("var __pendingCallbacks = new Array();"));
        if (!String.IsNullOrEmpty(CurrentError))
        {
            ShowError(CurrentError);
        }
    }

    #endregion
}