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();
            }
        }
Esempio n. 2
0
        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);
                }
            }
        }
Esempio n. 3
0
        public async Task <Chat> Update(Chat entity)
        {
            var result = context.Update(entity).Entity;
            await context.SaveChangesAsync();

            return(result);
        }
Esempio n. 4
0
        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);
            }
        }
Esempio n. 5
0
        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);
            }
        }
Esempio n. 6
0
        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);
            }
        }
Esempio n. 7
0
        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));
            }
        }
Esempio n. 9
0
        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);
                    }
                }
            }
        }
Esempio n. 10
0
        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();
            }
        }
Esempio n. 11
0
        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));
            }
        }
Esempio n. 12
0
        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);
                }
            }
        }
Esempio n. 13
0
        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);
                }
            }
        }
Esempio n. 14
0
        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);
                }
            }
        }
Esempio n. 15
0
        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));
            }
        }
Esempio n. 16
0
        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);
            }
        }
Esempio n. 17
0
        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);
            }
        }
Esempio n. 19
0
        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);
                }
            }
        }
Esempio n. 20
0
        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)));
            }
        }
Esempio n. 22
0
        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);
            }
        }