示例#1
0
        public async Task <PollDto> GetPollAsync(Guid pollId, long conversationId, ConversationType conversationType)
        {
            using (MessengerDbContext context = contextFactory.Create())
            {
                var poll = await context.Polls
                           .Include(opt => opt.Options)
                           .ThenInclude(opt => opt.PollOptionVotes)
                           .FirstOrDefaultAsync(opt =>
                                                opt.PollId == pollId &&
                                                opt.ConvertsationId == conversationId &&
                                                opt.ConversationType == conversationType)
                           .ConfigureAwait(false);

                if (poll == null)
                {
                    var nodeId = await conversationsService.GetConversationNodeIdAsync(conversationType, conversationId).ConfigureAwait(false);

                    var connection = connectionsService.GetNodeConnection(nodeId);
                    if (connection != null)
                    {
                        var loadedPoll = await nodeRequestSender.GetPollInformationAsync(conversationId, conversationType, pollId, connection).ConfigureAwait(false);

                        loadedPoll = await SavePollAsync(loadedPoll).ConfigureAwait(false);

                        return(loadedPoll);
                    }
                }
                return(PollConverter.GetPollDto(poll));
            }
        }
示例#2
0
        public async Task <Response> CreateResponseAsync()
        {
            try
            {
                PollDto poll;
                poll = await pollsService.VotePollAsync(
                    request.PollId,
                    request.ConversationId,
                    request.ConversationType,
                    request.Options,
                    clientConnection.UserId.GetValueOrDefault()).ConfigureAwait(false);

                List <long> nodesId = null;
                switch (poll.ConversationType)
                {
                case ConversationType.Chat:
                {
                    nodesId = await loadChatsService.GetChatNodeListAsync(poll.ConversationId).ConfigureAwait(false);
                }
                break;

                case ConversationType.Channel:
                {
                    nodesId = await loadChannelsService.GetChannelNodesIdAsync(poll.ConversationId).ConfigureAwait(false);
                }
                break;
                }
                nodeNoticeService.SendPollingNodeNoticeAsync(
                    poll.PollId,
                    poll.ConversationId,
                    poll.ConversationType,
                    request.Options,
                    clientConnection.UserId.GetValueOrDefault(),
                    nodesId);
                return(new PollResponse(request.RequestId, PollConverter.GetPollVm(poll, clientConnection.UserId.GetValueOrDefault())));
            }
            catch (PermissionDeniedException ex)
            {
                return(new ResultResponse(request.RequestId, ex.Message, ErrorCode.PermissionDenied));
            }
            catch (ObjectDoesNotExistsException ex)
            {
                return(new ResultResponse(request.RequestId, ex.Message, ErrorCode.ObjectDoesNotExists));
            }
            catch (InvalidOperationException ex)
            {
                return(new ResultResponse(request.RequestId, ex.Message, ErrorCode.InvalidArgument));
            }
            catch (InvalidSignException ex)
            {
                return(new ResultResponse(request.RequestId, ex.Message, ErrorCode.InvalidSign));
            }
        }
