Пример #1
0
        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);
        }
Пример #2
0
        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);
        }
Пример #3
0
        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);
        }
Пример #4
0
        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);
        }