Пример #1
0
        public Yield GetUsers(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            // TODO (steveb): add 'emailfilter' and use it to obsolete 'usernameemailfilter'; 'usernamefilter', 'fullnamefilter', and 'emailfilter'
            //                should be OR'ed together when they are present.

            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.READ);
            uint totalCount;
            uint queryCount;
            var  users  = UserBL.GetUsersByQuery(context, null, out totalCount, out queryCount);
            XDoc result = new XDoc("users");

            result.Attr("count", users.Count());
            result.Attr("querycount", queryCount);
            result.Attr("totalcount", totalCount);
            result.Attr("href", DekiContext.Current.ApiUri.At("users"));
            bool verbose = context.GetParam <bool>("verbose", true);

            foreach (UserBE u in users)
            {
                if (verbose)
                {
                    result.Add(UserBL.GetUserXmlVerbose(u, null, Utils.ShowPrivateUserInfo(u), true, true));
                }
                else
                {
                    result.Add(UserBL.GetUserXml(u, null, Utils.ShowPrivateUserInfo(u)));
                }
            }
            response.Return(DreamMessage.Ok(result));
            yield break;
        }
Пример #2
0
        public Yield GetFiles(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.READ);
            uint   skip        = context.GetParam <uint>("skip", 0);
            uint   numfiles    = 100;
            string numfilesStr = context.GetParam("numfiles", numfiles.ToString());

            if (StringUtil.EqualsInvariantIgnoreCase(numfilesStr, "ALL"))
            {
                numfiles = uint.MaxValue;
            }
            else
            {
                if (!uint.TryParse(numfilesStr, out numfiles))
                {
                    throw new AttachmentCannotParseNumFilesInvalidArgumentException();
                }
            }

            IList <ResourceBE> files = AttachmentBL.Instance.RetrieveAttachments(skip, numfiles);
            XDoc ret = AttachmentBL.Instance.GetFileXml(files, false, null, null, null);

            response.Return(DreamMessage.Ok(ret));
            yield break;
        }
Пример #3
0
        public Yield GetGroupUsers(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.READ);
            GroupBE      group       = GetGroupFromUrl();
            DreamMessage responseMsg = null;

            uint totalCount;
            uint queryCount;
            var  usersInGroup = UserBL.GetUsersByQuery(context, group.Id, out totalCount, out queryCount);

            XDoc ret = new XDoc("users");

            ret.Attr("count", usersInGroup.Count());
            ret.Attr("querycount", queryCount);
            ret.Attr("totalcount", totalCount);
            ret.Attr("href", DekiContext.Current.ApiUri.At("groups", group.Id.ToString(), "users"));

            foreach (UserBE member in usersInGroup)
            {
                ret.Add(UserBL.GetUserXml(member, null, Utils.ShowPrivateUserInfo(member)));
            }

            responseMsg = DreamMessage.Ok(ret);

            response.Return(responseMsg);
            yield break;
        }
Пример #4
0
        public Yield PostUserAuth(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            uint serviceId = context.GetParam <uint>("authprovider", 0);
            bool altPassword;

            //This will internally fail with a 501 response if credentials are invalid.
            //Anonymous accounts (no credentials/authtoken) are not allowed -> 401
            UserBE u = SetContextAndAuthenticate(request, serviceId, context.Verb == Verb.POST, false, true, out altPassword);

            PermissionsBL.CheckUserAllowed(u, Permissions.LOGIN);


            string token = AuthBL.CreateAuthTokenForUser(u);

            try {
                PageBL.CreateUserHomePage(DekiContext.Current.User);
            } catch { }
            XUri         redirectUri = XUri.TryParse(context.GetParam("redirect", null));
            DreamMessage ret         = BuildSetAuthTokenResponse(token, redirectUri);

            DekiContext.Current.Instance.EventSink.UserLogin(DekiContext.Current.Now, DekiContext.Current.User);

            //TODO Max: Set a response header or status to indicate that an alt password was used.
            response.Return(ret);
            yield break;
        }
