Added QR codes to ballot selection, and a couple other minor chchanges
This commit is contained in:
parent
4f1bf927bb
commit
77508479b4
9 changed files with 81 additions and 43 deletions
|
@ -1,5 +1,5 @@
|
||||||
{
|
{
|
||||||
"name": "Node DEMOS2 Cryptography Server",
|
"name": "node-demos2-cryptography-server",
|
||||||
"version": "1.0.0",
|
"version": "1.0.0",
|
||||||
"description": "Exposes Cryptographic Functionality from Various Endpoints",
|
"description": "Exposes Cryptographic Functionality from Various Endpoints",
|
||||||
"main": "index.js",
|
"main": "index.js",
|
||||||
|
|
|
@ -35,6 +35,7 @@ gpGen = function(){
|
||||||
B.rcopy(ctx.ROM_CURVE.CURVE_Pyb);
|
B.rcopy(ctx.ROM_CURVE.CURVE_Pyb);
|
||||||
var Qy=new ctx.FP2(0); Qy.bset(A,B);
|
var Qy=new ctx.FP2(0); Qy.bset(A,B);
|
||||||
var Q=new ctx.ECP2();
|
var Q=new ctx.ECP2();
|
||||||
|
var Q=new ctx.ECP2();
|
||||||
Q.setxy(Qy,Qy);
|
Q.setxy(Qy,Qy);
|
||||||
|
|
||||||
return{
|
return{
|
||||||
|
|
19
README.md
19
README.md
|
@ -59,9 +59,17 @@ python manage.py runserver
|
||||||
|
|
||||||
The application will then be available at `127.0.0.1:8000`.
|
The application will then be available at `127.0.0.1:8000`.
|
||||||
|
|
||||||
You can then click on 'Join' to create a new user account. Currently, a server error is thrown when you create a new email account saying something like 'Too Many Attempts'. Rest assured that the account will have been created. Navigate back to the home page and you should be able to log in. This will hopefully be fixed in a future version.
|
You can then click on 'Join' to create a new user account.
|
||||||
|
|
||||||
### Step 2: Running Celery
|
### Step 2: Running the Node.js Server
|
||||||
|
|
||||||
|
The Node.js server exposes a lot of cryptographic operations that the application depends on throughout. To run the server, issue the following command line request from the `Node/` folder:
|
||||||
|
|
||||||
|
```
|
||||||
|
node index.js
|
||||||
|
```
|
||||||
|
|
||||||
|
### Step 3: Running Celery
|
||||||
|
|
||||||
Celery is used to run tasks asynchronously and the DEMOS2 application can't run without this application. A bash script called `start_celery_worker.sh` is provided to make starting a worker as easy as possible:
|
Celery is used to run tasks asynchronously and the DEMOS2 application can't run without this application. A bash script called `start_celery_worker.sh` is provided to make starting a worker as easy as possible:
|
||||||
|
|
||||||
|
@ -69,10 +77,3 @@ Celery is used to run tasks asynchronously and the DEMOS2 application can't run
|
||||||
./start_celery_worker.sh
|
./start_celery_worker.sh
|
||||||
```
|
```
|
||||||
|
|
||||||
### Step 3: Running the Node.js Server
|
|
||||||
|
|
||||||
The Node.js server exposes a lot of cryptographic operations that the application depends on throughout. To run the server, issue the following command line request from the `Node/` folder:
|
|
||||||
|
|
||||||
```
|
|
||||||
node index.js
|
|
||||||
```
|
|
||||||
|
|
|
@ -30,7 +30,6 @@ def param():
|
||||||
jsondict = json.load(urllib2.urlopen(url))
|
jsondict = json.load(urllib2.urlopen(url))
|
||||||
return json.dumps(jsondict)
|
return json.dumps(jsondict)
|
||||||
|
|
||||||
|
|
||||||
def combpk(pks):
|
def combpk(pks):
|
||||||
url = 'http://localhost:8080/cmpkstring'
|
url = 'http://localhost:8080/cmpkstring'
|
||||||
|
|
||||||
|
|
|
@ -16,7 +16,7 @@ from .crypto_rpc import param, combpk, add_ciphers, get_tally
|
||||||
|
|
||||||
The following tasks were re-implemented by Thomas Smith: generate_event_param, tally_results, generate_combpk, generate_enc
|
The following tasks were re-implemented by Thomas Smith: generate_event_param, tally_results, generate_combpk, generate_enc
|
||||||
|
|
||||||
This file was also updated by Vincent de Almeida
|
This file was also updated by Vincent de Almeida and Ben Goldsworthy
|
||||||
'''
|
'''
|
||||||
|
|
||||||
# Will store the result of the initial cal to param() from .cpp_calls
|
# Will store the result of the initial cal to param() from .cpp_calls
|
||||||
|
|
|
@ -17,6 +17,7 @@
|
||||||
integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU="
|
integrity="sha256-VazP97ZCwtekAsvgPBSUwPFKdrwD3unUfSGVYrahUqU="
|
||||||
crossorigin="anonymous"></script>
|
crossorigin="anonymous"></script>
|
||||||
<script src="{% static 'js/papaparse.min.js' %}" type="text/javascript"></script>
|
<script src="{% static 'js/papaparse.min.js' %}" type="text/javascript"></script>
|
||||||
|
<script src="{% static 'js/qrcode.min.js' %}" type="text/javascript"></script>
|
||||||
<script src="{% static 'js/create-event-poll.js' %}" type="text/javascript"></script>
|
<script src="{% static 'js/create-event-poll.js' %}" type="text/javascript"></script>
|
||||||
<script src="{% static 'js/decrypt_event.js' %}" type="text/javascript"></script>
|
<script src="{% static 'js/decrypt_event.js' %}" type="text/javascript"></script>
|
||||||
<script src="{% static 'js/event_vote.js' %}" type="text/javascript"></script>
|
<script src="{% static 'js/event_vote.js' %}" type="text/javascript"></script>
|
||||||
|
|
|
@ -235,16 +235,12 @@ function isEventTimingsValid() {
|
||||||
var valid = true;
|
var valid = true;
|
||||||
var helpBlockId = "event-timings-error-block";
|
var helpBlockId = "event-timings-error-block";
|
||||||
|
|
||||||
// Extract the string val from the vote start and end input controls
|
// Extract the dates from the vote start and end input controls
|
||||||
var start_date_time = $('#vote-start-input').val();
|
var start_date_time = $('#vote-start-input').data('DateTimePicker').date();
|
||||||
var end_date_time = $('#vote-end-input').val();
|
var end_date_time = $('#vote-end-input').data('DateTimePicker').date();
|
||||||
|
|
||||||
// Convert the string vals to Date objects
|
|
||||||
var start_dateObj = new Date(start_date_time);
|
|
||||||
var end_dateObj = new Date(end_date_time);
|
|
||||||
|
|
||||||
// Ensure that the start date is before the end date and that the end date is after the start date
|
// Ensure that the start date is before the end date and that the end date is after the start date
|
||||||
if(!(start_dateObj < end_dateObj && end_dateObj > start_dateObj)) {
|
if(!(start_date_time < end_date_time && end_date_time > start_date_time)) {
|
||||||
checkAndAddError({
|
checkAndAddError({
|
||||||
error: "The start date must be before the end date and the end after the start date.",
|
error: "The start date must be before the end date and the end after the start date.",
|
||||||
helpBlockId: "event-timings-error-block"
|
helpBlockId: "event-timings-error-block"
|
||||||
|
|
|
@ -211,7 +211,7 @@ function csrfSafeMethod(method) {
|
||||||
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
|
return (/^(GET|HEAD|OPTIONS|TRACE)$/.test(method));
|
||||||
}
|
}
|
||||||
|
|
||||||
function sendBallotToServer(ballot) {
|
function sendBallotToServer(selection, altHash) {
|
||||||
$.ajaxSetup({
|
$.ajaxSetup({
|
||||||
beforeSend: function(xhr, settings) {
|
beforeSend: function(xhr, settings) {
|
||||||
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
|
if (!csrfSafeMethod(settings.type) && !this.crossDomain) {
|
||||||
|
@ -223,9 +223,9 @@ function sendBallotToServer(ballot) {
|
||||||
$.ajax({
|
$.ajax({
|
||||||
type : "POST",
|
type : "POST",
|
||||||
url : window.location,
|
url : window.location,
|
||||||
data : JSON.stringify({ ballot: ballot}),
|
data : JSON.stringify({ ballot: selection}),
|
||||||
success : function(){
|
success : function(){
|
||||||
voteSuccessfullyReceived();
|
onAfterBallotSend(altHash);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -272,30 +272,69 @@ function SHA256Hash(bytes, toStr) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// FAO Ben: Called once the ballot has been sent to the back-end and dialog has closed
|
// Called once the ballot has been sent to the back-end and dialog has closed
|
||||||
function onAfterBallotSend() {
|
function onAfterBallotSend(altHash) {
|
||||||
// TODO: FAO Ben: Implement QR func here.
|
let titleText = 'Vote Successfully Received';
|
||||||
// TODO: Currently, there is a dialog already implemented in the event_vote.html page which is
|
let bodyText = "Thank you for voting! This is your copy of your ballot - make sure to save it onto your phone before closing this window.";
|
||||||
// TODO: used for voting error information but could be used to display the QR code using JS in
|
|
||||||
// TODO: a similar way that showBallotChoiceDialog does.
|
if(POLL_NUM !== POLL_COUNT) {
|
||||||
|
bodyText += " You can vote on the next poll by closing down this dialog and clicking 'Next Poll'.";
|
||||||
}
|
}
|
||||||
|
|
||||||
function processBallotSelection(selection, selectionHash, successFn) {
|
// With one ballot selected, we can display a QR code of the voter's copy
|
||||||
// Dispatch the ballot to the server
|
|
||||||
sendBallotToServer(selection);
|
|
||||||
|
|
||||||
// Close the choice selection dialog
|
|
||||||
var modalDialog = $('#modalDialog');
|
var modalDialog = $('#modalDialog');
|
||||||
modal.modal('hide');
|
var title = modalDialog.find('.modal-title');
|
||||||
|
var body = modalDialog.find('.modal-body');
|
||||||
|
title.text(titleText);
|
||||||
|
body.empty();
|
||||||
|
|
||||||
|
var p = document.createElement("p");
|
||||||
|
p.innerHTML = bodyText;
|
||||||
|
body.append(p);
|
||||||
|
|
||||||
|
// Generate the body of the dialog which displays the unselected ballot QR code and hash
|
||||||
|
var choiceGroupDiv = document.createElement('div');
|
||||||
|
choiceGroupDiv.setAttribute('class', 'choice-group');
|
||||||
|
|
||||||
|
var QRCodeImg = document.createElement('img');
|
||||||
|
QRCodeImg.setAttribute('class', 'QR-code');
|
||||||
|
new QRCode(QRCodeImg, altHash);
|
||||||
|
|
||||||
|
choiceGroupDiv.append(QRCodeImg);
|
||||||
|
|
||||||
|
// ----------------------------------------------
|
||||||
|
|
||||||
|
var hashGroupDiv = document.createElement('div');
|
||||||
|
var br = document.createElement('br');
|
||||||
|
hashGroupDiv.append( br );
|
||||||
|
|
||||||
|
var hash = document.createElement("span");
|
||||||
|
hash.innerHTML = "Hash: " + altHash;
|
||||||
|
hashGroupDiv.append( hash );
|
||||||
|
|
||||||
|
// -----------------------------------------------
|
||||||
|
|
||||||
|
body.append(choiceGroupDiv);
|
||||||
|
body.append(hashGroupDiv);
|
||||||
|
|
||||||
|
modalDialog.modal('show');
|
||||||
|
}
|
||||||
|
|
||||||
|
function processBallotSelection(selection, selectionHash, alt, altHash) {
|
||||||
|
// Dispatch the ballot to the server
|
||||||
|
sendBallotToServer(selection, altHash);
|
||||||
|
|
||||||
// Call the successfn currently with the selection hash but this may not be needed
|
// Call the successfn currently with the selection hash but this may not be needed
|
||||||
successFn(selectionHash);
|
//successFn(alt, altHash);
|
||||||
}
|
}
|
||||||
|
|
||||||
function showBallotChoiceDialog(ballotA, ballotB) {
|
function showBallotChoiceDialog(ballotA, ballotB) {
|
||||||
// Output hashes of the 2 ballots
|
var ballots = new Array(ballotA, ballotB);
|
||||||
const BALLOT_A_HASH = SHA256Hash(stringtobytes(JSON.stringify(ballotA)), true);
|
var ballotHashes = new Array(2);
|
||||||
const BALLOT_B_HASH = SHA256Hash(stringtobytes(JSON.stringify(ballotB)), true);
|
|
||||||
|
// Hash both ballots and store
|
||||||
|
for (let i = 0; i <= 1; i++)
|
||||||
|
ballotHashes[i] = SHA256Hash(stringtobytes(JSON.stringify(ballots[i])), true);
|
||||||
|
|
||||||
// With the ballots and their hashes generated, we can display the ballot choice dialog
|
// With the ballots and their hashes generated, we can display the ballot choice dialog
|
||||||
var modalDialog = $('#modalDialog');
|
var modalDialog = $('#modalDialog');
|
||||||
|
@ -327,14 +366,14 @@ function showBallotChoiceDialog(ballotA, ballotB) {
|
||||||
hashGroupDiv.append( br );
|
hashGroupDiv.append( br );
|
||||||
|
|
||||||
var hashA = document.createElement("span");
|
var hashA = document.createElement("span");
|
||||||
hashA.innerHTML = "Hash A: " + BALLOT_A_HASH;
|
hashA.innerHTML = "Hash A: " + ballotHashes[0];
|
||||||
hashGroupDiv.append( hashA );
|
hashGroupDiv.append( hashA );
|
||||||
|
|
||||||
var br2 = document.createElement('br');
|
var br2 = document.createElement('br');
|
||||||
hashGroupDiv.append( br2 );
|
hashGroupDiv.append( br2 );
|
||||||
|
|
||||||
var hashB = document.createElement("span");
|
var hashB = document.createElement("span");
|
||||||
hashB.innerHTML = "Hash B: " + BALLOT_B_HASH;
|
hashB.innerHTML = "Hash B: " + ballotHashes[1];
|
||||||
hashGroupDiv.append( hashB );
|
hashGroupDiv.append( hashB );
|
||||||
|
|
||||||
// -----------------------------------------------
|
// -----------------------------------------------
|
||||||
|
@ -346,11 +385,11 @@ function showBallotChoiceDialog(ballotA, ballotB) {
|
||||||
|
|
||||||
// Register callback functions for the selection of either A or B
|
// Register callback functions for the selection of either A or B
|
||||||
$('#choice-A').click(function(e) {
|
$('#choice-A').click(function(e) {
|
||||||
processBallotSelection(ballotA, BALLOT_A_HASH, onAfterBallotSend);
|
processBallotSelection(ballots[0], ballotHashes[0], ballots[1], ballotHashes[1]);
|
||||||
});
|
});
|
||||||
|
|
||||||
$('#choice-B').click(function(e) {
|
$('#choice-B').click(function(e) {
|
||||||
processBallotSelection(ballotB, BALLOT_B_HASH, onAfterBallotSend);
|
processBallotSelection(ballots[1], ballotHashes[1], ballots[0], ballotHashes[0]);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
1
static/js/qrcode.min.js
vendored
Normal file
1
static/js/qrcode.min.js
vendored
Normal file
File diff suppressed because one or more lines are too long
Reference in a new issue