public async Task <ChannelVm> EditChannelAsync(ChannelVm channel, long editorUserId) { using (MessengerDbContext context = contextFactory.Create()) { ChannelUser channelUser = await context.ChannelUsers .Include(opt => opt.Channel) .FirstOrDefaultAsync(opt => opt.ChannelId == channel.ChannelId && opt.UserId == editorUserId && opt.ChannelUserRole >= ChannelUserRole.Administrator) .ConfigureAwait(false); if (channelUser != null) { if (channelUser.ChannelUserRole == ChannelUserRole.Administrator && (channelUser.Banned || channelUser.Deleted)) { throw new PermissionDeniedException(); } channelUser.Channel = ChannelConverter.GetChannel(channelUser.Channel, channel); context.Update(channelUser.Channel); await context.SaveChangesAsync().ConfigureAwait(false); var editedChannel = ChannelConverter.GetChannel(channelUser.Channel); editedChannel.UserRole = channelUser.ChannelUserRole; editedChannel.SubscribersCount = await context.ChannelUsers.CountAsync(opt => opt.Deleted == false && opt.ChannelId == channel.ChannelId).ConfigureAwait(false); return(editedChannel); } throw new PermissionDeniedException(); } }
public async Task NewOrEditUserAsync(ShortUser shortUser, long nodeId = 0) { using (MessengerDbContext context = contextFactory.Create()) { try { var user = await context.Users.FindAsync(shortUser.UserId).ConfigureAwait(false); if (user == null) { user = new User { Id = shortUser.UserId, NodeId = nodeId, Confirmed = true }; await context.Users.AddAsync(user).ConfigureAwait(false); } else { user.NodeId = nodeId; user.Confirmed = true; context.Update(user); } await context.SaveChangesAsync().ConfigureAwait(false); } catch (Exception ex) { Logger.WriteLog(ex); } } }
public async Task <Chat> Update(Chat entity) { var result = context.Update(entity).Entity; await context.SaveChangesAsync(); return(result); }
public async Task UpdateLastReadedMessageIdAsync(Guid messageId, long userId, long chatId) { try { using (MessengerDbContext context = contextFactory.Create()) { var targetChatUser = await context.ChatUsers .Where(chatUser => chatUser.ChatId == chatId && chatUser.UserId == userId) .FirstOrDefaultAsync() .ConfigureAwait(false); var updatingMessage = await context.Messages.FirstOrDefaultAsync(opt => opt.ChatId == chatId && opt.GlobalId == messageId).ConfigureAwait(false); var oldMessage = await context.Messages.FirstOrDefaultAsync(opt => opt.ChatId == chatId && opt.GlobalId == targetChatUser.LastReadedGlobalMessageId).ConfigureAwait(false); if (oldMessage != null && oldMessage.SendingTime > updatingMessage.SendingTime) { return; } targetChatUser.LastReadedGlobalMessageId = messageId; context.Update(targetChatUser); await context.SaveChangesAsync().ConfigureAwait(false); } } catch (Exception ex) { Logger.WriteLog(ex); } }
public async Task DeleteUserInformationAsync(long userId) { try { using (MessengerDbContext context = contextFactory.Create()) { User user = await context.Users .Include(opt => opt.Emails) .Include(opt => opt.Phones) .Include(opt => opt.Tokens) .FirstOrDefaultAsync(opt => opt.Id == userId) .ConfigureAwait(false); user.Phones = null; user.Emails = null; user.About = null; user.Birthday = null; user.City = null; user.Country = null; user.Sha512Password = null; user.Photo = null; user.NameSecond = null; user.NameFirst = "unknown"; user.Tokens = null; context.Update(user); await context.SaveChangesAsync().ConfigureAwait(false); } } catch (Exception ex) { Logger.WriteLog(ex); } }
public async Task <ChatVm> NewOrEditChatAsync(ChatVm targetChat) { if (targetChat == null) { return(null); } try { using (MessengerDbContext context = contextFactory.Create()) { var query = from chat in context.Chats where chat.Id == targetChat.Id select chat; Chat editableChat = await query.Include(opt => opt.ChatUsers).FirstOrDefaultAsync().ConfigureAwait(false); if (editableChat == null) { editableChat = ChatConverter.GetChat(targetChat); if (targetChat.Users != null) { editableChat.ChatUsers = ChatUserConverter.GetChatUsers(targetChat.Users).ToList(); } await context.AddAsync(editableChat).ConfigureAwait(false); } else { editableChat = ChatConverter.GetChat(editableChat, new EditChatVm { About = targetChat.About, Name = targetChat.Name, Photo = targetChat.Photo, Public = targetChat.Public, Security = targetChat.Security, Visible = targetChat.Visible }); if (!targetChat.Users.IsNullOrEmpty()) { editableChat.ChatUsers = ChatUserConverter.GetChatUsers(targetChat.Users); } context.Update(editableChat); } await context.SaveChangesAsync().ConfigureAwait(false); return(ChatConverter.GetChatVm(editableChat)); } } catch (DbUpdateException ex) { Logger.WriteLog(ex); return(targetChat); } catch (Exception ex) { Logger.WriteLog(ex); return(null); } }
public async Task NewOrEditNodeAsync(NodeVm targetNode) { try { using (MessengerDbContext context = contextFactory.Create()) { var node = await context.Nodes.FindAsync(targetNode.Id).ConfigureAwait(false); if (node == null) { node = NodeConverter.GetNode(targetNode); await context.AddAsync(node).ConfigureAwait(false); } else { node = NodeConverter.GetNode(targetNode); context.Update(node); } await context.SaveChangesAsync().ConfigureAwait(false); } } catch (Exception ex) { Logger.WriteLog(ex); } }
public async Task <UserDto> CreateOrUpdateUserAsync(UserDto user) { using (MessengerDbContext context = contextFactory.Create()) { User userInfo = await context.Users .Include(opt => opt.UserPublicKeys) .Include(opt => opt.Phones) .Include(opt => opt.Emails) .Include(opt => opt.BlackList) .Include(opt => opt.Tokens) .FirstOrDefaultAsync(opt => opt.Id == user.Id) .ConfigureAwait(false); if (userInfo != null) { userInfo = UserConverter.GetUser(userInfo, user); context.Update(userInfo); } else { userInfo = UserConverter.GetUser(user); await context.AddAsync(userInfo).ConfigureAwait(false); } await context.SaveChangesAsync().ConfigureAwait(false); return(UserConverter.GetUserDto(userInfo, null, null)); } }
public async Task <long> GetChatIdAsync() { using (MessengerDbContext context = contextFactory.Create()) { using (var transaction = await context.Database.BeginTransactionAsync().ConfigureAwait(false)) { try { ChatIdentificator identificator; if (!await context.UsersIdentificators.AnyAsync(opt => !opt.IsUsed).ConfigureAwait(false)) { var nodePools = await LicensorClient.Instance.GetNodePoolsAsync(PoolType.Chats).ConfigureAwait(false); await SaveNodePoolsAsync(nodePools).ConfigureAwait(false); } identificator = await context.ChatsIdentificators.FirstOrDefaultAsync(opt => !opt.IsUsed).ConfigureAwait(false); identificator.IsUsed = true; context.Update(identificator); transaction.Commit(); await context.SaveChangesAsync().ConfigureAwait(false); return(identificator.ChatId); } catch (Exception ex) { transaction.Rollback(); throw new InternalErrorException("Error getting identifier.", ex); } } } }
public async Task <TokenVm> CheckTokenAsync(TokenVm targetToken, long nodeId) { long userId = targetToken.UserId; using (MessengerDbContext context = contextFactory.Create()) { Token tokenPair = await context.Tokens .Include(token => token.User) .FirstOrDefaultAsync( token => token.UserId == userId && token.AccessToken == targetToken.AccessToken && !token.User.Deleted) .ConfigureAwait(false); if (tokenPair == null) { User userInfo = await context.Users.FindAsync(userId).ConfigureAwait(false); if (userInfo != null && userInfo.NodeId != nodeId) { throw new UserFromAnotherNodeException(userInfo.NodeId); } throw new InvalidTokenException(); } if (DateTime.UtcNow <= tokenPair.AccessTokenExpirationTime.ToDateTime()) { tokenPair.DeviceTokenId = targetToken.DeviceTokenId; context.Update(tokenPair); await context.SaveChangesAsync().ConfigureAwait(false); return(TokenConverter.GetTokenVm(tokenPair)); } if (DateTime.UtcNow >= tokenPair.AccessTokenExpirationTime.ToDateTime() && DateTime.UtcNow <= tokenPair.RefreshTokenExpirationTime.GetValueOrDefault().ToDateTime()) { string accessToken = RandomExtensions.NextString(64); string refreshToken = RandomExtensions.NextString(64); Token newToken = new Token { AccessToken = accessToken, RefreshToken = refreshToken, UserId = userId, DeviceTokenId = targetToken.DeviceTokenId, AccessTokenExpirationTime = DateTime.UtcNow.AddHours(ACCESS_LIFETIME_HOUR).ToUnixTime(), RefreshTokenExpirationTime = DateTime.UtcNow.AddHours(REFRESH_LIFETIME_HOUR).ToUnixTime() }; await context.Tokens.AddAsync(newToken).ConfigureAwait(false); context.Remove(tokenPair); await context.SaveChangesAsync().ConfigureAwait(false); context.Database.CloseConnection(); return(TokenConverter.GetTokenVm(newToken)); } throw new TokensTimeoutException(); } }
public async Task <FileInfoVm> UpdateFileInformationAsync(string fileName, string fileId) { using (MessengerDbContext context = contextFactory.Create()) { FileInfo fileInfo = await context.FilesInfo.FindAsync(fileId).ConfigureAwait(false); fileInfo.Url = fileName; context.Update(fileInfo); await context.SaveChangesAsync().ConfigureAwait(false); return(FileInfoConverter.GetFileInfoVm(fileInfo)); } }
public async Task DeleteChatAsync(long chatId) { using (MessengerDbContext context = contextFactory.Create()) { Chat chat = await context.Chats.FindAsync(chatId).ConfigureAwait(false); if (chat != null) { chat.Deleted = true; context.Update(chat); await context.SaveChangesAsync().ConfigureAwait(false); } } }
public async Task DeleteFileAsync(long fileId) { using (MessengerDbContext context = contextFactory.Create()) { FileInfo fileInfo = await context.FilesInfo.FindAsync(fileId).ConfigureAwait(false); if (fileInfo != null) { fileInfo.Deleted = true; context.Update(fileInfo); await context.SaveChangesAsync().ConfigureAwait(false); } } }
public async Task DeleteUserAsync(long userId) { using (MessengerDbContext context = contextFactory.Create()) { User user = await context.Users.FindAsync(userId).ConfigureAwait(false); if (user != null) { user.Deleted = true; context.Update(user); await context.SaveChangesAsync().ConfigureAwait(false); } } }
public async Task <UserVm> EditUserAsync(EditUserVm editableUser, long userId) { using (MessengerDbContext context = contextFactory.Create()) { User editedUser = await context.Users .Include(user => user.Phones) .Include(user => user.Emails) .FirstOrDefaultAsync(user => user.Id == userId && user.Deleted == false) .ConfigureAwait(false); editedUser = UserConverter.GetUser(editedUser, editableUser); context.Update(editedUser); await context.SaveChangesAsync().ConfigureAwait(false); return(UserConverter.GetUserVm(editedUser)); } }
public async Task <ContactDto> CreateOrEditContactAsync(ContactDto contactDto) { try { using (MessengerDbContext context = contextFactory.Create()) { Contact result; var contact = await context.Contacts .Include(opt => opt.ContactGroups) .FirstOrDefaultAsync(opt => opt.UserId == contactDto.UserId && opt.ContactUserId == contactDto.ContactUserId) .ConfigureAwait(false); if (contact == null) { Contact newContact = new Contact { Name = contactDto.Name, UserId = contactDto.UserId, ContactUserId = contactDto.ContactUserId, ContactId = contactDto.ContactId }; await context.Contacts.AddAsync(newContact).ConfigureAwait(false); result = newContact; } else { contact.Name = contactDto.Name; context.Update(contact); result = contact; } await context.SaveChangesAsync().ConfigureAwait(false); return(ContactConverter.GetContactDto(result)); } } catch (PostgresException ex) { if (ex.SqlState == "23503") { throw new ObjectDoesNotExistsException("User not found.", ex); } throw new InternalErrorException("Database error.", ex); } }
public async Task <KeyVm> SetNewSymmetricKeyForChat(KeyVm key, long chatId, long userId) { using (MessengerDbContext context = contextFactory.Create()) { ChatUser chatUser = await context.ChatUsers .Where(opt => opt.ChatId == chatId && opt.UserId == userId && opt.UserRole >= UserRole.Admin && !opt.Deleted && !opt.Banned) .FirstOrDefaultAsync() .ConfigureAwait(false); if (chatUser == null) { throw new UserIsNotInConversationException(); } Key chatKey = await context.Keys.FirstOrDefaultAsync(opt => opt.ChatId == chatId).ConfigureAwait(false); if (chatKey == null) { chatKey = KeyConverter.GetKey(key); chatKey.ChatId = chatId; chatKey.UserId = null; chatKey.KeyId = RandomExtensions.NextInt64(); await context.AddAsync(chatKey).ConfigureAwait(false); } else { chatKey.ChatId = chatId; chatKey.KeyData = key.Data; chatKey.Version = 1; chatKey.UserId = null; chatKey.GenerationTimeSeconds = key.GenerationTime; chatKey.ExpirationTimeSeconds = key.GenerationTime + key.Lifetime; context.Update(chatKey); } await context.SaveChangesAsync().ConfigureAwait(false); return(KeyConverter.GetKeyVm(chatKey)); } }
private async Task <List <MessageDto> > DeleteChannelMessagesInfoAsync(long channelId, IEnumerable <Guid> messagesIds, long userId) { try { using (MessengerDbContext context = contextFactory.Create()) { var messagesCondition = PredicateBuilder.New <Message>(); messagesCondition = messagesIds.Aggregate(messagesCondition, (current, value) => current.Or(opt => opt.GlobalId == value).Expand()); var channelUser = await context.ChannelUsers .Include(opt => opt.Channel) .FirstOrDefaultAsync(opt => opt.ChannelId == channelId && opt.UserId == userId && opt.ChannelUserRole >= ChannelUserRole.Administrator) .ConfigureAwait(false); if (channelUser == null) { throw new PermissionDeniedException(); } var messages = await context.Messages .Include(opt => opt.Attachments) .Where(messagesCondition) .Where(opt => opt.ChannelId == channelId) .ToListAsync() .ConfigureAwait(false); if (!messages.Any()) { return(new List <MessageDto>()); } var deletedMessagesIds = messages.Select(message => message.GlobalId).ToList(); var usersCondition = PredicateBuilder.New <ChannelUser>(); usersCondition = deletedMessagesIds.Aggregate(usersCondition, (current, value) => current.Or(opt => opt.LastReadedGlobalMessageId == value).Expand()); var channelUsers = await context.ChannelUsers.Where(usersCondition).ToListAsync().ConfigureAwait(false); var groupedChannelUsers = channelUsers.GroupBy(opt => opt.LastReadedGlobalMessageId); foreach (var group in groupedChannelUsers) { var message = await context.Messages .OrderByDescending(opt => opt.SendingTime) .ThenBy(opt => opt.GlobalId) .Where(opt => !deletedMessagesIds.Contains(opt.GlobalId) && opt.ChannelId == channelId && !opt.Deleted) .FirstOrDefaultAsync() .ConfigureAwait(false); foreach (var user in group) { user.LastReadedGlobalMessageId = message?.GlobalId; } context.ChannelUsers.UpdateRange(group); } var deletedMessages = MessageConverter.GetMessagesDto(messages); messages.ForEach(message => { message.Deleted = true; message.UpdatedAt = DateTime.UtcNow.ToUnixTime(); if (NodeSettings.Configs.Node.PermanentlyDeleting) { message.Attachments = null; message.Replyto = null; message.SendingTime = 0; message.Text = null; message.SenderId = null; } }); context.UpdateRange(messages); await context.SaveChangesAsync().ConfigureAwait(false); Message lastValidMessage = await _loadMessagesService.GetLastValidChannelMessageAsync(channelId).ConfigureAwait(false); channelUser.Channel.LastMessageId = lastValidMessage?.Id ?? null; channelUser.Channel.LastMessageGlobalId = lastValidMessage?.GlobalId; context.Update(channelUser); await context.SaveChangesAsync().ConfigureAwait(false); return(deletedMessages); } } catch (Exception ex) { throw new DeleteMessagesException("An error ocurred while deleting the messages.", ex); } }
public async Task <ChatVm> AddUsersToChatAsync(IEnumerable <long> usersId, long chatId, long userId) { using (MessengerDbContext context = contextFactory.Create()) { using (var transaction = await context.Database.BeginTransactionAsync().ConfigureAwait(false)) { Chat chat = await context.Chats.FirstOrDefaultAsync(opt => opt.Id == chatId).ConfigureAwait(false); if (chat == null) { throw new ConversationNotFoundException(chatId); } User requestingUser = await context.Users.FindAsync(userId).ConfigureAwait(false); if (requestingUser == null || requestingUser.Deleted) { throw new AddUserChatException(); } ChatUser chatUser = await context.ChatUsers .FirstOrDefaultAsync(opt => opt.ChatId == chatId && opt.UserId == userId).ConfigureAwait(false); List <ChatUserVm> addedUsers = new List <ChatUserVm>(); if (chat.Deleted) { throw new ConversationIsNotValidException(); } if (chatUser != null && chatUser.Banned) { throw new ChatUserBlockedException(); } if (usersId.Count() == 1 && usersId.FirstOrDefault() == userId) { if (chat.Type == (int)ChatType.Private) { throw new AddUserChatException(); } if (chatUser == null) { chatUser = ChatUserConverter.GetNewChatUser(chatId, userId, null); await context.AddAsync(chatUser).ConfigureAwait(false); } else if (chatUser.Deleted) { chatUser.Deleted = false; chatUser.User = requestingUser; context.Update(chatUser); } if (!chat.NodesId.Contains(NodeSettings.Configs.Node.Id)) { createMessagesService.DownloadMessageHistoryAsync(chat.NodesId.FirstOrDefault(), chat.Id, ConversationType.Chat, null, false); } chat.NodesId = chat.NodesId.Append(requestingUser.NodeId.Value).Distinct().ToArray(); addedUsers.Add(ChatUserConverter.GetChatUserVm(chatUser)); } else { if ((chatUser?.Deleted).GetValueOrDefault(true)) { throw new AddUserChatException(); } if (await loadUsersService.IsUserBlacklisted(userId, usersId).ConfigureAwait(false)) { throw new UserBlockedException(); } ExpressionStarter <User> usersCondition = PredicateBuilder.New <User>(); usersCondition = usersId.Aggregate(usersCondition, (current, value) => current.Or(opt => opt.Id == value).Expand()); List <User> existingUsers = await context.Users .AsNoTracking() .Where(usersCondition) .ToListAsync() .ConfigureAwait(false); ExpressionStarter <ChatUser> chatUsersCondition = PredicateBuilder.New <ChatUser>(); chatUsersCondition = existingUsers.Select(opt => opt.Id).Aggregate(chatUsersCondition, (current, value) => current.Or(opt => opt.UserId == value && opt.ChatId == chatId).Expand()); List <ChatUser> validChatUsers = await context.ChatUsers .Where(chatUsersCondition) .Include(opt => opt.User) .ToListAsync() .ConfigureAwait(false); foreach (ChatUser user in validChatUsers) { if (!user.Banned && user.Deleted) { user.Deleted = false; addedUsers.Add(ChatUserConverter.GetChatUserVm(user)); } } context.UpdateRange(validChatUsers); List <long> newChatUsersId = existingUsers.Select(opt => opt.Id).Except(validChatUsers.Select(opt => opt.UserId)).ToList(); List <ChatUser> newChatUsers = newChatUsersId.Select(id => ChatUserConverter.GetNewChatUser(chatId, id, userId)).ToList(); chat.NodesId = chat.NodesId?.Concat(existingUsers.Select(opt => opt.NodeId.GetValueOrDefault())).Distinct().ToArray() ?? existingUsers.Select(opt => opt.NodeId.GetValueOrDefault()).Distinct().ToArray(); await context.ChatUsers .AddRangeAsync(newChatUsers) .ConfigureAwait(false); /* foreach (ChatUser user in newChatUsers) * { * user.User = existingUsers.FirstOrDefault(opt => opt.Id == user.UserId); * }*/ addedUsers.AddRange(ChatUserConverter.GetChatUsersVm(newChatUsers)); } context.Update(chat); transaction.Commit(); await context.SaveChangesAsync() .ConfigureAwait(false); ChatVm resultChat = ChatConverter.GetChatVm(chat); resultChat.Users = addedUsers; return(resultChat); } } }
public async void UpdateConversationLastMessageId(long conversationId, ConversationType conversationType, Guid messageId) { try { using (MessengerDbContext context = contextFactory.Create()) { switch (conversationType) { case ConversationType.Dialog: { Dialog dialog = await context.Dialogs.FirstOrDefaultAsync(opt => opt.Id == conversationId).ConfigureAwait(false); var oldLastMessage = await context.Messages.FirstOrDefaultAsync(opt => opt.DialogId == conversationId && opt.GlobalId == dialog.LastMessageGlobalId).ConfigureAwait(false); var newLastMessage = await context.Messages.FirstOrDefaultAsync(opt => opt.DialogId == conversationId && opt.GlobalId == messageId).ConfigureAwait(false); if (oldLastMessage == null || oldLastMessage.SendingTime < newLastMessage?.SendingTime) { dialog.LastMessageId = newLastMessage.Id; dialog.LastMessageGlobalId = messageId; context.Update(dialog); } } break; case ConversationType.Chat: { Chat chat = await context.Chats.FirstOrDefaultAsync(opt => opt.Id == conversationId).ConfigureAwait(false); var oldLastMessage = await context.Messages.FirstOrDefaultAsync(opt => opt.ChatId == conversationId && opt.GlobalId == chat.LastMessageGlobalId).ConfigureAwait(false); var newLastMessage = await context.Messages.FirstOrDefaultAsync(opt => opt.ChatId == conversationId && opt.GlobalId == messageId).ConfigureAwait(false); if (oldLastMessage == null || oldLastMessage.SendingTime < newLastMessage?.SendingTime) { chat.LastMessageId = newLastMessage.Id; chat.LastMessageGlobalId = messageId; context.Update(chat); } } break; case ConversationType.Channel: { Channel channel = await context.Channels.FirstOrDefaultAsync(opt => opt.ChannelId == conversationId).ConfigureAwait(false); var oldLastMessage = await context.Messages.FirstOrDefaultAsync(opt => opt.ChannelId == conversationId && opt.GlobalId == channel.LastMessageGlobalId).ConfigureAwait(false); var newLastMessage = await context.Messages.FirstOrDefaultAsync(opt => opt.ChannelId == conversationId && opt.GlobalId == messageId).ConfigureAwait(false); if (oldLastMessage == null || oldLastMessage.SendingTime < newLastMessage?.SendingTime) { channel.LastMessageId = newLastMessage.Id; channel.LastMessageGlobalId = messageId; context.Update(channel); } } break; } await context.SaveChangesAsync().ConfigureAwait(false); } } catch (Exception ex) { Logger.WriteLog(ex); } }
public async Task <List <ChannelUserVm> > AddUsersToChannelAsync(List <long> usersId, long channelId, long requestorId) { using (MessengerDbContext context = contextFactory.Create()) { var usersCondition = PredicateBuilder.New <ChannelUser>(); usersCondition = usersId.Aggregate(usersCondition, (current, value) => current.Or(opt => opt.UserId == value).Expand()); var requestorUser = await context.ChannelUsers .FirstOrDefaultAsync(opt => opt.ChannelUserRole >= ChannelUserRole.Administrator && opt.ChannelId == channelId && opt.UserId == requestorId && opt.Channel.Deleted == false) .ConfigureAwait(false); if (requestorUser == null && (usersId.Count() > 1 || (usersId.Count() == 1 && usersId.ElementAt(0) != requestorId))) { throw new AddUserToChannelException(); } List <ChannelUser> existingUsers = await context.ChannelUsers .Where(usersCondition) .Where(opt => opt.ChannelId == channelId) .ToListAsync() .ConfigureAwait(false); List <long> nonExistingUsersId; if (existingUsers?.Any() ?? false) { nonExistingUsersId = usersId.Where(id => !existingUsers.Any(opt => opt.UserId == id)).ToList(); } else { nonExistingUsersId = usersId; } List <ChannelUser> newChannelUsers = nonExistingUsersId.Select(id => new ChannelUser { ChannelId = channelId, ChannelUserRole = ChannelUserRole.Subscriber, SubscribedTime = DateTime.UtcNow.ToUnixTime(), UserId = id }).ToList(); var users = await loadUsersService.GetUsersByIdAsync(nonExistingUsersId).ConfigureAwait(false); Channel channel = await context.Channels.FirstOrDefaultAsync(opt => opt.ChannelId == channelId).ConfigureAwait(false); channel.NodesId = channel.NodesId.Concat(users.Select(opt => opt.NodeId.GetValueOrDefault())).Distinct().ToArray(); context.Update(channel); var updatedUsers = new List <ChannelUser>(); if (existingUsers != null) { existingUsers.ForEach(channelUser => { if (!channelUser.Banned && channelUser.Deleted) { channelUser.Deleted = false; updatedUsers.Add(channelUser); } }); context.UpdateRange(existingUsers); } await context.AddRangeAsync(newChannelUsers).ConfigureAwait(false); await context.SaveChangesAsync().ConfigureAwait(false); return(ChannelConverter.GetChannelUsers(newChannelUsers.Concat(updatedUsers))); } }
public async Task <GroupDto> CreateOrEditGroupAsync(GroupDto groupDto) { try { using (MessengerDbContext context = contextFactory.Create()) { Group result; var group = await context.Groups .Include(opt => opt.ContactGroups) .ThenInclude(opt => opt.Contact) .FirstOrDefaultAsync(opt => opt.UserId == groupDto.UserId && opt.GroupId == groupDto.GroupId) .ConfigureAwait(false); if (group == null) { Group newGroup = new Group { PrivacySettings = groupDto.PrivacySettings, Title = groupDto.Title, UserId = groupDto.UserId, GroupId = groupDto.GroupId }; if (groupDto.UsersId != null && groupDto.UsersId.Any()) { var contacts = await context.Contacts .Where(opt => opt.UserId == groupDto.UserId && groupDto.UsersId.Contains(opt.ContactUserId)) .ToListAsync() .ConfigureAwait(false); HashSet <ContactGroup> contactGroups = contacts .Select(opt => new ContactGroup { ContactId = opt.ContactId }) .ToHashSet(); newGroup.ContactGroups = contactGroups; } await context.Groups.AddAsync(newGroup).ConfigureAwait(false); result = newGroup; } else { group.PrivacySettings = groupDto.PrivacySettings; group.Title = groupDto.Title; context.Update(group); result = group; } await context.SaveChangesAsync().ConfigureAwait(false); return(GroupConverter.GetGroupDto(result)); } } catch (PostgresException ex) { if (ex.SqlState == "23503") { throw new ObjectDoesNotExistsException("User is not exists.", ex); } throw new InternalErrorException("Database error.", ex); } }
private async Task <List <MessageDto> > DeleteChatMessagesInfoAsync(long chatId, IEnumerable <Guid> messagesIds, long userId) { try { using (MessengerDbContext context = contextFactory.Create()) { var messagesCondition = PredicateBuilder.New <Message>(); messagesCondition = messagesIds.Aggregate(messagesCondition, (current, value) => current.Or(opt => opt.GlobalId == value && opt.ChatId == chatId && opt.Deleted == false)); var query = from conversation in context.Chats join chatUser in context.ChatUsers on conversation.Id equals chatUser.ChatId where chatUser.Banned == false && chatUser.Deleted == false && conversation.Deleted == false && chatUser.UserId == userId && conversation.Id == chatId select new { Chat = conversation, User = chatUser }; var result = await query.FirstOrDefaultAsync().ConfigureAwait(false); if (result == null || result.User == null) { return(new List <MessageDto>()); } List <Message> messages = await context.Messages .Include(opt => opt.Attachments) .Where(messagesCondition) .ToListAsync() .ConfigureAwait(false); if (!messages.Any()) { return(new List <MessageDto>()); } var deletedMessagesIds = messages.Select(message => message.GlobalId).ToList(); var usersCondition = PredicateBuilder.New <ChatUser>(); usersCondition = deletedMessagesIds.Aggregate(usersCondition, (current, value) => current.Or(opt => opt.LastReadedGlobalMessageId == value).Expand()); var chatUsers = await context.ChatUsers.Where(usersCondition).ToListAsync().ConfigureAwait(false); var groupedChatUsers = chatUsers.GroupBy(opt => opt.LastReadedGlobalMessageId); foreach (var group in groupedChatUsers) { var message = await context.Messages .OrderByDescending(opt => opt.SendingTime) .ThenBy(opt => opt.GlobalId) .Where(opt => !deletedMessagesIds.Contains(opt.GlobalId) && opt.ChatId == chatId && !opt.Deleted) .FirstOrDefaultAsync() .ConfigureAwait(false); foreach (var chatUser in group) { chatUser.LastReadedGlobalMessageId = message?.GlobalId; } context.ChatUsers.UpdateRange(group); } List <MessageDto> deletedMessages = MessageConverter.GetMessagesDto(messages); foreach (var message in messages) { if (message.SenderId != result.User.UserId && result.User.UserRole == UserRole.User) { continue; } message.Deleted = true; message.UpdatedAt = DateTime.UtcNow.ToUnixTime(); if (NodeSettings.Configs.Node.PermanentlyDeleting) { message.Attachments = null; message.Replyto = null; message.SendingTime = 0; message.Text = null; message.SenderId = null; } } context.UpdateRange(messages); await context.SaveChangesAsync().ConfigureAwait(false); Message lastMessage = await _loadMessagesService.GetLastValidChatMessageAsync(chatId).ConfigureAwait(false); result.Chat.LastMessageId = lastMessage?.Id ?? null; result.Chat.LastMessageGlobalId = lastMessage?.GlobalId; context.Update(result.Chat); await context.SaveChangesAsync().ConfigureAwait(false); return(deletedMessages); } } catch (Exception ex) { throw new DeleteMessagesException("An error occurred while deleting messages.", ex); } }