Inheritance: IIdentifiable
        public void Create_WithFeedbackItem_SetsDateCreatedAndModifiedToUtcNow()
        {
            // Arrange
            var now = DateTime.UtcNow;
            var sps = new Mock<StoredProcedures>("test");
            sps.Setup(s => s.InsertFeedback(It.IsAny<string>(),
                It.IsAny<string>(),
                It.IsAny<int>(),
                It.IsAny<int?>(),
                It.IsAny<string>(),
                It.IsAny<bool>(),
                It.IsAny<string>(),
                It.IsAny<string>(),
                It.IsAny<int>(),
                It.IsAny<int>(),
                It.IsAny<bool>(),
                It.IsAny<string>(),
                It.IsAny<string>(),
                It.IsAny<string>(),
                It.IsAny<string>(),
                It.IsAny<DateTime>(),
                It.IsAny<DateTime?>(),
                It.IsAny<DateTime>()));
            var repository = new DatabaseObjectProvider(blogId: 1, procedures: sps.Object);
            var feedback = new FeedbackItem(FeedbackType.Comment) { Body = "blah" };

            // Act
            repository.Create(feedback);

            // Assert
            Assert.GreaterEqualThan(DateTime.UtcNow, feedback.DateCreatedUtc);
            Assert.GreaterEqualThan(DateTime.UtcNow, feedback.DateModifiedUtc);
            Assert.GreaterEqualThan(feedback.DateCreatedUtc, now);
            Assert.GreaterEqualThan(feedback.DateModifiedUtc, now);
        }
        public void CreateSetsDateCreated()
        {
            //arrange
            var blog = new Mock<Blog>();
            DateTime dateCreatedUtc = DateTime.UtcNow;
            blog.Object.Id = 1;
            var entry = new Entry(PostType.BlogPost, blog.Object) { Id = 123, BlogId = 1, CommentingClosed = false };
            var repository = new Mock<ObjectRepository>();
            repository.Setup(r => r.GetEntry(It.IsAny<int>(), true, true)).Returns(entry);
            var context = new Mock<ISubtextContext>();
            context.SetupGet(c => c.Repository).Returns(repository.Object);
            context.SetupGet(c => c.Blog).Returns(blog.Object);
            context.SetupGet(c => c.HttpContext.Items).Returns(new Hashtable());
            context.SetupGet(c => c.Cache).Returns(new TestCache());

            var service = new CommentService(context.Object, null);
            var comment = new FeedbackItem(FeedbackType.Comment) { EntryId = 123, BlogId = 1, Body = "test", Title = "title" };

            //act
            service.Create(comment, true/*runFilters*/);

            //assert
            Assert.GreaterEqualThan(comment.DateCreatedUtc, dateCreatedUtc);
            Assert.GreaterEqualThan(DateTime.UtcNow, comment.DateCreatedUtc);
        }
