public ActionResult Rules() { var ruleinfo = RuleDiscoveryProvider.GetDescriptions(Assembly.GetAssembly(typeof(VoatRuleContext))).Where(x => x.Enabled).Select(x => new RuleInformationWithOutcome(x)).OrderBy(x => x.Info.Rule.Number).ToList(); RuleOutcome unevaluated = new RuleOutcome(RuleResult.Unevaluated, "UnevaluatedRule", "0.0", "This rule is unevaluated."); if (User.Identity.IsAuthenticated) { var context = new VoatRuleContext(User); //run every rule we can for the current user foreach (var rule in VoatRulesEngine.Instance.Rules) { var info = ruleinfo.FirstOrDefault(x => x.Info.Rule.Name == rule.Name && x.Info.Rule.Number == rule.Number); if (info != null) { RuleOutcome outcome = null; if (((Rule <VoatRuleContext>)rule).TryEvaluate(context, out outcome)) { info.Outcome = outcome; } else { info.Outcome = unevaluated; } } } } return(View("Rules", ruleinfo)); }
protected override RuleOutcome EvaluateRule(VoatRuleContext context) { //// if user CCP or SCP is less than -10, allow only X submissions per 24 hours //if (result != null && (context.UserData.Information.CommentPoints.Sum <= -10 || context.UserData.Information.SubmissionPoints.Sum <= -10) // && UserHelper.UserDailyPostingQuotaForNegativeScoreUsed(context.UserName)) //{ // result = CreateOutcome(RuleResult.Denied, String.Format("You have reached your daily submission quota. Your current quota is {0} submission(s) per 24 hours", VoatSettings.Instance.DailyPostingQuotaForNegativeScore)); //} int postThreshold = VoatSettings.Instance.DailyPostingQuotaForNegativeScore; //var isModerator = context.UserData.Information.Moderates.Any(x => x == context.Subverse.Name); var userData = context.UserData; var userInfo = userData.Information; if (userInfo.CommentPoints.Sum <= base.MinimumCommentPoints && userData.TotalSubmissionsPostedIn24Hours >= postThreshold) { return(CreateOutcome(RuleResult.Denied, "An Account with a CCP value of {0} is limited to {1} posts(s) in 24 hours", userInfo.CommentPoints.Sum, postThreshold)); } if (userInfo.SubmissionPoints.Sum <= base.MinimumCommentPoints && userData.TotalSubmissionsPostedIn24Hours >= postThreshold) { return(CreateOutcome(RuleResult.Denied, "An Account with a SCP value of {0} is limited to {1} posts(s) in 24 hours", userInfo.SubmissionPoints.Sum, postThreshold)); } //less than zero turns off this check var minCCPForPost = VoatSettings.Instance.MinimumCommentPointsForSubmissionCreation; if (minCCPForPost != -1 && userInfo.CommentPoints.Sum < minCCPForPost) { return(CreateOutcome(RuleResult.Denied, $"An Account must have a minimum of {minCCPForPost} CCP to create a submission")); } return(base.EvaluateRule(context)); }
protected override RuleOutcome EvaluateRule(VoatRuleContext context) { UserSubmission submission = context.PropertyBag.UserSubmission; switch (submission.Type) { case SubmissionType.Link: Data.Models.Submission recentlySubmitted = null; using (var repo = new Repository()) { recentlySubmitted = repo.FindSubverseLinkSubmission(context.Subverse.Name, submission.Url, TimeSpan.FromDays(15)); } if (recentlySubmitted != null) { string url = VoatUrlFormatter.BuildUrlPath(null, new Common.PathOptions() { FullyQualified = true, ProvideProtocol = true }, $"v/{recentlySubmitted.Subverse}/{recentlySubmitted.ID}"); return(CreateOutcome(RuleResult.Denied, $"Sorry, this link has already been submitted recently. {url}")); } break; case SubmissionType.Text: //containsBannedDomain = BanningUtility.ContentContainsBannedDomain(context.Subverse.Name, submission.Content); break; } return(Allowed); }
protected override RuleOutcome EvaluateRule(VoatRuleContext context) { UserSubmission submission = context.PropertyBag.UserSubmission; switch (submission.Type) { case SubmissionType.Link: Data.Models.Submission recentlySubmitted = null; using (var repo = new Repository()) { recentlySubmitted = repo.FindSubverseLinkSubmission(context.Subverse.Name, submission.Url, TimeSpan.FromDays(15)); } if (recentlySubmitted != null) { return(CreateOutcome(RuleResult.Denied, $"Sorry, this link has already been submitted recently. https://voat.co/v/{recentlySubmitted.Subverse}/{recentlySubmitted.ID}")); } break; case SubmissionType.Text: //containsBannedDomain = BanningUtility.ContentContainsBannedDomain(context.Subverse.Name, submission.Content); break; } return(Allowed); }
protected override RuleOutcome EvaluateRule(VoatRuleContext context) { //bool isModerator = context.UserData.Information.Moderates.Any(x => x.Subverse.Equals(context.Subverse.Name, StringComparison.OrdinalIgnoreCase)); bool isModerator = ModeratorPermission.IsModerator(context.User, context.Subverse.Name, null); // check posting quotas if user is posting to subs they do not moderate if (!isModerator) { // reject if user has reached global daily submission quota if (UserDailyGlobalPostingQuotaUsed(context)) { return(CreateOutcome(RuleResult.Denied, "You have reached your daily global submission quota")); } // reject if user has reached global hourly submission quota if (UserHourlyGlobalPostingQuotaUsed(context)) { return(CreateOutcome(RuleResult.Denied, "You have reached your hourly global submission quota")); } // check if user has reached hourly posting quota for target subverse if (UserHourlyPostingQuotaForSubUsed(context, context.Subverse.Name)) { return(CreateOutcome(RuleResult.Denied, "You have reached your hourly submission quota for this subverse")); } // check if user has reached daily posting quota for target subverse if (UserDailyPostingQuotaForSubUsed(context, context.Subverse.Name)) { return(CreateOutcome(RuleResult.Denied, "You have reached your daily submission quota for this subverse")); } if (context.Subverse.IsAuthorizedOnly) { return(CreateOutcome(RuleResult.Denied, "You are not authorized to submit links or start discussions in this subverse. Please contact subverse moderators for authorization")); } } Domain.Models.UserSubmission userSubmission = context.PropertyBag.UserSubmission; if (userSubmission.Type == Domain.Models.SubmissionType.Link) { using (var repo = new Data.Repository()) { int crossPostCount = repo.FindUserLinkSubmissionCount(context.UserName, userSubmission.Url, TimeSpan.FromDays(1)); if (crossPostCount >= VoatSettings.Instance.DailyCrossPostingQuota) { return(CreateOutcome(RuleResult.Denied, "You have reached your daily crossposting quota for this Url")); } } //Old code //if (UserHelper.DailyCrossPostingQuotaUsed(userName, submissionModel.Content)) //{ // // ABORT // return ("You have reached your daily crossposting quota for this URL."); //} } return(Allowed); }
protected override RuleOutcome EvaluateRule(VoatRuleContext context) { if ((VoatSettings.Instance.RuntimeState & RuntimeStateSetting.Write) < 0) { return(CreateOutcome(RuleResult.Denied, "Runtime is in a ReadOnly state")); } return(Allowed); }
protected override RuleOutcome EvaluateRule(VoatRuleContext context) { if (context.UserName == "DerpyGuy") { return(CreateOutcome(RuleResult.Denied, "Your name is DerpyGuy")); } return(Allowed); }
protected override RuleOutcome EvaluateRule(VoatRuleContext context) { if (context.UserData.Information.CommentVoting.Sum < 0) { return(CreateOutcome(RuleResult.Denied, "Can not downvote more than you upvote")); } return(base.EvaluateRule(context)); }
protected override RuleOutcome EvaluateRule(VoatRuleContext context) { if (UserHelper.IsUserGloballyBanned(context.UserName)) { return(CreateOutcome(RuleResult.Denied, "User is globally banned")); } return(Allowed); }
protected override RuleOutcome EvaluateRule(VoatRuleContext context) { var submission = context.PropertyBag.Submission; if (submission.ArchiveDate != null) { return(CreateOutcome(RuleResult.Denied, "Archived Submissions do not allow new comments")); } return(Allowed); }
public void UpVoat_Submission_Allowed() { //rulesEngine.Context.PropertyBag.UserName = "******"; //rulesEngine.Context.PropertyBag.SubmissionID = 3; TestHelper.SetPrincipal("User50CCP"); var context = new VoatRuleContext(); context.PropertyBag.SubmissionID = 3;//A minCCP of 5000 is required in this comment sub var outcome = UnitTestRulesEngine.Instance.EvaluateRuleSet(context, RulesEngine.RuleScope.UpVoteSubmission, true); Assert.AreEqual(RuleResult.Allowed, outcome.Result); }
public void DownVoat_Submission_Denied_MinCCPInSubverse() { TestHelper.SetPrincipal("User100CCP"); var context = new VoatRuleContext(); context.PropertyBag.SubmissionID = 3; //A minCCP of 5000 is required in this comment sub var outcome = UnitTestRulesEngine.Instance.EvaluateRuleSet(context, RuleScope.DownVoteSubmission, RuleScope.DownVote, RuleScope.Vote); Assert.AreEqual(RuleResult.Denied, outcome.Result); Assert.AreEqual("2.4", outcome.RuleNumber); }
protected override RuleOutcome EvaluateRule(VoatRuleContext context) { var userName = context.UserName; if (!string.IsNullOrEmpty(userName)) { if (UserHelper.IsUserGloballyBanned(userName)) { return(CreateOutcome(RuleResult.Denied, "User is globally banned")); } } return(Allowed); }
protected override RuleOutcome EvaluateRule(VoatRuleContext context) { using (var repo = new Repository()) { int?existingVote = context.PropertyBag.CurrentVoteValue; if ((existingVote == null || existingVote.Value == 0) && repo.HasAddressVoted(context.PropertyBag.AddressHash, ContentType.Comment, context.CommentID.Value)) { return(CreateOutcome(RuleResult.Denied, "Vote has already been registered")); } } return(Allowed); }
public void DownVoat_Comment_Denied_MinCCPInSubverse() { TestHelper.SetPrincipal("User100CCP"); var context = new VoatRuleContext(); context.PropertyBag.CommentID = 5;//A minCCP of 5000 is required in this comment sub context.PropertyBag.AddressHash = IpHash.CreateHash("127.0.0.1"); var outcome = UnitTestRulesEngine.Instance.EvaluateRuleSet(context, RuleScope.DownVoteComment, RuleScope.DownVote, RuleScope.Vote); Assert.AreEqual(RuleResult.Denied, outcome.Result); Assert.AreEqual("2.4", outcome.RuleNumber); }
public void UpVoat_Comment_Allowed() { //rulesEngine.Context.PropertyBag.UserName = USERNAMES.User50CCP; //rulesEngine.Context.PropertyBag.CommentID = 1; var user = TestHelper.SetPrincipal(USERNAMES.User50CCP); var context = new VoatRuleContext(user); context.PropertyBag.CommentID = 1;//A minCCP of 5000 is required in this comment sub var outcome = UnitTestRulesEngine.Instance.EvaluateRuleSet(context, RulesEngine.RuleScope.UpVoteComment, true); Assert.AreEqual(RuleResult.Allowed, outcome.Result); }
protected override RuleOutcome EvaluateRule(VoatRuleContext context) { int dailyVotingQuota = VoatSettings.Instance.DailyVotingQuota; int dailyVotingQuotaScaledMinimum = VoatSettings.Instance.DailyVotingQuotaScaledMinimum; var userCCP = context.UserData.Information.CommentPoints.Sum; //TODO: Configure this scale in configuration file instead of hardcoding //if user has 20+ use scaled quota, else use 10 var scaledDailyVotingQuota = (userCCP >= 20 ? Math.Max(dailyVotingQuota, userCCP / 2) : dailyVotingQuotaScaledMinimum); var totalVotesUsedInPast24Hours = context.UserData.TotalVotesUsedIn24Hours; //see if they have a current vote on this item and only evaluate if they don't int?existingVote = context.PropertyBag.CurrentVoteValue; if ((existingVote == null || existingVote.Value == 0) && totalVotesUsedInPast24Hours >= scaledDailyVotingQuota) { return(CreateOutcome(RuleResult.Denied, "Vote limit exceeded based on CCP. Available votes per 24 hours: {0}", scaledDailyVotingQuota)); } //switch (context) //{ // case 1: // if (userCcp >= 20) // { // if (totalVotesUsedInPast24Hours < scaledDailyVotingQuota) // { // // perform upvoting or resetting // VotingComments.UpvoteComment(commentId, loggedInUser, IpHash.CreateHash(UserHelper.UserIpAddress(Request))); // } // } // else if (totalVotesUsedInPast24Hours < 11) // { // // perform upvoting or resetting even if user has no CCP but only allow 10 votes per 24 hours // VotingComments.UpvoteComment(commentId, loggedInUser, IpHash.CreateHash(UserHelper.UserIpAddress(Request))); // } // break; // case -1: // if (userCcp >= 100) // { // if (totalVotesUsedInPast24Hours < scaledDailyVotingQuota) // { // // perform downvoting or resetting // VotingComments.DownvoteComment(commentId, loggedInUser, IpHash.CreateHash(UserHelper.UserIpAddress(Request))); // } // } // break; //} return(base.EvaluateRule(context)); }
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); }
protected override RuleOutcome EvaluateRule(VoatRuleContext context) { Domain.Models.Submission submission = context.PropertyBag.Submission; if (submission.ArchiveDate != null) { return(CreateOutcome(RuleResult.Denied, "Archived Submissions do not allow voting")); } if (submission.IsDeleted) { return(CreateOutcome(RuleResult.Denied, "Deleted Submissions do not allow voting")); } return(base.EvaluateRule(context)); }
protected override RuleOutcome EvaluateRule(VoatRuleContext context) { var q = new QueryComment(context.CommentID.Value); var comment = q.Execute(); using (var repo = new Repository(context.User)) { var count = repo.VoteCount(context.UserName, comment.UserName, Domain.Models.ContentType.Comment, Domain.Models.VoteValue.Down, _timeSpan); if (count >= _threshold) { return(CreateOutcome(RuleResult.Denied, "You need a cooling down period")); } } return(base.EvaluateRule(context)); }
protected override RuleOutcome EvaluateRule(VoatRuleContext context) { var q = new QuerySubmission(context.SubmissionID.Value); var submission = q.Execute(); // do not execute downvoting if comment is older than 7 days var commentPostingDate = submission.CreationDate; TimeSpan timeElapsed = Repository.CurrentDate - commentPostingDate; if (timeElapsed.TotalDays > 7) { return(CreateOutcome(RuleResult.Denied, "Submission downvotes not registered after 7 days")); } return(base.EvaluateRule(context)); }
protected override RuleOutcome EvaluateRule(VoatRuleContext context) { Data.Models.Comment comment = context.PropertyBag.Comment; if (comment.IsDeleted) { return(base.CreateOutcome(RuleResult.Denied, "Deleted comments can not be edited")); } if (comment.UserName != context.UserName) { return(base.CreateOutcome(RuleResult.Denied, "User does not have permissions to perform requested action")); } //rules checkd in base class return(base.EvaluateRule(context)); }
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); }
protected override RuleOutcome EvaluateRule(VoatRuleContext context) { UserSubmission submission = context.PropertyBag.UserSubmission; //Check if content matches spam filters IEnumerable <FilterMatch> result = null; switch (submission.Type) { case SubmissionType.Link: result = FilterUtility.Match(String.Concat(submission.Title, " ", submission.Url)); break; case SubmissionType.Text: result = FilterUtility.Match(String.Concat(submission.Title, " ", submission.Content)); break; } if (result.Any()) { return(CreateOutcome(RuleResult.Denied, $"Submission does not pass filter: {result.First().Filter.Name}")); } return(Allowed); }
public async Task <CommandResponse <Domain.Models.Set> > CreateOrUpdateSet(Set set) { DemandAuthentication(); set.Name = set.Name.TrimSafe(); //Evaulate Rules var context = new VoatRuleContext(User); context.PropertyBag.Set = set; var outcome = VoatRulesEngine.Instance.EvaluateRuleSet(context, RuleScope.CreateSet); if (!outcome.IsAllowed) { return(MapRuleOutCome <Set>(outcome, null)); } var existingSet = _db.SubverseSet.FirstOrDefault(x => x.ID == set.ID); if (existingSet != null) { var perms = SetPermission.GetPermissions(existingSet.Map(), User.Identity); if (!perms.EditProperties) { return(CommandResponse.FromStatus <Set>(null, Status.Denied, "User does not have permission to edit this set")); } //HACK: Need to clear this entry out of cache if name changes and check name if (!existingSet.Name.IsEqual(set.Name)) { if (_db.SubverseSet.Any(x => x.Name.ToLower() == set.Name.ToLower() && x.UserName.ToLower() == UserName.ToLower())) { return(CommandResponse.FromStatus <Set>(null, Status.Denied, "A set with this name already exists")); } CacheHandler.Instance.Remove(CachingKey.Set(existingSet.Name, existingSet.UserName)); } existingSet.Name = set.Name; existingSet.Title = set.Title; existingSet.Description = set.Description; existingSet.IsPublic = set.IsPublic; await _db.SaveChangesAsync().ConfigureAwait(CONSTANTS.AWAIT_CAPTURE_CONTEXT); return(CommandResponse.FromStatus <Set>(existingSet.Map(), Status.Success)); } else { //Validation - MOVE TO RULES SYSTEM MAYBE if (!VoatSettings.Instance.SetCreationEnabled || VoatSettings.Instance.MaximumOwnedSets <= 0) { return(CommandResponse.FromStatus <Set>(null, Status.Denied, "Set creation is currently disabled")); } if (VoatSettings.Instance.MaximumOwnedSets > 0) { var d = new DapperQuery(); d.Select = $"SELECT COUNT(*) FROM {SqlFormatter.Table("SubverseSet", "subSet")}"; d.Where = "subSet.\"Type\" = @Type AND subSet.\"UserName\" = @UserName"; d.Parameters.Add("Type", (int)SetType.Normal); d.Parameters.Add("UserName", UserName); var setCount = _db.Connection.ExecuteScalar <int>(d.ToString(), d.Parameters); if (setCount >= VoatSettings.Instance.MaximumOwnedSets) { return(CommandResponse.FromStatus <Set>(null, Status.Denied, $"Sorry, Users are limited to {VoatSettings.Instance.MaximumOwnedSets} sets and you currently have {setCount}")); } } //Create new set try { var setCheck = GetSet(set.Name, UserName); if (setCheck != null) { return(CommandResponse.FromStatus <Set>(null, Status.Denied, "A set with same name and owner already exists")); } var newSet = new SubverseSet { Name = set.Name, Title = set.Title, Description = set.Description, UserName = UserName, Type = (int)SetType.Normal, IsPublic = set.IsPublic, CreationDate = Repository.CurrentDate, SubscriberCount = 1, //Owner is a subscriber. Reminds me of that hair club commercial: I"m not only the Set Owner, I'm also a subscriber. }; _db.SubverseSet.Add(newSet); await _db.SaveChangesAsync().ConfigureAwait(CONSTANTS.AWAIT_CAPTURE_CONTEXT); _db.SubverseSetSubscription.Add(new SubverseSetSubscription() { SubverseSetID = newSet.ID, UserName = UserName, CreationDate = CurrentDate }); await _db.SaveChangesAsync().ConfigureAwait(CONSTANTS.AWAIT_CAPTURE_CONTEXT); return(CommandResponse.Successful(newSet.Map())); } catch (Exception ex) { return(CommandResponse.Error <CommandResponse <Set> >(ex)); } } }
protected override RuleOutcome EvaluateRule(VoatRuleContext context) { var result = base.EvaluateRule(context); if (result.IsAllowed) { var subverse = context.Subverse; var userCcp = context.UserData.Information.CommentPoints.Sum; var userMembershipTimeSpan = Repository.CurrentDate.Subtract(context.UserData.Information.RegistrationDate); //TODO: Port UserHelper methods to Repository.UserCommentCount() // throttle comment posting if CCP is low, regardless of account age if (userCcp < 1) { var quotaUsed = UserDailyCommentPostingQuotaForNegativeScoreUsed(context); if (quotaUsed) { return(CreateOutcome(RuleResult.Denied, String.Format("You have reached your daily comment quota. Your current quota is {0} comment(s) per 24 hours.", Settings.DailyCommentPostingQuotaForNegativeScore.ToString()))); } } // if user account is new, allow max X comments per hour if (userMembershipTimeSpan.TotalDays < 7 && userCcp < 50) { var quotaUsed = UserHourlyCommentPostingQuotaUsed(context); if (quotaUsed) { return(CreateOutcome(RuleResult.Denied, String.Format("You have reached your hourly comment quota. Your current quota is {0} comment(s) per hour.", Settings.HourlyCommentPostingQuota.ToString()))); } } // if user CCP is < 10, allow only X comment submissions per 24 hours if (userMembershipTimeSpan.TotalDays < 7 && userCcp <= 10) { var quotaUsed = UserDailyCommentPostingQuotaUsed(context); if (quotaUsed) { return(CreateOutcome(RuleResult.Denied, String.Format("You have reached your daily comment quota. Your current quota is {0} comment(s) per 24 hours.", Settings.DailyCommentPostingQuota.ToString()))); } } //if (userCcp <= 0) //{ // var userMembershipTimeSpam = Repository.CurrentDate - context.UserData.Information.RegistrationDate; // // if user CCP is negative or account less than 6 months old, allow only x comment submissions per 24 hours // if ((userMembershipTimeSpam.TotalDays < 180 || userCcp <= -50) && UserHelper.UserDailyCommentPostingQuotaForNegativeScoreUsed(context.UserName)) // { // result = CreateOutcome(RuleResult.Denied, String.Format("You have reached your daily comment quota. Your current quota is {0} comment(s) per 24 hours.", Settings.DailyCommentPostingQuotaForNegativeScore.ToString())); // } //} } return(result); #region Original Logic //// 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); //var userCcp = Karma.CommentKarma(User.Identity.Name); //commentModel.IsAnonymized = submission.IsAnonymized || subverse.IsAnonymized; //// if user CCP is negative or account less than 6 months old, allow only x comment submissions per 24 hours //var userRegistrationDate = UserHelper.GetUserRegistrationDateTime(User.Identity.Name); //TimeSpan userMembershipTimeSpan = Repository.CurrentDate - userRegistrationDate; //// throttle comment posting if CCP is low, regardless of account age //if (userCcp < 1) //{ // 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."); // } //} //// if user account is new, allow max X comments per hour //if (userMembershipTimeSpan.TotalDays < 7 && userCcp < 50) //{ // var quotaUsed = UserHelper.UserHourlyCommentPostingQuotaUsed(User.Identity.Name); // if (quotaUsed) // { // return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "You have reached your hourly comment quota. Your current quota is " + Settings.HourlyCommentPostingQuota.ToString() + " comment(s) per hour."); // } //} //// if user CCP is < 10, allow only X comment submissions per 24 hours //if (userMembershipTimeSpan.TotalDays < 7 && userCcp <= 10) //{ // var quotaUsed = UserHelper.UserDailyCommentPostingQuotaUsed(User.Identity.Name); // if (quotaUsed) // { // return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "You have reached your daily comment quota. Your current quota is " + Settings.DailyCommentPostingQuota.ToString() + " comment(s) per 24 hours."); // } //} //PORTED //// check for copypasta //// TODO: use Levenshtein distance algo or similar for better results //var copyPasta = UserHelper.SimilarCommentSubmittedRecently(User.Identity.Name, commentModel.Content); //if (copyPasta) //{ // return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "You have recently submitted a similar comment. Please try to not use copy/paste so often."); //} //// 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)) //{ //PORTED // 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 = Voat.Utilities.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); //} //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); //} #endregion Original Logic }
protected override RuleOutcome EvaluateRule(VoatRuleContext context) { //rules checked in base common class return(base.EvaluateRule(context)); }
protected override RuleOutcome EvaluateRule(VoatRuleContext context) { UserSubmission userSubmission = context.PropertyBag.UserSubmission; if (userSubmission == null) { return(CreateOutcome(RuleResult.Denied, "The submission must not be null")); } if (String.IsNullOrEmpty(userSubmission.Subverse)) { return(CreateOutcome(RuleResult.Denied, "A subverse must be provided")); } switch (userSubmission.Type) { case SubmissionType.Link: if (String.IsNullOrEmpty(userSubmission.Url)) { return(CreateOutcome(RuleResult.Denied, "A link submission must include a url")); } //Ensure user isn't submitting links as titles if (userSubmission.Title.Equals(userSubmission.Url, StringComparison.InvariantCultureIgnoreCase) || userSubmission.Url.Contains(userSubmission.Title)) { return(CreateOutcome(RuleResult.Denied, "Submission title may not be the same as the URL you are trying to submit. Why would you even think about doing this?! Why?")); } // make sure the input URI is valid if (!UrlUtility.IsUriValid(userSubmission.Url)) { return(CreateOutcome(RuleResult.Denied, "The url you are trying to submit is invalid")); } break; case SubmissionType.Text: break; } if (String.IsNullOrEmpty(userSubmission.Title)) { return(CreateOutcome(RuleResult.Denied, "A text submission must include a title")); } if (Formatting.ContainsUnicode(userSubmission.Title)) { return(CreateOutcome(RuleResult.Denied, "Submission title can not contain Unicode or unprintable characters")); } int minTitleLength = 5; if (userSubmission.Title.Length < minTitleLength) { return(CreateOutcome(RuleResult.Denied, $"A title may not be less than {minTitleLength} characters")); } // make sure the title isn't a url if (UrlUtility.IsUriValid(userSubmission.Title)) { return(CreateOutcome(RuleResult.Denied, "Submission title is a url? Why would you even think about doing this?! Why?")); } //if context.Subverse is null this means that it can't be found/doesn't exist if (context.Subverse == null || userSubmission.Subverse.Equals("all", StringComparison.OrdinalIgnoreCase)) //<-- the all subverse actually exists? HA! (Putts: leaving this code in because it's rad) { return(CreateOutcome(RuleResult.Denied, "Subverse does not exist")); } //if (context.Subverse.IsAdminDisabled.HasValue && context.Subverse.IsAdminDisabled.Value) //{ // return CreateOutcome(RuleResult.Denied, "Submissions to disabled subverses are not allowed"); //} return(base.EvaluateRule(context)); }
protected override RuleOutcome EvaluateRule(VoatRuleContext context) { //base class will check for subverse and global bans here return(base.EvaluateRule(context)); }