示例#1
0
 private void StoreEvent(Metric eventToStore)
 {
     using (IVotingContext context = _contextFactory.CreateContext())
     {
         context.Metrics.Add(eventToStore);
         context.SaveChanges();
     }
 }
        public CopyPollResponseModel Copy(CopyPollRequestModel pollCopyRequest)
        {
            if (pollCopyRequest == null)
            {
                ThrowError(HttpStatusCode.BadRequest);
            }

            if (!ModelState.IsValid)
            {
                ThrowError(HttpStatusCode.BadRequest, ModelState);
            }

            using (IVotingContext context = _contextFactory.CreateContext())
            {
                string userId = User.Identity.GetUserId();

                Poll pollToCopy = context
                                  .Polls
                                  .Include(p => p.Choices)
                                  .SingleOrDefault(p => p.UUID == pollCopyRequest.UUIDToCopy);

                if (pollToCopy == null)
                {
                    ThrowError(HttpStatusCode.BadRequest);
                }


                if (pollToCopy.CreatorIdentity != userId)
                {
                    ThrowError(HttpStatusCode.Forbidden);
                }

                Poll newPoll = CopyPoll(pollToCopy);

                _metricHandler.HandlePollClonedEvent(newPoll);

                Ballot creatorBallot = CreateBallotForCreator();
                newPoll.Ballots.Add(creatorBallot);

                context.Polls.Add(newPoll);
                context.SaveChanges();

                return(new CopyPollResponseModel()
                {
                    NewPollId = newPoll.UUID,
                    NewManageId = newPoll.ManageId,
                    CreatorBallotToken = creatorBallot.TokenGuid
                });
            }
        }
示例#3
0
        public PollRequestResponseModel Get(Guid id)
        {
            using (IVotingContext context = _contextFactory.CreateContext())
            {
                Poll poll = PollByPollId(id, context);

                Guid?tokenGuid = GetTokenGuidFromHeaders();

                if (poll.InviteOnly)
                {
                    if (!tokenGuid.HasValue)
                    {
                        ThrowError(HttpStatusCode.Unauthorized);
                    }

                    if (poll.Ballots.All(b => b.TokenGuid != tokenGuid.Value))
                    {
                        ThrowError(HttpStatusCode.Unauthorized);
                    }
                }

                Ballot ballot;
                if (tokenGuid.HasValue)
                {
                    ballot = poll.Ballots.SingleOrDefault(b => b.TokenGuid == tokenGuid.Value);

                    if (ballot == null)
                    {
                        ThrowError(HttpStatusCode.NotFound);
                    }
                }
                else
                {
                    tokenGuid = Guid.NewGuid();

                    ballot = new Ballot()
                    {
                        TokenGuid = tokenGuid.Value
                    };

                    poll.Ballots.Add(ballot);
                    context.Ballots.Add(ballot);

                    context.SaveChanges();
                }

                return(CreateResponse(poll, tokenGuid.Value, ballot));
            }
        }
        public void Put(Guid manageId, ManageChoiceUpdateRequest request)
        {
            ValidateRequest(request);

            if (!ModelState.IsValid)
            {
                ThrowError(HttpStatusCode.BadRequest, ModelState);
            }

            using (IVotingContext context = _contextFactory.CreateContext())
            {
                Poll poll = GetPoll(manageId, context);

                List <int> existingPollOptionNumbers = GetExistingPollOptionNumbers(poll);
                List <int> requestPollOptionNumbers  = GetRequestPollOptionNumbers(request);

                if (requestPollOptionNumbers.Except(existingPollOptionNumbers).Any())
                {
                    ThrowError(HttpStatusCode.NotFound, String.Format("Options do not all belong to poll {0}", manageId));
                }


                List <int> optionsToRemove = existingPollOptionNumbers
                                             .Except(requestPollOptionNumbers)
                                             .ToList();

                RemoveOptions(context, poll, optionsToRemove);


                List <int> optionsToUpdate = existingPollOptionNumbers
                                             .Intersect(requestPollOptionNumbers)
                                             .ToList();

                UpdateOptions(request, poll, optionsToUpdate);


                List <ChoiceUpdate> optionUpdatesToAdd = request
                                                         .Choices
                                                         .Where(o => o.ChoiceNumber.HasValue == false)
                                                         .ToList();

                AddNewOptions(context, poll, optionUpdatesToAdd);


                poll.LastUpdatedUtc = DateTime.UtcNow;
                context.SaveChanges();
            }
        }
        protected internal Poll PollByManageId(Guid manageId, IVotingContext context)
        {
            Expression <Func <Poll, bool> > predicate = (p => p.ManageId == manageId);
            string errorMessage = string.Format("Poll for manage id {0} not found", manageId);

            Poll poll = PollByPredicate(predicate, errorMessage, context);

            if (String.IsNullOrEmpty(poll.CreatorIdentity) && !String.IsNullOrEmpty(User.Identity.GetUserId()))
            {
                poll.CreatorIdentity = User.Identity.GetUserId();
                poll.Creator         = User.Identity.GetUserName();
                context.SaveChanges();
            }

            return(poll);
        }
