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.

This commit is contained in:
vince0656 2018-09-03 15:39:42 +01:00
parent 59d3b26e95
commit 25a7f72160
7 changed files with 138 additions and 57 deletions

View file

@ -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)

View file

@ -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)

View file

@ -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"))