Esempio n. 1
0
        private IList <PageBE> GetTaggedPages(TagBE tag)
        {
            IList <ulong>  pageIds = _session.Tags_GetPageIds(tag.Id);
            IList <PageBE> pages   = PageBL.GetPagesByIdsPreserveOrder(pageIds);

            return(PermissionsBL.FilterDisallowed(_user, pages, false, Permissions.BROWSE));
        }
Esempio n. 2
0
        private XDoc GetFileXml(IList <ResourceBE> files, bool verbose, bool list, string fileSuffix, bool?explicitRevisionInfo, int?totalCount, XUri listUri)
        {
            Dictionary <uint, UserBE>  users = new Dictionary <uint, UserBE>();
            Dictionary <ulong, PageBE> pages = new Dictionary <ulong, PageBE>();
            List <uint> parentIds            = new List <uint>();

            //Collect related entity id's
            foreach (ResourceBE f in files)
            {
                users[f.UserId]             = null;
                pages[f.ParentPageId.Value] = null;
                parentIds.Add(f.ResourceId);
            }

            //Perform batch lookups of related entities
            users = _session.Users_GetByIds(users.Keys.ToArray()).AsHash(e => e.ID);
            if (verbose)
            {
                pages = PageBL.GetPagesByIdsPreserveOrder(pages.Keys.ToArray()).AsHash(e => e.ID);
            }

            //Associate properties with the given attachments
            files = _resourceBL.PopulateChildren(files.ToArray(), new[] { ResourceBE.Type.PROPERTY }, explicitRevisionInfo ?? false);

            XDoc ret = XDoc.Empty;

            if (list)
            {
                List <ResourceBE> sortedFiles = new List <ResourceBE>(files);
                files = SortFileListByNameAndRevision(sortedFiles).ToArray();
                ret   = new XDoc(string.IsNullOrEmpty(fileSuffix) ? "files" : "files." + fileSuffix);
                ret.Attr("count", files.Count);
                if (totalCount != null)
                {
                    ret.Attr("totalcount", totalCount.Value);
                }
                if (listUri != null)
                {
                    ret.Attr("href", listUri);
                }
            }
            foreach (ResourceBE f in files)
            {
                UserBE updatedByUser;
                PageBE parentPage;
                users.TryGetValue(f.UserId, out updatedByUser);
                pages.TryGetValue(f.ParentPageId.Value, out parentPage);
                ret = AppendFileXml(ret, f, fileSuffix, explicitRevisionInfo, updatedByUser, parentPage);
            }

            return(ret);
        }
Esempio n. 3
0
        private IList <TagBE> FilterDisallowed(IList <TagBE> tags)
        {
            List <TagBE> tagsToRemove = new List <TagBE>();

            tags = AssignDefinePages(tags);
            foreach (TagBE tag in tags)
            {
                if (tag.Type == TagType.DEFINE)
                {
                    if (tag.DefinedTo == null || PermissionsBL.FilterDisallowed(_user, new PageBE[] { tag.DefinedTo }, false, Permissions.BROWSE).Length != 1)
                    {
                        tagsToRemove.Add(tag);
                    }
                    tag.OccuranceCount = 1;
                }
                else
                {
                    // filter the tags based on permissions
                    IList <ulong>  pageIds = _session.Tags_GetPageIds(tag.Id);
                    IList <PageBE> pages   = PageBL.GetPagesByIdsPreserveOrder(pageIds);
                    if (pages == null)
                    {
                        // this should never happen
                        tagsToRemove.Add(tag);
                    }
                    else
                    {
                        // apply permissions
                        int count = PermissionsBL.FilterDisallowed(_user, pages, false, Permissions.BROWSE).Length;
                        if (count == 0)
                        {
                            tagsToRemove.Add(tag);
                        }
                        tag.OccuranceCount = count;
                    }
                }
            }
            foreach (TagBE tag in tagsToRemove)
            {
                tags.Remove(tag);
            }
            return(tags);
        }
Esempio n. 4
0
        public void RemoveAttachments(IList <ResourceBE> attachmentToRemove, DateTime timestamp, uint transactionId)
        {
            //TODO MaxM: This batch remove exists solely to mark all files as deleted when a parent page is deleted..
            List <ulong> pageIds = new List <ulong>();

            foreach (ResourceBE file in attachmentToRemove)
            {
                file.AssertHeadRevision();
                pageIds.Add(file.ParentPageId.Value);
            }
            Dictionary <ulong, PageBE> pagesById = PageBL.GetPagesByIdsPreserveOrder(pageIds).AsHash(e => e.ID);

            foreach (ResourceBE file in attachmentToRemove)
            {
                PageBE parentPage;
                if (pagesById.TryGetValue(file.ParentPageId.Value, out parentPage))
                {
                    _resourceBL.Delete(file, parentPage, transactionId);
                }
            }
        }
Esempio n. 5
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;
        }
Esempio n. 6
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);
        }