Пример #5
0
        public Yield PostArchiveFilesRestore(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);

            // parameter parsing
            PageBE destPage = null;
            string to       = context.GetParam("to", string.Empty);

            if (to != string.Empty)
            {
                destPage = PageBL_GetPageFromPathSegment(false, to);
            }
            PageBE     parentPage;
            ResourceBE removedFile = GetAttachment(context, request, Permissions.NONE, true, true, out parentPage);

            if (!removedFile.ResourceIsDeleted)
            {
                throw new AttachmentArchiveFileNotDeletedNotFoundException();
            }

            //Optionally move the restored file to the given page
            if (null == destPage)
            {
                destPage = parentPage;
            }
            AttachmentBL.Instance.RestoreAttachment(removedFile, destPage, DateTime.UtcNow, 0);
            response.Return(DreamMessage.Ok());
            yield break;
        }
Пример #6
0
        public Yield GetBan(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
            BanBE ban = GetBanFromRequest(context, context.GetParam <uint>("banid"));

            response.Return(DreamMessage.Ok(BanningBL.GetBanXml(ban)));
            yield break;
        }
Пример #7
0
        public Yield GetArchivePageSubpages(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
            XDoc responseXml = PageArchiveBL.GetArchivedSubPagesXml(context.GetParam <uint>("pageid"));

            response.Return(DreamMessage.Ok(responseXml));
            yield break;
        }
Пример #8
0
        public Yield GetArchivePageContents(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
            DreamMessage ret = PageArchiveBL.BuildDeletedPageContents(context.GetParam <uint>("pageid"));

            response.Return(ret);
            yield break;
        }
Пример #9
0
        public Yield PostGroupUsers(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
            GroupBE group = GetGroupFromUrl();

            group = GroupBL.AddGroupMembers(group, request.ToDocument());
            response.Return(DreamMessage.Ok(GroupBL.GetGroupXmlVerbose(group, null)));
            yield break;
        }
Пример #10
0
        public Yield DeleteGroup(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
            GroupBE group = GetGroupFromUrl();

            DbUtils.CurrentSession.Groups_Delete(group.Id);
            response.Return(DreamMessage.Ok());
            yield break;
        }
Пример #11
0
        public Yield GetGroup(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.READ);
            GroupBE      group       = GetGroupFromUrl();
            DreamMessage responseMsg = DreamMessage.Ok(GroupBL.GetGroupXmlVerbose(group, null));

            response.Return(responseMsg);
            yield break;
        }
Пример #12
0
        public Yield GetSiteStatus(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.UPDATE);
            var status = new XDoc("status")
                         .Elem("state", DekiContext.Current.Instance.Status);

            response.Return(DreamMessage.Ok(status));
            yield break;
        }
Пример #13
0
        public Yield GetArchiveFiles(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
            IList <ResourceBE> removedFiles = AttachmentBL.Instance.GetDeletedAttachments(null, null);
            XDoc responseXml = AttachmentBL.Instance.GetFileXml(removedFiles, true, "archive", null, null);

            response.Return(DreamMessage.Ok(responseXml));
            yield break;
        }
Пример #14
0
        public Yield PostBans(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
            BanBE ban = BanningBL.SaveBan(request.ToDocument());

            DekiContext.Current.Instance.EventSink.BanCreated(DekiContext.Current.Now, ban);
            response.Return(DreamMessage.Ok(BanningBL.GetBanXml(ban)));
            yield break;
        }
Пример #15
0
        public Yield DeleteGroupUser(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
            GroupBE group = GetGroupFromUrl();
            UserBE  user  = GetUserFromUrlMustExist();

            group = GroupBL.RemoveGroupMember(group, user);
            response.Return(DreamMessage.Ok(GroupBL.GetGroupXmlVerbose(group, null)));
            yield break;
        }
Пример #16
0
        public Yield PostGroup(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
            DreamMessage responseMsg = null;
            GroupBE      group       = GroupBL.PostGroupFromXml(request.ToDocument(), null, context.GetParam("authusername", null), context.GetParam("authpassword", null));

            responseMsg = DreamMessage.Ok(GroupBL.GetGroupXmlVerbose(group, null));
            response.Return(responseMsg);
            yield break;
        }
Пример #17
0
        public Yield DeleteBan(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
            BanBE ban = GetBanFromRequest(context, context.GetParam <uint>("banid"));

            BanningBL.DeleteBan(ban);
            DekiContext.Current.Instance.EventSink.BanRemoved(DekiContext.Current.Now, ban);
            response.Return(DreamMessage.Ok());
            yield break;
        }
