public Election FindElectionForUser(Guid electionId, User user)
        {
            Election election;
            if(!electionsDict.TryGetValue(electionId, out election))
                return null;
            TryDecryptElectionResultIfFinished(election);

            if(election.Candidates.Any(info => info.Id == user.Id))
            {
                lock(election)
                {
                    election = election.Clone();
                }

                var candidate = election.Candidates.FirstOrDefault(info => info.Id == user.Id);
                if(candidate != null)
                    candidate.IsMe = true;

                PrivateKey privateKey;
                if(electionPrivateKeys.TryGetValue(election.Id, out privateKey))
                    election.PrivateKeyForCandidates = privateKey;

                var winner = election.FindWinner();
                if(winner != null && winner.Id == user.Id)
                    election.Candidates.ForEach(info =>
                        {
                            var u = authController.FindUserAuthorized(info.Name);
                            if(u != null)
                                info.PrivateNotesForWinner = u.PrivateNotes;
                        }
                    );
            }

            return election;
        }
Example #2
0
 public static CandidateInfo Create(User user)
 {
     return new CandidateInfo
     {
         Id = user.Id,
         Name = user.Login,
         PublicMessage = user.PublicMessage,
     };
 }
Example #3
0
 public User AddUser(string login, string pass, string publicMessage, string privateNotes)
 {
     var user = new User
     {
         Id = Guid.NewGuid(),
         Login = login,
         PublicMessage = publicMessage,
         PrivateNotes = privateNotes,
         PasswordHash = CryptUtils.CalcHash(pass)
     };
     statePersister.SaveUser(user);
     return AddUser(user);
 }
        protected override void ProcessAuthorizedRequest(HttpListenerContext context, User user)
        {
            var idString = context.Request.QueryString["id"];
            Guid id;
            if(!Guid.TryParse(idString, out id))
                throw new HttpException(HttpStatusCode.BadRequest, string.Format("Invalid election id '{0}'", idString));

            var election = electroController.FindElectionForUser(id, user);
            if(election == null)
                throw new HttpException(HttpStatusCode.NotFound, string.Format("Can't find election with id '{0}'", id));

            WriteData(context, election.ToJson());

            log.InfoFormat("Found election '{0}'", id);
        }
		protected override void ProcessAuthorizedRequest(HttpListenerContext context, User user)
		{
			var finishedString = context.Request.QueryString["finished"];
			bool finished;
			if(!bool.TryParse(finishedString, out finished))
				throw new HttpException(HttpStatusCode.BadRequest, "Invalid request params");

			ElectionPublicCore[] elections;
			if(finished)
				elections = electroController.GetFinishedElections().Select(ElectionPublicCore.Create).ToArray();
			else
				elections = electroController.GetUnfinishedPublicElections().Select(ElectionPublicCore.Create).ToArray();

			WriteData(context, elections.ToJson());
		}
Example #6
0
        protected override void ProcessAuthorizedRequest(HttpListenerContext context, User user)
        {
            context.Request.AssertMethod(WebRequestMethods.Http.Post);
            var form = context.Request.GetPostData();

            string electionIdString; Guid electionId;
            if(!form.TryGetValue("electionId", out electionIdString) || !Guid.TryParse(electionIdString, out electionId))
                throw new HttpException(HttpStatusCode.BadRequest, "Invalid request params");

            var election = electroController.NominateCandidate(electionId, user);
            if(election == null)
                throw new HttpException(HttpStatusCode.BadRequest, "Nominate FAILED");

            WriteData(context, election.ToJson());

            log.InfoFormat("Nominated user '{0}' in election '{1}''", user.Id, election.Id);
        }
Example #7
0
        protected override void ProcessAuthorizedRequest(HttpListenerContext context, User user)
        {
            context.Request.AssertMethod(WebRequestMethods.Http.Post);
            var form = context.Request.GetPostData();

            string electionIdString; Guid electionId;
            string voteArrayString; string[] voteStringArray; BigInteger[] voteArray;
            if(!form.TryGetValue("electionId", out electionIdString) || !Guid.TryParse(electionIdString, out electionId) ||
                !form.TryGetValue("vote", out voteArrayString) || (voteStringArray = JsonHelper.TryParseJson<string[]>(voteArrayString)) == null || (voteArray = ParseVoteArray(voteStringArray)) == null)
                throw new HttpException(HttpStatusCode.BadRequest, "Invalid request params");

            var success = electroController.Vote(electionId, user, voteArray);
            if(!success)
                throw new HttpException(HttpStatusCode.BadRequest, "Vote FAILED");

            WriteString(context, "Vote OK");

            log.InfoFormat("Recorded user '{0}' vote in election '{1}'", user.Id, electionId);
        }
