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; }
public static CandidateInfo Create(User user) { return new CandidateInfo { Id = user.Id, Name = user.Login, PublicMessage = user.PublicMessage, }; }
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()); }
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); }
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); }
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; }
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; }
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()); }
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; } }
private User AddUser(User user) { if(user == null || user.Login == null) return null; return users.TryAdd(user.Login, user) ? user : null; }
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)); } }