protected override RuleOutcome EvaluateRule(VoatRuleContext context) { string content = context.PropertyBag.CommentContent; //Check banned domains in submission content var containsBannedDomain = BanningUtility.ContentContainsBannedDomain(context.Subverse.Name, content); if (containsBannedDomain) { return(CreateOutcome(RuleResult.Denied, "Comment contains banned domains")); } return(Allowed); }
public async Task <ActionResult> EditComment([Bind(Include = "ID, Content")] Comment commentModel) { if (ModelState.IsValid) { var existingComment = _db.Comments.Find(commentModel.ID); if (existingComment != null) { if (existingComment.UserName.Trim() == User.Identity.Name && !existingComment.IsDeleted) { bool containsBannedDomain = BanningUtility.ContentContainsBannedDomain(existingComment.Submission.Subverse, commentModel.Content); if (containsBannedDomain) { return(new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Comment contains links to banned domain(s).")); } existingComment.LastEditDate = DateTime.Now; existingComment.Content = commentModel.Content; if (ContentProcessor.Instance.HasStage(ProcessingStage.InboundPreSave)) { existingComment.Content = ContentProcessor.Instance.Process(existingComment.Content, ProcessingStage.InboundPreSave, existingComment); } //save fully formatted content var formattedComment = Formatting.FormatMessage(existingComment.Content); existingComment.FormattedContent = formattedComment; await _db.SaveChangesAsync(); if (ContentProcessor.Instance.HasStage(ProcessingStage.InboundPostSave)) { ContentProcessor.Instance.Process(existingComment.Content, ProcessingStage.InboundPostSave, existingComment); } //return the formatted comment so that it can replace the existing html comment which just got modified return(Json(new { response = formattedComment })); } return(Json("Unauthorized edit.", JsonRequestBehavior.AllowGet)); } } if (Request.IsAjaxRequest()) { return(new HttpStatusCodeResult(HttpStatusCode.BadRequest)); } return(Json("Unauthorized edit or comment not found - comment ID was.", JsonRequestBehavior.AllowGet)); }
protected override RuleOutcome EvaluateRule(VoatRuleContext context) { ChatMessage message = context.PropertyBag.ChatMessage; var currentDate = Data.Repository.CurrentDate; if (message == null) { return(CreateOutcome(RuleResult.Denied, "Rule needs chat message contexarstt")); } if (BanningUtility.ContentContainsBannedDomain(null, message.Message)) { return(CreateOutcome(RuleResult.Denied, "Content contains banned domain")); } var history = ChatHistory.History(message.RoomID); var historyArray = history.ToArray(); //Copy Pasta //check full history var duplicateFound = false; //duplicateFound = historyArray.Any(x => x.UserName == message.UserName && x.Message.IsEqual(message.Message.TrimSafe())); var lastMessage = historyArray.LastOrDefault(x => x.User.UserName == message.User.UserName); if (lastMessage != null) { duplicateFound = lastMessage.Message.IsEqual(message.Message.TrimSafe()); } if (duplicateFound) { return(CreateOutcome(RuleResult.Denied, "Chat message considered copy/paste spam")); } ////Spammer var countInWindow = historyArray.Count(x => x.User.UserName == message.User.UserName && currentDate.Subtract(x.CreationDate) <= _timeSpanWindow); if (countInWindow >= _count) { return(CreateOutcome(RuleResult.Denied, "Chat message considered spamming by user")); } return(base.EvaluateRule(context)); }
protected override RuleOutcome EvaluateRule(VoatRuleContext context) { UserSubmission submission = context.PropertyBag.UserSubmission; //Check banned domains in submission content var containsBannedDomain = false; switch (submission.Type) { case SubmissionType.Link: containsBannedDomain = BanningUtility.ContentContainsBannedDomain(context.Subverse.Name, $"{submission.Title} {submission.Url}"); break; case SubmissionType.Text: containsBannedDomain = BanningUtility.ContentContainsBannedDomain(context.Subverse.Name, $"{submission.Title} {submission.Content}"); break; } if (containsBannedDomain) { return(CreateOutcome(RuleResult.Denied, "Submission contains banned domains")); } return(Allowed); }
public ActionResult Submit([Bind(Include = "Id,Votes,Name,Date,Type,Linkdescription,Title,Rank,MessageContent,Subverse")] Message message) { // abort if model state is invalid if (!ModelState.IsValid) { return(View()); } // save temp values for the view in case submission fails ViewBag.selectedSubverse = message.Subverse; ViewBag.message = message.MessageContent; ViewBag.title = message.Title; ViewBag.linkDescription = message.Linkdescription; // check if user is banned if (Utils.User.IsUserGloballyBanned(message.Name) || Utils.User.IsUserBannedFromSubverse(User.Identity.Name, message.Subverse)) { ViewBag.SelectedSubverse = message.Subverse; return(View("~/Views/Home/Comments.cshtml", message)); } // check if user has reached hourly posting quota for target subverse if (Utils.User.UserHourlyPostingQuotaForSubUsed(User.Identity.Name, message.Subverse)) { ModelState.AddModelError("", "You have reached your hourly submission quota for this subverse."); return(View()); } // check if user has reached daily posting quota for target subverse if (Utils.User.UserDailyPostingQuotaForSubUsed(User.Identity.Name, message.Subverse)) { ModelState.AddModelError("", "You have reached your daily submission quota for this subverse."); return(View()); } // verify recaptcha if user has less than 25 CCP var userCcp = Karma.CommentKarma(User.Identity.Name); if (userCcp < 25) { string encodedResponse = Request.Form["g-Recaptcha-Response"]; bool isCaptchaCodeValid = (ReCaptchaUtility.Validate(encodedResponse) == "True" ? true : false); if (!isCaptchaCodeValid) { ModelState.AddModelError("", "Incorrect recaptcha answer."); // TODO // SET PREVENT SPAM DELAY TO 0 return(View()); } } // if user CCP or SCP is less than -50, allow only X submissions per 24 hours var userScp = Karma.LinkKarma(User.Identity.Name); if (userCcp <= -50 || userScp <= -50) { var quotaUsed = Utils.User.UserDailyPostingQuotaForNegativeScoreUsed(User.Identity.Name); if (quotaUsed) { ModelState.AddModelError("", "You have reached your daily submission quota. Your current quota is " + Convert.ToInt32(ConfigurationManager.AppSettings["dailyPostingQuotaForNegativeScore"]) + " submission(s) per 24 hours."); return(View()); } } // abort if model state is invalid if (!ModelState.IsValid) { return(View("Submit")); } // check if subverse exists var targetSubverse = _db.Subverses.Find(message.Subverse.Trim()); if (targetSubverse == null || message.Subverse.Equals("all", StringComparison.OrdinalIgnoreCase)) { ModelState.AddModelError(string.Empty, "Sorry, The subverse you are trying to post to does not exist."); return(View("Submit")); } // check if subverse has "authorized_submitters_only" set and dissalow submission if user is not allowed submitter if (targetSubverse.authorized_submitters_only) { if (!Utils.User.IsUserSubverseModerator(User.Identity.Name, targetSubverse.name)) { // user is not a moderator, check if user is an administrator if (!Utils.User.IsUserSubverseAdmin(User.Identity.Name, targetSubverse.name)) { ModelState.AddModelError("", "You are not authorized to submit links or start discussions in this subverse. Please contact subverse moderators for authorization."); return(View("Submit")); } } } // everything was okay, process incoming submission // submission is a link post // generate a thumbnail if submission is a direct link to image or video if (message.Type == 2 && message.MessageContent != null && message.Linkdescription != null) { // strip unicode if title contains unicode if (Submissions.ContainsUnicode(message.Linkdescription)) { message.Linkdescription = Submissions.StripUnicode(message.Linkdescription); } // abort if title less than 10 characters if (message.Linkdescription.Length < 10) { ModelState.AddModelError(string.Empty, "Sorry, the title may not be less than 10 characters."); return(View("Submit")); } var domain = UrlUtility.GetDomainFromUri(message.MessageContent); // check if target subvere allows submissions from globally banned hostnames if (!targetSubverse.exclude_sitewide_bans) { // check if hostname is banned before accepting submission if (BanningUtility.IsHostnameBanned(domain)) { ModelState.AddModelError(string.Empty, "Sorry, the hostname you are trying to submit is banned."); return(View("Submit")); } } // check if same link was submitted before and deny submission var existingSubmission = _db.Messages.FirstOrDefault(s => s.MessageContent.Equals(message.MessageContent, StringComparison.OrdinalIgnoreCase) && s.Subverse.Equals(message.Subverse, StringComparison.OrdinalIgnoreCase)); // submission is a repost, discard it and inform the user if (existingSubmission != null) { ModelState.AddModelError(string.Empty, "Sorry, this link has already been submitted by someone else."); // todo: offer the option to repost after informing the user about it return(RedirectToRoute( "SubverseComments", new { controller = "Comment", action = "Comments", id = existingSubmission.Id, subversetoshow = existingSubmission.Subverse } )); } // check if user has reached daily crossposting quota if (Utils.User.DailyCrossPostingQuotaUsed(User.Identity.Name, message.MessageContent)) { ModelState.AddModelError("", "You have reached your daily crossposting quota for this URL."); return(View()); } // check if target subverse has thumbnails setting enabled before generating a thumbnail if (targetSubverse.enable_thumbnails) { // try to generate and assign a thumbnail to submission model message.Thumbnail = ThumbGenerator.ThumbnailFromSubmissionModel(message); } // flag the submission as anonymized if it was submitted to a subverse with active anonymized_mode if (targetSubverse.anonymized_mode) { message.Anonymized = true; } else { message.Name = User.Identity.Name; } // accept submission and save it to the database message.Subverse = targetSubverse.name; // grab server timestamp and modify submission timestamp to have posting time instead of "started writing submission" time message.Date = DateTime.Now; message.Likes = 1; _db.Messages.Add(message); // update last submission received date for target subverse targetSubverse.last_submission_received = DateTime.Now; _db.SaveChanges(); } else if (message.Type == 1 && message.Title != null) { // submission is a self post // strip unicode if message contains unicode if (Submissions.ContainsUnicode(message.Title)) { message.Title = Submissions.StripUnicode(message.Title); } // abort if title less than 10 characters if (message.Title.Length < 10) { ModelState.AddModelError(string.Empty, "Sorry, the the message title may not be less than 10 characters."); return(View("Submit")); } // accept submission and save it to the database // trim trailing blanks from subverse name if a user mistakenly types them message.Subverse = targetSubverse.name; // flag the submission as anonymized if it was submitted to a subverse with active anonymized_mode if (targetSubverse.anonymized_mode) { message.Anonymized = true; } else { message.Name = User.Identity.Name; } // grab server timestamp and modify submission timestamp to have posting time instead of "started writing submission" time message.Date = DateTime.Now; message.Likes = 1; _db.Messages.Add(message); // update last submission received date for target subverse targetSubverse.last_submission_received = DateTime.Now; if (ContentProcessor.Instance.HasStage(ProcessingStage.InboundPreSave)) { message.MessageContent = ContentProcessor.Instance.Process(message.MessageContent, ProcessingStage.InboundPreSave, message); } _db.SaveChanges(); if (ContentProcessor.Instance.HasStage(ProcessingStage.InboundPostSave)) { ContentProcessor.Instance.Process(message.MessageContent, ProcessingStage.InboundPostSave, message); } } return(RedirectToRoute( "SubverseComments", new { controller = "Comment", action = "Comments", id = message.Id, subversetoshow = message.Subverse } )); }
public async Task <ActionResult> Submit([Bind(Include = "Id,Votes,Name,Date,Type,Linkdescription,Title,Rank,MessageContent,Subverse")] Message message) { // check if user is banned if (Utils.User.IsUserBanned(message.Name)) { ViewBag.SelectedSubverse = message.Subverse; return(View("~/Views/Home/Comments.cshtml", message)); } // verify recaptcha if user has less than 25 CCP if (Karma.CommentKarma(User.Identity.Name) < 25) { const string captchaMessage = ""; var isCaptchaCodeValid = ReCaptchaUtility.GetCaptchaResponse(captchaMessage, Request); if (!isCaptchaCodeValid) { ModelState.AddModelError("", "Incorrect recaptcha answer."); return(View()); } } if (!ModelState.IsValid) { return(View()); } // check if subverse exists var targetSubverse = _db.Subverses.Find(message.Subverse.Trim()); if (targetSubverse != null && !message.Subverse.Equals("all", StringComparison.OrdinalIgnoreCase)) { // check if subverse has "authorized_submitters_only" set and dissalow submission if user is not allowed submitter if (targetSubverse.authorized_submitters_only) { if (!Utils.User.IsUserSubverseModerator(User.Identity.Name, targetSubverse.name)) { // user is not a moderator, check if user is an administrator if (!Utils.User.IsUserSubverseAdmin(User.Identity.Name, targetSubverse.name)) { ModelState.AddModelError("", "You are not authorized to submit links or start discussions in this subverse. Please contact subverse moderators for authorization."); return(View()); } } } // submission is a link post // generate a thumbnail if submission is a direct link to image or video if (message.Type == 2 && message.MessageContent != null && message.Linkdescription != null) { var domain = UrlUtility.GetDomainFromUri(message.MessageContent); // check if hostname is banned before accepting submission if (BanningUtility.IsHostnameBanned(domain)) { ModelState.AddModelError(string.Empty, "Sorry, the hostname you are trying to submit is banned."); return(View()); } // check if same link was submitted before and deny submission var existingSubmission = _db.Messages.FirstOrDefault(s => s.MessageContent.Equals(message.MessageContent, StringComparison.OrdinalIgnoreCase) && s.Subverse == message.Subverse); // submission is a repost, discard it and inform the user if (existingSubmission != null) { ModelState.AddModelError(string.Empty, "Sorry, this link has already been submitted by someone else."); // todo: offer the option to repost after informing the user about it return(RedirectToRoute( "SubverseComments", new { controller = "Comment", action = "Comments", id = existingSubmission.Id, subversetoshow = existingSubmission.Subverse } )); } // check if target subverse has thumbnails setting enabled before generating a thumbnail if (targetSubverse.enable_thumbnails) { // try to generate and assign a thumbnail to submission model message.Thumbnail = ThumbGenerator.ThumbnailFromSubmissionModel(message); } // flag the submission as anonymized if it was submitted to a subverse with active anonymized_mode if (targetSubverse.anonymized_mode) { message.Anonymized = true; } else { message.Name = User.Identity.Name; } // accept submission and save it to the database message.Subverse = targetSubverse.name; // grab server timestamp and modify submission timestamp to have posting time instead of "started writing submission" time message.Date = DateTime.Now; message.Likes = 1; _db.Messages.Add(message); // update last submission received date for target subverse targetSubverse.last_submission_received = DateTime.Now; await _db.SaveChangesAsync(); } else if (message.Type == 1 && message.Title != null) { // submission is a self post // accept submission and save it to the database // trim trailing blanks from subverse name if a user mistakenly types them message.Subverse = targetSubverse.name; // flag the submission as anonymized if it was submitted to a subverse with active anonymized_mode if (targetSubverse.anonymized_mode) { message.Anonymized = true; } else { message.Name = User.Identity.Name; } // grab server timestamp and modify submission timestamp to have posting time instead of "started writing submission" time message.Date = DateTime.Now; message.Likes = 1; _db.Messages.Add(message); // update last submission received date for target subverse targetSubverse.last_submission_received = DateTime.Now; if (ContentProcessor.Instance.HasStage(ProcessingStage.InboundPreSave)) { message.MessageContent = ContentProcessor.Instance.Process(message.MessageContent, ProcessingStage.InboundPreSave, message); } await _db.SaveChangesAsync(); if (ContentProcessor.Instance.HasStage(ProcessingStage.InboundPostSave)) { ContentProcessor.Instance.Process(message.MessageContent, ProcessingStage.InboundPostSave, message); } } return(RedirectToRoute( "SubverseComments", new { controller = "Comment", action = "Comments", id = message.Id, subversetoshow = message.Subverse } )); } ModelState.AddModelError(string.Empty, "Sorry, The subverse you are trying to post to does not exist."); return(View()); }
public async Task <ActionResult> Update(SubverseSettingsViewModel updatedModel) { try { if (!ModelState.IsValid) { SetNavigationViewModel(updatedModel.Name); return(View("~/Views/Subverses/Admin/SubverseSettings.cshtml", updatedModel)); } var existingSubverse = _db.Subverse.FirstOrDefault(x => x.Name.ToUpper() == updatedModel.Name.ToUpper()); // check if subverse exists before attempting to edit it if (existingSubverse != null) { SetNavigationViewModel(existingSubverse.Name); // check if user requesting edit is authorized to do so for current subverse if (!ModeratorPermission.HasPermission(User, updatedModel.Name, Domain.Models.ModeratorAction.ModifySettings)) { return(new EmptyResult()); } //check description for banned domains if (BanningUtility.ContentContainsBannedDomain(existingSubverse.Name, updatedModel.Description)) { ModelState.AddModelError(string.Empty, "Sorry, description text contains banned domains."); return(View("~/Views/Subverses/Admin/SubverseSettings.cshtml", updatedModel)); } //check sidebar for banned domains if (BanningUtility.ContentContainsBannedDomain(existingSubverse.Name, updatedModel.SideBar)) { ModelState.AddModelError(string.Empty, "Sorry, sidebar text contains banned domains."); return(View("~/Views/Subverses/Admin/SubverseSettings.cshtml", updatedModel)); } // TODO investigate if EntityState is applicable here and use that instead // db.Entry(updatedModel).State = EntityState.Modified; existingSubverse.Title = updatedModel.Title; existingSubverse.Description = updatedModel.Description; existingSubverse.SideBar = updatedModel.SideBar; //if (updatedModel.Stylesheet != null) //{ // if (updatedModel.Stylesheet.Length < 50001) // { // existingSubverse.Stylesheet = updatedModel.Stylesheet; // } // else // { // ModelState.AddModelError(string.Empty, "Sorry, custom CSS limit is set to 50000 characters."); // return View("~/Views/Subverses/Admin/SubverseSettings.cshtml", updatedModel); // } //} //else //{ // existingSubverse.Stylesheet = updatedModel.Stylesheet; //} existingSubverse.IsAdult = updatedModel.IsAdult; existingSubverse.IsThumbnailEnabled = updatedModel.IsThumbnailEnabled; existingSubverse.IsAuthorizedOnly = updatedModel.IsAuthorizedOnly; existingSubverse.ExcludeSitewideBans = updatedModel.ExcludeSitewideBans; //Only update if time lock has expired if (existingSubverse.LastUpdateDate == null || (Repository.CurrentDate.Subtract(existingSubverse.LastUpdateDate.Value) > TimeSpan.FromHours(VoatSettings.Instance.SubverseUpdateTimeLockInHours))) { existingSubverse.MinCCPForDownvote = updatedModel.MinCCPForDownvote; existingSubverse.IsPrivate = updatedModel.IsPrivate; } // these properties are currently not implemented but they can be saved and edited for future use //existingSubverse.Type = updatedModel.Type; //existingSubverse.SubmitLinkLabel = updatedModel.SubmitLinkLabel; //existingSubverse.SubmitPostLabel = updatedModel.SubmitPostLabel; //existingSubverse.SubmissionText = updatedModel.SubmissionText; //existingSubverse.IsDefaultAllowed = updatedModel.IsDefaultAllowed; //if (existingSubverse.IsAnonymized == true && updatedModel.IsAnonymized == false) //{ // ModelState.AddModelError(string.Empty, "Sorry, this subverse is permanently locked to anonymized mode."); // return View("~/Views/Subverses/Admin/SubverseSettings.cshtml", updatedModel); //} // only subverse owners should be able to convert a sub to anonymized mode if (ModeratorPermission.IsLevel(User, updatedModel.Name, Domain.Models.ModeratorLevel.Owner)) { existingSubverse.IsAnonymized = updatedModel.IsAnonymized; } existingSubverse.LastUpdateDate = Repository.CurrentDate; await _db.SaveChangesAsync(); //purge new minified CSS CacheHandler.Instance.Remove(CachingKey.SubverseStylesheet(existingSubverse.Name)); //purge subvere CacheHandler.Instance.Remove(CachingKey.Subverse(existingSubverse.Name)); // go back to this subverse return(RedirectToRoute(Models.ROUTE_NAMES.SUBVERSE_INDEX, new { subverse = updatedModel.Name })); // user was not authorized to commit the changes, drop attempt } ModelState.AddModelError(string.Empty, "Sorry, The subverse you are trying to edit does not exist."); return(View("~/Views/Subverses/Admin/SubverseSettings.cshtml", updatedModel)); } catch (Exception ex) { EventLogger.Instance.Log(ex); ModelState.AddModelError(string.Empty, "Something bad happened."); return(View("~/Views/Subverses/Admin/SubverseSettings.cshtml", updatedModel)); } }
public async Task <ActionResult> SubmitComment([Bind(Include = "ID, Content, SubmissionID, ParentID")] Comment commentModel) { commentModel.CreationDate = DateTime.Now; commentModel.UserName = User.Identity.Name; commentModel.Votes = 0; commentModel.UpCount = 0; if (ModelState.IsValid) { // flag the comment as anonymized if it was submitted to a sub which has active anonymized_mode var submission = DataCache.Submission.Retrieve(commentModel.SubmissionID.Value); var subverse = DataCache.Subverse.Retrieve(submission.Subverse); commentModel.IsAnonymized = submission.IsAnonymized || subverse.IsAnonymized; // if user CCP is < 50, allow only X comment submissions per 24 hours var userCcp = Karma.CommentKarma(User.Identity.Name); if (userCcp <= -50) { var quotaUsed = UserHelper.UserDailyCommentPostingQuotaForNegativeScoreUsed(User.Identity.Name); if (quotaUsed) { return(new HttpStatusCodeResult(HttpStatusCode.BadRequest, "You have reached your daily comment quota. Your current quota is " + Settings.DailyCommentPostingQuotaForNegativeScore.ToString() + " comment(s) per 24 hours.")); //ModelState.AddModelError("", "You have reached your daily comment quota. Your current quota is " + Settings.DailyCommentPostingQuotaForNegativeScore + " comment(s) per 24 hours."); //return View(); } } // check if author is banned, don't save the comment or send notifications if true if (!UserHelper.IsUserGloballyBanned(User.Identity.Name) && !UserHelper.IsUserBannedFromSubverse(User.Identity.Name, submission.Subverse)) { bool containsBannedDomain = BanningUtility.ContentContainsBannedDomain(subverse.Name, commentModel.Content); if (containsBannedDomain) { return(new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Comment contains links to banned domain(s).")); } if (ContentProcessor.Instance.HasStage(ProcessingStage.InboundPreSave)) { commentModel.Content = ContentProcessor.Instance.Process(commentModel.Content, ProcessingStage.InboundPreSave, commentModel); } //save fully formatted content var formattedComment = Formatting.FormatMessage(commentModel.Content); commentModel.FormattedContent = formattedComment; _db.Comments.Add(commentModel); await _db.SaveChangesAsync(); DataCache.CommentTree.AddCommentToTree(commentModel); if (ContentProcessor.Instance.HasStage(ProcessingStage.InboundPostSave)) { ContentProcessor.Instance.Process(commentModel.Content, ProcessingStage.InboundPostSave, commentModel); } // send comment reply notification to parent comment author if the comment is not a new root comment await NotificationManager.SendCommentNotification(commentModel, new Action <string>(recipient => { //get count of unread notifications int unreadNotifications = UserHelper.UnreadTotalNotificationsCount(recipient); // send SignalR realtime notification to recipient var hubContext = Microsoft.AspNet.SignalR.GlobalHost.ConnectionManager.GetHubContext <MessagingHub>(); hubContext.Clients.User(recipient).setNotificationsPending(unreadNotifications); }) ); } if (Request.IsAjaxRequest()) { var comment = commentModel; ViewBag.CommentId = comment.ID; //why? ViewBag.rootComment = comment.ParentID == null; //why? if (submission.IsAnonymized || subverse.IsAnonymized) { comment.UserName = comment.ID.ToString(CultureInfo.InvariantCulture); } var model = new CommentBucketViewModel(comment); return(PartialView("~/Views/Shared/Submissions/_SubmissionComment.cshtml", model)); //return new HttpStatusCodeResult(HttpStatusCode.OK); } if (Request.UrlReferrer != null) { var url = Request.UrlReferrer.AbsolutePath; return(Redirect(url)); } } if (Request.IsAjaxRequest()) { return(new HttpStatusCodeResult(HttpStatusCode.BadRequest)); } ModelState.AddModelError(String.Empty, "Sorry, you are either banned from this sub or doing that too fast. Please try again in 2 minutes."); return(View("~/Views/Help/SpeedyGonzales.cshtml")); }
public async Task <ActionResult> Submit([Bind(Include = "ID,Votes,Name,CreationDate,Type,LinkDescription,Title,Rank,Content,Subverse")] Submission submission) { // abort if model state is invalid if (!ModelState.IsValid) { return(View()); } // save temp values for the view in case submission fails ViewBag.selectedSubverse = submission.Subverse; ViewBag.message = submission.Content; ViewBag.title = submission.Title; ViewBag.linkDescription = submission.LinkDescription; // grab server timestamp and modify submission timestamp to have posting time instead of "started writing submission" time submission.CreationDate = DateTime.Now; // check if user is banned if (UserHelper.IsUserGloballyBanned(User.Identity.Name) || UserHelper.IsUserBannedFromSubverse(User.Identity.Name, submission.Subverse)) { ViewBag.SelectedSubverse = submission.Subverse; return(View("~/Views/Home/Comments.cshtml", submission)); } if (String.IsNullOrEmpty(submission.Subverse)) { ModelState.AddModelError(string.Empty, "Please enter a subverse."); return(View("Submit")); } // check if subverse exists var targetSubverse = _db.Subverses.Find(submission.Subverse.Trim()); if (targetSubverse == null || submission.Subverse.Equals("all", StringComparison.OrdinalIgnoreCase)) { ModelState.AddModelError(string.Empty, "Sorry, The subverse you are trying to post to does not exist."); return(View("Submit")); } //wrap captcha check in anon method as following method is in non UI dll var captchaCheck = new Func <HttpRequestBase, Task <bool> >(request => { return(ReCaptchaUtility.Validate(request)); }); // check if this submission is valid and good to go var preProcessCheckResult = await Submissions.PreAddSubmissionCheck(submission, Request, User.Identity.Name, targetSubverse, captchaCheck); if (preProcessCheckResult != null) { ModelState.AddModelError(string.Empty, preProcessCheckResult); return(View("Submit")); } // submission is a link post if (submission.Type == 2 && submission.Content != null && submission.LinkDescription != null) { // check if same link was submitted before and deny submission var existingSubmission = _db.Submissions.FirstOrDefault(s => s.Content.Equals(submission.Content, StringComparison.OrdinalIgnoreCase) && s.Subverse.Equals(submission.Subverse, StringComparison.OrdinalIgnoreCase)); // submission is a repost, discard it and inform the user if (existingSubmission != null) { ModelState.AddModelError(string.Empty, "Sorry, this link has already been submitted by someone else."); // todo: offer the option to repost after informing the user about it return(RedirectToRoute( "SubverseComments", new { controller = "Comment", action = "Comments", id = existingSubmission.ID, subversetoshow = existingSubmission.Subverse } )); } // process new link submission var addLinkSubmissionResult = await Submissions.AddNewSubmission(submission, targetSubverse, User.Identity.Name); if (addLinkSubmissionResult != null) { ModelState.AddModelError(string.Empty, addLinkSubmissionResult); return(View("Submit")); } // update last submission received date for target subverse targetSubverse.LastSubmissionDate = DateTime.Now; await _db.SaveChangesAsync(); } // submission is a message type submission else if (submission.Type == 1 && submission.Title != null) { var containsBannedDomain = BanningUtility.ContentContainsBannedDomain(targetSubverse.Name, submission.Content); if (containsBannedDomain) { ModelState.AddModelError(string.Empty, "Sorry, this post contains links to banned domains."); return(View("Submit")); } // process new message type submission var addMessageSubmissionResult = await Submissions.AddNewSubmission(submission, targetSubverse, User.Identity.Name); if (addMessageSubmissionResult != null) { ModelState.AddModelError(string.Empty, addMessageSubmissionResult); return(View("Submit")); } // update last submission received date for target subverse targetSubverse.LastSubmissionDate = DateTime.Now; await _db.SaveChangesAsync(); } // redirect to comments section of newly posted submission return(RedirectToRoute( "SubverseComments", new { controller = "Comment", action = "Comments", id = submission.ID, subversetoshow = submission.Subverse } )); }