Example #3
0
 /// <summary>
 /// Filters the comment. Throws an exception should the comment not be allowed. 
 /// Otherwise returns true.  This interface may be changed.
 /// </summary>
 /// <remarks>
 /// <p>
 /// The first filter examines whether comments are coming in too quickly 
 /// from the same SourceUrl.  Looks at the <see cref="BlogInfo.CommentDelayInMinutes"/>.
 /// </p>
 /// <p>
 /// The second filter checks for duplicate comments. It only looks at the body 
 /// of the comment.
 /// </p>
 /// </remarks>
 /// <param name="feedbackItem">Entry.</param>
 public void FilterAfterPersist(FeedbackItem feedbackItem)
 {
     if (!SecurityHelper.IsAdmin)
     {
         if (!Config.CurrentBlog.ModerationEnabled)
         {
             //Akismet Check...
             if (Config.CurrentBlog.FeedbackSpamServiceEnabled)
             {
                 if (Config.CurrentBlog.FeedbackSpamService.IsSpam(feedbackItem))
                 {
                     FlagAsSpam(feedbackItem);
                     return;
                 }
             }
             //Note, we need to explicitely set the status flag here.
             //Just setting Approved = true would not reset any other bits in the flag that may be set.
             feedbackItem.Status = FeedbackStatusFlag.Approved;
         }
         else //Moderated!
         {
             //Note, we need to explicitely set the status flag here.
             //Just setting NeedsModeration = true would not reset any other bits in the flag that may be set.
             feedbackItem.Status = FeedbackStatusFlag.NeedsModeration;
         }
     }
     else
     {
         //Note, we need to explicitely set the status flag here.
         //Just setting Approved = true would not reset any other bits in the flag that may be set.
         feedbackItem.Status = FeedbackStatusFlag.Approved;
     }
     FeedbackItem.Update(feedbackItem);
 }
        public void CreateDoesNotChangeDateCreatedAndDateModifiedIfAlreadySpecified()
        {
            //arrange
            var blog = new Mock<Blog>();
            DateTime dateCreated = DateTime.Now;
            blog.Object.Id = 1;
            blog.Setup(b => b.TimeZone.Now).Returns(dateCreated);
            var entry = new Entry(PostType.BlogPost, blog.Object) {Id = 123, BlogId = 1, CommentingClosed = false};
            var repository = new Mock<ObjectProvider>();
            repository.Setup(r => r.GetEntry(It.IsAny<int>(), true, true)).Returns(entry);
            var context = new Mock<ISubtextContext>();
            context.SetupGet(c => c.Repository).Returns(repository.Object);
            context.SetupGet(c => c.Blog).Returns(blog.Object);
            context.SetupGet(c => c.HttpContext.Items).Returns(new Hashtable());
            context.SetupGet(c => c.Cache).Returns(new TestCache());

            var service = new CommentService(context.Object, null);
            var comment = new FeedbackItem(FeedbackType.Comment)
            {
                EntryId = 123,
                BlogId = 1,
                Body = "test",
                Title = "title",
                DateCreated = dateCreated.AddDays(-2),
                DateModified = dateCreated.AddDays(-1)
            };

            //act
            service.Create(comment, true/*runFilters*/);

            //assert
            Assert.AreEqual(dateCreated.AddDays(-2), comment.DateCreated);
            Assert.AreEqual(dateCreated.AddDays(-1), comment.DateModified);
        }
        public override int Create(FeedbackItem feedbackItem)
        {
            if (feedbackItem == null)
                throw new ArgumentNullException("feedbackItem");

            string ipAddress = null;
            if (feedbackItem.IpAddress != null)
                ipAddress = feedbackItem.IpAddress.ToString();

            string sourceUrl = null;
            if (feedbackItem.SourceUrl != null)
                sourceUrl = feedbackItem.SourceUrl.ToString();

            return _procedures.InsertFeedback(feedbackItem.Title,
                feedbackItem.Body,
                BlogId,
                feedbackItem.EntryId.NullIfMinValue(),
                feedbackItem.Author,
                feedbackItem.IsBlogAuthor,
                feedbackItem.Email,
                sourceUrl,
                (int)feedbackItem.FeedbackType,
                (int)feedbackItem.Status,
                feedbackItem.CreatedViaCommentApi,
                feedbackItem.Referrer,
                ipAddress,
                feedbackItem.UserAgent,
                feedbackItem.ChecksumHash,
                feedbackItem.DateCreated,
                feedbackItem.DateModified,
                CurrentDateTime);
        }
