Exemple #1
0
        private static XDoc BuildXmlSiteMap(PageBE current, XDoc doc, Dictionary <ulong, PageBE> allowedPagesById)
        {
            doc.Add(PageBL.GetPageXml(current, null));
            XDoc y = doc[doc.AsXmlNode.LastChild].Start("subpages");

            if (!ArrayUtil.IsNullOrEmpty(current.ChildPages))
            {
                PageBE[] visibleChildren = Array.FindAll(current.ChildPages, delegate(PageBE child) {
                    return(allowedPagesById.ContainsKey(child.ID));
                });
                foreach (PageBE child in visibleChildren)
                {
                    BuildXmlSiteMap(child, y, allowedPagesById);
                }
            }

            y.End();

            return(doc);
        }
        private XDoc AppendFileXml(XDoc doc, ResourceBE file, string fileSuffix, bool?explicitRevisionInfo, UserBE updatedByUser, PageBE parentPage)
        {
            bool   requiresEnd = false;
            string fileElement = string.IsNullOrEmpty(fileSuffix) ? "file" : "file." + fileSuffix;

            if (doc == null || doc.IsEmpty)
            {
                doc = new XDoc(fileElement);
            }
            else
            {
                doc.Start(fileElement);
                requiresEnd = true;
            }
            doc.Attr("id", file.MetaXml.FileId ?? 0);
            doc.Attr("revision", file.Revision);
            doc.Attr("res-id", file.ResourceId);
            if (file.IsHidden)
            {
                doc.Attr("hidden", true);
            }
            doc.Attr("href", GetUriInfo(file, explicitRevisionInfo));
            doc.Start("filename").Value(file.Name).End();

            //Description comes from a property
            string description = string.Empty;

            if (!ArrayUtil.IsNullOrEmpty(file.ChildResources))
            {
                ResourceBE descProp = Array.Find(file.ChildResources, p => p != null && p.ResourceType == ResourceBE.Type.PROPERTY && p.Name.EqualsInvariantIgnoreCase(PropertyBL.PROP_DESC));
                if (descProp != null)
                {
                    description = descProp.Content.ToText();
                }
            }
            doc.Start("description").Value(description).End();
            doc.Start("contents")
            .Attr("type", file.MimeType == null ? null : file.MimeType.ToString())
            .Attr("size", file.Size);
            if ((file.MetaXml.ImageHeight ?? 0) > 0 && (file.MetaXml.ImageWidth ?? 0) > 0)
            {
                doc.Attr("width", file.MetaXml.ImageWidth.Value);
                doc.Attr("height", file.MetaXml.ImageHeight.Value);
            }
            doc.Attr("href", GetUriContent(file, explicitRevisionInfo));
            doc.End(); //contents
            if ((file.MetaXml.ImageWidth ?? 0) > 0 && (file.MetaXml.ImageHeight ?? 0) > 0)
            {
                string previewMime = AttachmentPreviewBL.ResolvePreviewMime(file.MimeType).ToString();
                doc.Start("contents.preview")
                .Attr("rel", "thumb")
                .Attr("type", previewMime)
                .Attr("maxwidth", _dekiContext.Instance.ImageThumbPixels)
                .Attr("maxheight", _dekiContext.Instance.ImageThumbPixels)
                .Attr("href", GetUriContent(file, explicitRevisionInfo).With("size", "thumb"));
                if (!file.IsHeadRevision() || (explicitRevisionInfo ?? false))
                {
                    doc.Attr("revision", file.Revision);
                }
                doc.End(); //contents.preview: thumb
                doc.Start("contents.preview")
                .Attr("rel", "webview")
                .Attr("type", previewMime)
                .Attr("maxwidth", _dekiContext.Instance.ImageWebviewPixels)
                .Attr("maxheight", _dekiContext.Instance.ImageWebviewPixels)
                .Attr("href", GetUriContent(file, explicitRevisionInfo).With("size", "webview"));
                if (!file.IsHeadRevision() || (explicitRevisionInfo ?? false))
                {
                    doc.Attr("revision", file.Revision);
                }
                doc.End(); //contents.preview: webview
            }
            doc.Start("date.created").Value(file.Timestamp).End();
            if (updatedByUser != null)
            {
                doc.Add(UserBL.GetUserXml(updatedByUser, "createdby", Utils.ShowPrivateUserInfo(updatedByUser)));
            }
            if (file.ResourceIsDeleted && ((file.ChangeMask & ResourceBE.ChangeOperations.DELETEFLAG) == ResourceBE.ChangeOperations.DELETEFLAG))
            {
                if (updatedByUser != null)
                {
                    doc.Add(UserBL.GetUserXml(updatedByUser, "deletedby", Utils.ShowPrivateUserInfo(updatedByUser)));
                }
                doc.Start("date.deleted").Value(file.Timestamp).End();
            }
            if (file.IsHeadRevision() && !(explicitRevisionInfo ?? false) && !file.ResourceIsDeleted)
            {
                uint filteredCount = _session.Resources_GetRevisionCount(file.ResourceId, DEFAULT_REVISION_FILTER);
                doc.Start("revisions");
                doc.Attr("count", filteredCount);
                doc.Attr("totalcount", file.Revision);
                doc.Attr("href", GetUri(file).At("revisions"));
                doc.End();
            }
            else
            {
                if (file.ChangeMask != ResourceBE.ChangeOperations.UNDEFINED)
                {
                    doc.Start("user-action").Attr("type", file.ChangeMask.ToString().ToLowerInvariant()).End();
                }
            }

            //parent page is passed in for verbose output only
            if (parentPage != null)
            {
                doc.Add(PageBL.GetPageXml(parentPage, "parent"));
            }
            if (file.ChildResources != null)
            {
                List <ResourceBE> properties = new List <ResourceBE>();
                foreach (ResourceBE p in file.ChildResources)
                {
                    properties.Add(p);
                }
                doc = PropertyBL.Instance.GetPropertyXml(properties.ToArray(), GetUri(file), null, null, doc);
            }
            if (file.IsHidden)
            {
                uint?userIdHiddenBy = file.MetaXml.RevisionHiddenUserId;
                if (userIdHiddenBy != null)
                {
                    UserBE userHiddenBy = UserBL.GetUserById(userIdHiddenBy.Value);
                    if (userHiddenBy != null)
                    {
                        doc.Add(UserBL.GetUserXml(userHiddenBy, "hiddenby", Utils.ShowPrivateUserInfo(userHiddenBy)));
                    }
                }
                doc.Elem("date.hidden", file.MetaXml.RevisionHiddenTimestamp ?? DateTime.MinValue);
                doc.Elem("description.hidden", file.MetaXml.RevisionHiddenComment ?? string.Empty);
            }
            if (requiresEnd)
            {
                doc.End(); //file
            }
            return(doc);
        }
