public BanUserFromSubResponse Handle(BanUserFromSub command) { var response = new BanUserFromSubResponse(); try { var user = command.UserId.HasValue ? _membershipService.GetUserById(command.UserId.Value) : _membershipService.GetUserByUserName(command.UserName); if (user == null) { response.Error = "Invalid user."; return(response); } var bannedBy = _membershipService.GetUserById(command.BannedBy); if (bannedBy == null) { response.Error = "Invalid user."; return(response); } var sub = command.SubId.HasValue ? _subService.GetSubById(command.SubId.Value) : _subService.GetSubByName(command.SubName); if (sub == null) { response.Error = "Invalid sub."; return(response); } if (!_permissionDao.CanUserManageSubAccess(bannedBy, sub.Id)) { response.Error = "You are not authorized to ban."; return(response); } _subUserBanService.BanUserFromSub(sub.Id, user.Id, user.UserName, command.DateBanned, command.BannedBy, command.ReasonPrivate, command.ReasonPublic); return(response); } catch (Exception ex) { // TODO: log error response.Error = "An unknown error occured."; return(response); } }
public BanUserFromSubResponse Handle(BanUserFromSub command) { var response = new BanUserFromSubResponse(); try { var user = command.UserId.HasValue ? _membershipService.GetUserById(command.UserId.Value) : _membershipService.GetUserByUserName(command.Username); if (user == null) { response.Error = "Invalid user."; return(response); } var bannedBy = _membershipService.GetUserById(command.BannedBy); if (bannedBy == null) { response.Error = "Invalid user."; return(response); } var sub = command.SubId.HasValue ? _subService.GetSubById(command.SubId.Value) : _subService.GetSubByName(command.SubName); if (sub == null) { response.Error = "Invalid sub."; return(response); } if (!_permissionService.CanUserManageSubAccess(bannedBy, sub.Id)) { response.Error = "You are not authorized to ban."; return(response); } _subUserBanService.BanUserFromSub(sub.Id, user.Id, command.DateBanned, command.BannedBy, command.Reason, command.Expires); } catch (Exception ex) { // todo: log response.Error = ex.Message; } return(response); }
public EditSubResponse Handle(EditSub command) { var response = new EditSubResponse(); try { var sub = _subService.GetSubByName(command.Name); if (sub == null) { response.Error = "No sub found with the given name."; return(response); } var user = _membershipService.GetUserById(command.EditedByUserId); if (user == null) { response.Error = "Invalid user."; return(response); } if (!_subService.CanUserEditSub(user.UserName, sub.Name)) { response.Error = "You are not allowed to modify this sub."; return(response); } if (string.IsNullOrEmpty(command.Description)) { response.Error = "Please describe your sub."; return(response); } sub.Description = command.Description; sub.SidebarText = command.SidebarText; _subService.UpdateSub(sub); } catch (Exception ex) { // todo: log response.Error = ex.Message; } return(response); }
public EditSubStylesCommandResponse Handle(EditSubStylesCommand command) { var response = new EditSubStylesCommandResponse(); try { var user = _membershipService.GetUserById(command.EditedByUserId); if (user == null) { response.Error = "Invalid user."; return(response); } var sub = command.SubId.HasValue ? _subService.GetSubById(command.SubId.Value) : _subService.GetSubByName(command.SubName); if (sub == null) { response.Error = "Invalid sub."; return(response); } if (!_permissionService.CanUserManageSubStyles(user, sub.Id)) { response.Error = "You are not authorized to manage styles for this sub."; return(response); } var styles = _subStylesService.GetStylesForSub(sub.Id); if (styles == null) { styles = new SubCss(); } styles.SubId = sub.Id; styles.CssType = command.CssType; styles.Embedded = command.Embedded; styles.ExternalCss = command.ExternalCss; styles.GitHubCssProjectName = command.GitHubCssProjectName; styles.GitHubCssProjectTag = command.GitHubCssProjectTag; styles.GitHubLessProjectName = command.GitHubLessProjectName; styles.GitHubLessProjectTag = command.GitHubLessProjectTag; _subStylesService.UpdateStylesForSub(styles); } catch (Exception ex) { _logger.Error("Error trying to edit a sub's styles.", ex); response.Error = "An unknown error occured."; } return(response); }
public RemoveModFromSubResponse Handle(RemoveModFromSub command) { var response = new RemoveModFromSubResponse(); try { var requestingUser = _membershipService.GetUserById(command.RequestingUser); if (requestingUser == null) { response.Error = "Invalid user."; return(response); } var userToRemove = command.UserIdToRemove.HasValue ? _membershipService.GetUserById(command.UserIdToRemove.Value) : _membershipService.GetUserByUserName(command.UserNameToRemove); if (userToRemove == null) { response.Error = "Invalid user."; return(response); } Sub sub = null; if (command.SubId.HasValue) { sub = _subService.GetSubById(command.SubId.Value); } else if (!string.IsNullOrEmpty(command.SubName)) { sub = _subService.GetSubByName(command.SubName); } if (sub == null) { response.Error = "Invalid sub."; return(response); } var userToRemoveModInfo = _moderationService.GetModeratorInfoForUserInSub(userToRemove.Id, sub.Id); if (userToRemoveModInfo == null) { response.Error = "The user is not a mod of this sub."; return(response); } if (requestingUser.IsAdmin) { _moderationService.RemoveModFromSub(userToRemove.Id, sub.Id); } else { var requestingUserModInfo = _moderationService.GetModeratorInfoForUserInSub(requestingUser.Id, sub.Id); if (requestingUserModInfo == null) { response.Error = "You are not a mod of this sub."; return(response); } if ( // if the user is removing himself (doable) requestingUser.Id == userToRemove.Id || // or the requesting user is an admin requestingUser.IsAdmin || // or the user has has "full" access and the user we are changing has is a newby. (requestingUserModInfo.AddedOn <= userToRemoveModInfo.AddedOn && requestingUserModInfo.Permissions.HasFlag( ModeratorPermissions.All)) ) { _moderationService.RemoveModFromSub(userToRemove.Id, sub.Id); } else { response.Error = "You are not permitted to remove the mod from this sub."; return(response); } } } catch (Exception ex) { response.Error = "An unknown error occured."; _logger.Error("An error occured removing a user from sub.", ex); } return(response); }
public CreateSubResponse Handle(CreateSub command) { var response = new CreateSubResponse(); try { if (string.IsNullOrEmpty(command.Name)) { response.Error = "Sub name is required."; return(response); } if (!Regex.IsMatch(command.Name, "^[a-zA-Z0-9]*$")) { response.Error = "No spaces or special characters."; return(response); } if (command.Name.Length > 20) { response.Error = "The name length is limited to 20 characters."; return(response); } if (string.IsNullOrEmpty(command.Description)) { response.Error = "Please describe your sub."; return(response); } if (!string.IsNullOrEmpty(command.SubmissionText) && command.SubmissionText.Length > 1000) { response.Error = "The sidebar text cannot be greater than 1000 characters"; return(response); } if (!string.IsNullOrEmpty(command.SidebarText) && command.SidebarText.Length > 3000) { response.Error = "The submission text cannot be greater than 1000 characters"; return(response); } var user = _membershipService.GetUserById(command.CreatedByUserId); if (user == null) { response.Error = "Invalid user."; return(response); } var userAccountAge = Common.CurrentTime() - user.CreatedDate; if (!user.IsAdmin && userAccountAge.TotalDays < _subSettings.Settings.MinUserAgeCreateSub) { response.Error = "Your account is too new to create a sub."; return(response); } if (_subService.GetSubByName(command.Name) != null) { response.Error = "The sub already exist."; return(response); } if (command.Name.Equals("random", StringComparison.InvariantCultureIgnoreCase) || command.Name.Equals("all", StringComparison.InvariantCultureIgnoreCase) || Common.IsReservedKeyword(command.Name)) { response.Error = "The name is invalid."; return(response); } // let's make sure the user creating this sub doesn't already have the maximum number of subs they are modding. var moddedSubsForUser = _moderationService.GetSubsModeratoredByUser(user.Id); if (moddedSubsForUser.Count >= _subSettings.Settings.MaximumNumberOfModdedSubs) { response.Error = "You can only moderate a maximum of " + _subSettings.Settings.MaximumNumberOfModdedSubs + " subs."; return(response); } var sub = new Sub { Id = GuidUtil.NewSequentialId(), CreatedDate = Common.CurrentTime(), Name = command.Name, Description = command.Description, SidebarText = command.SidebarText, SidebarTextFormatted = _markdownCompiler.Compile(command.SidebarText), SubmissionText = command.SubmissionText, SubmissionTextFormatted = _markdownCompiler.Compile(command.SubmissionText), SubType = command.Type, CreatedBy = user.Id, InAll = command.InAll, Nsfw = command.Nsfw }; // only admins can configure default subs if (user.IsAdmin && command.IsDefault.HasValue) { sub.IsDefault = command.IsDefault.Value; } _subService.InsertSub(sub); response.SubId = sub.Id; response.SubName = sub.Name; _subService.SubscribeToSub(user.Id, sub.Id); _moderationService.AddModToSub(user.Id, sub.Id, ModeratorPermissions.All); } catch (Exception ex) { // todo: log response.Error = ex.Message; } return(response); }
static void Main(string[] args) { try { SkimurContext.Initialize( new Program(), new Skimur.App.Registrar()); _mirrorSettings = SkimurContext.ServiceProvider.GetRequiredService <ISettingsProvider <MirrorSettings> >().Settings; _subService = SkimurContext.ServiceProvider.GetRequiredService <ISubService>(); _postService = SkimurContext.ServiceProvider.GetRequiredService <IPostService>(); _membershipService = SkimurContext.ServiceProvider.GetRequiredService <IMembershipService>(); _commandBus = SkimurContext.ServiceProvider.GetRequiredService <ICommandBus>(); if (_mirrorSettings.SubsToMirror == null || _mirrorSettings.SubsToMirror.Count == 0) { return; } var botUser = _membershipService.GetUserByUserName(_mirrorSettings.BotName); if (botUser == null) { return; } var reddit = new Reddit(); foreach (var subToMirror in _mirrorSettings.SubsToMirror) { Console.WriteLine("Attempting to mirror " + subToMirror + "."); var sub = _subService.GetSubByName(subToMirror); if (sub == null) { Console.WriteLine("Sub doesn't exist."); continue; } var redditSub = reddit.GetSubreddit("/r/" + subToMirror); if (redditSub == null) { Console.WriteLine("Couldn't find reddit sub."); continue; } foreach (var redditPost in redditSub.GetTop(_mirrorSettings.FromTime).Take(_mirrorSettings.PostsPerSub)) { Console.WriteLine("Syncing " + redditPost.Title); var existing = _postService.QueryPosts(redditPost.Title, sub.Id).Select(x => _postService.GetPostById(x)).ToList(); var exists = false; if (existing.Count > 0) { foreach (var item in existing) { if (item.Title == redditPost.Title && item.Mirrored == "reddit") { exists = true; } } } if (exists) { Console.WriteLine("Already exists."); continue; } var createPostResponse = _commandBus.Send <CreatePost, CreatePostResponse>( new CreatePost { CreatedByUserId = botUser.Id, Title = redditPost.Title, Url = redditPost.Url.ToString(), Content = redditPost.SelfText, PostType = redditPost.IsSelfPost ? PostType.Text : PostType.Link, SubName = subToMirror, NotifyReplies = false, Mirror = "reddit", OverrideDateCreated = redditPost.CreatedUTC }); if (!string.IsNullOrEmpty(createPostResponse.Error)) { Console.WriteLine("Couldn't create post. " + createPostResponse.Error); continue; } if (!createPostResponse.PostId.HasValue) { Console.WriteLine("No post id"); continue; } var createCommentResponse = _commandBus.Send <CreateComment, CreateCommentResponse>( new CreateComment { PostId = createPostResponse.PostId.Value, DateCreated = Common.CurrentTime(), AuthorUserName = botUser.UserName, Body = string.Format("Mirrored from [here]({0}).", redditPost.Shortlink), SendReplies = false }); if (!string.IsNullOrEmpty(createCommentResponse.Error)) { Console.WriteLine("Couldn't create comment. " + createCommentResponse.Error); } } } } catch (Exception ex) { Console.WriteLine(ex.Message); } }
public CreatePostResponse Handle(CreatePost command) { var response = new CreatePostResponse(); try { var user = _membershipService.GetUserById(command.CreatedByUserId); if (user == null) { response.Error = "Invalid user."; return(response); } if (string.IsNullOrEmpty(command.SubName)) { response.Error = "The sub name is required."; return(response); } var sub = _subService.GetSubByName(command.SubName); if (sub == null) { response.Error = "That sub doesn't exist."; return(response); } if (!user.IsAdmin) { // make sure the user isn't banned from this sub if (_subUserBanService.IsUserBannedFromSub(sub.Id, user.Id)) { response.Error = "You are currently banned from this sub."; return(response); } } // TODO: does user look like spam? // todo: make sure the post type is allowed if (string.IsNullOrEmpty(command.Title)) { response.Error = "The title is required."; return(response); } // remove extrenous white space, and trim whitespace from the edges command.Title = Regex.Replace(command.Title, @"\s+", " ").Trim(); if (command.Title.Length > 300) { response.Error = "The title is too long."; return(response); } string domain = null; if (command.PostType == PostType.Link) { if (string.IsNullOrEmpty(command.Url)) { response.Error = "You must provide a url."; return(response); } // check https://github.com/skimur/skimur/issues/83 command.Url = command.Url.RemoveBOM(); // todo: improve url validation string scheme; string formattedUrl; if (!UrlParser.TryParseUrl(command.Url, out formattedUrl, out domain, out scheme)) { response.Error = "The url appears to be invalid."; return(response); } command.Url = formattedUrl; switch (scheme) { case "http": case "https": break; default: response.Error = "The scheme is invalid for the url."; return(response); } // todo: make sure the domain isn't banned // todo: make sure the url wasn't already submitted } else if (command.PostType == PostType.Text) { if (!user.IsAdmin) { if (!string.IsNullOrEmpty(command.Content) && command.Content.Length > 40000) { response.Error = "The post content is too long (maximum 40000 characters)."; return(response); } } } else { throw new Exception("unknown post type " + command.PostType); } bool isNsfw; if (sub.Nsfw) { // NSFW by default isNsfw = true; } else { // Let's see if the user marked this as NSFW. isNsfw = Common.IsNsfw(command.Title); } var post = new Post { Id = GuidUtil.NewSequentialId(), DateCreated = command.OverrideDateCreated.HasValue ? command.OverrideDateCreated.Value : Common.CurrentTime(), LastEditDate = null, SubId = sub.Id, UserId = user.Id, UserIp = command.IpAddress, PostType = command.PostType, Title = command.Title, SendReplies = command.NotifyReplies, Mirrored = command.Mirror, Nsfw = isNsfw, InAll = sub.InAll }; List <string> mentions = null; if (post.PostType == PostType.Link) { post.Url = command.Url; post.Domain = domain; } else { post.Content = command.Content; post.ContentFormatted = _markdownCompiler.Compile(post.Content, out mentions); } _postService.InsertPost(post); _commandBus.Send(new CastVoteForPost { DateCasted = post.DateCreated, IpAddress = command.IpAddress, PostId = post.Id, UserId = user.Id, VoteType = VoteType.Up }); if (mentions != null && mentions.Count > 0) { _eventBus.Publish(new UsersMentioned { PostId = post.Id, Users = mentions }); } _commandBus.Send(new GenerateThumbnailForPost { PostId = post.Id }); if (_embeddedProvider.IsEnabled) { _commandBus.Send(new GenerateEmbeddedMediaObject { PostId = post.Id }); } response.Title = command.Title; response.PostId = post.Id; } catch (Exception ex) { // todo: log response.Error = ex.Message; } return(response); }
static void Main(string[] args) { try { SkimurContext.Initialize( new Program(), new Skimur.App.Registrar()); _mirrorSettings = SkimurContext.ServiceProvider.GetRequiredService<ISettingsProvider<MirrorSettings>>().Settings; _subService = SkimurContext.ServiceProvider.GetRequiredService<ISubService>(); _postService = SkimurContext.ServiceProvider.GetRequiredService<IPostService>(); _membershipService = SkimurContext.ServiceProvider.GetRequiredService<IMembershipService>(); _commandBus = SkimurContext.ServiceProvider.GetRequiredService<ICommandBus>(); if (_mirrorSettings.SubsToMirror == null || _mirrorSettings.SubsToMirror.Count == 0) return; var botUser = _membershipService.GetUserByUserName(_mirrorSettings.BotName); if (botUser == null) return; var reddit = new Reddit(); foreach (var subToMirror in _mirrorSettings.SubsToMirror) { Console.WriteLine("Attempting to mirror " + subToMirror + "."); var sub = _subService.GetSubByName(subToMirror); if (sub == null) { Console.WriteLine("Sub doesn't exist."); continue; } var redditSub = reddit.GetSubreddit("/r/" + subToMirror); if (redditSub == null) { Console.WriteLine("Couldn't find reddit sub."); continue; } foreach (var redditPost in redditSub.GetTop(_mirrorSettings.FromTime).Take(_mirrorSettings.PostsPerSub)) { Console.WriteLine("Syncing " + redditPost.Title); var existing = _postService.QueryPosts(redditPost.Title, sub.Id).Select(x => _postService.GetPostById(x)).ToList(); var exists = false; if (existing.Count > 0) { foreach (var item in existing) { if (item.Title == redditPost.Title && item.Mirrored == "reddit") exists = true; } } if (exists) { Console.WriteLine("Already exists."); continue; } var createPostResponse = _commandBus.Send<CreatePost, CreatePostResponse>( new CreatePost { CreatedByUserId = botUser.Id, Title = redditPost.Title, Url = redditPost.Url.ToString(), Content = redditPost.SelfText, PostType = redditPost.IsSelfPost ? PostType.Text : PostType.Link, SubName = subToMirror, NotifyReplies = false, Mirror = "reddit", OverrideDateCreated = redditPost.CreatedUTC }); if (!string.IsNullOrEmpty(createPostResponse.Error)) { Console.WriteLine("Couldn't create post. " + createPostResponse.Error); continue; } if (!createPostResponse.PostId.HasValue) { Console.WriteLine("No post id"); continue; } var createCommentResponse = _commandBus.Send<CreateComment, CreateCommentResponse>( new CreateComment { PostId = createPostResponse.PostId.Value, DateCreated = Common.CurrentTime(), AuthorUserName = botUser.UserName, Body = string.Format("Mirrored from [here]({0}).", redditPost.Shortlink), SendReplies = false }); if (!string.IsNullOrEmpty(createCommentResponse.Error)) { Console.WriteLine("Couldn't create comment. " + createCommentResponse.Error); } } } } catch (Exception ex) { Console.WriteLine(ex.Message); } }
public SendMessageResponse Handle(SendMessage command) { var response = new SendMessageResponse(); try { var author = _membershipService.GetUserById(command.Author); if (author == null) { response.Error = "No author provided."; return(response); } Sub sendAsSub = null; Sub sendingToSub = null; User sendingToUser = null; if (command.SendAsSub.HasValue) { var sub = _subService.GetSubById(command.SendAsSub.Value); if (sub == null) { response.Error = "Invalid sub to send as."; return(response); } // the user is trying to send this message as a sub moderator. // let's make sure that this user has this permission for the sub. if (!_permissionService.CanUserManageSubMail(author, command.SendAsSub.Value)) { response.Error = "You are not authorized to send a message as a sub moderator."; return(response); } sendAsSub = sub; } if (string.IsNullOrEmpty(command.To) && !command.ToUserId.HasValue) { response.Error = "You must provide a user/sub to send the message to."; return(response); } if (command.ToUserId.HasValue && !string.IsNullOrEmpty(command.To)) { throw new Exception("A message with a userid and to was provided. Pick one."); } if (command.ToUserId.HasValue) { sendingToUser = _membershipService.GetUserById(command.ToUserId.Value); if (sendingToUser == null) { response.Error = "No user found to send message to."; return(response); } } else { if (command.To.StartsWith("/u/", StringComparison.InvariantCultureIgnoreCase)) { var userName = command.To.Substring(3); sendingToUser = _membershipService.GetUserByUserName(userName); if (sendingToUser == null) { response.Error = string.Format("No user found with the name {0}.", userName); return(response); } } else if (command.To.StartsWith("/s/", StringComparison.InvariantCultureIgnoreCase)) { var subName = command.To.Substring(3); sendingToSub = _subService.GetSubByName(subName); if (sendingToSub == null) { response.Error = string.Format("No sub found with the name {0}.", subName); return(response); } } else { // maybe they are trying to send a message to a user sendingToUser = _membershipService.GetUserByUserName(command.To); if (sendingToUser == null) { response.Error = string.Format("No user found with the name {0}.", command.To); return(response); } } } // let's make sure the message type is correct switch (command.Type) { case MessageType.Private: if (command.CommentId.HasValue) { throw new Exception("A privat message was sent with a reference to a comment id. How?"); } break; case MessageType.CommentReply: if (!command.CommentId.HasValue) { throw new Exception("The message type was a comment reply, but no comment id was given."); } break; case MessageType.PostReply: if (!command.CommentId.HasValue) { throw new Exception("The message type was a post reply, but no comment id was given."); } break; case MessageType.Mention: // ensure either 1 comment is given, or 1 post is given if (!command.CommentId.HasValue && !command.PostId.HasValue) { throw new Exception("The message type was a mention, but neither a comment or a post was given."); } if (command.PostId.HasValue && command.CommentId.HasValue) { throw new Exception("The message type was a mention, but both a comment and post were given. Pick one."); } break; default: throw new Exception("Unknown message type"); } var message = new Message { Id = GuidUtil.NewSequentialId(), DateCreated = Common.CurrentTime(), MessageType = command.Type, ParentId = null, FirstMessage = null, AuthorId = author.Id, AuthorIp = command.AuthorIp, IsNew = true, ToUser = sendingToUser != null ? sendingToUser.Id : (Guid?)null, ToSub = sendingToSub != null ? sendingToSub.Id : (Guid?)null, FromSub = sendAsSub != null ? sendAsSub.Id : (Guid?)null, Subject = command.Subject, Body = command.Body, BodyFormatted = _markdownCompiler.Compile(command.Body), CommentId = command.CommentId, PostId = command.PostId }; _messageService.InsertMessage(message); response.MessageId = message.Id; } catch (Exception ex) { _logger.Error("Error sending a message.", ex); response.Error = "An unknown error occured."; } return(response); }