Example #6
0
        /// <summary>
        /// Enables processing of HTTP Web requests by a custom HttpHandler that implements the <see cref="T:System.Web.IHttpHandler"></see> interface.
        /// </summary>
        /// <param name="context">An <see cref="T:System.Web.HttpContext"></see> object that provides references to the intrinsic server objects (for example, Request, Response, Session, and Server) used to service HTTP requests.</param>
        public void ProcessRequest(HttpContext context)
        {
            HttpRequest Request = context.Request;
            if(Request.RequestType == "POST" && Request.ContentType == "text/xml")
            {
                XmlDocument doc = new XmlDocument();
                doc.Load(Request.InputStream);

                FeedbackItem comment = new FeedbackItem(FeedbackType.Comment);
                comment.CreatedViaCommentAPI = true;
                string name = doc.SelectSingleNode("//item/author").InnerText;
                if(name.IndexOf("<") != -1)
                {
                    name = name.Substring(0, name.IndexOf("<"));
                }
                comment.Author = name.Trim();
                comment.Body = doc.SelectSingleNode("//item/description").InnerText;
                comment.Title = doc.SelectSingleNode("//item/title").InnerText;
                comment.SourceUrl = HtmlHelper.CheckForUrl(doc.SelectSingleNode("//item/link").InnerText);
                comment.EntryId = UrlFormats.GetPostIDFromUrl(Request.Path);

                // [ 1644691 ] Closing comments didn't stop the CommentAPI
                if(!Subtext.Framework.Data.Cacher.GetEntry(comment.EntryId,CacheDuration.Medium).CommentingClosed)
                    FeedbackItem.Create(comment, new CommentFilter(HttpContext.Current.Cache));
            }
        }
Example #7
0
        public void EmailCommentToBlogAuthor_WithBlog_UsesBlogEmailForToEmail()
        {
            //arrange
            var comment = new FeedbackItem(FeedbackType.Comment)
            {Id = 121, Author = "me", Title = "the subject", FlaggedAsSpam = false};
            var emailProvider = new Mock<EmailProvider>();
            var templateEngine = new Mock<ITemplateEngine>();
            var template = new Mock<ITextTemplate>();
            templateEngine.Setup(t => t.GetTemplate(It.IsAny<string>())).Returns(template.Object);
            template.Setup(t => t.Format(It.IsAny<object>())).Returns("message");
            var urlHelper = new Mock<BlogUrlHelper>();
            urlHelper.Setup(u => u.FeedbackUrl(comment)).Returns("/");
            var context = new Mock<ISubtextContext>();
            context.Setup(c => c.UrlHelper).Returns(urlHelper.Object);
            context.Setup(c => c.Blog).Returns(new Blog
            {Email = "*****@*****.**", Author = "to", Host = "localhost", Title = "the blog"});

            string toEmail = null;
            emailProvider.Setup(
                e => e.Send(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>())).Callback
                <string, string, string, string>((to, from, title, message) => toEmail = to);
            var emailService = new EmailService(emailProvider.Object, templateEngine.Object, context.Object);

            //act
            emailService.EmailCommentToBlogAuthor(comment);

            //assert
            Assert.AreEqual("*****@*****.**", toEmail);
        }
Example #8
0
        public void FeedbackCreateCallsCommentService(bool isSpam, bool isAdmin)
        {
            Assert.IsTrue(Config.CreateBlog("", "username", "password", _hostName, string.Empty));
            MockRepository mocks = new MockRepository();
            IFeedbackSpamService service = (IFeedbackSpamService)mocks.CreateMock(typeof(IFeedbackSpamService));
            Config.CurrentBlog.FeedbackSpamService = service;
            Config.CurrentBlog.DuplicateCommentsEnabled = true;
            Config.CurrentBlog.FeedbackSpamServiceKey = "my-secret-key";
            Config.CurrentBlog.ModerationEnabled = false;
            FeedbackItem feedback = new FeedbackItem(FeedbackType.Comment);
            Expect.Call(service.IsSpam(feedback)).Return(isSpam);
            feedback.Title = "blah";
            feedback.Body = UnitTestHelper.GenerateRandomString();
            mocks.ReplayAll();

            Assert.AreEqual(isAdmin, SecurityHelper.IsAdmin);

            try
            {
                FeedbackItem.Create(feedback, new CommentFilter(new Cache()));
            }
            catch(BaseCommentException)
            {
            }
            Assert.AreEqual(!isSpam, feedback.Approved);
        }