Пример #18
0
        public Yield PutSiteRole(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);

            RoleBE role = GetRoleFromUrl(false);

            role = PermissionsBL.PutRole(role, request, context);
            response.Return(DreamMessage.Ok(PermissionsBL.GetRoleXml(role, null)));
            yield break;
        }
Пример #19
0
        public Yield GetArchive(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
            XDoc ret = new XDoc("archive");

            ret.Start("pages.archive").Attr("href", DekiContext.Current.ApiUri.At("archive", "pages")).End();
            ret.Start("files.archive").Attr("href", DekiContext.Current.ApiUri.At("archive", "files")).End();
            response.Return(DreamMessage.Ok(ret));
            yield break;
        }
Пример #20
0
        public Yield GetArchiveFileInfo(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
            PageBE     parentPage  = null;
            ResourceBE removedFile = GetAttachment(context, request, Permissions.NONE, true, true, out parentPage);

            if (!removedFile.ResourceIsDeleted)
            {
                throw new AttachmentArchiveFileNotDeletedNotFoundException();
            }
            response.Return(DreamMessage.Ok(AttachmentBL.Instance.GetFileXml(removedFile, true, "archive", null)));
            yield break;
        }
Пример #21
0
        public Yield GetUser(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            UserBE u = GetUserFromUrlMustExist();

            //Perform permission check if not looking yourself up
            if (u.ID != DekiContext.Current.User.ID)
            {
                PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.READ);
            }
            var showGroups     = !context.GetParam("exclude", "").Contains("groups");
            var showProperties = !context.GetParam("exclude", "").Contains("properties");

            response.Return(DreamMessage.Ok(UserBL.GetUserXmlVerbose(u, null, Utils.ShowPrivateUserInfo(u), showGroups, showProperties)));
            yield break;
        }
Пример #22
0
 public static void DeleteComment(PageBE page, CommentBE comment)
 {
     if (comment.PosterUserId != DekiContext.Current.User.ID)
     {
         PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
     }
     if (!comment.IsCommentMarkedAsDeleted)
     {
         comment.DeleteDate    = DateTime.UtcNow;
         comment.DeleterUserId = DekiContext.Current.User.ID;
         DbUtils.CurrentSession.Comments_Update(comment);
         PageBL.Touch(page, comment.DeleteDate.Value);
         RecentChangeBL.AddCommentDeleteRecentChange(comment.DeleteDate.Value, page, DekiContext.Current.User, DekiResources.COMMENT_DELETED(comment.Number), comment);
         DekiContext.Current.Instance.EventSink.CommentDelete(DekiContext.Current.Now, comment, page, DekiContext.Current.User);
     }
 }
Пример #23
0
        public Yield PostArchivePagesPageIdRestore(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
            uint   pageid        = context.GetParam <uint>("pageid");
            string targetPathStr = context.GetParam("to", string.Empty);
            string reason        = context.GetParam("reason", string.Empty);
            Title  targetPath    = null;

            if (!string.IsNullOrEmpty(targetPathStr))
            {
                targetPath = Title.FromUIUri(null, context.GetParam("to"), false);
            }
            XDoc responseXml = PageArchiveBL.RestoreDeletedPage(pageid, targetPath, reason);

            response.Return(DreamMessage.Ok(responseXml));
            yield break;
        }
Пример #24
0
        public static CommentBE EditExistingComment(PageBE page, CommentBE comment, DreamMessage request, DreamContext context)
        {
            if (comment.PosterUserId != DekiContext.Current.User.ID)
            {
                PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
            }
            ValidateCommentText(request.ContentType, request.AsText());
            comment.LastEditDate    = DateTime.UtcNow;
            comment.LastEditUserId  = DekiContext.Current.User.ID;
            comment.Content         = request.AsText();
            comment.ContentMimeType = request.ContentType.ToString();

            DbUtils.CurrentSession.Comments_Update(comment);
            PageBL.Touch(page, comment.LastEditDate.Value);
            RecentChangeBL.AddCommentUpdateRecentChange(comment.LastEditDate.Value, page, DekiContext.Current.User, DekiResources.COMMENT_EDITED(comment.Number), comment);
            return(comment);
        }