示例#6
0
        public void Put(Guid manageId, ManagePollTypeRequest updateRequest)
        {
            using (IVotingContext context = _contextFactory.CreateContext())
            {
                Poll poll = PollByManageId(manageId, context);

                PollType pollType;
                if (!Enum.TryParse <PollType>(updateRequest.PollType, true, out pollType))
                {
                    ModelState.AddModelError("PollType", "Invalid PollType");
                }

                if (!ModelState.IsValid)
                {
                    ThrowError(HttpStatusCode.BadRequest, ModelState);
                }

                if (poll.PollType == pollType)
                {
                    if (pollType != PollType.Points || (poll.MaxPoints == updateRequest.MaxPoints && poll.MaxPerVote == updateRequest.MaxPerVote))
                    {
                        return;
                    }
                }

                List <Vote> removedVotes = context.Votes.Include(v => v.Poll)
                                           .Where(v => v.Poll.UUID == poll.UUID)
                                           .ToList();
                foreach (Vote oldVote in removedVotes)
                {
                    _metricHandler.HandleVoteDeletedEvent(oldVote, poll.UUID);
                    context.Votes.Remove(oldVote);
                }

                _metricHandler.HandlePollTypeChangedEvent(pollType, updateRequest.MaxPerVote ?? 0, updateRequest.MaxPoints ?? 0, poll.UUID);

                poll.PollType   = pollType;
                poll.MaxPerVote = updateRequest.MaxPerVote;

                poll.MaxPoints = updateRequest.MaxPoints;

                poll.LastUpdatedUtc = DateTime.UtcNow;

                context.SaveChanges();
            }
        }
        public void Post(Guid pollId, ChoiceCreationRequestModel choiceCreationRequest)
        {
            using (IVotingContext context = _contextFactory.CreateContext())
            {
                if (choiceCreationRequest == null)
                {
                    ThrowError(HttpStatusCode.BadRequest);
                }

                Poll poll = context
                            .Polls
                            .Include(p => p.Choices)
                            .SingleOrDefault(p => p.UUID == pollId);

                if (poll == null)
                {
                    ThrowError(HttpStatusCode.NotFound, string.Format("Poll {0} does not exist", pollId));
                }

                if (!poll.ChoiceAdding)
                {
                    ThrowError(HttpStatusCode.MethodNotAllowed, string.Format("Option adding not allowed for poll {0}", pollId));
                }

                if (!ModelState.IsValid)
                {
                    ThrowError(HttpStatusCode.BadRequest, ModelState);
                }

                Choice newOption = CreateChoiceFromRequest(choiceCreationRequest);

                _metricHandler.HandleChoiceAddedEvent(newOption, pollId);

                poll.Choices.Add(newOption);
                context.Choices.Add(newOption);

                poll.LastUpdatedUtc = DateTime.UtcNow;

                context.SaveChanges();

                ClientSignaller.SignalUpdate(poll.UUID.ToString());
            }
        }
        public void Put(Guid pollId, Guid tokenGuid, BallotRequestModel ballotRequest)
        {
            using (IVotingContext context = _contextFactory.CreateContext())
            {
                if (ballotRequest == null)
                {
                    ThrowError(HttpStatusCode.BadRequest);
                }

                if (!ModelState.IsValid)
                {
                    ThrowError(HttpStatusCode.BadRequest, ModelState);
                }

                Poll poll = context
                            .Polls
                            .Where(p => p.UUID == pollId)
                            .Include(p => p.Ballots)
                            .Include(p => p.Choices)
                            .SingleOrDefault();

                if (poll == null)
                {
                    ThrowError(HttpStatusCode.NotFound, String.Format("Poll {0} not found", pollId));
                }

                if (poll.ExpiryDateUtc.HasValue && poll.ExpiryDateUtc < DateTime.UtcNow)
                {
                    ThrowError(HttpStatusCode.Forbidden, String.Format("Poll {0} has expired", pollId));
                }


                foreach (VoteRequestModel voteRequest in ballotRequest.Votes)
                {
                    if (poll.Choices.All(o => o.Id != voteRequest.ChoiceId))
                    {
                        ModelState.AddModelError("OptionId", "Option choice not valid for this poll");
                    }
                }

                Ballot ballot = poll
                                .Ballots
                                .SingleOrDefault(t => t.TokenGuid == tokenGuid);

                if (ballot == null)
                {
                    if (poll.InviteOnly)
                    {
                        ThrowError(HttpStatusCode.Forbidden, String.Format("Token {0} not valid for this poll", tokenGuid));
                    }
                    else
                    {
                        ballot = new Ballot()
                        {
                            TokenGuid = tokenGuid
                        };
                        poll.Ballots.Add(ballot);
                    }
                }

                // Poll specific validation
                IVoteValidator voteValidator = _voteValidatorFactory.CreateValidator(poll.PollType);
                voteValidator.Validate(ballotRequest.Votes, poll, ModelState);

                if (!ModelState.IsValid)
                {
                    ThrowError(HttpStatusCode.BadRequest, ModelState);
                }

                List <Vote> existingVotes = context
                                            .Votes
                                            .Include(v => v.Poll)
                                            .Where(v => v.Ballot.TokenGuid == tokenGuid && v.Poll.UUID == pollId)
                                            .ToList();

                foreach (Vote contextVote in existingVotes)
                {
                    _metricHandler.HandleVoteDeletedEvent(contextVote, pollId);
                    context.Votes.Remove(contextVote);
                }

                // For some reason, we don't have an addrange function on Entity Framework
                foreach (VoteRequestModel voteRequest in ballotRequest.Votes)
                {
                    Choice option = context
                                    .Choices
                                    .Single(o => o.Id == voteRequest.ChoiceId);

                    Vote modelToVote = ModelToVote(voteRequest, ballot, option, poll);
                    context.Votes.Add(modelToVote);

                    _metricHandler.HandleVoteAddedEvent(modelToVote, pollId);
                }

                if (!String.IsNullOrEmpty(ballotRequest.VoterName))
                {
                    ballot.VoterName = Regex.Replace(ballotRequest.VoterName, ValidVoterNameRegex, "");
                }

                ballot.HasVoted = true;

                poll.LastUpdatedUtc = DateTime.UtcNow;

                context.SaveChanges();

                ClientSignaller.SignalUpdate(poll.UUID.ToString());
            }
        }
