/// <summary> /// Delete a comment. /// </summary> /// <param name="comment"></param> public void DeleteComment(Comment comment) { //using (NHTransactionScope tx = new NHTransactionScope()) //{ comment.ContentItem.Comments.Remove(comment); Repository<Comment>.Delete(comment); // tx.VoteCommit(); //} }
public bool CheckIfCommentIsDuplicate(Comment commentToCheck) { DetachedCriteria criteria = DetachedCriteria.For<Comment>() .Add(Restrictions.Eq("ContentItem", commentToCheck.ContentItem)) .Add(Restrictions.Eq("CommentText", commentToCheck.CommentText)) .SetProjection(Projections.Count("CommentId")); if (commentToCheck.CreatedBy != null) criteria.Add(Restrictions.Eq("CreatedBy", commentToCheck.CreatedBy)); else criteria.Add(Restrictions.Eq("Email", commentToCheck.Email)); ICriteria c = criteria.GetExecutableCriteria(Session); return Convert.ToInt64(c.UniqueResult()) > 0; }
public ActionResult SaveComment(string year, string month, string day, string name, string author, string email, string url, string comment, int comment_post_ID, bool captchaValid) { // TODO: use a ContactModel with AllowHtmlAttribute instead of ValidateInput(false) // if the captcha is disabled, set the captcha variable to true if (!Context.CurrentSite.EnableCaptchaForComments) { captchaValid = true; log.InfoFormat("PostController.SaveComment: WARNING: saving comment with CAPTCHA DISABLED for Site {0}!!", Context.CurrentSite.SiteId.ToString()); } // validation if (string.IsNullOrEmpty(author) || string.IsNullOrEmpty(email) || !Validation.IsEmail(email) || !captchaValid) return ViewError("", ThemeResource("Comment_Message_ValidationErrors")); try { Post post = contentItemService.GetById(comment_post_ID); // Check if post comments are already allowed if (!post.AllowComments) return ViewError("", ThemeResource("Comment_Message_Closed")); // Create a new comment Comment c = new Comment { ContentItem = post, Name = author, Email = email, Url = url, UserIp = Request.UserHostAddress, CommentText = comment, CreatedDate = DateTime.UtcNow }; // Check if the comment is duplicated (by the same author) if (commentService.CheckIfCommentIsDuplicate(c)) return ViewError("", ThemeResource("Comment_Message_DuplicateComment")); // Evaluate comment if valid for auto approval // this check if the comments contains spam or must be contained in the moderation queue // as set in the Site Settings c.Status = commentService.EvaluateComment(c); // add the new comment to the post post.Comments.Add(c); // save the post (and the comment in cascade) contentItemService.Save(post); // strange behavior: RedirectToAction give strange exception (no route found....) bah return new RedirectResult(GetAbsoluteUrl(post.GetContentUrl())); } catch (Exception ex) { log.Error("PostController.SaveComment", ex); return ViewError("", ThemeResource("Comment_Message_GenericError")); } }
public void ProcessRequest(HttpContext context) { ISiteService siteService = IoC.Resolve<ISiteService>(); IContentItemService<Post> contentItemService = IoC.Resolve<IContentItemService<Post>>(); ICommentService commentService = IoC.Resolve<ICommentService>(); Site currentSite = siteService.GetSiteByHostName(WebHelper.GetHostName()); // Allow only HTTP POST for pingbacks if (context.Request.HttpMethod != "POST") { log.Error("PingbackHandler Exception: the request MUST be with HTTP POST method!"); context.Response.StatusCode = 403; context.Response.End(); return; } if (currentSite == null) { log.ErrorFormat("PingbackHandler Exception: cannot retrieve current site [Request.Uri: {0}]", context.Request.Url.ToString()); context.Response.StatusCode = 500; context.Response.End(); return; } if (!currentSite.AllowPings) { context.Response.StatusCode = 404; context.Response.End(); return; } try { XmlDocument doc = RetrieveXmlDocument(context); XmlNodeList list = doc.SelectNodes("methodCall/params/param/value/string") ?? doc.SelectNodes("methodCall/params/param/value"); if (list != null) { string sourceUrl = list[0].InnerText.Trim(); string targetUrl = list[1].InnerText.Trim(); log.DebugFormat("PingbackHandler: sourceUrl = ", sourceUrl); log.DebugFormat("PingbackHandler: targetUrl = ", targetUrl); // Examine the source page ExamineSourcePage(sourceUrl, targetUrl); // Check if there is a ping link if (!sourceHasLink) { log.Debug("PingbackHandler: sourceHasLink = false. Exiting..."); context.Response.StatusCode = 404; context.Response.End(); return; } context.Response.ContentType = "text/xml"; Uri url = new Uri(targetUrl); string postUrl = url.Segments[url.Segments.Length - 1]; string[] routeSegment = new string[4]; // get the url witout the querystring string path = url.GetLeftPart(UriPartial.Path); // remove the authrity and split by slash string[] routes = path.Substring(url.GetLeftPart(UriPartial.Authority).Length).Split('/'); // the post url is in format "/{year}/{month}/{day}/{friendlyname}/" if (routes.Length < 4) { context.Response.StatusCode = 404; context.Response.End(); return; } int index2 = 0; for (int index = 0; index < routes.Length; index++) { if (!string.IsNullOrEmpty(routes[index])) { routeSegment[index2] = routes[index]; index2++; } } // last check: year, month and day must be integer int dummy; for (int index = 0; index < 3; index++) { if (!Int32.TryParse(routeSegment[index], out dummy)) { log.DebugFormat("PingbackHandler: routeSegment[{0}] = {1} is not int32", index.ToString(), routeSegment[index]); context.Response.StatusCode = 404; context.Response.End(); return; } } //PostDTO post = new PostService().GetByUrl(postUrl); Post post = contentItemService.GetPublishedByPublishedDateAndFriendlyName(currentSite, Convert.ToInt32(routeSegment[0]), Convert.ToInt32(routeSegment[1]), Convert.ToInt32(routeSegment[2]), routeSegment[3]); if (post != null && !post.AllowPings) { log.ErrorFormat("PingbackHandler: post is null or post.AllowPings == false [post is null = {0}, post.AllowPings = {1}]", (post == null).ToString(), post.AllowPings.ToString()); context.Response.StatusCode = 403; context.Response.End(); return; } if (post != null) { bool isFirstPing = commentService.IsFirstPing(post, CommentType.Pingback, url.ToString()); log.ErrorFormat("PingbackHandler: isFirstPing = ", isFirstPing.ToString()); if (isFirstPing) { Comment comment = new Comment { CommentText = title, ContentItem = post, Url = sourceUrl, UserIp = context.Request.UserHostAddress, UserAgent = context.Request.UserAgent, Type = CommentType.Pingback, Status = CommentStatus.Unapproved, CreatedDate = DateTime.Now.ToUniversalTime() }; commentService.SaveComment(comment); context.Response.Write(SUCCESS); log.Debug("PingbackHandler: New Pingback created!"); } else { SendError(context, 48, "The pingback has already been registered."); } } else { SendError(context, 32, "The specified target URI does not exist."); } } } catch (Exception e) { log.Error("PingbackHandler.ProcessRequest", e); } }
public CommentStatus EvaluateComment(Comment comment) { #region Check Max Links in comment text string regex = "<[Aa][^>]*[Hh][Rr][Ee][Ff]=['\"]([^\"'>]+)[^>]*>"; int matchesCount = Regex.Matches(comment.CommentText, regex).Count; if (matchesCount > comment.ContentItem.Site.MaxLinksInComments) return CommentStatus.Unapproved; #endregion #region Check Moderation Keys string moderationKeys = comment.ContentItem.Site.ModerationKeys; if (!string.IsNullOrEmpty(moderationKeys)) { foreach (string key in moderationKeys.Split('\n')) { if (string.IsNullOrEmpty(key)) continue; // check for moderation key in the Author Name, Email, Url, Comment text, IP if (!string.IsNullOrEmpty(comment.Name)) if (comment.Name.IndexOf(key, 0, StringComparison.InvariantCultureIgnoreCase) > -1) return CommentStatus.Unapproved; if (comment.Email.IndexOf(key, 0, StringComparison.InvariantCultureIgnoreCase) > -1) return CommentStatus.Unapproved; if (comment.Url.IndexOf(key, 0, StringComparison.InvariantCultureIgnoreCase) > -1) return CommentStatus.Unapproved; if (comment.CommentText.IndexOf(key, 0, StringComparison.InvariantCultureIgnoreCase) > -1) return CommentStatus.Unapproved; if (comment.UserIp.IndexOf(key, 0, StringComparison.InvariantCultureIgnoreCase) > -1) return CommentStatus.Unapproved; //if ( preg_match($pattern, $user_agent) ) return false; } } #endregion #region Check Blacklist Keys (indetify SPAM) string blacklistKeys = comment.ContentItem.Site.BlacklistKeys; if (!string.IsNullOrEmpty(blacklistKeys)) { foreach (string blackKey in blacklistKeys.Split('\n')) { if (string.IsNullOrEmpty(blackKey)) continue; // check for moderation key in the Author Name, Email, Url, Comment text, IP if (!string.IsNullOrEmpty(comment.Name)) if (comment.Name.IndexOf(blackKey, 0, StringComparison.InvariantCultureIgnoreCase) > -1) return CommentStatus.Spam; if (comment.Email.IndexOf(blackKey, 0, StringComparison.InvariantCultureIgnoreCase) > -1) return CommentStatus.Spam; if (comment.Url.IndexOf(blackKey, 0, StringComparison.InvariantCultureIgnoreCase) > -1) return CommentStatus.Spam; if (comment.CommentText.IndexOf(blackKey, 0, StringComparison.InvariantCultureIgnoreCase) > -1) return CommentStatus.Spam; if (comment.UserIp.IndexOf(blackKey, 0, StringComparison.InvariantCultureIgnoreCase) > -1) return CommentStatus.Spam; //if ( preg_match($pattern, $user_agent) ) return false; } } #endregion // if all is ok... return CommentStatus.Approved; }
public ActionResult SaveReply(int replyToCommentId, string replyContent) { // get the original comment to reply to Comment originalComment = commentService.GetById(replyToCommentId); try { // ensure the content is valid if (string.IsNullOrEmpty(replyContent)) { MessageModel noContentMessage = new MessageModel { Text = "Please type the content of the reply!", Icon = MessageModel.MessageIcon.Alert }; RegisterMessage(noContentMessage, true); return Index(null, string.Empty); } // get the comment post Post post = contentItemService.GetById(originalComment.ContentItem.Id); // Check if post comments are already allowed if (!post.AllowComments) { MessageModel commentsCloseMessage = new MessageModel { Text = "Sorry, comments are close on this post!", Icon = MessageModel.MessageIcon.Alert }; RegisterMessage(commentsCloseMessage, true); return Index(null, string.Empty); } // Create a new comment Comment comment = new Comment { ContentItem = post, Name = Context.CurrentUser.DisplayName, Email = Context.CurrentUser.Email, Url = Context.CurrentUser.WebSite, UserIp = Request.UserHostAddress, CommentText = replyContent.StripHtml(), CreatedDate = DateTime.UtcNow, CreatedBy = Context.CurrentUser }; // Check if the comment is duplicated (by the same author) if (commentService.CheckIfCommentIsDuplicate(comment)) { MessageModel duplicateCommentMessage = new MessageModel { Text = "It seems that you have already added this comment", Icon = MessageModel.MessageIcon.Alert }; RegisterMessage(duplicateCommentMessage, true); return Index(null, string.Empty); } // Evaluate comment if valid for auto approval // this check if the comments contains spam or must be contained in the moderation queue // as set in the Site Settings comment.Status = commentService.EvaluateComment(comment); // add the new comment to the post post.Comments.Add(comment); // save the post (and the comment in cascade) contentItemService.Save(post); MessageModel message = new MessageModel { Text = "Reply saved!", Icon = MessageModel.MessageIcon.Info }; RegisterMessage(message, true); } catch (Exception ex) { log.Error("AdminCommentController.SaveReply", ex); MessageModel message = new MessageModel { Text = GlobalResource("Message_GenericError"), Icon = MessageModel.MessageIcon.Alert }; RegisterMessage(message, true); } // Refresh the comments list return Index(null, string.Empty); }
public void ProcessRequest(HttpContext context) { ISiteService siteService = IoC.Resolve<ISiteService>(); IContentItemService<Post> contentItemService = IoC.Resolve<IContentItemService<Post>>(); ICommentService commentService = IoC.Resolve<ICommentService>(); Site currentSite = siteService.GetSiteByHostName(WebHelper.GetHostName()); // Allow only HTTP POST for pingbacks if (context.Request.HttpMethod != "POST") { log.Error("PingbackHandler Exception: the request MUST be with HTTP POST method!"); context.Response.StatusCode = 403; context.Response.End(); return; } if (currentSite == null) { log.ErrorFormat("TrackbackHandler Exception: cannot retrieve current site [Request.Uri: {0}]", context.Request.Url.ToString()); context.Response.StatusCode = 500; context.Response.End(); return; } if (!currentSite.AllowPings) { context.Response.StatusCode = 404; context.Response.End(); return; } string postId = context.Request.Params["id"]; string title = context.Request.Form["title"]; string excerpt = context.Request.Form["excerpt"]; string blogName = context.Request.Form["blog_name"]; string url = string.Empty; log.DebugFormat("TrackbackHandler: postId[{0}] title[{1}] excerpt[{2}] blogName[{3}] url[{4}]", postId, title, excerpt, blogName, url); if (!string.IsNullOrEmpty(context.Request.Params["url"])) url = context.Request.Params["url"].Split(',')[0]; Post post = null; if (!string.IsNullOrEmpty(title) && !string.IsNullOrEmpty(postId) && !string.IsNullOrEmpty(blogName) && postId.Length > 2) { //TraceService trackBackService = new TraceService(); //TrackBackRequestDTO trackBackRequest = null; Comment comment = null; bool isFirstPing = false; try { //post = new PostService().GetByID(postId.ToInt32()); post = contentItemService.GetById(Convert.ToInt32(postId)); string partialUrl = post.GetContentUrl(); string targetUrl = string.Concat(context.Request.Url.GetLeftPart(UriPartial.Authority), "/", partialUrl.StartsWith("~") || partialUrl.StartsWith("/") ? partialUrl.Substring(1) : partialUrl); // Examine the source page ExamineSourcePage(url, targetUrl); // Create a new Trackback comment = new Comment { CommentText = excerpt, ContentItem = post, Url = url, UserIp = context.Request.UserHostAddress, UserAgent = context.Request.UserAgent, Type = CommentType.Trackback, Status = CommentStatus.Unapproved, CreatedDate = DateTime.Now.ToUniversalTime() }; } catch (Exception ex) { log.Error("TrackbackHandler ProcessRequest", ex); } if (post != null && post.AllowPings) { try { isFirstPing = commentService.IsFirstPing(post, CommentType.Trackback, url.ToString()); log.DebugFormat("TrackbackHandler: isFirstPing = ", isFirstPing.ToString()); } catch (Exception ex) { log.Error("TrackbackHandler ProcessRequest", ex); } if (isFirstPing && sourceHasLink) { commentService.SaveComment(comment); log.Debug("TrackbackHandler: New Trackback created!"); context.Response.Write("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><response><error>0</error></response>"); context.Response.End(); } else if (!isFirstPing) { context.Response.Write("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><response><error>Trackback already registered</error></response>"); context.Response.End(); } else if (!sourceHasLink) { context.Response.Write("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><response><error>The source page does not link</error></response>"); context.Response.End(); } } else { log.ErrorFormat("TrackbackHandler: post is null or post.AllowPings == false [post is null = {0}, post.AllowPings = {1}]", (post == null).ToString(), post.AllowPings.ToString()); context.Response.Write("<?xml version=\"1.0\" encoding=\"iso-8859-1\"?><response><error>The source page does not link</error></response>"); context.Response.End(); } } else { log.Debug("TrackbackHandler: some parameters are null, exit."); context.Response.Redirect(context.Request.Url.GetLeftPart(UriPartial.Authority)); } }