예제 #1
0
        public ApiUserInfo UserInfo(string userName)
        {
            if (userName != "deleted" && !Utils.User.UserExists(userName))
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            if (userName == "deleted")
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            var resultModel = new ApiUserInfo();

            var userBadgesList   = Utils.User.UserBadges(userName);
            var resultBadgesList = userBadgesList.Select(item => new ApiUserBadge {
                Awarded = item.Awarded, BadgeName = item.Badge.BadgeName
            }).ToList();

            resultModel.Name             = userName;
            resultModel.CCP              = Karma.CommentKarma(userName);
            resultModel.LCP              = Karma.LinkKarma(userName);
            resultModel.RegistrationDate = Utils.User.GetUserRegistrationDateTime(userName);
            resultModel.Badges           = resultBadgesList;

            return(resultModel);
        }
예제 #2
0
        public JsonResult Vote(int messageId, int typeOfVote)
        {
            var loggedInUser = User.Identity.Name;

            switch (typeOfVote)
            {
            case 1:
                if (Karma.CommentKarma(loggedInUser) > 20)
                {
                    // perform upvoting or resetting
                    Voting.UpvoteSubmission(messageId, loggedInUser);
                }
                else if (Utils.User.TotalVotesUsedInPast24Hours(User.Identity.Name) < 11)
                {
                    // perform upvoting or resetting even if user has no CCP but only allow 10 votes per 24 hours
                    Voting.UpvoteSubmission(messageId, loggedInUser);
                }
                break;

            case -1:
                if (Karma.CommentKarma(loggedInUser) > 100)
                {
                    // perform downvoting or resetting
                    Voting.DownvoteSubmission(messageId, loggedInUser);
                }
                break;
            }
            return(Json("Voting ok", JsonRequestBehavior.AllowGet));
        }
예제 #3
0
        public async Task <ActionResult> Compose([Bind(Include = "ID,Recipient,Subject,Body")] PrivateMessage privateMessage)
        {
            if (!ModelState.IsValid)
            {
                return(View());
            }
            if (privateMessage.Recipient == null || privateMessage.Subject == null || privateMessage.Body == null)
            {
                return(RedirectToAction("Sent", "Messaging"));
            }

            if (Karma.CommentKarma(User.Identity.Name) < 100)
            {
                bool isCaptchaValid = await ReCaptchaUtility.Validate(Request);

                if (!isCaptchaValid)
                {
                    ModelState.AddModelError(string.Empty, "Incorrect recaptcha answer.");
                    return(View());
                }
            }

            var response = MesssagingUtility.SendPrivateMessage(User.Identity.Name, privateMessage.Recipient, privateMessage.Subject, privateMessage.Body);

            return(RedirectToAction("Sent", "Messaging"));
        }
예제 #4
0
        public async Task <ActionResult> Compose([Bind(Include = "Id,Recipient,Subject,Body")] Privatemessage privateMessage)
        {
            if (!ModelState.IsValid)
            {
                return(View());
            }
            if (privateMessage.Recipient == null || privateMessage.Subject == null || privateMessage.Body == null)
            {
                return(RedirectToAction("Sent", "Messaging"));
            }

            if (Karma.CommentKarma(User.Identity.Name) < 100)
            {
                bool isCaptchaValid = await ReCaptchaUtility.Validate(Request);

                if (!isCaptchaValid)
                {
                    ModelState.AddModelError(string.Empty, "Incorrect recaptcha answer.");
                    return(View());
                }
            }

            // check if recipient exists
            if (Voat.Utilities.UserHelper.UserExists(privateMessage.Recipient) && !Voat.Utilities.UserHelper.IsUserGloballyBanned(User.Identity.Name))
            {
                // send the submission
                privateMessage.Timestamp = DateTime.Now;
                privateMessage.Sender    = User.Identity.Name;
                privateMessage.Status    = true;
                if (Voat.Utilities.UserHelper.IsUserGloballyBanned(User.Identity.Name))
                {
                    return(RedirectToAction("Sent", "Messaging"));
                }
                _db.Privatemessages.Add(privateMessage);
                try
                {
                    await _db.SaveChangesAsync();

                    // get count of unread notifications
                    int unreadNotifications = Voat.Utilities.UserHelper.UnreadTotalNotificationsCount(privateMessage.Recipient);

                    // send SignalR realtime notification to recipient
                    var hubContext = GlobalHost.ConnectionManager.GetHubContext <MessagingHub>();
                    hubContext.Clients.User(privateMessage.Recipient).setNotificationsPending(unreadNotifications);
                }
                catch (Exception)
                {
                    return(View("~/Views/Errors/DbNotResponding.cshtml"));
                }
            }
            else
            {
                ModelState.AddModelError(string.Empty, "Sorry, there is no recipient with that username.");
                return(View());
            }
            return(RedirectToAction("Sent", "Messaging"));
        }
예제 #5
0
        public ActionResult UserBasicInfo(string userName)
        {
            var userRegistrationDateTime = UserHelper.GetUserRegistrationDateTime(userName);
            var memberFor = Submissions.CalcSubmissionAge(userRegistrationDateTime);
            var scp       = Karma.LinkKarma(userName);
            var ccp       = Karma.CommentKarma(userName);

            var userInfoModel = new BasicUserInfo()
            {
                MemberSince = memberFor,
                Ccp         = ccp,
                Scp         = scp
            };

            return(PartialView("~/Views/AjaxViews/_BasicUserInfo.cshtml", userInfoModel));
        }
예제 #6
0
        public JsonResult VoteComment(int commentId, int typeOfVote)
        {
            lock (_locker)
            {
                int dailyVotingQuota            = Settings.DailyVotingQuota;
                var loggedInUser                = User.Identity.Name;
                var userCcp                     = Karma.CommentKarma(loggedInUser);
                var scaledDailyVotingQuota      = Math.Max(dailyVotingQuota, userCcp / 2);
                var totalVotesUsedInPast24Hours = UserHelper.TotalVotesUsedInPast24Hours(User.Identity.Name);

                switch (typeOfVote)
                {
                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;
                }

                Response.StatusCode = 200;
                return(Json("Voting ok", JsonRequestBehavior.AllowGet));
            }
        }
예제 #7
0
        public JsonResult Vote(int messageId, int typeOfVote)
        {
            string loggedInUser = User.Identity.Name;

            if (typeOfVote == 1)
            {
                // perform upvoting or resetting
                Voting.UpvoteSubmission(messageId, loggedInUser);
            }
            else if (typeOfVote == -1)
            {
                // ignore downvote if user link karma is below certain treshold
                if (Karma.CommentKarma(loggedInUser) > 100)
                {
                    // perform downvoting or resetting
                    Voting.DownvoteSubmission(messageId, loggedInUser);
                }
            }
            return(Json("Voting ok", JsonRequestBehavior.AllowGet));
        }
예제 #8
0
        public JsonResult VoteComment(int commentId, int typeOfVote)
        {
            int dailyVotingQuota            = Convert.ToInt32(ConfigurationManager.AppSettings["dailyVotingQuota"]);
            var loggedInUser                = User.Identity.Name;
            var userCcp                     = Karma.CommentKarma(loggedInUser);
            var scaledDailyVotingQuota      = Math.Max(dailyVotingQuota, userCcp / 2);
            var totalVotesUsedInPast24Hours = Utils.User.TotalVotesUsedInPast24Hours(User.Identity.Name);

            switch (typeOfVote)
            {
            case 1:
                if (userCcp >= 20)
                {
                    if (totalVotesUsedInPast24Hours < scaledDailyVotingQuota)
                    {
                        // perform upvoting or resetting
                        VotingComments.UpvoteComment(commentId, loggedInUser);
                    }
                }
                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);
                }
                break;

            case -1:
                if (userCcp >= 100)
                {
                    if (totalVotesUsedInPast24Hours < scaledDailyVotingQuota)
                    {
                        // perform downvoting or resetting
                        VotingComments.DownvoteComment(commentId, loggedInUser);
                    }
                }
                break;
            }

            Response.StatusCode = 200;
            return(Json("Voting ok", JsonRequestBehavior.AllowGet));
        }
예제 #9
0
        public JsonResult VoteComment(int commentId, int typeOfVote)
        {
            string loggedInUser = User.Identity.Name;

            if (typeOfVote == 1)
            {
                // perform upvoting or resetting
                VotingComments.UpvoteComment(commentId, loggedInUser);
            }
            else if (typeOfVote == -1)
            {
                // ignore downvote if user comment karma is below certain treshold
                if (Karma.CommentKarma(loggedInUser) > 100)
                {
                    // perform downvoting or resetting
                    VotingComments.DownvoteComment(commentId, loggedInUser);
                }
            }
            Response.StatusCode = 200;
            return(Json("Voting ok", JsonRequestBehavior.AllowGet));
        }
예제 #10
0
        public JsonResult Vote(int messageId, int typeOfVote)
        {
            int dailyVotingQuota            = MvcApplication.DailyVotingQuota;
            var loggedInUser                = User.Identity.Name;
            var userCcp                     = Karma.CommentKarma(loggedInUser);
            var scaledDailyVotingQuota      = Math.Max(dailyVotingQuota, userCcp / 2);
            var totalVotesUsedInPast24Hours = Utils.User.TotalVotesUsedInPast24Hours(User.Identity.Name);

            switch (typeOfVote)
            {
            case 1:
                if (userCcp >= 20)
                {
                    if (totalVotesUsedInPast24Hours < scaledDailyVotingQuota)
                    {
                        // perform upvoting or resetting
                        Voting.UpvoteSubmission(messageId, loggedInUser, IpHash.CreateHash(Utils.User.UserIpAddress(Request)));
                    }
                }
                else if (totalVotesUsedInPast24Hours < 11)
                {
                    // perform upvoting or resetting even if user has no CCP but only allow 10 votes per 24 hours
                    Voting.UpvoteSubmission(messageId, loggedInUser, IpHash.CreateHash(Utils.User.UserIpAddress(Request)));
                }
                break;

            case -1:
                if (userCcp >= 100)
                {
                    if (totalVotesUsedInPast24Hours < scaledDailyVotingQuota)
                    {
                        // perform downvoting or resetting
                        Voting.DownvoteSubmission(messageId, loggedInUser, IpHash.CreateHash(Utils.User.UserIpAddress(Request)));
                    }
                }
                break;
            }
            return(Json("Voting ok", JsonRequestBehavior.AllowGet));
        }
예제 #11
0
        public ApiUserInfo UserInfo(string userName)
        {
            if (userName != "deleted" && !UserHelper.UserExists(userName))
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            if (userName == "deleted")
            {
                throw new HttpResponseException(HttpStatusCode.NotFound);
            }

            ApiUserInfo userInfo = CacheHandler.Register <ApiUserInfo>(String.Format("LegacyApi.UserInfo.{0}", userName),
                                                                       new Func <ApiUserInfo>(() =>
            {
                using (voatEntities db = new voatEntities(CONSTANTS.CONNECTION_READONLY))
                {
                    var resultModel = new ApiUserInfo();

                    var userBadgesList   = UserHelper.UserBadges(userName);
                    var resultBadgesList = userBadgesList.Select(item => new ApiUserBadge {
                        Awarded = item.CreationDate, BadgeName = item.Badge.Name
                    }).ToList();

                    resultModel.Name             = userName;
                    resultModel.CCP              = Karma.CommentKarma(userName);
                    resultModel.LCP              = Karma.LinkKarma(userName);
                    resultModel.RegistrationDate = UserHelper.GetUserRegistrationDateTime(userName);
                    resultModel.Badges           = resultBadgesList;

                    return(resultModel);
                }
            }), TimeSpan.FromMinutes(90));

            return(userInfo);
        }
예제 #12
0
        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"));
        }
예제 #13
0
        // url: "/comments/" + submission + "/" + parentId + "/" + command + "/" + startingIndex + "/" + count + "/" + nestingLevel + "/" + sort + "/",
        // GET: comments for a given submission
        public ActionResult BucketOfComments(int submissionId, int?parentId, string command, int startingIndex, string sort)
        {
            #region Validation

            if (submissionId <= 0)
            {
                return(View("~/Views/Errors/Error.cshtml"));
            }

            var submission = DataCache.Submission.Retrieve(submissionId);

            if (submission == null)
            {
                return(View("~/Views/Errors/Error_404.cshtml"));
            }

            var subverse = DataCache.Subverse.Retrieve(submission.Subverse);
            //var subverse = _db.Subverse.Find(subversetoshow);

            if (subverse == null)
            {
                return(View("~/Views/Errors/Error_404.cshtml"));
            }

            //HACK: Disable subverse
            if (subverse.IsAdminDisabled.HasValue && subverse.IsAdminDisabled.Value)
            {
                ViewBag.Subverse = subverse.Name;
                return(View("~/Views/Errors/SubverseDisabled.cshtml"));
            }

            #endregion

            ViewBag.SelectedSubverse   = subverse.Name;
            ViewBag.SubverseAnonymized = subverse.IsAnonymized;

            //Temp cache user votes for this thread
            ViewBag.VoteCache         = UserCommentVotesBySubmission(submissionId);
            ViewBag.SavedCommentCache = UserSavedCommentsBySubmission(submissionId);
            ViewBag.CCP = Karma.CommentKarma(User.Identity.Name);


            var SortingMode = (sort == null ? "top" : sort).ToLower();
            ViewBag.SortingMode = SortingMode;



            var commentTree = DataCache.CommentTree.Retrieve <usp_CommentTree_Result>(submission.ID, null, null);
            var model       = new CommentBucketViewModel()
            {
                StartingIndex = startingIndex,
                //NestingThreshold = nestingLevel,
                Subverse    = subverse,
                Submission  = submission,
                CommentTree = commentTree,
                ParentID    = parentId,
                Sort        = (CommentSort)Enum.Parse(typeof(CommentSort), SortingMode, true)
            };
            model.CollapseSiblingThreshold = 5;

            IQueryable <usp_CommentTree_Result> displayTree = commentTree.AsQueryable();
            displayTree = displayTree.Where(x => x.ParentID == parentId);
            model.TotalInDisplayBranch = displayTree.Count();

            //calculate offsets
            model.EndingIndex = Math.Min(model.StartingIndex + model.CollapseSiblingThreshold, model.TotalInDisplayBranch);


            if (model.Sort == CommentSort.Top)
            {
                displayTree = displayTree.OrderByDescending(x => x.UpCount - x.DownCount);
            }
            else
            {
                displayTree = displayTree.OrderByDescending(x => x.CreationDate);
            }

            displayTree = displayTree.Skip(model.StartingIndex).Take(model.Count);

            model.DisplayTree = displayTree;

            return(PartialView("~/Views/Shared/Comments/_CommentBucket.cshtml", model));
        }
예제 #14
0
        // GET: comments for a given submission
        public ActionResult Comments(int?id, string subversetoshow, int?startingcommentid, string sort, int?commentToHighLight)
        {
            #region Validation

            if (id == null)
            {
                return(View("~/Views/Errors/Error.cshtml"));
            }

            var submission = _db.Submissions.Find(id.Value);

            if (submission == null)
            {
                return(View("~/Views/Errors/Error_404.cshtml"));
            }

            // make sure that the combination of selected subverse and submission subverse are linked
            if (!submission.Subverse.Equals(subversetoshow, StringComparison.OrdinalIgnoreCase))
            {
                return(View("~/Views/Errors/Error_404.cshtml"));
            }

            var subverse = DataCache.Subverse.Retrieve(subversetoshow);
            //var subverse = _db.Subverse.Find(subversetoshow);

            if (subverse == null)
            {
                return(View("~/Views/Errors/Error_404.cshtml"));
            }

            //HACK: Disable subverse
            if (subverse.IsAdminDisabled.HasValue && subverse.IsAdminDisabled.Value)
            {
                ViewBag.Subverse = subverse.Name;
                return(View("~/Views/Errors/SubverseDisabled.cshtml"));
            }

            #endregion

            ViewBag.SelectedSubverse   = subverse.Name;
            ViewBag.SubverseAnonymized = subverse.IsAnonymized;

            //Temp cache user votes for this thread
            ViewBag.VoteCache         = UserCommentVotesBySubmission(id.Value);
            ViewBag.SavedCommentCache = UserSavedCommentsBySubmission(id.Value);
            ViewBag.CCP = Karma.CommentKarma(User.Identity.Name);

            if (startingcommentid != null)
            {
                ViewBag.StartingCommentId = startingcommentid;
            }

            if (commentToHighLight != null)
            {
                ViewBag.CommentToHighLight = commentToHighLight;
            }

            var SortingMode = (sort == null ? "top" : sort).ToLower();
            ViewBag.SortingMode = SortingMode;



            // experimental: register a new session for this subverse
            string clientIpAddress = String.Empty;

            if (Request.ServerVariables["HTTP_X_FORWARDED_FOR"] != null)
            {
                clientIpAddress = Request.ServerVariables["HTTP_X_FORWARDED_FOR"];
            }
            else if (Request.UserHostAddress.Length != 0)
            {
                clientIpAddress = Request.UserHostAddress;
            }

            if (clientIpAddress != String.Empty)
            {
                // generate salted hash of client IP address
                string ipHash = IpHash.CreateHash(clientIpAddress);

                var currentSubverse = (string)RouteData.Values["subversetoshow"];

                // register a new session for this subverse
                SessionHelper.Add(currentSubverse, ipHash);

                // register a new view for this thread
                // check if this hash is present for this submission id in viewstatistics table
                var existingView = _db.ViewStatistics.Find(submission.ID, ipHash);

                // this IP has already viwed this thread, skip registering a new view
                if (existingView == null)
                {
                    // this is a new view, register it for this submission
                    var view = new ViewStatistic {
                        SubmissionID = submission.ID, ViewerID = ipHash
                    };
                    _db.ViewStatistics.Add(view);

                    submission.Views++;

                    _db.SaveChanges();
                }
            }

            var commentTree = DataCache.CommentTree.Retrieve <usp_CommentTree_Result>(submission.ID, null, null);

            var model = new CommentBucketViewModel()
            {
                StartingIndex = 0,
                EndingIndex   = 5,
                Subverse      = subverse,
                Submission    = submission,
                CommentTree   = commentTree,
                //DisplayTree = displayTree,
                ParentID = null,
                Sort     = (CommentSort)Enum.Parse(typeof(CommentSort), SortingMode, true)
            };

            IQueryable <usp_CommentTree_Result> displayTree = commentTree.AsQueryable().Where(x => x.ParentID == null);
            model.TotalInDisplayBranch = displayTree.Count();

            if (model.Sort == CommentSort.Top)
            {
                displayTree = displayTree.OrderByDescending(x => x.UpCount - x.DownCount).Take(model.EndingIndex);
            }
            else
            {
                displayTree = displayTree.OrderByDescending(x => x.CreationDate).Take(model.EndingIndex);
            }
            model.DisplayTree = displayTree;


            return(View("~/Views/Home/Comments.cshtml", model));
        }
예제 #15
0
        // GET: comments for a given submission
        public ActionResult BucketOfComments(int?id, int?startingcommentid, int?startingpos, string sort)
        {
            const int threadsToFetch = 5;

            if (id == null)
            {
                return(View("~/Views/Errors/Error.cshtml"));
            }

            var submission = _db.Messages.Find(id);

            if (submission == null)
            {
                return(View("~/Views/Errors/Error_404.cshtml"));
            }

            //Temp cache user votes for this thread
            ViewBag.VoteCache = UserVotesBySubmission(id.Value);


            ViewData["StartingPos"] = startingpos;

            if (User.Identity.IsAuthenticated)
            {
                ViewData["CCP"] = Karma.CommentKarma(User.Identity.Name);
            }

            ViewBag.SelectedSubverse   = submission.Subverses.name;
            ViewBag.SubverseAnonymized = submission.Subverses.anonymized_mode;

            if (startingcommentid != null)
            {
                ViewBag.StartingCommentId = startingcommentid;
            }
            if (sort != null)
            {
                ViewBag.SortingMode = sort;
            }

            // load first comments
            IEnumerable <Comment> firstComments;

            if (sort == "new")
            {
                firstComments = from f in submission.Comments
                                let commentScore = f.Likes - f.Dislikes
                                                   where f.ParentId == null
                                                   orderby f.Date descending
                                                   select f;
            }
            else
            {
                firstComments = from f in submission.Comments
                                let commentScore = f.Likes - f.Dislikes
                                                   where f.ParentId == null
                                                   orderby commentScore descending
                                                   select f;
            }

            if (startingpos == null)
            {
                return(new HttpStatusCodeResult(HttpStatusCode.BadRequest));
            }

            var cbvm = new CommentBucketViewModel
            {
                FirstComments = firstComments.Skip((int)startingpos * threadsToFetch).Take(threadsToFetch),
                Submission    = submission
            };

            if (!cbvm.FirstComments.Any())
            {
                return(new HttpStatusCodeResult(HttpStatusCode.BadRequest));
            }

            return(PartialView("~/Views/Shared/Comments/_CommentBucket.cshtml", cbvm));
        }
예제 #16
0
        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());
        }