Пример #25
0
        private static UserBE RenameUser(UserBE user, string newUserName, string newFullName)
        {
            //Renaming requires admin rights.
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);

            if (!ServiceBL.IsLocalAuthService(user.ServiceId))
            {
                //TODO MaxM: allow renaming of external users
                throw new ExternalUserRenameNotImplementedExceptionException();
            }

            //Check for already existing user with same name
            UserBE existingUser = DbUtils.CurrentSession.Users_GetByName(newUserName);

            if (existingUser != null)
            {
                throw new UserWithIdExistsConflictException(existingUser.Name, existingUser.ID);
            }

            PageBE existingTargetUserHomePage = PageBL.GetPageByTitle(Title.FromUIUsername(newUserName));

            if (existingTargetUserHomePage != null && existingTargetUserHomePage.ID != 0 && !existingTargetUserHomePage.IsRedirect)
            {
                throw new UserHomepageRenameConflictException();
            }

            //Try to move the homepage.
            PageBE userHomePage = GetHomePage(user);

            if (userHomePage != null && userHomePage.ID != 0)
            {
                Title newTitle = Title.FromUIUsername(newUserName);

                // new user homepage displayname is the user's full name or rebuilt from the username
                newTitle.DisplayName = !string.IsNullOrEmpty(newFullName) ? newFullName : newTitle.AsUserFriendlyDisplayName();
                PageBL.MovePage(userHomePage, newTitle, true);
            }

            //Rename the user
            user.Name = newUserName;
            UserBL.UpdateUser(user);
            return(user);
        }
Пример #26
0
        public Yield GetArchivePages(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
            uint          limit, offset;
            SortDirection sortDir;
            string        sortField;

            Utils.GetOffsetAndCountFromRequest(context, 100, out limit, out offset, out sortDir, out sortField);
            Title  filterTitle = null;
            string titleStr    = context.GetParam("title", null);

            if (!string.IsNullOrEmpty(titleStr))
            {
                filterTitle = Title.FromUIUri(null, titleStr, false);
            }
            XDoc responseXml = PageArchiveBL.GetArchivedPagesXml(limit, offset, filterTitle);

            response.Return(DreamMessage.Ok(responseXml));
            yield break;
        }
Пример #27
0
        public Yield GetGroups(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.READ);
            uint            totalCount, queryCount;
            IList <GroupBE> groups = GroupBL.GetGroupsByQuery(context, out totalCount, out queryCount);

            XDoc result = new XDoc("groups");

            result.Attr("count", groups.Count);
            result.Attr("querycount", queryCount);
            result.Attr("totalcount", totalCount);
            result.Attr("href", DekiContext.Current.ApiUri.At("groups"));

            foreach (GroupBE g in groups)
            {
                result.Add(GroupBL.GetGroupXmlVerbose(g, null));
            }

            response.Return(DreamMessage.Ok(result));
            yield break;
        }
Пример #28
0
        public Yield GetArchiveFile(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
            PageBE     parentPage  = null;
            ResourceBE removedFile = GetAttachment(context, request, Permissions.NONE, true, true, out parentPage);

            if (!removedFile.ResourceIsDeleted)
            {
                throw new AttachmentArchiveFileNotDeletedNotFoundException();
            }
            StreamInfo file = DekiContext.Current.Instance.Storage.GetFile(removedFile, SizeType.ORIGINAL, false);

            if (file == null)
            {
                throw new AttachmentDoesNotExistFatalException(removedFile.ResourceId, removedFile.Revision);
            }
            var responseMsg = DreamMessage.Ok(file.Type, file.Length, file.Stream);

            responseMsg.Headers.ContentDisposition = new ContentDisposition(true, removedFile.Timestamp, null, null, removedFile.Name, file.Length);

            response.Return(responseMsg);
            yield break;
        }