Exemple #3
0
        private static XDoc AppendCommentXml(XDoc doc, CommentBE comment, string suffix, bool?includeParentInfo)
        {
            bool   requiresEnd    = false;
            string commentElement = string.IsNullOrEmpty(suffix) ? "comment" : "comment." + suffix;

            if (doc == null || doc.IsEmpty)
            {
                doc = new XDoc(commentElement);
            }
            else
            {
                doc.Start(commentElement);
                requiresEnd = true;
            }

            doc.Attr("id", comment.Id).Attr("href", CommentBL.GetUri(comment));

            //include parentinfo by default if the parent page is populated
            PageBE page = PageBL.GetPageById(comment.PageId);

            if (page != null && (includeParentInfo ?? true))
            {
                doc.Add(PageBL.GetPageXml(page, "parent"));
            }

            UserBE posterUser = UserBL.GetUserById(comment.PosterUserId);

            if (posterUser != null)
            {
                doc.Add(UserBL.GetUserXml(posterUser, "createdby", Utils.ShowPrivateUserInfo(posterUser)));
            }
            doc.Start("date.posted").Value(comment.CreateDate).End();
            doc.Start("title").Value(comment.Title).End();
            doc.Start("number").Value(comment.Number).End();

            //Note (MaxM): Replytoid/replies not yet exposed
            //if (ReplyToId.HasValue) {
            //    doc.Start("comment.replyto")
            //        .Attr("number", ReplyToId.Value.ToString())
            //        .Attr("href", DekiContext.Current.ApiUri.At("pages", PageId.ToString(), "comments", ReplyToId.Value.ToString())).End();
            //}

            bool displayContent = true;

            //Only display content for nondeleted comments or for admins
            if (comment.IsCommentMarkedAsDeleted)
            {
                displayContent = PermissionsBL.IsUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
            }

            if (displayContent)
            {
                doc.Start("content")
                .Attr("type", comment.ContentMimeType)
                .Attr("href", CommentBL.GetUri(comment).At("content"))
                .Value(comment.Content).End();
            }

            if (comment.LastEditUserId.HasValue)
            {
                UserBE lastEditUser = UserBL.GetUserById(comment.LastEditUserId.Value);
                if (null != lastEditUser)
                {
                    doc.Add(UserBL.GetUserXml(lastEditUser, "editedby", Utils.ShowPrivateUserInfo(lastEditUser)));
                    doc.Start("date.edited").Value(comment.LastEditDate).End();
                }
            }

            if (comment.IsCommentMarkedAsDeleted && comment.DeleterUserId.HasValue)
            {
                UserBE deleteUser = UserBL.GetUserById(comment.DeleterUserId.Value);
                if (null != deleteUser)
                {
                    doc.Add(UserBL.GetUserXml(deleteUser, "deletedby", Utils.ShowPrivateUserInfo(deleteUser)));
                    doc.Start("date.deleted").Value(comment.DeleteDate).End();
                }
            }

            if (requiresEnd)
            {
                doc.End(); //comment
            }

            return(doc);
        }
