// check if a given user has used his global daily posting quota public static bool UserDailyGlobalPostingQuotaUsed(string userName) { // only execute this check if user account is less than a month old and user SCP is less than 50 and user is not posting to a sub they own/moderate DateTime userRegistrationDateTime = GetUserRegistrationDateTime(userName); int memberInDays = (DateTime.Now - userRegistrationDateTime).Days; int userScp = Karma.LinkKarma(userName); if (memberInDays > 30 && userScp >= 50) { return(false); } // set starting date to 24 hours ago from now var fromDate = DateTime.Now.Add(new TimeSpan(0, -24, 0, 0, 0)); var toDate = DateTime.Now; // read daily global posting quota configuration parameter from web.config int dpqps = Settings.DailyGlobalPostingQuota; using (var db = new voatEntities()) { // check how many submission user made today var userSubmissionsToTargetSub = db.Submissions.Count(m => m.UserName.Equals(userName, StringComparison.OrdinalIgnoreCase) && m.CreationDate >= fromDate && m.CreationDate <= toDate); if (dpqps <= userSubmissionsToTargetSub) { return(true); } return(false); } }
// submit comment upvote public static void UpvoteComment(int commentId, string userWhichUpvoted, string clientIpHash) { int result = CheckIfVotedComment(userWhichUpvoted, commentId); using (voatEntities db = new voatEntities()) { Comment comment = db.Comments.Find(commentId); if (comment.Message.Anonymized) { // do not execute voting, subverse is in anonymized mode return; } switch (result) { // never voted before case 0: if (comment.Name != userWhichUpvoted) { // check if this IP already voted on the same comment, abort voting if true var ipVotedAlready = db.Commentvotingtrackers.Where(x => x.CommentId == commentId && x.ClientIpAddress == clientIpHash); if (ipVotedAlready.Any()) { return; } comment.Likes++; // register upvote var tmpVotingTracker = new Commentvotingtracker { CommentId = commentId, UserName = userWhichUpvoted, VoteStatus = 1, Timestamp = DateTime.Now, ClientIpAddress = clientIpHash }; db.Commentvotingtrackers.Add(tmpVotingTracker); db.SaveChanges(); Karma.UpdateUserCcp(comment.Name, 1); Voting.SendVoteNotification(comment.Name, "upvote"); } break; // downvoted before, turn downvote to upvote case -1: if (comment.Name != userWhichUpvoted) { comment.Likes++; comment.Dislikes--; // register Turn DownVote To UpVote var votingTracker = db.Commentvotingtrackers.FirstOrDefault(b => b.CommentId == commentId && b.UserName == userWhichUpvoted); if (votingTracker != null) { votingTracker.VoteStatus = 1; votingTracker.Timestamp = DateTime.Now; } db.SaveChanges(); Karma.UpdateUserCcp(comment.Name, 2); Voting.SendVoteNotification(comment.Name, "downtoupvote"); } break; // upvoted before, reset case 1: comment.Likes--; db.SaveChanges(); Karma.UpdateUserCcp(comment.Name, -1); Voting.SendVoteNotification(comment.Name, "downvote"); ResetCommentVote(userWhichUpvoted, commentId); break; } } }
// submit submission downvote public static void DownvoteComment(int commentId, string userWhichDownvoted, string clientIpHash) { int result = CheckIfVotedComment(userWhichDownvoted, commentId); using (voatEntities db = new voatEntities()) { Comment comment = db.Comments.Find(commentId); // do not execute downvoting, subverse is in anonymized mode if (comment.Message.Anonymized) { return; } // do not execute downvoting if user has insufficient CCP for target subverse if (Karma.CommentKarmaForSubverse(userWhichDownvoted, comment.Message.Subverse) < comment.Message.Subverses.minimumdownvoteccp) { return; } switch (result) { // never voted before case 0: { // this user is downvoting more than upvoting, don't register the downvote if (UserHelper.IsUserCommentVotingMeanie(userWhichDownvoted)) { return; } // check if this IP already voted on the same comment, abort voting if true var ipVotedAlready = db.Commentvotingtrackers.Where(x => x.CommentId == commentId && x.ClientIpAddress == clientIpHash); if (ipVotedAlready.Any()) { return; } comment.Dislikes++; // register downvote var tmpVotingTracker = new Commentvotingtracker { CommentId = commentId, UserName = userWhichDownvoted, VoteStatus = -1, Timestamp = DateTime.Now, ClientIpAddress = clientIpHash }; db.Commentvotingtrackers.Add(tmpVotingTracker); db.SaveChanges(); Karma.UpdateUserCcp(comment.Name, -1); Voting.SendVoteNotification(comment.Name, "downvote"); } break; // upvoted before, turn upvote to downvote case 1: { comment.Likes--; comment.Dislikes++; //register Turn DownVote To UpVote var votingTracker = db.Commentvotingtrackers.FirstOrDefault(b => b.CommentId == commentId && b.UserName == userWhichDownvoted); if (votingTracker != null) { votingTracker.VoteStatus = -1; votingTracker.Timestamp = DateTime.Now; } db.SaveChanges(); Karma.UpdateUserCcp(comment.Name, -2); Voting.SendVoteNotification(comment.Name, "uptodownvote"); } break; // downvoted before, reset case -1: comment.Dislikes--; db.SaveChanges(); Karma.UpdateUserCcp(comment.Name, 1); ResetCommentVote(userWhichDownvoted, commentId); Voting.SendVoteNotification(comment.Name, "upvote"); break; } } }
// various spam checks, to be replaced with new rule engine public static async Task <string> PreAddSubmissionCheck(Submission submissionModel, HttpRequestBase request, string userName, Subverse targetSubverse, Func <HttpRequestBase, Task <bool> > captchaValidator) { // TODO: reject if a submission with this title was posted in the last 60 minutes // check posting quotas if user is posting to subs they do not moderate if (!UserHelper.IsUserSubverseModerator(userName, submissionModel.Subverse)) { // reject if user has reached global daily submission quota if (UserHelper.UserDailyGlobalPostingQuotaUsed(userName)) { return("You have reached your daily global submission quota."); } // reject if user has reached global hourly submission quota if (UserHelper.UserHourlyGlobalPostingQuotaUsed(userName)) { return("You have reached your hourly global submission quota."); } // check if user has reached hourly posting quota for target subverse if (UserHelper.UserHourlyPostingQuotaForSubUsed(userName, submissionModel.Subverse)) { return("You have reached your hourly submission quota for this subverse."); } // check if user has reached daily posting quota for target subverse if (UserHelper.UserDailyPostingQuotaForSubUsed(userName, submissionModel.Subverse)) { return("You have reached your daily submission quota for this subverse."); } } // verify recaptcha if user has less than 25 CCP var userCcp = Karma.CommentKarma(userName); if (userCcp < 25) { bool isCaptchaCodeValid = await captchaValidator(request); if (!isCaptchaCodeValid) { // TODO: SET PREVENT SPAM DELAY TO 0 return("Incorrect recaptcha answer."); } } // if user CCP or SCP is less than -10, allow only X submissions per 24 hours var userScp = Karma.LinkKarma(userName); if (userCcp <= -10 || userScp <= -10) { var quotaUsed = UserHelper.UserDailyPostingQuotaForNegativeScoreUsed(userName); if (quotaUsed) { return("You have reached your daily submission quota. Your current quota is " + Settings.DailyPostingQuotaForNegativeScore + " submission(s) per 24 hours."); } } // check if subverse has "authorized_submitters_only" set and dissalow submission if user is not allowed submitter if (targetSubverse.IsAuthorizedOnly) { if (!UserHelper.IsUserSubverseModerator(userName, targetSubverse.Name)) { return("You are not authorized to submit links or start discussions in this subverse. Please contact subverse moderators for authorization."); } } // null is returned if all checks have passed return(null); }
// submit submission downvote public static void DownvoteSubmission(int submissionID, string userName, string clientIp) { //int result = CheckIfVoted(userWhichDownvoted, submissionId); using (var db = new voatEntities()) { Submission submission = db.Submissions.Find(submissionID); SubmissionVoteTracker previousVote = db.SubmissionVoteTrackers.Where(u => u.UserName == userName && u.SubmissionID == submissionID).FirstOrDefault(); // do not execute downvoting if subverse is in anonymized mode if (submission.IsAnonymized) { return; } // do not execute downvoting if submission is older than 7 days var submissionPostingDate = submission.CreationDate; TimeSpan timeElapsed = DateTime.Now - submissionPostingDate; if (timeElapsed.TotalDays > 7) { return; } // do not execute downvoting if user has insufficient CCP for target subverse if (Karma.CommentKarmaForSubverse(userName, submission.Subverse) < submission.Subverse1.MinCCPForDownvote) { return; } int result = (previousVote == null ? 0 : previousVote.VoteStatus.Value); switch (result) { // never voted before case 0: { // this user is downvoting more than upvoting, don't register the downvote if (UserHelper.IsUserCommentVotingMeanie(userName)) { return; } // check if this IP already voted on the same submission, abort voting if true var ipVotedAlready = db.SubmissionVoteTrackers.Where(x => x.SubmissionID == submissionID && x.IPAddress == clientIp); if (ipVotedAlready.Any()) { return; } submission.DownCount++; //calculate new ranks Ranking.RerankSubmission(submission); // register downvote var tmpVotingTracker = new SubmissionVoteTracker { SubmissionID = submissionID, UserName = userName, VoteStatus = -1, CreationDate = DateTime.Now, IPAddress = clientIp }; db.SubmissionVoteTrackers.Add(tmpVotingTracker); db.SaveChanges(); SendVoteNotification(submission.UserName, "downvote"); } break; // upvoted before, turn upvote to downvote case 1: { submission.UpCount--; submission.DownCount++; //calculate new ranks Ranking.RerankSubmission(submission); // register Turn DownVote To UpVote var votingTracker = db.SubmissionVoteTrackers.FirstOrDefault(b => b.SubmissionID == submissionID && b.UserName == userName); previousVote.VoteStatus = -1; previousVote.CreationDate = DateTime.Now; db.SaveChanges(); SendVoteNotification(submission.UserName, "uptodownvote"); } break; // downvoted before, reset case -1: { //ResetMessageVote(userName, submissionID); submission.DownCount--; //calculate new ranks Ranking.RerankSubmission(submission); db.SubmissionVoteTrackers.Remove(previousVote); db.SaveChanges(); SendVoteNotification(submission.UserName, "upvote"); } break; } } }
// submit submission upvote public static void UpvoteSubmission(int submissionId, string userWhichUpvoted, string clientIp) { // user account voting check int result = CheckIfVoted(userWhichUpvoted, submissionId); using (var db = new voatEntities()) { Message submission = db.Messages.Find(submissionId); if (submission.Anonymized) { // do not execute voting, subverse is in anonymized mode return; } switch (result) { // never voted before case 0: if (submission.Name != userWhichUpvoted) { // check if this IP already voted on the same submission, abort voting if true var ipVotedAlready = db.Votingtrackers.Where(x => x.MessageId == submissionId && x.ClientIpAddress == clientIp); if (ipVotedAlready.Any()) { return; } submission.Likes++; double currentScore = submission.Likes - submission.Dislikes; double submissionAge = Submissions.CalcSubmissionAgeDouble(submission.Date); double newRank = Ranking.CalculateNewRank(submission.Rank, submissionAge, currentScore); submission.Rank = newRank; // register upvote var tmpVotingTracker = new Votingtracker { MessageId = submissionId, UserName = userWhichUpvoted, VoteStatus = 1, Timestamp = DateTime.Now, ClientIpAddress = clientIp }; db.Votingtrackers.Add(tmpVotingTracker); db.SaveChanges(); Karma.UpdateUserScp(submission.Name, 1); SendVoteNotification(submission.Name, "upvote"); } break; // downvoted before, turn downvote to upvote case -1: if (submission.Name != userWhichUpvoted) { submission.Likes++; submission.Dislikes--; double currentScore = submission.Likes - submission.Dislikes; double submissionAge = Submissions.CalcSubmissionAgeDouble(submission.Date); double newRank = Ranking.CalculateNewRank(submission.Rank, submissionAge, currentScore); submission.Rank = newRank; // register Turn DownVote To UpVote var votingTracker = db.Votingtrackers.FirstOrDefault(b => b.MessageId == submissionId && b.UserName == userWhichUpvoted); if (votingTracker != null) { votingTracker.VoteStatus = 1; votingTracker.Timestamp = DateTime.Now; } db.SaveChanges(); Karma.UpdateUserScp(submission.Name, 2); SendVoteNotification(submission.Name, "downtoupvote"); } break; // upvoted before, reset case 1: { submission.Likes--; double currentScore = submission.Likes - submission.Dislikes; double submissionAge = Submissions.CalcSubmissionAgeDouble(submission.Date); double newRank = Ranking.CalculateNewRank(submission.Rank, submissionAge, currentScore); submission.Rank = newRank; db.SaveChanges(); Karma.UpdateUserScp(submission.Name, -1); ResetMessageVote(userWhichUpvoted, submissionId); SendVoteNotification(submission.Name, "downvote"); } break; } } }
// submit submission downvote public static void DownvoteSubmission(int submissionId, string userWhichDownvoted, string clientIp) { int result = CheckIfVoted(userWhichDownvoted, submissionId); using (var db = new voatEntities()) { Message submission = db.Messages.Find(submissionId); // do not execute downvoting if subverse is in anonymized mode if (submission.Anonymized) { return; } // do not execute downvoting if user has insufficient CCP for target subverse if (Karma.CommentKarmaForSubverse(userWhichDownvoted, submission.Subverse) < submission.Subverses.minimumdownvoteccp) { return; } switch (result) { // never voted before case 0: { // this user is downvoting more than upvoting, don't register the downvote if (UserHelper.IsUserCommentVotingMeanie(userWhichDownvoted)) { return; } // check if this IP already voted on the same submission, abort voting if true var ipVotedAlready = db.Votingtrackers.Where(x => x.MessageId == submissionId && x.ClientIpAddress == clientIp); if (ipVotedAlready.Any()) { return; } submission.Dislikes++; double currentScore = submission.Likes - submission.Dislikes; double submissionAge = Submissions.CalcSubmissionAgeDouble(submission.Date); double newRank = Ranking.CalculateNewRank(submission.Rank, submissionAge, currentScore); submission.Rank = newRank; // register downvote var tmpVotingTracker = new Votingtracker { MessageId = submissionId, UserName = userWhichDownvoted, VoteStatus = -1, Timestamp = DateTime.Now, ClientIpAddress = clientIp }; db.Votingtrackers.Add(tmpVotingTracker); db.SaveChanges(); Karma.UpdateUserScp(submission.Name, -1); SendVoteNotification(submission.Name, "downvote"); } break; // upvoted before, turn upvote to downvote case 1: { submission.Likes--; submission.Dislikes++; double currentScore = submission.Likes - submission.Dislikes; double submissionAge = Submissions.CalcSubmissionAgeDouble(submission.Date); double newRank = Ranking.CalculateNewRank(submission.Rank, submissionAge, currentScore); submission.Rank = newRank; // register Turn DownVote To UpVote var votingTracker = db.Votingtrackers.FirstOrDefault(b => b.MessageId == submissionId && b.UserName == userWhichDownvoted); if (votingTracker != null) { votingTracker.VoteStatus = -1; votingTracker.Timestamp = DateTime.Now; } db.SaveChanges(); Karma.UpdateUserScp(submission.Name, -2); SendVoteNotification(submission.Name, "uptodownvote"); } break; // downvoted before, reset case -1: { submission.Dislikes--; double currentScore = submission.Likes - submission.Dislikes; double submissionAge = Submissions.CalcSubmissionAgeDouble(submission.Date); double newRank = Ranking.CalculateNewRank(submission.Rank, submissionAge, currentScore); submission.Rank = newRank; db.SaveChanges(); Karma.UpdateUserScp(submission.Name, 1); ResetMessageVote(userWhichDownvoted, submissionId); SendVoteNotification(submission.Name, "upvote"); } break; } } }
// submit submission downvote public static void DownvoteComment(int commentId, string userWhichDownvoted, string clientIpHash) { int result = CheckIfVotedComment(userWhichDownvoted, commentId); using (voatEntities db = new voatEntities()) { Comment comment = db.Comments.Find(commentId); // do not execute downvoting, subverse is in anonymized mode if (comment.Submission.IsAnonymized) { return; } // do not execute downvoting if user has insufficient CCP for target subverse if (Karma.CommentKarmaForSubverse(userWhichDownvoted, comment.Submission.Subverse) < comment.Submission.Subverse1.MinCCPForDownvote) { return; } // do not execute downvoting if comment is older than 7 days var commentPostingDate = comment.CreationDate; TimeSpan timeElapsed = DateTime.Now - commentPostingDate; if (timeElapsed.TotalDays > 7) { return; } switch (result) { // never voted before case 0: { // this user is downvoting more than upvoting, don't register the downvote if (UserHelper.IsUserCommentVotingMeanie(userWhichDownvoted)) { return; } // check if this IP already voted on the same comment, abort voting if true var ipVotedAlready = db.CommentVoteTrackers.Where(x => x.CommentID == commentId && x.IPAddress == clientIpHash); if (ipVotedAlready.Any()) { return; } comment.DownCount++; // register downvote var tmpVotingTracker = new CommentVoteTracker { CommentID = commentId, UserName = userWhichDownvoted, VoteStatus = -1, CreationDate = DateTime.Now, IPAddress = clientIpHash }; db.CommentVoteTrackers.Add(tmpVotingTracker); db.SaveChanges(); Voting.SendVoteNotification(comment.UserName, "downvote"); } break; // upvoted before, turn upvote to downvote case 1: { comment.UpCount--; comment.DownCount++; //register Turn DownVote To UpVote var votingTracker = db.CommentVoteTrackers.FirstOrDefault(b => b.CommentID == commentId && b.UserName == userWhichDownvoted); if (votingTracker != null) { votingTracker.VoteStatus = -1; votingTracker.CreationDate = DateTime.Now; } db.SaveChanges(); Voting.SendVoteNotification(comment.UserName, "uptodownvote"); } break; // downvoted before, reset case -1: comment.DownCount--; db.SaveChanges(); ResetCommentVote(userWhichDownvoted, commentId); Voting.SendVoteNotification(comment.UserName, "upvote"); break; } } }