public List <int> GetIndexIds(int boardId, int page, int unreadFilter, DateTime historyTimeLimit, List <DataModels.Participant> participation, List <DataModels.ViewLog> viewLogs) { var take = SettingsRepository.TopicsPerPage(); var skip = (page - 1) * take; var forbiddenBoardIdsQuery = from role in RoleRepository.SiteRoles join board in RoleRepository.BoardRoles on role.Id equals board.RoleId where !UserContext.Roles.Contains(role.Id) select board.BoardId; var forbiddenBoardIds = forbiddenBoardIdsQuery.ToList(); var messageQuery = from message in DbContext.Messages where message.ParentId == 0 select new { message.Id, message.LastReplyPosted }; if (boardId > 0) { messageQuery = from message in DbContext.Messages join messageBoard in DbContext.MessageBoards on message.Id equals messageBoard.MessageId where message.ParentId == 0 where messageBoard.BoardId == boardId select new { message.Id, message.LastReplyPosted }; } if (unreadFilter > 0) { messageQuery = messageQuery.Where(m => m.LastReplyPosted > historyTimeLimit); } var pinnedTopicIds = PinRepository.Select(item => item.MessageId).ToList(); var sortedMessageQuery = from message in messageQuery let pinned = pinnedTopicIds.Contains(message.Id) orderby message.LastReplyPosted descending orderby pinned descending select new { message.Id, message.LastReplyPosted }; var messageIds = new List <int>(); var attempts = 0; var skipped = 0; foreach (var message in sortedMessageQuery) { if (IsAccessDenied(message.Id, forbiddenBoardIds)) { if (attempts++ > 100) { break; } continue; } var unreadLevel = unreadFilter == 0 ? 0 : GetUnreadLevel(message.Id, message.LastReplyPosted, participation, viewLogs); if (unreadLevel < unreadFilter) { if (attempts++ > 100) { break; } continue; } if (skipped++ < skip) { continue; } messageIds.Add(message.Id); if (messageIds.Count == take) { break; } } return(messageIds); }
public ServiceModels.ServiceResponse GetLatest(int messageId) { var serviceResponse = new ServiceModels.ServiceResponse(); var record = DbContext.Messages.Find(messageId); if (record is null) { throw new HttpNotFoundError(); } if (record.ParentId > 0) { record = DbContext.Messages.Find(record.ParentId); } if (!UserContext.IsAuthenticated) { serviceResponse.RedirectPath = UrlHelper.Action(nameof(Controllers.Topics.Display), nameof(Controllers.Topics), new { id = record.LastReplyId }); return(serviceResponse); } var historyTimeLimit = SettingsRepository.HistoryTimeLimit(); var viewLogs = DbContext.ViewLogs.Where(r => r.UserId == UserContext.ApplicationUser.Id && r.LogTime >= historyTimeLimit).ToList(); var latestViewTime = historyTimeLimit; foreach (var viewLog in viewLogs) { switch (viewLog.TargetType) { case EViewLogTargetType.All: if (viewLog.LogTime >= latestViewTime) { latestViewTime = viewLog.LogTime; } break; case EViewLogTargetType.Message: if (viewLog.TargetId == record.Id && viewLog.LogTime >= latestViewTime) { latestViewTime = viewLog.LogTime; } break; } } var messageIdQuery = from message in DbContext.Messages where message.Id == record.Id || message.ParentId == record.Id where message.TimePosted > latestViewTime select message.Id; var latestMessageId = messageIdQuery.FirstOrDefault(); if (latestMessageId == 0) { latestMessageId = record.LastReplyId; } if (latestMessageId == 0) { latestMessageId = record.Id; } serviceResponse.RedirectPath = UrlHelper.Action(nameof(Controllers.Topics.Display), nameof(Controllers.Topics), new { id = latestMessageId }); return(serviceResponse); }
public List <ItemModels.MessagePreview> GetPreviews(int boardId, int page, int unread) { var participation = new List <DataModels.Participant>(); var viewLogs = new List <DataModels.ViewLog>(); var historyTimeLimit = SettingsRepository.HistoryTimeLimit(); if (UserContext.IsAuthenticated) { participation = DbContext.Participants.Where(r => r.UserId == UserContext.ApplicationUser.Id).ToList(); viewLogs = DbContext.ViewLogs.Where(r => r.LogTime >= historyTimeLimit && r.UserId == UserContext.ApplicationUser.Id).ToList(); } var sortedMessageIds = GetIndexIds(boardId, page, unread, historyTimeLimit, participation, viewLogs); var messageQuery = from message in DbContext.Messages where sortedMessageIds.Contains(message.Id) select new { message.Id, message.ShortPreview, message.ViewCount, message.ReplyCount, message.TimePosted, message.LastReplyId, message.LastReplyById, message.LastReplyPosted }; var messages = messageQuery.ToList(); var take = SettingsRepository.MessagesPerPage(); var popularityLimit = SettingsRepository.PopularityLimit(); var messagePreviews = new List <ItemModels.MessagePreview>(); foreach (var messageId in sortedMessageIds) { var message = messages.First(item => item.Id == messageId); var messagePreview = new ItemModels.MessagePreview { Id = message.Id, ShortPreview = string.IsNullOrEmpty(message.ShortPreview.Trim()) ? "No subject" : message.ShortPreview, Views = message.ViewCount, Replies = message.ReplyCount, Pages = Convert.ToInt32(Math.Ceiling(1.0 * message.ReplyCount / take)), LastReplyId = message.Id, Popular = message.ReplyCount > popularityLimit, Pinned = PinRepository.Any(item => item.MessageId == message.Id) }; messagePreviews.Add(messagePreview); var lastMessageTime = message.TimePosted; if (message.LastReplyId != 0) { var lastReplyDetails = (from item in DbContext.Messages join postedBy in DbContext.Users on item.PostedById equals postedBy.Id where item.Id == message.LastReplyId select new { postedBy.DisplayName, item.ShortPreview }).FirstOrDefault(); if (lastReplyDetails != null) { messagePreview.LastReplyId = message.LastReplyId; messagePreview.LastReplyPreview = lastReplyDetails.ShortPreview; messagePreview.LastReplyByName = lastReplyDetails.DisplayName; messagePreview.LastReplyById = message.LastReplyById; messagePreview.LastReplyPosted = message.LastReplyPosted.ToPassedTimeString(); messagePreview.LastReplyPostedDT = message.LastReplyPosted; lastMessageTime = message.LastReplyPosted; } } if (lastMessageTime > historyTimeLimit) { messagePreview.Unread = GetUnreadLevel(message.Id, lastMessageTime, participation, viewLogs); } } return(messagePreviews); }
public async Task <ServiceModels.ServiceResponse> UpdateAccount(InputModels.UpdateAccountInput input) { var serviceResponse = new ServiceModels.ServiceResponse(); if (!await UserManager.CheckPasswordAsync(UserContext.ApplicationUser, input.Password)) { var message = $"Invalid password for '{input.DisplayName}'."; serviceResponse.Error(nameof(InputModels.UpdateAccountInput.Password), message); Log.LogWarning(message); } var userRecord = await UserManager.FindByIdAsync(input.Id); if (userRecord is null) { var message = $"No user record found for '{input.DisplayName}'."; serviceResponse.Error(message); Log.LogCritical(message); } CanEdit(userRecord.Id); if (userRecord is null) { var message = $"No user account found for '{input.DisplayName}'."; serviceResponse.Error(message); Log.LogCritical(message); } if (!serviceResponse.Success) { return(serviceResponse); } if (input.DisplayName != userRecord.DisplayName) { userRecord.DisplayName = input.DisplayName; DbContext.Update(userRecord); Log.LogInformation($"Display name was modified by '{UserContext.ApplicationUser.DisplayName}' for account '{userRecord.DisplayName}'."); } var birthday = new DateTime(input.BirthdayYear, input.BirthdayMonth, input.BirthdayDay); if (birthday != userRecord.Birthday) { userRecord.Birthday = birthday; DbContext.Update(userRecord); Log.LogInformation($"Birthday was modified by '{UserContext.ApplicationUser.DisplayName}' for account '{userRecord.DisplayName}'."); } DbContext.SaveChanges(); if (input.NewEmail != userRecord.Email) { serviceResponse.RedirectPath = UrlHelper.Action(nameof(Account.Details), nameof(Account), new { id = input.DisplayName }); var identityResult = await UserManager.SetEmailAsync(userRecord, input.NewEmail); if (!identityResult.Succeeded) { foreach (var error in identityResult.Errors) { Log.LogError($"Error modifying email by '{UserContext.ApplicationUser.DisplayName}' from '{userRecord.Email}' to '{input.NewEmail}'. Message: {error.Description}"); serviceResponse.Error(error.Description); } return(serviceResponse); } identityResult = await UserManager.SetUserNameAsync(userRecord, input.NewEmail); if (!identityResult.Succeeded) { foreach (var error in identityResult.Errors) { Log.LogError($"Error modifying username by '{UserContext.ApplicationUser.DisplayName}' from '{userRecord.Email}' to '{input.NewEmail}'. Message: {error.Description}"); serviceResponse.Error(error.Description); } return(serviceResponse); } Log.LogInformation($"Email address was modified by '{UserContext.ApplicationUser.DisplayName}' from '{userRecord.Email}' to '{input.NewEmail}'."); var code = await UserManager.GenerateEmailConfirmationTokenAsync(userRecord); if (EmailSender.Ready) { var callbackUrl = EmailConfirmationLink(userRecord.Id, code); await EmailSender.SendEmailConfirmationAsync(input.NewEmail, callbackUrl); if (userRecord.Id == UserContext.ApplicationUser.Id) { await SignOut(); } } else { identityResult = await UserManager.ConfirmEmailAsync(userRecord, code); if (!identityResult.Succeeded) { foreach (var error in identityResult.Errors) { Log.LogError($"Error confirming '{userRecord.Email}'. Message: {error.Description}"); serviceResponse.Error(error.Description); } } else { Log.LogInformation($"User confirmed email '{userRecord.Email}'."); } } return(serviceResponse); } SettingsRepository.UpdateUserSettings(input); if (!string.IsNullOrEmpty(input.NewPassword) && input.Password != input.NewPassword && UserContext.ApplicationUser.Id == input.Id) { var identityResult = await UserManager.ChangePasswordAsync(userRecord, input.Password, input.NewPassword); if (!identityResult.Succeeded) { foreach (var error in identityResult.Errors) { Log.LogError($"Error modifying password by '{UserContext.ApplicationUser.DisplayName}' for '{userRecord.DisplayName}'. Message: {error.Description}"); serviceResponse.Error(nameof(InputModels.UpdateAccountInput.NewPassword), error.Description); } } else if (userRecord.Id == UserContext.ApplicationUser.Id) { Log.LogInformation($"Password was modified by '{UserContext.ApplicationUser.DisplayName}' for '{userRecord.DisplayName}'."); await SignOut(); serviceResponse.RedirectPath = UrlHelper.Action(nameof(Login)); return(serviceResponse); } } if (serviceResponse.Success) { serviceResponse.RedirectPath = UrlHelper.Action(nameof(Account.Details), nameof(Account), new { id = input.DisplayName }); } return(serviceResponse); }