Пример #29
0
        public Yield GetFile(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PageBE       parentPage   = null;
            DreamMessage responseMsg  = null;
            ResourceBE   fileRevision = GetAttachment(context, request, Permissions.READ, true, false, out parentPage);

            if (fileRevision.IsHidden)
            {
                PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
            }

            // check if only file information is requested
            if (context.Verb == Verb.HEAD)
            {
                response.Return(new DreamMessage(DreamStatus.Ok, null, fileRevision.MimeType, (long)fileRevision.Size, Stream.Null));
                yield break;
            }
            try {
                if (request.CheckCacheRevalidation(fileRevision.Timestamp))
                {
                    responseMsg = DreamMessage.NotModified();
                }
                if (responseMsg == null)
                {
                    #region Preview related parameter parsing
                    string sFormat    = context.GetParam("format", string.Empty);
                    string sRatio     = context.GetParam("ratio", string.Empty);
                    uint   height     = context.GetParam <uint>("height", 0);
                    uint   width      = context.GetParam <uint>("width", 0);
                    string cachedSize = context.GetParam("size", string.Empty);

                    // check 'ratio' parameter
                    RatioType ratio = RatioType.UNDEFINED;
                    if (!string.IsNullOrEmpty(sRatio))
                    {
                        switch (sRatio.ToLowerInvariant().Trim())
                        {
                        case "var":
                        case "variable":
                            ratio = RatioType.VARIABLE;
                            break;

                        case "fixed":
                            ratio = RatioType.FIXED;
                            break;

                        default:
                            throw new AttachmentFileRatioInvalidArgumentException();
                        }
                    }

                    // check 'size' parameter
                    SizeType size = SizeType.UNDEFINED;
                    if (!string.IsNullOrEmpty(cachedSize) && !SysUtil.TryParseEnum(cachedSize.Trim(), out size))
                    {
                        throw new AttachmentFilesizeInvalidArgumentException();
                    }

                    // check 'format' parameter
                    FormatType format = FormatType.UNDEFINED;
                    if (!string.IsNullOrEmpty(sFormat) && !SysUtil.TryParseEnum(sFormat.Trim(), out format))
                    {
                        throw new AttachmentFileFormatInvalidArgumentException();
                    }
                    #endregion

                    //if any preview related parameters are set, do preview logic. Otherwise return the file
                    StreamInfo file = null;
                    if ((size != SizeType.UNDEFINED && size != SizeType.ORIGINAL) ||
                        ratio != RatioType.UNDEFINED ||
                        format != FormatType.UNDEFINED ||
                        height != 0 ||
                        width != 0
                        )
                    {
                        file = AttachmentPreviewBL.RetrievePreview(fileRevision, height, width, ratio, size, format);
                    }
                    else
                    {
                        var isMSWebDAV = MSWEBDAV_USER_AGENT_REGEX.IsMatch(request.Headers.UserAgent ?? string.Empty);
                        file = DekiContext.Current.Instance.Storage.GetFile(fileRevision, SizeType.ORIGINAL, !isMSWebDAV);
                    }

                    // prepare response
                    if (file == null)
                    {
                        throw new AttachmentDoesNotExistFatalException(fileRevision.ResourceId, fileRevision.Revision);
                    }

                    if (file.Uri != null)
                    {
                        responseMsg = DreamMessage.Redirect(file.Uri);
                    }
                    else
                    {
                        bool inline = fileRevision.MetaXml.ImageHeight.HasValue;

                        // see if we can use the MimeType map for allowing inlining
                        if (!inline)
                        {
                            // if IE inline security is not disabled
                            bool isIE = false;
                            if (!DekiContext.Current.Instance.EnableUnsafeIEContentInlining)
                            {
                                // check the user agent to see if we're dealing with IE
                                isIE = MSIE_USER_AGENT_REGEX.IsMatch(request.Headers.UserAgent ?? string.Empty);
                            }

                            // see if the mime-type could allow inlining
                            inline = DekiContext.Current.Instance.MimeTypeCanBeInlined(fileRevision.MimeType);
                            if (inline && isIE)
                            {
                                // check whether the creator of the file had unsafecontent permission, to override IE security
                                IList <ResourceBE> revisions         = ResourceBL.Instance.GetResourceRevisions(fileRevision.ResourceId, ResourceBE.ChangeOperations.CONTENT, SortDirection.DESC, 1);
                                UserBE             lastContentEditor = UserBL.GetUserById(revisions[0].UserId);
                                inline = PermissionsBL.IsUserAllowed(lastContentEditor, parentPage, Permissions.UNSAFECONTENT);
                            }
                        }
                        responseMsg = DreamMessage.Ok(fileRevision.MimeType, file.Length, file.Stream);
                        responseMsg.Headers["X-Content-Type-Options"] = "nosniff";
                        responseMsg.Headers.ContentDisposition        = new ContentDisposition(inline, fileRevision.Timestamp, null, null, fileRevision.Name, file.Length, request.Headers.UserAgent);

                        // MSIE6 will delete a downloaded file before the helper app trying to use it can get to it so we
                        //have to do custom cache control headers for MSIE6 so that the file can actually be opened
                        if (MSIE6_USER_AGENT_REGEX.IsMatch(request.Headers.UserAgent ?? string.Empty))
                        {
                            responseMsg.Headers["Expires"]   = "0";
                            responseMsg.Headers.Pragma       = "cache";
                            responseMsg.Headers.CacheControl = "private";
                        }
                        else
                        {
                            responseMsg.SetCacheMustRevalidate(fileRevision.Timestamp);
                        }
                    }
                }
            } catch {
                if (responseMsg != null)
                {
                    responseMsg.Close();
                }
                throw;
            }
            response.Return(responseMsg);
            yield break;
        }