Example #9
0
        public int Create(FeedbackItem comment, bool runFilters)
        {
            Entry entry = Cacher.GetEntry(comment.EntryId, SubtextContext);
            if(entry != null && entry.CommentingClosed)
            {
                return NullValue.NullInt32;
            }

            ISubtextContext context = SubtextContext;
            HttpContextBase httpContext = context.HttpContext;

            if(httpContext != null && httpContext.Request != null)
            {
                comment.UserAgent = httpContext.Request.UserAgent;
                comment.IpAddress = HttpHelper.GetUserIpAddress(httpContext);
            }

            if(runFilters)
            {
                comment.FlaggedAsSpam = true; //We're going to start with this assumption.
            }
            comment.Author = HtmlHelper.SafeFormat(comment.Author, context.HttpContext.Server);
            comment.Body = HtmlHelper.ConvertUrlsToHyperLinks(HtmlHelper.ConvertToAllowedHtml(comment.Body));
            comment.Title = HtmlHelper.SafeFormat(comment.Title, context.HttpContext.Server);

            // If we are creating this feedback item as part of an import, we want to
            // be sure to use the item's datetime, and not set it to the current time.
            if(NullValue.NullDateTime.Equals(comment.DateCreated))
            {
                comment.DateCreated = context.Blog.TimeZone.Now;
                comment.DateModified = comment.DateCreated;
            }
            else if(NullValue.NullDateTime.Equals(comment.DateModified))
            {
                comment.DateModified = comment.DateCreated;
            }

            comment.Entry = entry;

            if(runFilters)
            {
                OnBeforeCreate(comment);
            }

            comment.Id = Repository.Create(comment);

            if(runFilters)
            {
                OnAfterCreate(comment);
            }

            return comment.Id;
        }
Example #10
0
        /// <summary>
        /// Confirms the feedback as spam and moves it to the trash.
        /// </summary>
        /// <param name="feedback">The feedback.</param>
        public static void Delete(this ObjectRepository repository, FeedbackItem feedback)
        {
            if (feedback == null)
            {
                throw new ArgumentNullException("feedback");
            }

            feedback.SetStatus(FeedbackStatusFlag.Approved, false);
            feedback.SetStatus(FeedbackStatusFlag.Deleted, true);

            repository.Update(feedback);
        }
Example #11
0
        public void EmailCommentToBlogAuthor_WithAuthor_SetsAuthorName()
        {
            //arrange
            var comment = new FeedbackItem(FeedbackType.Comment)
            {Id = 121, Author = "me", Title = "subject", Email = null};
            string sentMessage = null;
            EmailService emailService = SetupEmailService(comment, "{comment.author}", sent => sentMessage = sent);

            //act
            emailService.EmailCommentToBlogAuthor(comment);

            //assert
            Assert.AreEqual("me", sentMessage);
        }
Example #12
0
        public void CannotCreateDuplicateComments()
        {
            Assert.IsTrue(Config.CreateBlog("", "username", "password", _hostName, string.Empty));
            BlogInfo blog = Config.CurrentBlog;
            blog.CommentDelayInMinutes = 0;

            FeedbackItem feedbackItem = new FeedbackItem(FeedbackType.Comment);
            feedbackItem.DateCreated = DateTime.Now;
            feedbackItem.SourceUrl = new Uri("http://localhost/ThisUrl/");
            feedbackItem.Title = "Some Title";
            feedbackItem.Body = "Some Body";
            FeedbackItem.Create(feedbackItem, new CommentFilter(HttpContext.Current.Cache));
            FeedbackItem.Create(feedbackItem, new CommentFilter(HttpContext.Current.Cache));
        }
