1
1
# -*- coding: utf-8 -*-
2
- from flask import Blueprint , render_template , redirect , url_for , session , request , flash
2
+ from damgard_jurik import EncryptedNumber
3
+ from flask import Blueprint , render_template , redirect , url_for , session , request , flash , json
3
4
from random import shuffle
4
5
from ..helpers import election_exists
5
6
from ..models import Voter , Candidate , Authority
@@ -57,42 +58,52 @@ def vote(election):
57
58
return redirect (url_for ('election.election_home' , election = election .name ))
58
59
candidates = election .candidates
59
60
shuffle (candidates )
61
+
62
+ authority = Authority .query .filter_by (election = election ).first ()
63
+ if not authority :
64
+ flash ("Election is missing authorities." )
65
+ return redirect (url_for ('election.election_home' , election = election .name ))
66
+ public_key = authority .public_key
67
+ if not public_key :
68
+ flash ("Authority missing public key." )
69
+ return redirect (url_for ('election.election_home' , election = election .name ))
70
+
60
71
if request .method == 'GET' :
61
- return render_template ('vote/vote.html' , election = election , candidates = candidates )
72
+ return render_template ('vote/vote.html' , election = election , candidates = candidates , public_key = public_key )
62
73
else :
63
74
ballot = request .form .get ("ballot" )
64
75
if not ballot :
65
76
flash ("No ballot submitted." )
66
77
return render_template ('vote/vote.html' , election = election , candidates = candidates )
67
- authority = Authority .query .filter_by (election = election ).first ()
68
- if not authority :
69
- flash ("Election is missing authorities." )
70
- return redirect (url_for ('election.election_home' , election = election .name ))
71
- public_key = authority .public_key
72
- if not public_key :
73
- flash ("Authority missing public key." )
74
- return redirect (url_for ('election.election_home' , election = election .name ))
75
- candidates = []
76
- for candidate in ballot .split (',' ):
78
+ ballot_dec = json .loads (ballot )
79
+
80
+ # here, candidates and preferences are strings
81
+ cand_prefs_raw = [(cand_pref ['candidate' ], cand_pref ['preference' ]) for cand_pref in ballot_dec ]
82
+
83
+ # here they are both ints
84
+ cand_prefs = []
85
+ for candidate , preference in cand_prefs_raw :
77
86
c = Candidate .query .filter_by (election = election , name = candidate ).first ()
78
87
if not c :
79
88
flash ("Invalid ballot." )
80
89
return render_template ('vote/vote.html' , election = election , candidates = candidates )
81
- candidates .append (c .id )
82
- if len (election .candidates ) != len (candidates ):
90
+
91
+ pref = EncryptedNumber (int (preference ), public_key )
92
+ cand_prefs .append ((c .id , pref ))
93
+
94
+ if len (election .candidates ) != len (cand_prefs ):
83
95
flash ("Invalid number of votes on ballot." )
84
96
return render_template ('vote/vote.html' , election = election , candidates = candidates )
85
- preferences = list (range (1 , len (candidates )+ 1 ))
86
- candidate_to_preference = {candidate : preference for candidate , preference in zip (candidates , preferences )}
87
- candidates .sort ()
88
- preferences = [candidate_to_preference [candidate ] for candidate in candidates ]
97
+
89
98
weight = public_key .encrypt (1 )
90
- enc_preferences = list (map (lambda p : public_key .encrypt (p ), preferences ))
99
+ candidates = [cand_pref [0 ] for cand_pref in cand_prefs ]
100
+ enc_preferences = [cand_pref [1 ] for cand_pref in cand_prefs ]
101
+
91
102
voter .ballot = CandidateOrderBallot (candidates , enc_preferences , weight )
92
103
election .bulletin += f"{ voter .id } : "
93
104
for preference in enc_preferences :
94
105
election .bulletin += str (preference .value ) + " "
95
106
election .bulletin += "\n \n "
96
107
db .session .commit ()
97
108
flash ("Ballot cast successfully" )
98
- return redirect (url_for ('election.election_home' , election = election .name ))
109
+ return redirect (url_for ('election.election_home' , election = election .name ))
0 commit comments