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)); } }
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)); } }
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); } }
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)); } }