コード例 #1
0
ファイル: DekiWiki-Pages.cs プロジェクト: heran/DekiWiki
        public Yield PostPageContents(DreamContext context, DreamMessage request, Result<DreamMessage> response) {
            PageBE cur = PageBL_GetPageFromUrl(context, false);

            // load page contents based on mime type
            string contents;
            MimeType mimeType = request.ContentType;
            if(mimeType.IsXml) {
                XDoc contentsDoc = request.ToDocument();
                if(contentsDoc == null || contentsDoc.IsEmpty || !contentsDoc.HasName("content")) {
                    throw new PostedDocumentInvalidArgumentException("content");
                }
                contents = contentsDoc["body"].ToInnerXHtml();
            } else if(MimeType.TEXT.Match(mimeType) || MimeType.FORM_URLENCODED.Match(mimeType)) {
                contents = request.AsText();
            } else {
                throw new UnsupportedContentTypeInvalidArgumentException(mimeType);
            }

            bool isExistingPage = cur.ID != 0 && !cur.IsRedirect;
            string abort = context.GetParam("abort", "never").ToLowerInvariant();
            if(isExistingPage && "exists" == abort) {
                throw new PageExistsConflictException();
            }

            // Retrieve the title used for path normalization (if any)
            Title relToTitle = Utils.GetRelToTitleFromUrl(context);
            string editTimeStr = context.GetParam("edittime", null);
            DateTime editTime = DateTime.MinValue;
            if(!string.IsNullOrEmpty(editTimeStr)) {
                editTime = editTimeStr.EqualsInvariantIgnoreCase("now") ? DateTime.UtcNow : DbUtils.ToDateTime(editTimeStr);
            }
            string comment = context.GetParam("comment", String.Empty);
            string language = context.GetParam("language", null);
            string displayName = context.GetParam("title", null);
            int section = context.GetParam<int>("section", -1);
            if((section < -1) || ((!isExistingPage) && (0 < section))) {
                throw new SectionParamInvalidArgumentException();
            }

            // determin how unsafe/invalid content should be handled
            bool removeIllegalElements = StringUtil.EqualsInvariantIgnoreCase(context.GetParam("tidy", "convert"), "remove");

            // a new revision is created when no changes are detected when overwrite is enabled
            bool overwrite = context.GetParam<bool>("overwrite", false);

            // check whether the page exists and is not a redirect
            DateTime pageLastEditTime = cur.TimeStamp;
            OldBE baseOld = null;
            OldBE overwrittenOld = null;
            if(isExistingPage) {
                PageBL.AuthorizePage(DekiContext.Current.User, Permissions.UPDATE, cur, false);

                // ensure that 'edittime' is set
                if(DateTime.MinValue == editTime) {
                    throw new PageEditTimeInvalidArgumentException();
                }

                // check if page was modified since since the specified time
                if(pageLastEditTime > editTime) {

                    // ensure we're allowed to save a modified page
                    if("modified" == abort) {
                        throw new PageModifiedConflictException();
                    }

                    // if an edit has occurred since the specified edit time, retrieve the revision upon which it is based
                    // NOTE: this can be null if someone created the page after the specified edit time (ie. no common base revision)
                    baseOld = DbUtils.CurrentSession.Old_GetOldByTimestamp(cur.ID, editTime);

                    // if editing a particular section, use the page upon which the section edits were based.
                    if(0 < section && null == baseOld) {
                        throw new PageHeadingInvalidArgumentException();
                    }
                }
            }

            // save page
            bool conflict;
            try {
                overwrittenOld = PageBL.Save(cur, baseOld, comment, contents, DekiMimeType.DEKI_TEXT, displayName, language, section, context.GetParam("xpath", null), DateTime.UtcNow, 0, true, removeIllegalElements, relToTitle, overwrite, out conflict);
            } catch(DekiScriptDocumentTooLargeException e) {
                response.Return(DreamMessage.Forbidden(string.Format(e.Message)));
                yield break;
            }

            // check if this post is part of an import action
            var importTimeStr = context.GetParam("importtime", null);
            if(!string.IsNullOrEmpty(importTimeStr)) {
                var dateModified = DbUtils.ToDateTime(importTimeStr);
                var lastImport = PropertyBL.Instance.GetPageProperty((uint)cur.ID, SiteImportBuilder.LAST_IMPORT);
                var lastImportDoc = new XDoc("last-import").Elem("etag", cur.Etag).Elem("date.modified", dateModified);
                var content = new ResourceContentBE(lastImportDoc);
                if(lastImport == null) {
                    PropertyBL.Instance.CreateProperty((uint)cur.ID, PageBL.GetUri(cur), ResourceBE.ParentType.PAGE, SiteImportBuilder.LAST_IMPORT, content, string.Format("import at revision {0}", cur.Revision), content.ComputeHashString(), AbortEnum.Never);
                } else {
                    PropertyBL.Instance.UpdatePropertyContent(lastImport, content, string.Format("updated import at revision {0}", cur.Revision), content.ComputeHashString(), AbortEnum.Never, PageBL.GetUri(cur), ResourceBE.ParentType.PAGE);
                }
            }

            // generate xml output
            XDoc editXml = new XDoc("edit") { PageBL.GetPageXml(cur, String.Empty) };

            // if a non-redirect was overwritten, report it
            if((overwrittenOld != null) && (pageLastEditTime != editTime) && isExistingPage && conflict) {
                editXml.Attr("status", "conflict");
                editXml.Add(baseOld == null ? new XDoc("page.base") : PageBL.GetOldXml(cur, baseOld, "base"));
                editXml.Add(PageBL.GetOldXml(cur, overwrittenOld, "overwritten"));
            } else {
                editXml.Attr("status", "success");
            }

            response.Return(DreamMessage.Ok(editXml));
            yield break;
        }
コード例 #2
0
 public void BE_hashes_stream() {
     var value = StringUtil.CreateAlphaNumericKey(20);
     var be = new ResourceContentBE(value,MimeType.TEXT_UTF8);
     Assert.AreEqual(StringUtil.ComputeHashString(value,Encoding.UTF8), be.ComputeHashString());
 }