Example #8
0
        public static Election NominateUsers(string host, Election election, User[] candidates)
        {
            log.InfoFormat("Nominating rest {0} candidates for election...", candidates.Length);
            var nominateTasks = candidates.Select(candidate => new { candidate, task = ElectroClient.NominateAsync(host, Program.PORT, candidate.Cookies, election.Id) }).ToArray();
            Election[] elections;
            try
            {
                elections = nominateTasks.Select(arg => arg.task.Result).ToArray();
            }
            catch(Exception e)
            {
                throw new ServiceException(ExitCode.DOWN, string.Format("Failed to nominate {0} candidates in parallel: {1}", nominateTasks.Length, e));
            }

            var electionId = election.Id;
            election = elections.FirstOrDefault(election1 => election1 != null && election1.Candidates.Count >= candidates.Length + 1);
            if(election == null)
                throw new ServiceException(ExitCode.MUMBLE, string.Format("Nominated '{0}' candidates for election '{1}', but got less in result", candidates.Length + 1, electionId));

            log.Info("Candidates nomindated");
            return election;
        }
        protected override void ProcessAuthorizedRequest(HttpListenerContext context, User user)
        {
            context.Request.AssertMethod(WebRequestMethods.Http.Post);
            var form = context.Request.GetPostData();
            string electionName;
            string isPublicString; bool isPublic;
            string nominateDurationString; int nominateDuration;
            string voteDurationString; int voteDuration;
            if(!form.TryGetValue("name", out electionName) ||
               !form.TryGetValue("isPublic", out isPublicString) || !bool.TryParse(isPublicString, out isPublic) ||
               !form.TryGetValue("nominateDuration", out nominateDurationString) || !int.TryParse(nominateDurationString, out nominateDuration) || nominateDuration <= 0 ||
               !form.TryGetValue("voteDuration", out voteDurationString) || !int.TryParse(voteDurationString, out voteDuration) || voteDuration <= 0)
            {
                throw new HttpException(HttpStatusCode.BadRequest, "Invalid request params");
            }

            var now = DateTime.UtcNow;
            var electionId = electroController.StartElection(electionName, user, isPublic, now.AddSeconds(nominateDuration), now.AddSeconds(nominateDuration + voteDuration));

            var election = electroController.FindElectionForUser(electionId, user);
            WriteData(context, election.ToJson());

            log.InfoFormat("Started election '{0}''", election.Id);
        }
 protected abstract void ProcessAuthorizedRequest(HttpListenerContext context, User user);
        public bool Vote(Guid electionId, User user, BigInteger[] voteArray)
        {
            Election election;
            if(!electionsDict.TryGetValue(electionId, out election))
                return false;

            lock(election)
            {
                if(!election.IsNominationFinished || election.IsFinished)
                    return false;

                if(election.Votes.Count == MaxVotesPerElection)
                    return false;

                if(election.Candidates.Count != voteArray.Length)
                    return false;

                if(election.Votes.Any(v => v.UserId == user.Id))
                    return false;

                var vote = new Vote { UserId = user.Id, EncryptedVector = voteArray };
                var result = election.EncryptedResult ?? new BigInteger[vote.EncryptedVector.Length];
                election.EncryptedResult = TryMerge(result, vote);

                election.Votes.Add(vote);
            }

            return true;
        }
        public Guid StartElection(string electionName, User firstCandidate, bool isPublic, DateTime nominateTill, DateTime till)
        {
            var homoKeyPair = HomoKeyPair.GenKeyPair(MaxVotesPerElection);
            var election = new Election
            {
                Id = Guid.NewGuid(),
                Name = electionName,
                NominateTill = nominateTill,
                VoteTill = till,
                PublicKey = homoKeyPair.PublicKey,
                Votes = new List<Vote>(),
                Candidates = new List<CandidateInfo> { CandidateInfo.Create(firstCandidate) },
                IsPublic = isPublic
            };

            statePersister.SaveKey(election.Id, homoKeyPair.PrivateKey);

            lock (electionsList)
            {
                electionPrivateKeys[election.Id] = homoKeyPair.PrivateKey;
                electionsDict[election.Id] = election;

                electionsList.AddFirst(election);
                while(electionsList.Count > MaxElections)
                {
                    var node = electionsList.Last;
                    Election dummy;
                    electionsDict.TryRemove(node.Value.Id, out dummy);
                    electionsList.RemoveLast();
                }
            }

            return election.Id;
        }
