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
Hai Brenner 2015-11-29 17:09:29 +02:00
parent 6e64c57431
commit f1c5a7d204
4 changed files with 136 additions and 74 deletions

View File

@ -22,21 +22,21 @@ public interface VotingBooth {
*
* Called by votingbooth thread.
*/
void commitToEncryptedBallot(EncryptedBallot ballot);
void commitToEncryptedBallot(EncryptedBallot ballot, BallotSecrets secrets);
/**
* Finalize a vote for casting
* Called by votingbooth in case user decides to cast.
*/
void castVote();
//void castVote();
/**
* Submit audit information and spoil vote.
* Called by votingbooth in case user decides to audit
* @param ballotSecrets
*/
void auditVote(BallotSecrets ballotSecrets);
//void auditVote(BallotSecrets ballotSecrets);
}

View File

@ -1,5 +1,6 @@
package meerkat.voting;
import meerkat.protobuf.Voting.BallotSecrets;
import meerkat.protobuf.Voting.EncryptedBallot;
import meerkat.protobuf.Voting.PlaintextBallot;
@ -15,6 +16,7 @@ public class VBMessage {
private VBMessageType m_type;
private EncryptedBallot m_encryptedBallot;
private PlaintextBallot m_plaintextBallot;
private BallotSecrets m_secrets;
public static VBMessage newTick () {
VBMessage retVal = new VBMessage();
@ -29,10 +31,11 @@ public class VBMessage {
return retVal;
}
public static VBMessage newControllerResponse (EncryptedBallot encryptedBallot) {
public static VBMessage newControllerResponse (EncryptedBallot encryptedBallot, BallotSecrets ballotSecrets) {
VBMessage retVal = new VBMessage();
retVal.m_type = VBMessageType.VB_CONTROLLER_RESPONSE;
retVal.m_encryptedBallot = encryptedBallot;
retVal.m_secrets = ballotSecrets;
return retVal;
}
@ -41,6 +44,11 @@ public class VBMessage {
return m_encryptedBallot;
}
public BallotSecrets getSecrets () {
assert m_type == VBMessageType.VB_CONTROLLER_RESPONSE;
return m_secrets;
}
public PlaintextBallot getPlaintextBallot () {
assert m_type == VBMessageType.VB_ENCRYPTION_QUERY;
return m_plaintextBallot;

View File

@ -29,6 +29,27 @@ public class VotingBoothToy implements VotingBooth, Runnable {
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 () {
}
@ -46,7 +67,6 @@ public class VotingBoothToy implements VotingBooth, Runnable {
@Override
public void init(ElectionParams globalParams, BoothParams boothParams) {
System.err.println ("debug VB: init.");
//this.m_electionParams = globalParams;
this.m_ballotEncryptionKey = globalParams.getBallotEncryptionKey();
this.l_questions = globalParams.getQuestionsList();

View File

@ -34,6 +34,7 @@ public class VotingBoothToyConsoleUI implements UI, Runnable {
private int m_serialNumber;
private PlaintextBallot m_plaintextBallot;
private EncryptedBallot m_encryptedBallot;
private BallotSecrets m_ballotSecrets;
private int m_waitForControllerMillisecTimeout = 10;
@ -54,62 +55,132 @@ public class VotingBoothToyConsoleUI implements UI, Runnable {
}
}
/* (non-Javadoc)
* @see meerkat.voting.VotingBooth.UI#votingBegin()
*/
@Override
public void votingBegin() {
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");
readInputLine();
++ m_serialNumber;
boolean votingOccured = listQuestionsToUserAndGetAnswers ();
if (! votingOccured)
{
// cancel vote;
return;
runVotingFlow ();
}
private void runVotingFlow () {
try {
boolean votingOccured = listQuestionsToUserAndGetAnswers ();
if (! votingOccured)
{
// cancel vote;
return;
}
else {
printBallotFlow();
}
}
else {
sendBallotToControllerForEncryptionAndWaitForResponse ();
catch (IOException e) {
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)
* @see meerkat.voting.VotingBooth.UI#commitToEncryptedBallot(meerkat.voting.EncryptedBallot)
*/
@Override
public void commitToEncryptedBallot(EncryptedBallot encryptedBallot) {
public void commitToEncryptedBallot(EncryptedBallot encryptedBallot, BallotSecrets secrets) {
try {
a_queue.put (VBMessage.newControllerResponse(encryptedBallot));
a_queue.put (VBMessage.newControllerResponse(encryptedBallot, secrets));
}
catch (InterruptedException e) {
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 () {
System.out.println("UI screen: Initializing the magic");
@ -119,47 +190,10 @@ public class VotingBoothToyConsoleUI implements UI, Runnable {
while (true) {
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)
{
@ -186,7 +220,7 @@ public class VotingBoothToyConsoleUI implements UI, Runnable {
String s = readInputLine();
if (s.equals("cancel") || (index == 0 && s.equals("back"))) {
m_plaintextBallot = null;
erasePlaintext();
return false;
}
@ -269,9 +303,9 @@ public class VotingBoothToyConsoleUI implements UI, Runnable {
}
}
eraseEncryption();
System.out.println("UI screen: Please wait for encryption");
m_vbController.submitBallot(m_plaintextBallot);
m_encryptedBallot = null;
Timer timer = new Timer();
timer.scheduleAtFixedRate(new TickerTask(this), new Date(), m_waitForControllerMillisecTimeout);
@ -292,7 +326,7 @@ public class VotingBoothToyConsoleUI implements UI, Runnable {
m_encryptedBallot = msg.getEncryptedBallot();
if (m_encryptedBallot.getSerialNumber() != m_plaintextBallot.getSerialNumber())
{
m_encryptedBallot = null;
eraseEncryption();
}
}
}