Пример #30
0
        public ResourceBE[] ModifyRevisionVisibility(ResourceBE res, XDoc request, string comment)
        {
            List <ResourceBE> revisionsToHide   = new List <ResourceBE>();
            List <ResourceBE> revisionsToUnhide = new List <ResourceBE>();
            List <ResourceBE> ret = new List <ResourceBE>();

            foreach (XDoc fileDoc in request["/revisions/file"])
            {
                ulong?id = fileDoc["@id"].AsULong;

                //Provided id of all file revision must match the file id
                if (id != null && id.Value != res.MetaXml.FileId)
                {
                    throw new MismatchedIdInvalidArgumentException();
                }

                int?revNum = fileDoc["@revision"].AsInt;
                if ((revNum ?? 0) <= 0)
                {
                    throw new RevisionInvalidArgumentException();
                }

                //Hiding the head revision is not allowed. Reasons include:
                //* Behavior of search indexing undefined
                //* Behavior of accessing HEAD revision is undefined
                if (revNum == res.ResourceHeadRevision)
                {
                    throw new HideHeadInvalidOperationException();
                }

                bool?hide = fileDoc["@hidden"].AsBool;
                if (hide == null)
                {
                    throw new HiddenAttributeInvalidArgumentException();
                }

                ResourceBE rev = _resourceBL.GetResourceRevision(res.ResourceId, revNum.Value);
                if (rev == null)
                {
                    throw new RevisionNotFoundInvalidArgumentException();
                }

                //Only allow hiding revisions with content changes
                if ((rev.ChangeMask & ResourceBE.ChangeOperations.CONTENT) != ResourceBE.ChangeOperations.CONTENT)
                {
                    throw new RevisionCannotBeHiddenConflictException();
                }

                if (hide.Value != rev.IsHidden)
                {
                    if (hide.Value)
                    {
                        revisionsToHide.Add(rev);
                    }
                    else
                    {
                        revisionsToUnhide.Add(rev);
                    }
                }
            }

            if (revisionsToUnhide.Count == 0 && revisionsToHide.Count == 0)
            {
                throw new NoRevisionToHideUnHideInvalidOperationException();
            }

            uint     currentUserId = _dekiContext.User.ID;
            DateTime currentTs     = DateTime.UtcNow;

            foreach (ResourceBE rev in revisionsToHide)
            {
                rev.IsHidden = true;
                rev.MetaXml.RevisionHiddenUserId    = currentUserId;
                rev.MetaXml.RevisionHiddenTimestamp = currentTs;
                rev.MetaXml.RevisionHiddenComment   = comment;
                ret.Add(_resourceBL.UpdateResourceRevision(rev));
            }

            if (revisionsToUnhide.Count > 0)
            {
                PermissionsBL.CheckUserAllowed(_dekiContext.User, Permissions.ADMIN);
            }

            foreach (ResourceBE rev in revisionsToUnhide)
            {
                rev.IsHidden = false;
                rev.MetaXml.RevisionHiddenUserId    = null;
                rev.MetaXml.RevisionHiddenTimestamp = null;
                rev.MetaXml.RevisionHiddenComment   = null;
                ret.Add(_resourceBL.UpdateResourceRevision(rev));
            }

            return(ret.ToArray());
        }