Managed the UI flow for now.
Still has to write the controller and tests.... Made changes to the UI interface because the decision of cast/audit comes immediately from the UI itself. The UI now controls the flow as this seems to be the more reasonable thread to do it.vbdev
parent
6e64c57431
commit
f1c5a7d204
|
@ -22,21 +22,21 @@ public interface VotingBooth {
|
||||||
*
|
*
|
||||||
* Called by votingbooth thread.
|
* Called by votingbooth thread.
|
||||||
*/
|
*/
|
||||||
void commitToEncryptedBallot(EncryptedBallot ballot);
|
void commitToEncryptedBallot(EncryptedBallot ballot, BallotSecrets secrets);
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Finalize a vote for casting
|
* Finalize a vote for casting
|
||||||
* Called by votingbooth in case user decides to cast.
|
* Called by votingbooth in case user decides to cast.
|
||||||
*/
|
*/
|
||||||
void castVote();
|
//void castVote();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Submit audit information and spoil vote.
|
* Submit audit information and spoil vote.
|
||||||
* Called by votingbooth in case user decides to audit
|
* Called by votingbooth in case user decides to audit
|
||||||
* @param ballotSecrets
|
* @param ballotSecrets
|
||||||
*/
|
*/
|
||||||
void auditVote(BallotSecrets ballotSecrets);
|
//void auditVote(BallotSecrets ballotSecrets);
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
package meerkat.voting;
|
package meerkat.voting;
|
||||||
|
|
||||||
|
import meerkat.protobuf.Voting.BallotSecrets;
|
||||||
import meerkat.protobuf.Voting.EncryptedBallot;
|
import meerkat.protobuf.Voting.EncryptedBallot;
|
||||||
import meerkat.protobuf.Voting.PlaintextBallot;
|
import meerkat.protobuf.Voting.PlaintextBallot;
|
||||||
|
|
||||||
|
@ -15,6 +16,7 @@ public class VBMessage {
|
||||||
private VBMessageType m_type;
|
private VBMessageType m_type;
|
||||||
private EncryptedBallot m_encryptedBallot;
|
private EncryptedBallot m_encryptedBallot;
|
||||||
private PlaintextBallot m_plaintextBallot;
|
private PlaintextBallot m_plaintextBallot;
|
||||||
|
private BallotSecrets m_secrets;
|
||||||
|
|
||||||
public static VBMessage newTick () {
|
public static VBMessage newTick () {
|
||||||
VBMessage retVal = new VBMessage();
|
VBMessage retVal = new VBMessage();
|
||||||
|
@ -29,10 +31,11 @@ public class VBMessage {
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static VBMessage newControllerResponse (EncryptedBallot encryptedBallot) {
|
public static VBMessage newControllerResponse (EncryptedBallot encryptedBallot, BallotSecrets ballotSecrets) {
|
||||||
VBMessage retVal = new VBMessage();
|
VBMessage retVal = new VBMessage();
|
||||||
retVal.m_type = VBMessageType.VB_CONTROLLER_RESPONSE;
|
retVal.m_type = VBMessageType.VB_CONTROLLER_RESPONSE;
|
||||||
retVal.m_encryptedBallot = encryptedBallot;
|
retVal.m_encryptedBallot = encryptedBallot;
|
||||||
|
retVal.m_secrets = ballotSecrets;
|
||||||
return retVal;
|
return retVal;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -41,6 +44,11 @@ public class VBMessage {
|
||||||
return m_encryptedBallot;
|
return m_encryptedBallot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public BallotSecrets getSecrets () {
|
||||||
|
assert m_type == VBMessageType.VB_CONTROLLER_RESPONSE;
|
||||||
|
return m_secrets;
|
||||||
|
}
|
||||||
|
|
||||||
public PlaintextBallot getPlaintextBallot () {
|
public PlaintextBallot getPlaintextBallot () {
|
||||||
assert m_type == VBMessageType.VB_ENCRYPTION_QUERY;
|
assert m_type == VBMessageType.VB_ENCRYPTION_QUERY;
|
||||||
return m_plaintextBallot;
|
return m_plaintextBallot;
|
||||||
|
|
|
@ -29,6 +29,27 @@ public class VotingBoothToy implements VotingBooth, Runnable {
|
||||||
private VotingBooth.UI m_ui;
|
private VotingBooth.UI m_ui;
|
||||||
|
|
||||||
|
|
||||||
|
public static void main (String[] args)
|
||||||
|
{
|
||||||
|
VotingBoothToy vbController = new VotingBoothToy ();
|
||||||
|
VotingBoothToyConsoleUI ui = new VotingBoothToyConsoleUI();
|
||||||
|
|
||||||
|
vbController.registerUI (ui);
|
||||||
|
ui.registerVBController(vbController);
|
||||||
|
|
||||||
|
BoothParams boothParams = new BoothParams();
|
||||||
|
ElectionParams electionParams = new ElectionParams();
|
||||||
|
|
||||||
|
vbController.init(electionParams, boothParams);
|
||||||
|
|
||||||
|
Thread controllerThread = new Thread(new VotingBoothToy ());
|
||||||
|
Thread uiThread = new Thread(ui);
|
||||||
|
|
||||||
|
controllerThread.start();
|
||||||
|
uiThread.start();
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
public VotingBoothToy () {
|
public VotingBoothToy () {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +67,6 @@ public class VotingBoothToy implements VotingBooth, Runnable {
|
||||||
@Override
|
@Override
|
||||||
public void init(ElectionParams globalParams, BoothParams boothParams) {
|
public void init(ElectionParams globalParams, BoothParams boothParams) {
|
||||||
System.err.println ("debug VB: init.");
|
System.err.println ("debug VB: init.");
|
||||||
//this.m_electionParams = globalParams;
|
|
||||||
this.m_ballotEncryptionKey = globalParams.getBallotEncryptionKey();
|
this.m_ballotEncryptionKey = globalParams.getBallotEncryptionKey();
|
||||||
this.l_questions = globalParams.getQuestionsList();
|
this.l_questions = globalParams.getQuestionsList();
|
||||||
|
|
||||||
|
|
|
@ -34,6 +34,7 @@ public class VotingBoothToyConsoleUI implements UI, Runnable {
|
||||||
private int m_serialNumber;
|
private int m_serialNumber;
|
||||||
private PlaintextBallot m_plaintextBallot;
|
private PlaintextBallot m_plaintextBallot;
|
||||||
private EncryptedBallot m_encryptedBallot;
|
private EncryptedBallot m_encryptedBallot;
|
||||||
|
private BallotSecrets m_ballotSecrets;
|
||||||
private int m_waitForControllerMillisecTimeout = 10;
|
private int m_waitForControllerMillisecTimeout = 10;
|
||||||
|
|
||||||
|
|
||||||
|
@ -54,62 +55,132 @@ public class VotingBoothToyConsoleUI implements UI, Runnable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see meerkat.voting.VotingBooth.UI#votingBegin()
|
* @see meerkat.voting.VotingBooth.UI#votingBegin()
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void votingBegin() {
|
public void votingBegin() {
|
||||||
System.err.println ("UI debug: preparing console UI for a new user.");
|
System.err.println ("UI debug: preparing console UI for a new user.");
|
||||||
|
|
||||||
|
// clear history from memory
|
||||||
|
// TODO: should we clean memory better?
|
||||||
|
eraseEncryption();
|
||||||
|
erasePlaintext();
|
||||||
|
|
||||||
System.out.println ("UI screen: Welcome. Press to start");
|
System.out.println ("UI screen: Welcome. Press to start");
|
||||||
readInputLine();
|
readInputLine();
|
||||||
|
|
||||||
++ m_serialNumber;
|
++ m_serialNumber;
|
||||||
boolean votingOccured = listQuestionsToUserAndGetAnswers ();
|
|
||||||
|
|
||||||
if (! votingOccured)
|
runVotingFlow ();
|
||||||
{
|
}
|
||||||
// cancel vote;
|
|
||||||
return;
|
private void runVotingFlow () {
|
||||||
|
|
||||||
|
try {
|
||||||
|
|
||||||
|
boolean votingOccured = listQuestionsToUserAndGetAnswers ();
|
||||||
|
|
||||||
|
if (! votingOccured)
|
||||||
|
{
|
||||||
|
// cancel vote;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
printBallotFlow();
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
else {
|
catch (IOException e) {
|
||||||
sendBallotToControllerForEncryptionAndWaitForResponse ();
|
System.err.println("UI debug: IO error");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void sendBallotToPrinterAndWaitToEnd () {
|
||||||
|
System.err.println("UI debug: sendBallotToPrinterAndWaitToEnd: still not multithreaded...");
|
||||||
|
System.out.println("UI screen: printing ballot wait for printing to end");
|
||||||
|
System.out.println("UI printer: printing ballot");
|
||||||
|
}
|
||||||
|
|
||||||
|
// returns true if cast or cancelled
|
||||||
|
private boolean castOrAudit () throws IOException{
|
||||||
|
System.out.println("UI screen: (c)ast or (a)udit?");
|
||||||
|
String choice = readInputLine();
|
||||||
|
if (choice.equals("a") || choice.equals("audit")) {
|
||||||
|
System.err.println ("UI debug: voter decided to audit");
|
||||||
|
System.out.println("UI screen: printing audit wait for printing to end");
|
||||||
|
System.out.println("UI printer: printing audit");
|
||||||
|
System.out.println("Do you still want to keep this vote? Type 'y' for casting/auditing the same vote. Type 'n' tp start from scratch");
|
||||||
|
String choice2 = readInputLine();
|
||||||
|
if (choice2.equals("y") || choice.equals("yes")) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (choice2.equals("n") || choice.equals("no")) {
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new IOException ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (choice.equals("c") || choice.equals("cast") || choice.equals("cancel")) {
|
||||||
|
System.err.println ("UI debug: voter decided to cast vote.");
|
||||||
|
System.out.println("UI screen: wait for printer to finish");
|
||||||
|
System.out.println("UI printer: printing empty space till end of page");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new IOException ();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
private void eraseEncryption () {
|
||||||
|
//TODO: should we clean memory stronger?
|
||||||
|
if (m_encryptedBallot != null) {
|
||||||
|
m_encryptedBallot = null;
|
||||||
|
}
|
||||||
|
if (m_ballotSecrets != null) {
|
||||||
|
m_ballotSecrets = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void erasePlaintext () {
|
||||||
|
//TODO: should we clean memory stronger?
|
||||||
|
if (m_plaintextBallot != null) {
|
||||||
|
m_plaintextBallot = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void printBallotFlow () throws IOException{
|
||||||
|
System.err.println("UI debug: printBallotFlow currently not multithreaded... will fix it...");
|
||||||
|
|
||||||
|
boolean ended = false;
|
||||||
|
while (!ended) {
|
||||||
|
sendBallotToControllerForEncryptionAndWaitForResponse ();
|
||||||
|
sendBallotToPrinterAndWaitToEnd();
|
||||||
|
ended = castOrAudit();
|
||||||
|
eraseEncryption();
|
||||||
|
}
|
||||||
|
erasePlaintext();
|
||||||
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
/* (non-Javadoc)
|
||||||
* @see meerkat.voting.VotingBooth.UI#commitToEncryptedBallot(meerkat.voting.EncryptedBallot)
|
* @see meerkat.voting.VotingBooth.UI#commitToEncryptedBallot(meerkat.voting.EncryptedBallot)
|
||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void commitToEncryptedBallot(EncryptedBallot encryptedBallot) {
|
public void commitToEncryptedBallot(EncryptedBallot encryptedBallot, BallotSecrets secrets) {
|
||||||
try {
|
try {
|
||||||
a_queue.put (VBMessage.newControllerResponse(encryptedBallot));
|
a_queue.put (VBMessage.newControllerResponse(encryptedBallot, secrets));
|
||||||
}
|
}
|
||||||
catch (InterruptedException e) {
|
catch (InterruptedException e) {
|
||||||
System.err.println ("Interrupted in VotingBoothToyConsoleUI.commitToEncryptedBallot");
|
System.err.println ("Interrupted in VotingBoothToyConsoleUI.commitToEncryptedBallot");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see meerkat.voting.VotingBooth.UI#castVote()
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void castVote() {
|
|
||||||
System.err.println ("UI debug: voter decided to cast vote.");
|
|
||||||
System.out.println ("UI printer: print empty space until end of page");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* (non-Javadoc)
|
|
||||||
* @see meerkat.voting.VotingBooth.UI#auditVote(meerkat.protobuf.Voting.BallotSecrets)
|
|
||||||
*/
|
|
||||||
@Override
|
|
||||||
public void auditVote(BallotSecrets ballotSecrets) {
|
|
||||||
// audit = calcAudit (ballotSecrets)
|
|
||||||
// sendToPrinter (audit)
|
|
||||||
System.err.println ("UI debug: voter decided to audit vote.");
|
|
||||||
System.out.println ("UI printer: here we should print audit of ballot");
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void run () {
|
public void run () {
|
||||||
System.out.println("UI screen: Initializing the magic");
|
System.out.println("UI screen: Initializing the magic");
|
||||||
|
@ -119,47 +190,10 @@ public class VotingBoothToyConsoleUI implements UI, Runnable {
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
votingBegin();
|
votingBegin();
|
||||||
|
|
||||||
if (m_encryptedBallot != null) {
|
|
||||||
|
|
||||||
printBallot();
|
|
||||||
|
|
||||||
castOrAudit ();
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void castOrAudit () {
|
|
||||||
|
|
||||||
// fix the flow here!!
|
|
||||||
// keeping the same vote should return for a new encryption
|
|
||||||
|
|
||||||
System.out.println("UI screen: printing ended. Do you want to (c)ast the ballot or (a)udit?");
|
|
||||||
|
|
||||||
boolean keepThisVote = true;
|
|
||||||
String s = readInputLine();
|
|
||||||
if (s.equals("c") || s.equals("cancel") || s.equals("cast")) {
|
|
||||||
castVote();
|
|
||||||
keepThisVote = false;
|
|
||||||
}
|
|
||||||
else if (s.equals("a") || s.equals("audit")) {
|
|
||||||
auditVote();
|
|
||||||
System.out.println("Do you still want to keep this vote? Type 'y' for casting/auditing the same vote. Type 'n' tp start from scratch");
|
|
||||||
if (s.equals("y") || s.equals("yes")) {
|
|
||||||
//
|
|
||||||
}
|
|
||||||
else if (s.equals("n") || s.equals("no")) {
|
|
||||||
keepThisVote = false;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new IOException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw new IOException();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void registerVBController (VotingBooth vb)
|
public void registerVBController (VotingBooth vb)
|
||||||
{
|
{
|
||||||
|
@ -186,7 +220,7 @@ public class VotingBoothToyConsoleUI implements UI, Runnable {
|
||||||
String s = readInputLine();
|
String s = readInputLine();
|
||||||
|
|
||||||
if (s.equals("cancel") || (index == 0 && s.equals("back"))) {
|
if (s.equals("cancel") || (index == 0 && s.equals("back"))) {
|
||||||
m_plaintextBallot = null;
|
erasePlaintext();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -269,9 +303,9 @@ public class VotingBoothToyConsoleUI implements UI, Runnable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
eraseEncryption();
|
||||||
System.out.println("UI screen: Please wait for encryption");
|
System.out.println("UI screen: Please wait for encryption");
|
||||||
m_vbController.submitBallot(m_plaintextBallot);
|
m_vbController.submitBallot(m_plaintextBallot);
|
||||||
m_encryptedBallot = null;
|
|
||||||
Timer timer = new Timer();
|
Timer timer = new Timer();
|
||||||
timer.scheduleAtFixedRate(new TickerTask(this), new Date(), m_waitForControllerMillisecTimeout);
|
timer.scheduleAtFixedRate(new TickerTask(this), new Date(), m_waitForControllerMillisecTimeout);
|
||||||
|
|
||||||
|
@ -292,7 +326,7 @@ public class VotingBoothToyConsoleUI implements UI, Runnable {
|
||||||
m_encryptedBallot = msg.getEncryptedBallot();
|
m_encryptedBallot = msg.getEncryptedBallot();
|
||||||
if (m_encryptedBallot.getSerialNumber() != m_plaintextBallot.getSerialNumber())
|
if (m_encryptedBallot.getSerialNumber() != m_plaintextBallot.getSerialNumber())
|
||||||
{
|
{
|
||||||
m_encryptedBallot = null;
|
eraseEncryption();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue