Пример #1
0
        public void MiscPathTests()
        {
            var options = new PathOptions(true, true, "Somesite.com");

            string[] parts       = new string[] { "", " ", "white space ", "x.jpg" };
            var      expectedUrl = $"http{(VoatSettings.Instance.ForceHTTPS ? "s" : "")}://Somesite.com/white space/x.jpg";

            options.EscapeUrl = false;
            var url = VoatUrlFormatter.BuildUrlPath(null, options, parts);

            Assert.AreEqual(expectedUrl, url, "Condition:1.1");

            options.EscapeUrl = true;
            url = VoatUrlFormatter.BuildUrlPath(null, options, parts);

            Assert.AreEqual(Uri.EscapeUriString(expectedUrl), url, "Condition:1.2");

            options.EscapeUrl     = false;
            options.Normalization = Normalization.Lower;
            url = VoatUrlFormatter.BuildUrlPath(null, options, parts);
            Assert.AreEqual(expectedUrl.ToLower(), url, "Condition:1.3");

            options.EscapeUrl     = false;
            options.Normalization = Normalization.Upper;
            url = VoatUrlFormatter.BuildUrlPath(null, options, parts);
            Assert.AreEqual(expectedUrl.ToUpper(), url, "Condition:1.4");
        }
Пример #2
0
        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);
        }
        public override string Uri(FileKey key, PathOptions options = null)
        {
            if (key == null || String.IsNullOrEmpty(key.ID))
            {
                return(null);
            }

            options             = options == null ? new PathOptions() : options;
            options.ForceDomain = Domain;

            var result = "";

            switch (key.FileType)
            {
            case FileType.Badge:
                options.ForceDomain = VoatSettings.Instance.SiteDomain;
                result = base.Uri(key, options);
                break;

            case FileType.Avatar:
            case FileType.Thumbnail:
                return(VoatUrlFormatter.BuildUrlPath(null, options, (new string[] { ContentPath(key), key.ID }).ToPathParts()));

                break;
            }
            return(result);
        }
Пример #4
0
        public SubverseLinkFilter()
        {
            ProcessingStage = ProcessingStage.Outbound;
            Priority        = 10;
            IsReadOnly      = false;

            ProcessLogic = delegate(Match m, string matchSource, object state)
            {
                return(String.Format("[{0}]({1})", m.Value, VoatUrlFormatter.Subverse(m.Groups["sub"].Value + (m.Groups["anchor"].Success ? m.Groups["anchor"].Value : ""))));
            };
        }