Example #13
0
        public void EmailCommentToBlogAuthor(FeedbackItem comment)
        {
            if(String.IsNullOrEmpty(Blog.Email)
               || comment.FeedbackType == FeedbackType.PingTrack
               || Context.User.IsAdministrator())
            {
                return;
            }

            string fromEmail = comment.Email;
            if(String.IsNullOrEmpty(fromEmail))
            {
                fromEmail = null;
            }

            var commentForTemplate = new
            {
                blog = Blog,
                comment = new
                {
                    author = comment.Author,
                    title = comment.Title,
                    source = Url.FeedbackUrl(comment).ToFullyQualifiedUrl(Blog),
                    email = fromEmail ?? "none given",
                    authorUrl = comment.SourceUrl,
                    ip = comment.IpAddress,
                    // we're sending plain text email by default, but body includes <br />s for crlf
                    body =
                        (comment.Body ?? string.Empty).Replace("<br />", Environment.NewLine).Replace("&lt;br /&gt;",
                                                                                                      Environment.
                                                                                                          NewLine)
                },
                spamFlag = comment.FlaggedAsSpam ? "Spam Flagged " : ""
            };

            ITextTemplate template = TemplateEngine.GetTemplate("CommentReceived");
            string message = template.Format(commentForTemplate);
            string subject = String.Format(CultureInfo.InvariantCulture, Resources.Email_CommentVia, comment.Title,
                                           Blog.Title);
            if(comment.FlaggedAsSpam)
            {
                subject = "[SPAM Flagged] " + subject;
            }
            string from = EmailProvider.UseCommentersEmailAsFromAddress
                              ? (fromEmail ?? EmailProvider.AdminEmail)
                              : EmailProvider.AdminEmail;

            EmailProvider.Send(Blog.Email, from, subject, message);
        }
        public void ConvertToAkismetItem_WithContactPageFeedback_DoesNotSetPermalink()
        {
            // arrange
            var feedback = new FeedbackItem(FeedbackType.ContactPage);
            var urlHelper = new Mock<BlogUrlHelper>();
            urlHelper.Setup(helper => helper.FeedbackUrl(It.IsAny<FeedbackItem>())).Returns((VirtualPath)null);
            urlHelper.Setup(helper => helper.BlogUrl()).Returns("/");
            var service = new AkismetSpamService("abracadabra", new Blog {Host = "localhost"}, null, urlHelper.Object);

            // act
            var comment = service.ConvertToAkismetItem(feedback);

            // assert
            Assert.IsNull(comment.Permalink);
        }
Example #15
0
        /// <summary>
        /// Approves the comment, and removes it from the SPAM folder or from the 
        /// Trash folder.
        /// </summary>
        /// <param name="feedback"></param>
        /// <param name="spamService"></param>
        /// <returns></returns>
        public static void Approve(this ObjectRepository repository, FeedbackItem feedback, ICommentSpamService spamService)
        {
            if (feedback == null)
            {
                throw new ArgumentNullException("feedback");
            }

            feedback.SetStatus(FeedbackStatusFlag.Approved, true);
            feedback.SetStatus(FeedbackStatusFlag.Deleted, false);
            if (spamService != null)
            {
                spamService.SubmitGoodFeedback(feedback);
            }

            repository.Update(feedback);
        }
