From 25a7f72160d8319766195fdfb6c8d2bce4a59f42 Mon Sep 17 00:00:00 2001 From: vince0656 Date: Mon, 3 Sep 2018 15:39:42 +0100 Subject: [PATCH] Updated various parts of the application to improve usability. Started laying some of the ground work for a bulletin board. Added informative emails that keep voters, trustees and organisers updated with the state of an event. --- allauthdemo/polls/models.py | 1 + allauthdemo/polls/tasks.py | 52 +++++++++++++ allauthdemo/polls/views.py | 15 +++- .../templates/bases/bootstrap-jquery.html | 32 -------- .../templates/polls/event_decrypt.html | 17 +++-- allauthdemo/templates/polls/event_setup.html | 2 +- static/js/decrypt_event.js | 76 +++++++++++++++---- 7 files changed, 138 insertions(+), 57 deletions(-) diff --git a/allauthdemo/polls/models.py b/allauthdemo/polls/models.py index 3766f4b..8239ccb 100755 --- a/allauthdemo/polls/models.py +++ b/allauthdemo/polls/models.py @@ -206,6 +206,7 @@ class Ballot(models.Model): voter = models.ForeignKey(EmailUser, on_delete=models.CASCADE, related_name="ballots") poll = models.ForeignKey(Poll, on_delete=models.CASCADE, related_name="ballots") selection = models.CharField(max_length=1) + json_str = models.CharField(max_length=10240) cast = models.BooleanField(default=False) diff --git a/allauthdemo/polls/tasks.py b/allauthdemo/polls/tasks.py index 35d9766..8df40c6 100755 --- a/allauthdemo/polls/tasks.py +++ b/allauthdemo/polls/tasks.py @@ -68,6 +68,26 @@ def get_email_sign_off(): return sign_off +def email_e_results_ready(event): + event_title = event.title + email_subject = "Event Results for '" + event_title + "' Have Been Decrypted" + + # Construct the email body. This can be later replaced by a HTML email. + email_body = str("") + email_body += "Dear Event Organiser,\n\n" + email_body += "This email is to inform you that all of the partial decryptions for the event '" + event_title + \ + "' have been supplied. These have been used to decrypt the results which are now available.\n\n" + email_body += "As an organiser, the event results can be found at the following URL:\n\n" + email_body += "http://" + settings.DOMAIN + "/event/" + str(event.pk) + "/results/" + email_body += get_email_sign_off() + + # Get all of the organisers for the event and send them an email + organisers = event.users_organisers.all() + + for organiser in organisers: + organiser.email_user(email_subject, email_body) + + ''' Combines all of the voter ballots for a poll option into a single 'CombinedBallot' ''' @@ -99,6 +119,11 @@ def combine_ballots(polls): combined_cipher = add_ciphers(ciphers) + # If a combined ballot already exists, clear it + if CombinedBallot.objects.filter(poll=poll, option=option).exists(): + CombinedBallot.objects.filter(poll=poll, option=option).delete() + + # Create a combined ballot for this option in the poll CombinedBallot.objects.create(poll=poll, option=option, cipher_text_c1=combined_cipher['C1'], @@ -179,6 +204,30 @@ def email_trustees_prep(trustees, event): trustee.send_email(email_subject, email_body) +''' + Task triggered when all trustees have supplied their partial public keys and the event has been prepared +''' +@task() +def email_organisers_next_steps(event): + event_title = event.title + email_subject = "Event '" + event_title + "' Successfully Prepared by All Trustees" + + email_body = str("") + email_body += "Dear Event Organiser,\n\n" + email_body += "This email is to inform you that all trustees have supplied their public keys for the event '" \ + + event_title + "'. The event is therefore prepared and ready to accept votes when voting opens.\n\n" + email_body += "Once voting has ended, you need to visit the following URL to begin the decryption process:\n\n" + email_body += "http://" + settings.DOMAIN + "/event/" + str(event.pk) + "/\n\n" + email_body += "Once you've accessed the page, simply hit the 'End' button to email all trustees to ask for their " \ + "partial decryptions for all polls for this event." + email_body += get_email_sign_off() + + # Get the list of organisers that need emailing and email them + organisers = event.users_organisers.all() + + for organiser in organisers: + organiser.email_user(email_subject, email_body) + ''' Emails a URL containing an access key for all of the voters for an event ''' @@ -317,3 +366,6 @@ def combine_decryptions_and_tally(event): poll.result_json = result poll.save() + # Email the list of organisers to inform them that the results for this event are ready + email_e_results_ready(event) + diff --git a/allauthdemo/polls/views.py b/allauthdemo/polls/views.py index 8ae6a4a..cd0a48f 100755 --- a/allauthdemo/polls/views.py +++ b/allauthdemo/polls/views.py @@ -18,7 +18,7 @@ from allauthdemo.auth.models import DemoUser from .tasks import email_trustees_prep, update_EID, generate_combpk, event_ended, create_ballots from .tasks import create_ballots_for_poll, email_voters_vote_url, combine_decryptions_and_tally, combine_encrypted_votes -from .tasks import email_voting_success +from .tasks import email_voting_success, email_organisers_next_steps from .utils.EventModelAdaptor import EventModelAdaptor @@ -187,7 +187,8 @@ def event_vote(request, event_id, poll_id): cant_vote_reason = "The event either isn't ready for voting or it has expired and therefore you cannot vote." if request.method == "POST": - ballot_json = json.loads(request.POST.get('ballot')) + ballot_str = request.POST.get('ballot') + ballot_json = json.loads(ballot_str) selection = request.POST.get('selection') encrypted_votes_json = ballot_json['encryptedVotes'] @@ -219,6 +220,7 @@ def event_vote(request, event_id, poll_id): ballot.cast = True ballot.selection = selection + ballot.json_str = ballot_str ballot.save() voter = email_key[0].user @@ -270,6 +272,7 @@ def event_trustee_setup(request, event_id): create_ballots.delay(event) generate_combpk.delay(event) email_voters_vote_url.delay(event.voters.all(), event) + email_organisers_next_steps.delay(event) success_msg = 'You have successfully submitted your public key for this event!' messages.add_message(request, messages.SUCCESS, success_msg) @@ -365,8 +368,14 @@ def event_trustee_decrypt(request, event_id): text=part_dec) if event.all_part_decs_received(): - # TODO: Combine partial decryptions and gen results + # Decrypt the result once all partial decryptions have been received + # This will email all organisers once the results are ready combine_decryptions_and_tally.delay(event) + else: + # TODO: Get how many trustees have submitted a partial decryption + # TODO: Then get how many are left to submit their partial decryptions + # TODO: Then email the list of organisers to update them with this information + str("") messages.add_message(request, messages.SUCCESS, 'Your partial decryptions have been successfully submitted') return HttpResponseRedirect(reverse("user_home")) diff --git a/allauthdemo/templates/bases/bootstrap-jquery.html b/allauthdemo/templates/bases/bootstrap-jquery.html index 8e87f58..16b6754 100755 --- a/allauthdemo/templates/bases/bootstrap-jquery.html +++ b/allauthdemo/templates/bases/bootstrap-jquery.html @@ -76,39 +76,7 @@ //new function demosEncrypt.decryptSubmitCiphers = function() { - var skString = $('#secret-key').val(); - if (!skString) { - alert("Please enter your secret key"); - } - else { - //rebuild our secret key - var ctx = new CTX("BN254CX"); - var skBytes = skString.split(","); - var sk = new ctx.BIG.fromBytes(skBytes); - var inputs = $("form input[type=text]"); - - inputs.each(function() { //for each ciphertext to decrypt - var ciphertext = { - C1: null, - C2: null - }; - - var temp = JSON.parse($(this).val()); - var c1Bytes = getBytes(temp.C1.split(',')); - ciphertext.C1 = new ctx.ECP.fromBytes(c1Bytes); - - var c2Bytes = getBytes(temp.C2.split(',')); - ciphertext.C2 = new ctx.ECP.fromBytes(c2Bytes); - - // Perform partial decryption where the method returns an object containing an ECP() - var partial = partDec(sk, ciphertext); - - var bytes = []; - partial.D.toBytes(bytes); - $(this).val(bytes.toString());//submit in byte array form - }); - } }; //new function diff --git a/allauthdemo/templates/polls/event_decrypt.html b/allauthdemo/templates/polls/event_decrypt.html index ca38235..808011e 100755 --- a/allauthdemo/templates/polls/event_decrypt.html +++ b/allauthdemo/templates/polls/event_decrypt.html @@ -16,7 +16,7 @@

Trustee Event Decryption for Event '{{ event.title }}'


-
Submit your Secret Key as '{{ user_email }}'
+
Upload your Secret Key as '{{ user_email }}'

-
Ciphers
+
Encrypted Event Data
{% csrf_token %} @@ -48,25 +48,26 @@
{% endfor %} + Send Partial Decryptions
-