Manages Page Editing collisions.
Ejemplo n.º 1
0
        protected void Page_Load(object sender, EventArgs e)
        {
            // Manage the case when the application is for some reason restarted
            // during the editing of a Page or File

            if (Request["Page"] != null)
            {
                PageInfo page = Pages.FindPage(Request["Page"]);
                if (page == null)
                {
                    return;
                }
                else
                {
                    // The system already authenticates the user, if any, at the request level
                    string username = Request.UserHostAddress;
                    if (SessionFacade.LoginKey != null)
                    {
                        username = SessionFacade.CurrentUsername;
                    }

                    Collisions.RenewEditingSession(page, username);
                }
            }
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Verifies for editing collisions, and if no collision is found, "locks" the page
        /// </summary>
        private void ManageEditingCollisions()
        {
            if (currentPage == null)
            {
                return;
            }

            lblRefreshLink.Text = @"<a href=""" +
                                  UrlTools.BuildUrl(currentWiki, "Edit.aspx?Page=", Tools.UrlEncode(currentPage.FullName), (Request["Section"] != null ? "&amp;Section=" + currentSection.ToString() : "")) +
                                  @""">" + Properties.Messages.Refresh + " &raquo;</a>";

            string username = Request.UserHostAddress;

            if (SessionFacade.LoginKey != null)
            {
                username = SessionFacade.CurrentUsername;
            }

            if (Collisions.IsPageBeingEdited(currentPage, username))
            {
                pnlCollisions.Visible             = true;
                lblConcurrentEditingUsername.Text = "(" + Users.UserLink(currentWiki, Collisions.WhosEditing(currentPage)) + ")";
                if (Settings.GetDisableConcurrentEditing(currentWiki))
                {
                    lblSaveDisabled.Visible    = true;
                    lblSaveDangerous.Visible   = false;
                    btnSave.Enabled            = false;
                    btnSaveAndContinue.Enabled = false;
                }
                else
                {
                    lblSaveDisabled.Visible    = false;
                    lblSaveDangerous.Visible   = true;
                    btnSave.Enabled            = true;
                    btnSaveAndContinue.Enabled = true;
                }
            }
            else
            {
                pnlCollisions.Visible      = false;
                btnSave.Enabled            = true;
                btnSaveAndContinue.Enabled = true;
                Collisions.RenewEditingSession(currentPage, username);
            }
        }
Ejemplo n.º 3
0
        protected void btnSave_Click(object sender, EventArgs e)
        {
            bool wasVisible = pnlPageName.Visible;

            pnlPageName.Visible = true;

            if (!wasVisible && Settings.GetAutoGeneratePageNames(currentWiki) && txtName.Enabled)
            {
                txtName.Text = GenerateAutoName(txtTitle.Text);
            }

            txtName.Text = txtName.Text.Trim();

            Page.Validate("nametitle");
            Page.Validate("captcha");
            if (!Page.IsValid)
            {
                if (!rfvTitle.IsValid || !rfvName.IsValid || !cvName1.IsValid || !cvName2.IsValid)
                {
                    pnlPageName.Visible   = true;
                    pnlManualName.Visible = false;
                }

                return;
            }

            pnlPageName.Visible = wasVisible;

            // Check permissions
            if (currentPage == null)
            {
                // Check permissions for creating new pages
                if (!canCreateNewPages)
                {
                    UrlTools.Redirect("AccessDenied.aspx");
                }
            }
            else
            {
                // Check permissions for editing current page
                if (!canEdit && !canEditWithApproval)
                {
                    UrlTools.Redirect("AccessDenied.aspx");
                }
            }

            chkMinorChange.Visible = true;
            chkSaveAsDraft.Visible = true;

            // Verify edit with approval
            if (!canEdit && canEditWithApproval)
            {
                chkSaveAsDraft.Checked = true;
            }

            // Check for scripts (Administrators can always add SCRIPT tags)
            if (!SessionFacade.GetCurrentGroupNames(currentWiki).Contains(Settings.GetAdministratorsGroup(currentWiki)) && !Settings.GetScriptTagsAllowed(currentWiki))
            {
                Regex r = new Regex(@"\<script.*?\>", RegexOptions.Compiled | RegexOptions.IgnoreCase);
                if (r.Match(editor.GetContent()).Success)
                {
                    lblResult.Text = @"<span style=""color: #FF0000;"">" + Properties.Messages.ScriptDetected + "</span>";
                    return;
                }
            }

            bool redirect = true;

            if (sender == btnSaveAndContinue)
            {
                redirect = false;
            }

            lblResult.Text     = "";
            lblResult.CssClass = "";

            string username = "";

            if (SessionFacade.LoginKey == null)
            {
                username = Request.UserHostAddress;
            }
            else
            {
                username = SessionFacade.CurrentUsername;
            }

            IPagesStorageProviderV40 provider = FindAppropriateProvider();

            // Create list of selected categories
            List <CategoryInfo> categories = new List <CategoryInfo>();

            for (int i = 0; i < lstCategories.Items.Count; i++)
            {
                if (lstCategories.Items[i].Selected)
                {
                    CategoryInfo cat = Pages.FindCategory(currentWiki, lstCategories.Items[i].Value);

                    // Sanity check
                    if (cat.Provider == provider)
                    {
                        categories.Add(cat);
                    }
                }
            }

            txtComment.Text     = txtComment.Text.Trim();
            txtDescription.Text = txtDescription.Text.Trim();

            SaveMode saveMode = SaveMode.Backup;

            if (chkSaveAsDraft.Checked)
            {
                saveMode = SaveMode.Draft;
            }
            if (chkMinorChange.Checked)
            {
                saveMode = SaveMode.Normal;
            }

            if (txtName.Enabled)
            {
                // Find page, if inexistent create it
                Log.LogEntry("Page update requested for " + txtName.Text, EntryType.General, username, currentWiki);

                string nspace = DetectNamespaceInfo() != null?DetectNamespaceInfo().Name : null;

                PageContent pg = Pages.FindPage(NameTools.GetFullName(DetectNamespace(), txtName.Text), provider);
                if (pg == null)
                {
                    saveMode = SaveMode.Normal;
                    pg       = Pages.SetPageContent(currentWiki, nspace, txtName.Text, provider, txtTitle.Text, username, DateTime.UtcNow, txtComment.Text, editor.GetContent(),
                                                    GetKeywords(), txtDescription.Text, saveMode);
                    attachmentManager.CurrentPage = pg;
                }
                else
                {
                    Pages.SetPageContent(currentWiki, nspace, txtName.Text, provider, txtTitle.Text, username, DateTime.UtcNow, txtComment.Text, editor.GetContent(),
                                         GetKeywords(), txtDescription.Text, saveMode);
                }
                // Save categories binding
                Pages.Rebind(pg, categories.ToArray());

                // If not a draft, remove page draft
                if (saveMode != SaveMode.Draft)
                {
                    Pages.DeleteDraft(pg.FullName, pg.Provider);
                    isDraft = false;
                }
                else
                {
                    isDraft = true;
                }

                ManageDraft();

                lblResult.CssClass = "resultok";
                lblResult.Text     = Properties.Messages.PageSaved;

                // This is a new page, so only who has page management permissions can execute this code
                // No notification must be sent for drafts awaiting approval
                if (redirect)
                {
                    Collisions.CancelEditingSession(pg, username);
                    string target = UrlTools.BuildUrl(currentWiki, Tools.UrlEncode(txtName.Text), GlobalSettings.PageExtension, "?NoRedirect=1");
                    UrlTools.Redirect(target);
                }
                else
                {
                    // Disable PageName, because the name cannot be changed anymore
                    txtName.Enabled       = false;
                    pnlManualName.Visible = false;
                }
            }
            else
            {
                // Used for redirecting to a specific section after editing it
                string anchor = "";

                if (currentPage == null)
                {
                    currentPage = Pages.FindPage(currentWiki, NameTools.GetFullName(DetectNamespace(), txtName.Text));
                }

                // Save data
                Log.LogEntry("Page update requested for " + currentPage.FullName, EntryType.General, username, currentWiki);
                if (!isDraft && currentSection != -1)
                {
                    StringBuilder sb = new StringBuilder(currentPage.Content.Length);
                    int           start, len;
                    ExtractSection(currentPage.Content, currentSection, out start, out len, out anchor);
                    if (start > 0)
                    {
                        sb.Append(currentPage.Content.Substring(0, start));
                    }
                    sb.Append(editor.GetContent());
                    if (start + len < currentPage.Content.Length - 1)
                    {
                        sb.Append(currentPage.Content.Substring(start + len));
                    }
                    Pages.SetPageContent(currentPage.Provider.CurrentWiki, NameTools.GetNamespace(currentPage.FullName), NameTools.GetLocalName(currentPage.FullName), txtTitle.Text, username, DateTime.UtcNow, txtComment.Text, sb.ToString(),
                                         GetKeywords(), txtDescription.Text, saveMode);
                }
                else
                {
                    Pages.SetPageContent(currentPage.Provider.CurrentWiki, NameTools.GetNamespace(currentPage.FullName), NameTools.GetLocalName(currentPage.FullName), txtTitle.Text, username, DateTime.UtcNow, txtComment.Text, editor.GetContent(),
                                         GetKeywords(), txtDescription.Text, saveMode);
                }

                // Save Categories binding
                Pages.Rebind(currentPage, categories.ToArray());

                // If not a draft, remove page draft
                if (saveMode != SaveMode.Draft)
                {
                    Pages.DeleteDraft(currentPage.FullName, currentPage.Provider);
                    isDraft = false;
                }
                else
                {
                    isDraft = true;
                }

                ManageDraft();

                lblResult.CssClass = "resultok";
                lblResult.Text     = Properties.Messages.PageSaved;

                // This code is executed every time the page is saved, even when "Save & Continue" is clicked
                // This causes a draft approval notification to be sent multiple times for the same page,
                // but this is the only solution because the user might navigate away from the page after
                // clicking "Save & Continue" but not "Save" or "Cancel" - in other words, it is necessary
                // to take every chance to send a notification because no more chances might be available
                if (!canEdit && canEditWithApproval)
                {
                    Pages.SendEmailNotificationForDraft(currentPage.Provider.CurrentWiki, currentPage.FullName, txtTitle.Text, txtComment.Text, username);
                }

                if (redirect)
                {
                    Collisions.CancelEditingSession(currentPage, username);
                    string target = UrlTools.BuildUrl(currentWiki, Tools.UrlEncode(currentPage.FullName), GlobalSettings.PageExtension, "?NoRedirect=1",
                                                      (!string.IsNullOrEmpty(anchor) ? ("#" + anchor + "_" + currentSection.ToString()) : ""));
                    UrlTools.Redirect(target);
                }
            }
        }