Example #16
0
        public void EmailCommentToBlogAuthor_WithBlogHavingNullEmail_DoesNotSendEmail()
        {
            //arrange
            var comment = new FeedbackItem(FeedbackType.Comment) {};
            var blog = new Blog {Email = string.Empty};
            var emailProvider = new Mock<EmailProvider>();
            var context = new Mock<ISubtextContext>();
            context.Setup(c => c.UrlHelper).Returns(new Mock<BlogUrlHelper>().Object);
            context.Setup(c => c.Blog).Returns(blog);
            var emailService = new EmailService(emailProvider.Object, new Mock<ITemplateEngine>().Object, context.Object);
            emailProvider.Setup(
                e => e.Send(It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>(), It.IsAny<string>())).Throws(
                new Exception());

            //act
            emailService.EmailCommentToBlogAuthor(comment);
        }
        public void ConvertComment_WithDateCreated_ConvertsToUtc()
        {
            // arrange
            DateTime dateCreatedUtc = DateTime.ParseExact("2009/08/15 11:00 PM", "yyyy/MM/dd hh:mm tt", CultureInfo.InvariantCulture, DateTimeStyles.AdjustToUniversal).ToUniversalTime();
            var feedback = new FeedbackItem(FeedbackType.Comment)
            {
                DateCreatedUtc = dateCreatedUtc,
            };
            var subtextContext = new Mock<ISubtextContext>();
            var converter = new BlogMLExportMapper(subtextContext.Object);

            // act
            var comment = converter.ConvertComment(feedback);

            // assert
            Assert.AreEqual(dateCreatedUtc, comment.DateCreated);
        }
        public FeedbackAuthorViewModel(FeedbackItem comment)
        {
            IpAddress = comment.IpAddress;
            Name = HttpUtility.HtmlEncode(comment.Author);
            Url = HttpUtility.HtmlEncode(comment.SourceUrl);
            if (!string.IsNullOrEmpty(Url))
            {
                SetUrlLink();
            }

            if (!string.IsNullOrEmpty(comment.Email) && comment.Email.IndexOf("@") > 0)
            {
                Email = HttpUtility.HtmlEncode(comment.Email);
                FormattedEmail = "&lt;" + Email + "&gt;";
                SetMailTo(comment);
            }
        }
        public void Delete_WithEntryId_CallsDeleteEntryOnRepository()
        {
            // arrange
            var feedback = new FeedbackItem(FeedbackType.Comment) { Id = 123, Author = "Bugs" };
            var service = new Mock<ICommentService>();
            service.Setup(s => s.Get(123)).Returns(feedback);
            service.Setup(s => s.UpdateStatus(feedback, FeedbackStatusFlag.Deleted));
            var controller = new CommentController(service.Object);

            // act
            var result = controller.UpdateStatus(123, FeedbackStatusFlag.Deleted) as JsonResult;

            // assert
            service.Verify(c => c.UpdateStatus(feedback, FeedbackStatusFlag.Deleted));
            var data = new RouteValueDictionary(result.Data);
            Assert.AreEqual("Comment by Bugs", data["subject"]);
            Assert.AreEqual("has been removed", data["predicate"]);
        }
        public void Destroy_WithEntryId_CallsDestroyFeedbackOnRepository()
        {
            // arrange
            var feedback = new FeedbackItem(FeedbackType.Comment) { Id = 123, Author = "Calvin"};
            var service = new Mock<ICommentService>();
            service.Setup(s => s.Get(123)).Returns(feedback);
            service.Setup(s => s.Destroy(123));
            var controller = new CommentController(service.Object);

            // act
            var result = controller.Destroy(123) as JsonResult;

            // assert
            service.Verify(c => c.Destroy(123));
            var data = new RouteValueDictionary(result.Data);
            Assert.AreEqual("Comment by Calvin", data["subject"]);
            Assert.AreEqual("was destroyed (there is no undo)", data["predicate"]);
        }
        public void ConvertToAkismetItem_WithFeedback_SetsProperties()
        {
            // arrange
            var feedback = new FeedbackItem(FeedbackType.ContactPage)
            {
                SourceUrl = new Uri("http://example.com/author-source")
            };
            var urlHelper = new Mock<BlogUrlHelper>();
            urlHelper.Setup(helper => helper.FeedbackUrl(It.IsAny<FeedbackItem>())).Returns("/foo");
            urlHelper.Setup(helper => helper.BlogUrl()).Returns("/");
            var service = new AkismetSpamService("abracadabra", new Blog { Host = "localhost" }, null, urlHelper.Object);

            // act
            var comment = service.ConvertToAkismetItem(feedback);

            // assert
            Assert.AreEqual("http://example.com/author-source", comment.AuthorUrl.ToString());
            Assert.AreEqual("http://localhost/foo", comment.Permalink.ToString());
        }
