From ffe9af3bd959f2a6f82a238563870f8184e9d422 Mon Sep 17 00:00:00 2001 From: RunasSudo Date: Mon, 11 Dec 2017 17:04:57 +1030 Subject: [PATCH] Implement pre-poll voting --- eos/base/election.py | 3 +- .../static/nunjucks/booth/cast_prepoll.html | 41 +++++++++++ .../static/nunjucks/booth/review_prepoll.html | 45 ++++++++++++ .../core/templates/election/view/booth.html | 72 ++++++++++++------- eosweb/core/templates/election/view/view.html | 2 + 5 files changed, 138 insertions(+), 25 deletions(-) create mode 100644 eosweb/core/static/nunjucks/booth/cast_prepoll.html create mode 100644 eosweb/core/static/nunjucks/booth/review_prepoll.html diff --git a/eos/base/election.py b/eos/base/election.py index 321f823..2f8cff6 100644 --- a/eos/base/election.py +++ b/eos/base/election.py @@ -47,10 +47,11 @@ class Ballot(EmbeddedObject): return Ballot(encrypted_answers=encrypted_answers_deaudit, election_id=self.election_id, election_hash=self.election_hash) class Vote(EmbeddedObject): - _ver = StringField(default='0.4') + _ver = StringField(default='0.5') ballot = EmbeddedObjectField() cast_at = DateTimeField() + comment = StringField() cast_ip = StringField(is_protected=True) cast_fingerprint = BlobField(is_protected=True) diff --git a/eosweb/core/static/nunjucks/booth/cast_prepoll.html b/eosweb/core/static/nunjucks/booth/cast_prepoll.html new file mode 100644 index 0000000..269b2a2 --- /dev/null +++ b/eosweb/core/static/nunjucks/booth/cast_prepoll.html @@ -0,0 +1,41 @@ +{% extends templates['booth/base.html'] %} + +{# + Eos - Verifiable elections + Copyright © 2017 RunasSudo (Yingtong Li) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see . +#} + +{% block content %} +

Your vote has not yet been cast.

+ +
+

Your vote has not yet been cast. Please follow the instructions to continue.

+
+ +

If you have not already done so, please make a note of your ballot fingerprint, {{ eosjs.eos.core.hashing.__all__.SHA256().update_obj(ballot).hash_as_b64() }}. Please retain a copy of your ballot fingerprint – you can use it to verify that your vote has been counted correctly. You may print this page as a receipt if you wish.

+ +

To continue, copy and paste the ballot below and provide it to the election administrator.

+ +
+ {# For some reason nunjucks doesn't like calling this the normal way #} + {% set ballot_deaudit = ballot.deaudit() %} + +
+{% endblock %} + +{% block buttons %} + + +{% endblock %} + +{% block after %} +
+

If you would like to audit your ballot, click here. Auditing your ballot is an optional step you can take to check that your vote has been prepared correctly. You do not need to audit your ballot in order to cast a vote.

+{% endblock %} diff --git a/eosweb/core/templates/election/view/booth.html b/eosweb/core/templates/election/view/booth.html index 6fa0436..9bf85e7 100644 --- a/eosweb/core/templates/election/view/booth.html +++ b/eosweb/core/templates/election/view/booth.html @@ -214,30 +214,54 @@ } }); templates['booth/encrypt.html'] = null; - boothTasks.append({ - activate: function(fromLeft) { - showTemplate('booth/review.html', {ballot: booth.ballot}); - } - }); - templates['booth/review.html'] = null; - boothTasks.append({ - activate: function(fromLeft) { - showTemplate('booth/audit.html', {ballot: booth.ballot}); - } - }); - templates['booth/audit.html'] = null; - boothTasks.append({ - activate: function(fromLeft) { - showTemplate('booth/cast.html', {ballot: booth.ballot}); - } - }); - templates['booth/cast.html'] = null; - boothTasks.append({ - activate: function(fromLeft) { - showTemplate('booth/complete.html', {voter: booth.voter, vote: booth.vote}); - } - }); - templates['booth/complete.html'] = null; + + if (location.search.indexOf('?prepoll') >= 0) { + // Pre-poll + boothTasks.append({ + activate: function(fromLeft) { + showTemplate('booth/review_prepoll.html', {ballot: booth.ballot}); + } + }); + templates['booth/review_prepoll.html'] = null; + boothTasks.append({ + activate: function(fromLeft) { + showTemplate('booth/audit.html', {ballot: booth.ballot}); + } + }); + templates['booth/audit.html'] = null; + boothTasks.append({ + activate: function(fromLeft) { + showTemplate('booth/cast_prepoll.html', {ballot: booth.ballot}); + } + }); + templates['booth/cast_prepoll.html'] = null; + } else { + // Real voting booth + boothTasks.append({ + activate: function(fromLeft) { + showTemplate('booth/review.html', {ballot: booth.ballot}); + } + }); + templates['booth/review.html'] = null; + boothTasks.append({ + activate: function(fromLeft) { + showTemplate('booth/audit.html', {ballot: booth.ballot}); + } + }); + templates['booth/audit.html'] = null; + boothTasks.append({ + activate: function(fromLeft) { + showTemplate('booth/cast.html', {ballot: booth.ballot}); + } + }); + templates['booth/cast.html'] = null; + boothTasks.append({ + activate: function(fromLeft) { + showTemplate('booth/complete.html', {voter: booth.voter, vote: booth.vote}); + } + }); + templates['booth/complete.html'] = null; + } // === END BOOTH TASKS === diff --git a/eosweb/core/templates/election/view/view.html b/eosweb/core/templates/election/view/view.html index f6483b5..1d16fac 100644 --- a/eosweb/core/templates/election/view/view.html +++ b/eosweb/core/templates/election/view/view.html @@ -76,6 +76,8 @@

Voting booth

Voting in this {{ election.kind }} has not yet begun. If you would like to preview the voting booth, click here. Note that you will not be able to cast any ballots until voting opens.

+ +

If you are a registered pre-poll voter, you may access the pre-poll voting booth here.

{% elif election.workflow.get_task('eos.base.workflow.TaskCloseVoting').status == Status.EXITED %}

Voting booth