示例#9
0
        public void Delete(Guid manageId, DeleteVotersRequestModel request)
        {
            if (request == null)
            {
                ThrowError(HttpStatusCode.BadRequest);
            }

            if (!request.BallotDeleteRequests.Any())
            {
                ThrowError(HttpStatusCode.BadRequest);
            }

            if (request.BallotDeleteRequests.Any(b => !b.VoteDeleteRequests.Any()))
            {
                ThrowError(HttpStatusCode.BadRequest);
            }

            using (IVotingContext context = _contextFactory.CreateContext())
            {
                Poll poll = PollByManageId(manageId, context);

                List <Guid> requestBallotGuids = request
                                                 .BallotDeleteRequests
                                                 .Select(b => b.BallotManageGuid)
                                                 .ToList();

                List <Guid> pollBallotGuids = poll
                                              .Ballots
                                              .Select(b => b.ManageGuid)
                                              .ToList();

                if (requestBallotGuids.Except(pollBallotGuids).Any())
                {
                    ThrowError(HttpStatusCode.NotFound, String.Format("Ballots requested for delete do not all belong to poll {0}", manageId));
                }

                List <Ballot> ballots = poll.Ballots.ToList();

                foreach (DeleteBallotRequestModel ballotRequest in request.BallotDeleteRequests)
                {
                    Ballot ballot = ballots.Single(b => b.ManageGuid == ballotRequest.BallotManageGuid);

                    foreach (DeleteVoteRequestModel voteRequest in ballotRequest.VoteDeleteRequests)
                    {
                        Vote vote = ballot.Votes.ToList().SingleOrDefault(v => v.Choice.PollChoiceNumber == voteRequest.ChoiceNumber);

                        if (vote == null)
                        {
                            ThrowError(HttpStatusCode.NotFound, String.Format("Ballot {0} does not contain an option {1}", ballotRequest.BallotManageGuid, voteRequest.ChoiceNumber));
                        }

                        _metricHandler.HandleVoteDeletedEvent(vote, poll.UUID);
                        ballot.Votes.Remove(vote);
                        context.Votes.Remove(vote);
                    }

                    if (!ballot.Votes.Any())
                    {
                        poll.Ballots.Remove(ballot);
                        context.Ballots.Remove(ballot);
                    }
                }

                poll.LastUpdatedUtc = DateTime.UtcNow;

                context.SaveChanges();
            }
        }