Exemple #4
0
        public Yield PostUsersAllowed(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            var permissionMask = context.GetParam <ulong>("mask", 0);
            var operationList  = context.GetParam("operations", "");
            var user           = GetUserFromUrlMustExist();
            var verbose        = context.GetParam("verbose", true);
            var invert         = context.GetParam("invert", false);

            // Use comma separated permission list or permissionmask from request.
            var permissions = Permissions.NONE;

            if (permissionMask != 0)
            {
                permissions = (Permissions)permissionMask;
            }

            // Convert operation list to mask combined with provided mask
            if (!string.IsNullOrEmpty(operationList))
            {
                try {
                    permissions |= (Permissions)PermissionsBL.MaskFromPermissionList(PermissionsBL.PermissionListFromString(operationList));
                } catch {
                    throw new UserOperationListInvalidArgumentException();
                }
            }
            IEnumerable <ulong> pageIds;
            var textOutput = false;

            if (request.HasDocument)
            {
                if (!request.ToDocument().HasName("pages"))
                {
                    throw new UserExpectedRootNodePagesInvalidDocumentException();
                }
                pageIds = from pageIdXml in request.ToDocument()["page/@id"]
                          let pageId = pageIdXml.AsULong
                                       where pageId.HasValue
                                       select pageId.Value;
            }
            else if (verbose)
            {
                throw new UserPageFilterVerboseNotAllowedException();
            }
            else if (!request.ContentType.Match(MimeType.TEXT))
            {
                throw new UserPageFilterInvalidInputException();
            }
            else
            {
                textOutput = true;
                pageIds    = request.ToText().CommaDelimitedToULong();
            }
            IEnumerable <ulong> filtered;
            var allowedPages = PermissionsBL.FilterDisallowed(user, pageIds, false, out filtered, permissions);

            if (textOutput)
            {
                var output = invert
                    ? filtered.ToCommaDelimitedString()
                    : allowedPages.ToCommaDelimitedString();
                response.Return(DreamMessage.Ok(MimeType.TEXT, output ?? string.Empty));
            }
            else
            {
                var responseDoc = new XDoc("pages");
                if (invert)
                {
                    foreach (var pageId in filtered)
                    {
                        responseDoc.Start("page").Attr("id", pageId).End();
                    }
                }
                else if (allowedPages.Any())
                {
                    if (verbose)
                    {
                        foreach (var page in PageBL.GetPagesByIdsPreserveOrder(allowedPages))
                        {
                            responseDoc.Add(PageBL.GetPageXml(page, null));
                        }
                    }
                    else
                    {
                        foreach (var pageId in allowedPages)
                        {
                            responseDoc.Start("page").Attr("id", pageId).End();
                        }
                    }
                }
                response.Return(DreamMessage.Ok(responseDoc));
            }
            yield break;
        }