Example #13
0
        public static KeyValuePair<User, int[]>[] RegisterVoters(string host, int[][] votes, User[] candidateUsers)
        {
            var fakeTasks = votes.Take(candidateUsers.Length).Zip(candidateUsers, (vote, voter) => new {vote, voter, task = Task.FromResult(voter.Cookies)});
            var newVotersTasks = votes.Skip(candidateUsers.Length).Select(vote =>
            {
                var voter = UsersManager.GenRandomUser();
                return new  { vote, voter, task = ElectroClient.RegUserAsync(host, Program.PORT, voter.Login, voter.Pass, voter.PublicMessage, voter.PrivateMessage) };
            }).ToArray();

            log.InfoFormat("Registering {0} new voters", newVotersTasks.Length);

            var voterTasks = fakeTasks.Concat(newVotersTasks).ToArray();

            KeyValuePair<User, int[]>[] voters;
            try
            {
                voters = voterTasks.Select(arg => { arg.voter.Cookies = arg.task.Result; return new KeyValuePair<User, int[]>(arg.voter, arg.vote); }).ToArray();
            }
            catch(AggregateException e)
            {
                throw new ServiceException(ExitCode.DOWN, string.Format("Failed to reg {0} voters in parallel: {1}", newVotersTasks.Length, e.Flatten()));
            }

            log.Info("Voters registered");
            return voters;
        }
Example #14
0
 public void SaveUser(User user)
 {
     if(usersWriter == null)
     {
         lock(usersFilePath)
         {
             if(usersWriter == null)
                 usersWriter = new StreamWriter(new FileStream(usersFilePath, FileMode.Append)) {AutoFlush = true};
         }
     }
     usersWriter.WriteLine(user.ToJsonString());
 }
Example #15
0
 public static Election StartElection(string host, User candidate, bool isPublic, int nominateTimeInSec, int voteTimeInSec)
 {
     log.Info("Starting election...");
     var election = ElectroClient.StartElection(host, Program.PORT, candidate.Cookies, Utils.GenRandomElectionName(), isPublic, nominateTimeInSec, voteTimeInSec);
     if(election == null)
         throw new ServiceException(ExitCode.MUMBLE, "Can't start election - result is NULL");
     log.InfoFormat("Election {0} sarted", election.Id);
     return election;
 }
        public Election NominateCandidate(Guid electionId, User user)
        {
            Election election;
            if(!electionsDict.TryGetValue(electionId, out election))
                return null;

            lock (election)
            {
                if(election.IsNominationFinished)
                    return null;

                if(election.Candidates.Any(info => info.Id == user.Id))
                    return null;

                election.Candidates.Add(CandidateInfo.Create(user));

                var clone = election.Clone();
                PrivateKey privateKey;
                if(electionPrivateKeys.TryGetValue(clone.Id, out privateKey))
                    clone.PrivateKeyForCandidates = privateKey;

                return clone;
            }
        }
Example #17
0
 private User AddUser(User user)
 {
     if(user == null || user.Login == null)
         return null;
     return users.TryAdd(user.Login, user) ? user : null;
 }
Example #18
0
 public static User[] RegisterCandidates(string host, User[] users)
 {
     log.Info("Registering candidates...");
     var candidateTasks = users.Select(candidate => new { candidate, task = ElectroClient.RegUserAsync(host, Program.PORT, candidate.Login, candidate.Pass, candidate.PublicMessage, candidate.PrivateMessage) }).ToArray();
     try
     {
         var result = candidateTasks.Select(arg =>
         {
             arg.candidate.Cookies = arg.task.Result;
             return arg.candidate;
         }).ToArray();
         log.InfoFormat("Registered {0} candidates", result.Length);
         return result;
     }
     catch(Exception e)
     {
         throw new ServiceException(ExitCode.DOWN, string.Format("Failed to reg {0} candidates in parallel: {1}", candidateTasks.Length, e));
     }
 }