Пример #5
0
        public SetLinkFilter()
        {
            ProcessingStage = ProcessingStage.Outbound;
            Priority        = 10;
            IsReadOnly      = false;

            ProcessLogic = delegate(Match m, string matchSource, object state)
            {
                return(String.Format("[{0}]({1})", m.Value, VoatUrlFormatter.Set(m.Groups["name"].Value + (m.Groups["fullPath"].Success ? m.Groups["fullPath"].Value : ""), new Common.PathOptions(true, true))));
            };
        }
        private void SetMenuNavigationModel(string name, MenuType menuType, string subverse = null)
        {
            string suffix = "/messages";

            ViewBag.NavigationViewModel = new NavigationViewModel()
            {
                Description = (String.IsNullOrEmpty(subverse) ? "Messages" : String.Format("v/{0} Smail", subverse)),
                Name        = name,
                MenuType    = menuType,
                BasePath    = (String.IsNullOrEmpty(subverse) ? suffix : String.Format("{0}/about{1}", VoatUrlFormatter.BasePath(new DomainReference(DomainType.Subverse, subverse)), suffix)),
                Sort        = null
            };
        }
        public async Task <ActionResult> AddModerator([Bind("ID,Subverse,UserName,Power")] SubverseModerator subverseAdmin)
        {
            if (!ModelState.IsValid)
            {
                return(View(subverseAdmin));
            }

            // check if caller can add mods, if not, deny posting
            if (!ModeratorPermission.HasPermission(User, subverseAdmin.Subverse, Domain.Models.ModeratorAction.InviteMods))
            {
                return(RedirectToAction("Index", "Home"));
            }

            subverseAdmin.UserName = subverseAdmin.UserName.TrimSafe();
            Subverse subverseModel = null;

            //lots of premature retuns so wrap the common code
            var sendFailureResult = new Func <string, ActionResult>(errorMessage =>
            {
                ViewBag.SubverseModel    = subverseModel;
                ViewBag.SubverseName     = subverseAdmin.Subverse;
                ViewBag.SelectedSubverse = string.Empty;
                ModelState.AddModelError(string.Empty, errorMessage);
                SetNavigationViewModel(subverseAdmin.Subverse);

                return(View("~/Views/Subverses/Admin/AddModerator.cshtml",
                            new SubverseModeratorViewModel
                {
                    UserName = subverseAdmin.UserName,
                    Power = subverseAdmin.Power
                }
                            ));
            });

            // prevent invites to the current moderator
            if (User.Identity.Name.IsEqual(subverseAdmin.UserName))
            {
                return(sendFailureResult("Can not add yourself as a moderator"));
            }

            string originalRecipientUserName = UserHelper.OriginalUsername(subverseAdmin.UserName);

            // prevent invites to the current moderator
            if (String.IsNullOrEmpty(originalRecipientUserName))
            {
                return(sendFailureResult("User can not be found"));
            }

            // get model for selected subverse
            subverseModel = DataCache.Subverse.Retrieve(subverseAdmin.Subverse);
            if (subverseModel == null)
            {
                return(ErrorView(ErrorViewModel.GetErrorViewModel(ErrorType.SubverseNotFound)));
            }

            if ((subverseAdmin.Power < 1 || subverseAdmin.Power > 4) && subverseAdmin.Power != 99)
            {
                return(sendFailureResult("Only powers levels 1 - 4 and 99 are supported currently"));
            }

            //check current mod level and invite level and ensure they are a lower level
            var currentModLevel = ModeratorPermission.Level(User, subverseModel.Name);

            if (subverseAdmin.Power <= (int)currentModLevel && currentModLevel != Domain.Models.ModeratorLevel.Owner)
            {
                return(sendFailureResult("Sorry, but you can only add moderators that are a lower level than yourself"));
            }

            int maximumOwnedSubs = VoatSettings.Instance.MaximumOwnedSubs;

            // check if the user being added is not already a moderator of 10 subverses
            var currentlyModerating = _db.SubverseModerator.Where(a => a.UserName == originalRecipientUserName).ToList();

            SubverseModeratorViewModel tmpModel;

            if (currentlyModerating.Count <= maximumOwnedSubs)
            {
                // check that user is not already moderating given subverse
                var isAlreadyModerator = _db.SubverseModerator.FirstOrDefault(a => a.UserName == originalRecipientUserName && a.Subverse == subverseAdmin.Subverse);

                if (isAlreadyModerator == null)
                {
                    // check if this user is already invited
                    var userModeratorInvitations = _db.ModeratorInvitation.Where(i => i.Recipient.ToLower() == originalRecipientUserName.ToLower() && i.Subverse.ToLower() == subverseModel.Name.ToLower());
                    if (userModeratorInvitations.Any())
                    {
                        return(sendFailureResult("Sorry, the user is already invited to moderate this subverse"));
                    }

                    // send a new moderator invitation
                    ModeratorInvitation modInv = new ModeratorInvitation
                    {
                        CreatedBy    = User.Identity.Name,
                        CreationDate = Repository.CurrentDate,
                        Recipient    = originalRecipientUserName,
                        Subverse     = subverseAdmin.Subverse,
                        Power        = subverseAdmin.Power
                    };

                    _db.ModeratorInvitation.Add(modInv);
                    _db.SaveChanges();
                    int invitationId   = modInv.ID;
                    var invitationBody = new StringBuilder();

                    //v/{subverse}/about/moderatorinvitations/accept/{invitationId}

                    string acceptInviteUrl = VoatUrlFormatter.BuildUrlPath(this.HttpContext, new PathOptions(true, true), $"/v/{subverseModel.Name}/about/moderatorinvitations/accept/{invitationId}");

                    invitationBody.Append("Hello,");
                    invitationBody.Append(Environment.NewLine);
                    invitationBody.Append($"@{User.Identity.Name} invited you to moderate v/" + subverseAdmin.Subverse + ".");
                    invitationBody.Append(Environment.NewLine);
                    invitationBody.Append(Environment.NewLine);
                    invitationBody.Append($"Please visit the following link if you want to accept this invitation: {acceptInviteUrl}");
                    invitationBody.Append(Environment.NewLine);
                    invitationBody.Append(Environment.NewLine);
                    invitationBody.Append("Thank you.");

                    var cmd = new SendMessageCommand(new Domain.Models.SendMessage()
                    {
                        Sender    = $"v/{subverseAdmin.Subverse}",
                        Recipient = originalRecipientUserName,
                        Subject   = $"v/{subverseAdmin.Subverse} moderator invitation",
                        Message   = invitationBody.ToString()
                    }, true).SetUserContext(User);
                    await cmd.Execute();

                    return(RedirectToAction("SubverseModerators"));
                }
                else
                {
                    return(sendFailureResult("Sorry, the user is already moderating this subverse"));
                }
            }
            else
            {
                return(sendFailureResult("Sorry, the user is already moderating a maximum of " + maximumOwnedSubs + " subverses"));
            }
        }