示例#3
0
        public async Task <PollDto> SavePollAsync(PollDto pollDto)
        {
            using (MessengerDbContext context = contextFactory.Create())
            {
                Poll poll         = PollConverter.GetPoll(pollDto);
                bool isPollExists = await context.Polls.AnyAsync(opt => opt.PollId == poll.PollId &&
                                                                 opt.ConvertsationId == poll.ConvertsationId && opt.ConversationType == poll.ConversationType)
                                    .ConfigureAwait(false);

                if (!isPollExists)
                {
                    await context.Polls.AddAsync(poll).ConfigureAwait(false);

                    await context.SaveChangesAsync().ConfigureAwait(false);
                }
                return(PollConverter.GetPollDto(poll));
            }
        }
        private async Task <bool> HandleAndValidatePollAttachmentAsync(AttachmentVm attachment, MessageVm message)
        {
            try
            {
                PollVm pollAttachment;
                if (attachment.Payload.GetType() == typeof(string))
                {
                    pollAttachment = ObjectSerializer.JsonToObject <PollVm>((string)attachment.Payload);
                }
                else
                {
                    pollAttachment = ObjectSerializer.JsonToObject <PollVm>(ObjectSerializer.ObjectToJson(attachment.Payload));
                }

                bool isValid = !string.IsNullOrWhiteSpace(pollAttachment.Title) &&
                               pollAttachment.Title.Length < 100 &&
                               pollAttachment.PollOptions != null &&
                               pollAttachment.PollOptions.All(opt => !string.IsNullOrWhiteSpace(opt.Description));
                if (isValid)
                {
                    pollAttachment = await PollConverter.InitPollConversationAsync(pollAttachment, message).ConfigureAwait(false);

                    if (pollAttachment.PollId == null || pollAttachment.PollId == Guid.Empty)
                    {
                        pollAttachment.PollId = RandomExtensions.NextGuid();
                    }
                    attachment.Payload = pollAttachment;
                    await _pollsService.SavePollAsync(PollConverter.GetPollDto(pollAttachment, message.SenderId.GetValueOrDefault())).ConfigureAwait(false);

                    return(true);
                }
                return(false);
            }
            catch (Exception ex)
            {
                Logger.WriteLog(ex);
                return(false);
            }
        }
        public async Task <bool> CheckEditedMessageAttachmentsAsync(MessageVm message, long userId)
        {
            try
            {
                foreach (var attachment in message.Attachments)
                {
                    switch (attachment.Type)
                    {
                    case AttachmentType.Audio:
                    case AttachmentType.File:
                    case AttachmentType.Picture:
                    case AttachmentType.Video:
                    {
                        if (attachment.Payload is string stringPayload)
                        {
                            var fileInfo = _filesService.GetFileInfoAsync(stringPayload);
                            if (fileInfo == null)
                            {
                                return(false);
                            }
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    break;

                    case AttachmentType.ForwardedMessages:
                    {
                        if (attachment.Payload is ForwardedMessagesInfo messagesInfo)
                        {
                            var messages = await _loadMessagesService.GetMessagesByIdAsync(
                                messagesInfo.MessagesGlobalId,
                                messagesInfo.ConversationType,
                                messagesInfo.ConversationId.GetValueOrDefault(),
                                userId).ConfigureAwait(false);

                            if (messages == null || !messages.Any())
                            {
                                return(false);
                            }
                        }
                        else if (attachment.Payload is List <MessageVm> messages)
                        {
                            await _createMessagesService.SaveForwardedMessagesAsync(MessageConverter.GetMessagesDto(messages)).ConfigureAwait(false);
                        }
                        else
                        {
                            return(false);
                        }
                    }
                    break;

                    case AttachmentType.Poll:
                    {
                        if (attachment.Payload is PollVm poll)
                        {
                            var existingPoll = await _pollsService.GetPollAsync(
                                poll.PollId.GetValueOrDefault(),
                                message.ConversationId.GetValueOrDefault(),
                                message.ConversationType).ConfigureAwait(false);

                            if (existingPoll == null)
                            {
                                poll = await PollConverter.InitPollConversationAsync(poll, message).ConfigureAwait(false);

                                poll.PollId = RandomExtensions.NextGuid();
                                await _pollsService.SavePollAsync(PollConverter.GetPollDto(poll, userId)).ConfigureAwait(false);

                                attachment.Payload = poll;
                            }
                        }
                    }
                    break;

                    case AttachmentType.VoiceMessage:
                    {
                        await ValidateVoiceMessageAttachmentAsync(attachment);
                    }
                    break;
                    }
                }
                return(true);
            }
            catch (Exception ex)
            {
                Logger.WriteLog(ex);
                return(false);
            }
        }
示例#6
0
        public async Task <PollDto> VotePollAsync(Guid pollId, long conversationId, ConversationType conversationType, List <PollVoteVm> options, long votingUserId)
        {
            if (!await conversationsService.IsUserInConversationAsync(conversationType, conversationId, votingUserId).ConfigureAwait(false))
            {
                throw new PermissionDeniedException("User is not in conversation.");
            }
            using (MessengerDbContext context = contextFactory.Create())
            {
                var poll = await context.Polls
                           .Include(opt => opt.Options)
                           .ThenInclude(opt => opt.PollOptionVotes)
                           .FirstOrDefaultAsync(opt =>
                                                opt.PollId == pollId &&
                                                opt.ConvertsationId == conversationId &&
                                                opt.ConversationType == conversationType)
                           .ConfigureAwait(false);

                if (poll == null)
                {
                    throw new ObjectDoesNotExistsException($"Poll not found (Poll Id: {pollId}, {conversationType.ToString()}Id: {conversationId}).");
                }
                if (options == null || !options.Any())
                {
                    foreach (var option in poll.Options)
                    {
                        option.PollOptionVotes = option.PollOptionVotes.Where(vote => vote.UserId != votingUserId).ToList();
                    }
                }
                List <PollOptionVote> newVotes     = new List <PollOptionVote>();
                List <PollOptionVote> removedVotes = new List <PollOptionVote>();
                foreach (var voteOption in options)
                {
                    var option = poll.Options.FirstOrDefault(opt => opt.OptionId == voteOption.OptionId);
                    if (option != null && voteOption.Sign != null && voteOption.Sign.Data != null)
                    {
                        if (!option.PollOptionVotes.Any(vote => vote.UserId == votingUserId))
                        {
                            if (poll.SignRequired)
                            {
                                if (voteOption.Sign == null || voteOption.Sign.Data == null || !voteOption.Sign.Data.Any())
                                {
                                    throw new InvalidSignException($"Vote №{voteOption.OptionId} is not signed.");
                                }
                                var signKey = await context.Keys
                                              .FirstOrDefaultAsync(key => key.KeyId == voteOption.Sign.KeyId && key.Type == KeyType.SignAsymKey)
                                              .ConfigureAwait(false);

                                if (signKey == null)
                                {
                                    throw new ObjectDoesNotExistsException($"Key not found (Key Id: {voteOption.Sign.KeyId}.");
                                }
                            }
                            newVotes.Add(new PollOptionVote
                            {
                                ConversationId   = conversationId,
                                ConversationType = conversationType,
                                OptionId         = voteOption.OptionId,
                                UserId           = votingUserId,
                                PollId           = pollId,
                                Sign             = voteOption.Sign?.Data,
                                SignKeyId        = voteOption.Sign?.KeyId
                            });
                        }
                        else
                        {
                            removedVotes.Add(option.PollOptionVotes
                                             .FirstOrDefault(opt => opt.UserId == votingUserId && opt.OptionId == voteOption.OptionId));
                        }
                    }
                    else
                    {
                        if (!option.PollOptionVotes.Any(vote => vote.UserId == votingUserId))
                        {
                            newVotes.Add(new PollOptionVote
                            {
                                ConversationId   = conversationId,
                                ConversationType = conversationType,
                                OptionId         = voteOption.OptionId,
                                UserId           = votingUserId,
                                PollId           = pollId
                            });
                        }
                        else
                        {
                            removedVotes.Add(option.PollOptionVotes
                                             .FirstOrDefault(opt => opt.UserId == votingUserId && opt.OptionId == voteOption.OptionId));
                        }
                    }
                    foreach (var vote in newVotes)
                    {
                        option.PollOptionVotes.Add(vote);
                    }
                    foreach (var vote in removedVotes)
                    {
                        option.PollOptionVotes.Remove(vote);
                    }
                }
                if (!poll.MultipleSelection && poll.Options.Count(opt => opt.PollOptionVotes.Any(vote => vote.UserId == votingUserId)) > 1)
                {
                    throw new InvalidOperationException("Multiple voting is not allowed in current poll.");
                }
                context.Polls.Update(poll);
                await context.SaveChangesAsync().ConfigureAwait(false);

                return(PollConverter.GetPollDto(poll));
            }
        }