예제 #17
0
        // GET: comments for a given submission
        public ActionResult BucketOfComments(int?id, int?startingcommentid, int?startingpos, string sort)
        {
            const int threadsToFetch = 5;

            if (id == null)
            {
                return(View("~/Views/Errors/Error.cshtml"));
            }
            if (startingpos == null)
            {
                return(new HttpStatusCodeResult(HttpStatusCode.BadRequest));
            }

            var submission = _db.Messages.Find(id);

            if (submission == null)
            {
                return(View("~/Views/Errors/Error_404.cshtml"));
            }

            //Temp cache user votes for this thread
            ViewBag.VoteCache         = UserVotesBySubmission(id.Value);
            ViewBag.SavedCommentCache = UserSavedCommentsBySubmission(id.Value);

            ViewData["StartingPos"] = startingpos;

            if (User.Identity.IsAuthenticated)
            {
                ViewData["CCP"] = Karma.CommentKarma(User.Identity.Name);
            }

            ViewBag.SelectedSubverse   = submission.Subverses.name;
            ViewBag.SubverseAnonymized = submission.Subverses.anonymized_mode;

            if (startingcommentid != null)
            {
                ViewBag.StartingCommentId = startingcommentid;
            }
            if (sort != null)
            {
                ViewBag.SortingMode = sort;
            }



            string cacheKey = String.Format("comments.bucket.{0}.{1}.{2}.{3}", id, startingcommentid, startingpos, sort);

            CommentBucketViewModel cbvm = CacheHandler.Retrieve <CommentBucketViewModel>(cacheKey);

            if (cbvm == null)
            {
                //This can not be recached
                cbvm = CacheHandler.Register <CommentBucketViewModel>(cacheKey, new Func <CommentBucketViewModel>(() => {
                    // load first comments
                    IEnumerable <Comment> firstComments;
                    if (sort == "new")
                    {
                        firstComments = from f in submission.Comments
                                        let commentScore = f.Likes - f.Dislikes
                                                           where f.ParentId == null
                                                           orderby f.Date descending
                                                           select f;
                    }
                    else
                    {
                        firstComments = from f in submission.Comments
                                        let commentScore = f.Likes - f.Dislikes
                                                           where f.ParentId == null
                                                           orderby commentScore descending
                                                           select f;
                    }

                    var x = new CommentBucketViewModel
                    {
                        FirstComments = firstComments.Skip((int)startingpos * threadsToFetch).Take(threadsToFetch),
                        Submission    = submission
                    };
                    return(x);
                }), TimeSpan.FromSeconds(60));
            }


            if (!cbvm.FirstComments.Any())
            {
                return(new HttpStatusCodeResult(HttpStatusCode.BadRequest));
            }

            return(PartialView("~/Views/Shared/Comments/_CommentBucket.cshtml", cbvm));
        }
예제 #18
0
        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
            }
                       ));
        }
예제 #19
0
        public async Task <ActionResult> SubmitComment([Bind(Include = "Id, CommentContent, MessageId, ParentId")] Comment commentModel)
        {
            commentModel.Date  = DateTime.Now;
            commentModel.Name  = User.Identity.Name;
            commentModel.Votes = 0;
            commentModel.Likes = 0;

            if (ModelState.IsValid)
            {
                // flag the comment as anonymized if it was submitted to a sub which has active anonymized_mode
                var message = _db.Messages.Find(commentModel.MessageId);
                if (message != null && (message.Anonymized || message.Subverses.anonymized_mode))
                {
                    commentModel.Anonymized = true;
                }

                // 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 = Utils.User.UserDailyCommentPostingQuotaForNegativeScoreUsed(User.Identity.Name);
                    if (quotaUsed)
                    {
                        ModelState.AddModelError("", "You have reached your daily comment quota. Your current quota is " + MvcApplication.DailyCommentPostingQuotaForNegativeScore + " comment(s) per 24 hours.");
                        return(View());
                    }
                }

                // check if author is banned, don't save the comment or send notifications if true
                if (!Utils.User.IsUserGloballyBanned(User.Identity.Name) && !Utils.User.IsUserBannedFromSubverse(User.Identity.Name, message.Subverse))
                {
                    if (ContentProcessor.Instance.HasStage(ProcessingStage.InboundPreSave))
                    {
                        commentModel.CommentContent = ContentProcessor.Instance.Process(commentModel.CommentContent, ProcessingStage.InboundPreSave, commentModel);
                    }

                    //save fully formatted content
                    var formattedComment = Formatting.FormatMessage(commentModel.CommentContent);
                    commentModel.FormattedContent = formattedComment;

                    _db.Comments.Add(commentModel);

                    await _db.SaveChangesAsync();

                    if (ContentProcessor.Instance.HasStage(ProcessingStage.InboundPostSave))
                    {
                        ContentProcessor.Instance.Process(commentModel.CommentContent, 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.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"));
        }