Exemple #5
0
        public static XDoc RestoreDeletedPage(uint pageid, Title newRootPath, string revertReason)
        {
            //Retrieve initial revisions of pages to restore
            //First item in the list is the page that initiated the transaction.
            //Talk pages are included.
            uint initialDeleteTranId             = 0;
            IList <ArchiveBE> pagesToRestore     = DbUtils.CurrentSession.Archive_GetPagesInTransaction(pageid, out initialDeleteTranId);
            TransactionBE     initialDeleteTrans = DbUtils.CurrentSession.Transactions_GetById(initialDeleteTranId);

            //Validate deleted page + transaction
            if (pagesToRestore.Count == 0)
            {
                throw new PageArchiveLogicNotFoundException(pageid);
            }

            if (initialDeleteTrans == null)
            {
                throw new PageArchiveBadTransactionFatalException(initialDeleteTranId, pageid);
            }

            //TODO MaxM: move the above gathering of what pages to restore to another method. Make this private.

            //Look for title conflicts
            List <Title> titles           = new List <Title>();
            List <ulong> pageidsToRestore = new List <ulong>();
            Dictionary <ulong, PageBE> restoredPagesById = null;
            DateTime utcTimestamp = DateTime.UtcNow;

            foreach (ArchiveBE p in pagesToRestore)
            {
                Title t = p.Title;
                if (newRootPath != null)
                {
                    t = BuildNewTitlesForMovedPage(pagesToRestore[0].Title, p.Title, newRootPath);
                }
                titles.Add(t);

                pageidsToRestore.Add(p.LastPageId);
            }

            IList <PageBE> currentPages = DbUtils.CurrentSession.Pages_GetByTitles(titles.ToArray());

            if (currentPages.Count > 0)
            {
                //Remove all conflicting redirect pages from target of restore if all conflicting pages are redirects
                List <PageBE> conflictingRedirects = new List <PageBE>();
                foreach (PageBE p in currentPages)
                {
                    if (p.IsRedirect)
                    {
                        conflictingRedirects.Add(p);
                    }
                }

                if (currentPages.Count == conflictingRedirects.Count && conflictingRedirects.Count > 0)
                {
                    //Remove existing redirects and refresh the conflicting pages list
                    PageBL.DeletePages(conflictingRedirects.ToArray(), utcTimestamp, 0, false);
                    currentPages = DbUtils.CurrentSession.Pages_GetByTitles(titles.ToArray());
                }
            }

            if (currentPages.Count > 0)
            {
                //return the name(s) of the conflicting page title(s)
                StringBuilder conflictTitles = new StringBuilder();
                foreach (PageBE p in currentPages)
                {
                    if (conflictTitles.Length > 0)
                    {
                        conflictTitles.Append(", ");
                    }

                    conflictTitles.Append(p.Title.AsPrefixedUserFriendlyPath());
                }

                throw new PageArchiveRestoreNamedPageConflictException(conflictTitles.ToString());
            }

            //Gather revisions for all pages to be restored.
            //Revisions are sorted by timestamp: oldest first.
            Dictionary <ulong, IList <ArchiveBE> > revisionsByPageId = DbUtils.CurrentSession.Archive_GetRevisionsByPageIds(pageidsToRestore);

            uint restoredPageTranId = 0;

            try {
                TransactionBE newTrans = new TransactionBE();
                newTrans.UserId    = DekiContext.Current.User.ID;
                newTrans.PageId    = pageid;
                newTrans.Title     = pagesToRestore[0].Title;
                newTrans.Type      = RC.PAGERESTORED;
                newTrans.TimeStamp = DateTime.UtcNow;
                restoredPageTranId = DbUtils.CurrentSession.Transactions_Insert(newTrans);

                //Pages must be restored in correct order (alphabetical ensures parent pages are restored before children).
                //pagesToRestore must be in alphabetical title order

                bool minorChange = false;
                foreach (ArchiveBE pageToRestore in pagesToRestore)
                {
                    IList <ArchiveBE> revisions = null;
                    if (revisionsByPageId.TryGetValue(pageToRestore.LastPageId, out revisions))
                    {
                        //Optionally restore page to different title
                        Title restoreToTitle = pageToRestore.Title;
                        if (newRootPath != null)
                        {
                            restoreToTitle = BuildNewTitlesForMovedPage(pagesToRestore[0].Title, pageToRestore.Title, newRootPath);
                        }

                        RestorePageRevisionsForPage(revisions.ToArray(), restoreToTitle, restoredPageTranId, minorChange, utcTimestamp);
                        DbUtils.CurrentSession.Archive_Delete(revisions.Select(e => e.Id).ToList());
                    }
                    minorChange = true;
                }

                //Retrieve the restored pages
                restoredPagesById = PageBL.GetPagesByIdsPreserveOrder(pageidsToRestore).AsHash(e => e.ID);

                // Restore attachments
                IList <ResourceBE> attachmentsToRestore = ResourceBL.Instance.GetResourcesByChangeSet(initialDeleteTrans.Id, ResourceBE.Type.FILE);
                foreach (ResourceBE at in attachmentsToRestore)
                {
                    PageBE restoredPage;
                    if (restoredPagesById.TryGetValue(at.ParentPageId.Value, out restoredPage))
                    {
                        AttachmentBL.Instance.RestoreAttachment(at, restoredPage, utcTimestamp, restoredPageTranId);
                    }
                }

                //Update the old transaction as reverted
                initialDeleteTrans.Reverted        = true;
                initialDeleteTrans.RevertTimeStamp = utcTimestamp;
                initialDeleteTrans.RevertUserId    = DekiContext.Current.User.ID;
                initialDeleteTrans.RevertReason    = revertReason;
                DbUtils.CurrentSession.Transactions_Update(initialDeleteTrans);
            } catch (Exception) {
                DbUtils.CurrentSession.Transactions_Delete(restoredPageTranId);
                throw;
            }

            //Build restore summary
            XDoc ret = new XDoc("pages.restored");

            foreach (ulong restoredPageId in pageidsToRestore)
            {
                PageBE restoredPage = null;
                if (restoredPagesById.TryGetValue((uint)restoredPageId, out restoredPage))
                {
                    ret.Add(PageBL.GetPageXml(restoredPage, string.Empty));
                }
            }

            return(ret);
        }