Example #22
0
        public int Create(FeedbackItem comment, bool runFilters)
        {
            Entry entry = Cacher.GetEntry(comment.EntryId, SubtextContext);
            if (entry != null && entry.CommentingClosed)
            {
                return NullValue.NullInt32;
            }

            ISubtextContext context = SubtextContext;
            HttpContextBase httpContext = context.HttpContext;

            if (httpContext != null && httpContext.Request != null)
            {
                comment.UserAgent = httpContext.Request.UserAgent;
                comment.IpAddress = HttpHelper.GetUserIpAddress(httpContext);
            }

            if (runFilters)
            {
                comment.FlaggedAsSpam = true; //We're going to start with this assumption.
            }
            comment.Author = HtmlHelper.SafeFormat(comment.Author, context.HttpContext.Server);
            comment.Body = HtmlHelper.ConvertUrlsToHyperLinks(HtmlHelper.ConvertToAllowedHtml(comment.Body));
            comment.Title = HtmlHelper.SafeFormat(comment.Title, context.HttpContext.Server);
            comment.Entry = entry;
            comment.DateCreatedUtc = comment.DateCreatedUtc.IsNull() ? DateTime.UtcNow : comment.DateCreatedUtc;
            comment.DateModifiedUtc = comment.DateModifiedUtc.IsNull() ? DateTime.UtcNow : comment.DateModifiedUtc;

            if (runFilters)
            {
                OnBeforeCreate(comment);
            }

            comment.Id = Repository.Create(comment);

            if (runFilters)
            {
                OnAfterCreate(comment);
            }

            return comment.Id;
        }
        public void Create(int id, [ModelBinder(typeof(XmlModelBinder))] XmlDocument xml)
        {
            if (xml == null)
            {
                throw new ArgumentNullException("xml");
            }
            var comment = new FeedbackItem(FeedbackType.Comment) { CreatedViaCommentApi = true };

            string name = (xml.SelectSingleNode("//item/author") ?? Empty).InnerText;
            if (name.IndexOf("<") != -1)
            {
                name = name.Substring(0, name.IndexOf("<"));
            }
            comment.Author = name.Trim();
            comment.Body = (xml.SelectSingleNode("//item/description") ?? Empty).InnerText;
            comment.Title = (xml.SelectSingleNode("//item/title") ?? Empty).InnerText;
            comment.SourceUrl = HtmlHelper.EnsureUrl((xml.SelectSingleNode("//item/link") ?? Empty).InnerText);
            comment.EntryId = id;
            CommentService.Create(comment, true/*runFilters*/);
        }
Example #24
0
        public void CannotCreateMoreThanOneCommentWithinDelay()
        {
            Assert.IsTrue(Config.CreateBlog("", "username", "password", _hostName, string.Empty));
            BlogInfo blog = Config.CurrentBlog;
            blog.CommentDelayInMinutes = 1;

            FeedbackItem trackback = new FeedbackItem(FeedbackType.PingTrack);
            trackback.DateCreated = DateTime.Now;
            trackback.SourceUrl = new Uri("http://localhost/ThisUrl/");
            trackback.Title = "Some Title";
            trackback.Body = "Some Body Some Body";
            FeedbackItem.Create(trackback, new CommentFilter(HttpContext.Current.Cache));

            Thread.Sleep(100);

            FeedbackItem comment = new FeedbackItem(FeedbackType.Comment);
            comment.DateCreated = DateTime.Now;
            comment.SourceUrl = new Uri("http://localhost/ThisUrl/");
            comment.Title = "Some Title";
            comment.Body = "Some Body Else";
            FeedbackItem.Create(comment, new CommentFilter(HttpContext.Current.Cache));
        }
Example #25
0
        public void FilterAfterPersistWithCommentModerationDisabledCausesNewCommentsToBeActive()
        {
            //arrange
            var subtextContext = new Mock<ISubtextContext>();
            var cache = new TestCache();
            subtextContext.Setup(c => c.Cache).Returns(cache);
            subtextContext.Setup(c => c.User.IsInRole("Admins")).Returns(false);
            subtextContext.Setup(c => c.Blog).Returns(new Blog { ModerationEnabled = false });
            FeedbackItem savedFeedback = null;
            subtextContext.Setup(c => c.Repository.UpdateInternal(It.IsAny<FeedbackItem>())).Callback<FeedbackItem>(
                f => savedFeedback = f);

            var commentSpamFilter = new Mock<ICommentSpamService>();
            var commentFilter = new CommentFilter(subtextContext.Object, commentSpamFilter.Object);
            var feedback = new FeedbackItem(FeedbackType.Comment) { };
            Assert.IsFalse(feedback.Approved);

            //act
            commentFilter.FilterAfterPersist(feedback);

            //assert
            Assert.IsTrue(savedFeedback.Approved);
        }