Пример #8
0
        //// POST: votecomment/{commentId}/{typeOfVote}
        //[HttpPost]
        //[Authorize]
        //[VoatValidateAntiForgeryToken]
        //public async Task<JsonResult> VoteComment(int commentId, int typeOfVote)
        //{
        //    var cmd = new CommentVoteCommand(commentId, typeOfVote, IpHash.CreateHash(UserHelper.UserIpAddress(this.Request)));
        //    var result = await cmd.Execute();
        //    return Json(result);
        //}



        // GET: Renders Primary Submission Comments Page
        public async Task <ActionResult> Comments(int?submissionID, string subverseName, int?commentID, string sort, int?context)
        {
            #region Validation

            if (submissionID == null)
            {
                return(ErrorView(new ErrorViewModel()
                {
                    Description = "Can not find what was requested because input is not valid"
                }));
            }

            var q = new QuerySubmission(submissionID.Value, true).SetUserContext(User);

            var submission = await q.ExecuteAsync().ConfigureAwait(false);

            if (submission == null)
            {
                return(ErrorView(ErrorViewModel.GetErrorViewModel(ErrorType.NotFound)));
            }

            // make sure that the combination of selected subverse and submission subverse are linked
            if (!submission.Subverse.IsEqual(subverseName))
            {
                return(ErrorView(ErrorViewModel.GetErrorViewModel(ErrorType.NotFound)));
            }

            var subverse = DataCache.Subverse.Retrieve(subverseName);

            if (subverse == null)
            {
                return(ErrorView(ErrorViewModel.GetErrorViewModel(ErrorType.NotFound)));
            }

            if (subverse.IsAdminDisabled.HasValue && subverse.IsAdminDisabled.Value)
            {
                ViewBag.Subverse = subverse.Name;
                return(ErrorView(ErrorViewModel.GetErrorViewModel(ErrorType.SubverseDisabled)));
            }

            #endregion

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

            #region Set ViewBag
            ViewBag.Subverse   = subverse;
            ViewBag.Submission = submission;
            //This is a required view bag property in _Layout.cshtml - Update: hmmm, don't think so but too lazy to look
            ViewBag.SelectedSubverse = subverse.Name;

            var sortingMode = GetSortMode(sort);

            ViewBag.SortingMode = sortingMode;

            #endregion

            var cmd = new LogVisitCommand(null, submissionID.Value, Request.RemoteAddress()).SetUserContext(User);
            cmd.Execute();

            CommentSegment model = null;
            if (commentID != null)
            {
                ViewBag.CommentToHighLight = commentID.Value;
                model = await GetCommentContext(submission.ID, commentID.Value, context, sortingMode);
            }
            else
            {
                model = await GetCommentSegment(submission.ID, null, 0, sortingMode);
            }

            var q2 = new QuerySubverseModerators(subverseName).SetUserContext(User);
            ViewBag.ModeratorList = await q2.ExecuteAsync();



            ViewBag.NavigationViewModel = new NavigationViewModel()
            {
                Description = "Subverse",
                Name        = subverseName,
                MenuType    = MenuType.Subverse,
                BasePath    = VoatUrlFormatter.BasePath(new DomainReference(DomainType.Subverse, subverseName)),
                Sort        = null
            };

            return(View("~/Views/Home/Comments.cshtml", model));
        }