Exemple #6
0
        public static XDoc GetUserXmlVerbose(UserBE user, string relationAttr, bool showPrivateInfo, bool showGroups, bool showProperties)
        {
            XDoc userXml = GetUserXml(user, relationAttr, showPrivateInfo);

            userXml.Elem("date.created", user.CreateTimestamp);

            if (!IsAnonymous(user))
            {
                PageBE homePage = GetHomePage(user);
                if (homePage != null && homePage.ID != 0)
                {
                    userXml.Add(PageBL.GetPageXml(homePage, "home"));
                }
            }

            userXml.Start("status").Value(user.UserActive ? "active" : "inactive").End();
            userXml.Start("date.lastlogin").Value(user.Touched).End();
            userXml.Start("language").Value(user.Language).End();
            userXml.Start("timezone").Value(user.Timezone).End();

            ServiceBE authService = ServiceBL.GetServiceById(user.ServiceId);

            if (authService != null)
            {
                userXml.Add(ServiceBL.GetServiceXml(authService, "authentication"));
            }

            //Permissions for the user from user role
            userXml.Add(PermissionsBL.GetRoleXml(PermissionsBL.GetRoleById(user.RoleId), "user"));

            ulong effectivePermissions = PermissionsBL.CalculateEffectiveUserRights(user);

            //Effective permissions for the user from the role + group roles.
            userXml.Add(PermissionsBL.GetPermissionXml(effectivePermissions, "effective"));

            // Set of permissions revoked from the user
            userXml.Add(PermissionsBL.GetPermissionsRevokedXml(user));

            // check if groups should be included
            if (showGroups)
            {
                userXml.Start("groups");
                IList <GroupBE> groups = DbUtils.CurrentSession.Groups_GetByUser(user.ID);
                if (null != groups)
                {
                    foreach (GroupBE g in groups)
                    {
                        userXml.Add(GroupBL.GetGroupXmlVerbose(g, null));
                    }
                }
                userXml.End();
            }

            // retrieve properties for current user while providing an href for other users.
            if (showProperties && (DekiContext.Current != null && DekiContext.Current.User != null && DekiContext.Current.User.ID == user.ID))
            {
                IList <ResourceBE> props = PropertyBL.Instance.GetUserProperties(user.ID);
                userXml = PropertyBL.Instance.GetPropertyXml(props, GetUri(user), null, null, userXml);
            }
            else
            {
                userXml.Start("properties").Attr("href", GetUri(user).At("properties")).End();
            }

            // TODO Max: get <subscriptions> (watchlist) not implemented
            return(userXml);
        }