Example #26
0
        public Comment ConvertToAkismetItem(FeedbackItem feedback)
        {
            var comment = new Comment(feedback.IpAddress, feedback.UserAgent) { Author = feedback.Author ?? string.Empty, AuthorEmail = feedback.Email };
            if (feedback.SourceUrl != null)
            {
                comment.AuthorUrl = feedback.SourceUrl;
            }
            comment.Content = feedback.Body;
            comment.Referrer = feedback.Referrer;

            var feedbackUrl = _urlHelper.FeedbackUrl(feedback);
            if (feedbackUrl != null)
            {
                Uri permalink = feedbackUrl.ToFullyQualifiedUrl(_blog);
                if (permalink != null)
                {
                    comment.Permalink = permalink;
                }
            }

            comment.CommentType = feedback.FeedbackType.ToString().ToLower(CultureInfo.InvariantCulture);
            return comment;
        }
Example #27
0
        // Returns true if the source of the entry is not
        // posting too many.
        bool SourceFrequencyIsValid(FeedbackItem feedbackItem)
        {
            if (Blog.CommentDelayInMinutes <= 0)
            {
                return true;
            }

            object lastComment = Cache[FilterCacheKey + feedbackItem.IpAddress];

            if (lastComment != null)
            {
                //Comment was made too frequently.
                return false;
            }

            //Add to cache.
            Cache.Insert(FilterCacheKey + feedbackItem.IpAddress, string.Empty, null, DateTime.UtcNow.AddMinutes(Blog.CommentDelayInMinutes), TimeSpan.Zero);

            return true;
        }
Example #28
0
        // Returns true if this entry is a duplicate.
        bool IsDuplicateComment(FeedbackItem feedbackItem)
        {
            const int recentEntryCapacity = 10;

            if (Cache == null)
            {
                return false;
            }

            // Check the cache for the last 10 comments
            // Chances are, if a spam attack is occurring, then
            // this entry will be a duplicate of a recent entry.
            // This checks in memory before going to the database (or other persistent store).
            var recentCommentChecksums = Cache[FilterCacheKey + ".RECENT_COMMENTS"] as Queue<string>;
            if (recentCommentChecksums != null)
            {
                if (recentCommentChecksums.Contains(feedbackItem.ChecksumHash))
                {
                    return true;
                }
            }
            else
            {
                recentCommentChecksums = new Queue<string>(recentEntryCapacity);
                Cache[FilterCacheKey + ".RECENT_COMMENTS"] = recentCommentChecksums;
            }

            // Check the database
            FeedbackItem duplicate = SubtextContext.Repository.GetFeedbackByChecksumHash(feedbackItem.ChecksumHash);
            if (duplicate != null)
            {
                return true;
            }

            //Ok, this is not a duplicate... Update recent comments.
            if (recentCommentChecksums.Count == recentEntryCapacity)
            {
                recentCommentChecksums.Dequeue();
            }

            recentCommentChecksums.Enqueue(feedbackItem.ChecksumHash);
            return false;
        }
Example #29
0
 private void FlagAsSpam(FeedbackItem feedbackItem)
 {
     feedbackItem.FlaggedAsSpam = true;
     feedbackItem.Approved = false;
     SubtextContext.Repository.Update(feedbackItem);
 }
Example #30
0
        /// <summary>
        /// Validates the feedback before it has been persisted.
        /// </summary>
        /// <param name="feedback"></param>
        /// <exception type="CommentFrequencyException">Thrown if too many comments are received from the same source in a short period.</exception>
        /// <exception type="CommentDuplicateException">Thrown if the blog does not allow duplicate comments and too many are received in a short period of time.</exception>
        public void FilterBeforePersist(FeedbackItem feedback)
        {
            if (!SubtextContext.User.IsAdministrator())
            {
                if (!SourceFrequencyIsValid(feedback))
                {
                    throw new CommentFrequencyException(Blog.CommentDelayInMinutes);
                }

                if (!Blog.DuplicateCommentsEnabled && IsDuplicateComment(feedback))
                {
                    throw new CommentDuplicateException();
                }
            }
        }