Пример #9
0
        public override string MatchFound(Match match, string matchSource, object context)
        {
            string replace = String.Format("{0}{1}", match.Groups["prefix"].Value, match.Groups["user"].Value);

            return(String.Format("[{0}]({1})", replace, VoatUrlFormatter.UserProfile(match.Groups["user"].Value)));
        }
Пример #10
0
        public async Task <ActionResult> Details(string name)
        {
            //TODO: Implement Command/Query - Remove direct Repository access
            using (var repo = new Repository(User))
            {
                var domainReference = DomainReference.Parse(name, DomainType.Set);
                var set             = repo.GetSet(domainReference.Name, domainReference.OwnerName);
                if (set == null)
                {
                    //Since system sets are not created until needed we show a slightly better error message for front/blocked.
                    if (name.IsEqual(SetType.Front.ToString()))
                    {
                        ViewBag.NavigationViewModel = new Models.ViewModels.NavigationViewModel()
                        {
                            Description = "Discover Search",
                            Name        = "No Idea",
                            MenuType    = Models.ViewModels.MenuType.Discovery,
                            BasePath    = VoatUrlFormatter.BasePath(domainReference),
                            Sort        = null
                        };
                        return(ErrorView(new ErrorViewModel()
                        {
                            Title = "No Subscriptions!", Description = "You don't have any subscriptions so we have to show you this instead", Footer = "Subscribe to a subverse you silly goat"
                        }));
                    }
                    else if (name.IsEqual(SetType.Blocked.ToString()))
                    {
                        ViewBag.NavigationViewModel = new Models.ViewModels.NavigationViewModel()
                        {
                            Description = "Discover Search",
                            Name        = "No Idea",
                            MenuType    = Models.ViewModels.MenuType.Discovery,
                            BasePath    = VoatUrlFormatter.BasePath(domainReference),
                            Sort        = null
                        };
                        return(ErrorView(new ErrorViewModel()
                        {
                            Title = "No Blocked Subs!", Description = "You don't have any blocked subs. Golf clap.", Footer = "Block some subs and this page will magically change!"
                        }));
                    }
                    else
                    {
                        return(ErrorView(new ErrorViewModel()
                        {
                            Title = "Can't find this set", Description = "Maybe it's gone?", Footer = "Probably yeah"
                        }));
                    }
                }

                var perms = SetPermission.GetPermissions(set.Map(), User.Identity);

                if (!perms.View)
                {
                    return(ErrorView(new ErrorViewModel()
                    {
                        Title = "Set is Private", Description = "This set doesn't allow the viewing of its properties", Footer = "It's ok, I can't see it either"
                    }));
                }

                var options = new SearchOptions(Request.QueryString.Value);
                options.Count = 50;

                var setList = await repo.GetSetListDescription(set.ID, options.Page);

                var model = new SetViewModel();
                model.Permissions    = perms;
                model.Set            = set.Map();
                model.List           = new PaginatedList <Domain.Models.SubverseSubscriptionDetail>(setList, options.Page, options.Count);
                model.List.RouteName = "SetDetails";

                ViewBag.NavigationViewModel = new NavigationViewModel()
                {
                    Name        = domainReference.FullName,
                    Description = set.Description,
                    BasePath    = VoatUrlFormatter.BasePath(domainReference),
                    MenuType    = (set.Type == (int)SetType.Front || set.Type == (int)SetType.Blocked ?  MenuType.Discovery : MenuType.Set)
                };
                return(View("Details", model));
            }
        }