Allow hiding voters and/or votes
This commit is contained in:
parent
d44c21cbd7
commit
fc4366c028
@ -214,6 +214,8 @@ class STVResult(Result):
|
||||
random = BlobField()
|
||||
|
||||
class Election(TopLevelObject):
|
||||
_ver = StringField(default='0.9')
|
||||
|
||||
_id = UUIDField()
|
||||
workflow = EmbeddedObjectField(Workflow) # Once saved, we don't care what kind of workflow it is
|
||||
name = StringField()
|
||||
@ -222,6 +224,9 @@ class Election(TopLevelObject):
|
||||
questions = EmbeddedObjectListField()
|
||||
results = EmbeddedObjectListField(is_hashed=False)
|
||||
|
||||
is_voters_public = BooleanField(is_hashed=False, default=False)
|
||||
is_votes_public = BooleanField(is_hashed=False, default=False)
|
||||
|
||||
def can_audit(self):
|
||||
"""Can prepared votes be audited?"""
|
||||
return False
|
||||
|
@ -225,6 +225,9 @@ class InternalMixingTrustee(MixingTrustee):
|
||||
return True
|
||||
|
||||
class PSRElection(Election):
|
||||
is_voters_public = BooleanField(is_hashed=False, default=True)
|
||||
is_votes_public = BooleanField(is_hashed=False, default=True)
|
||||
|
||||
sk = EmbeddedObjectField(SEGPrivateKey, is_protected=True) # TODO: Threshold
|
||||
|
||||
public_key = EmbeddedObjectField(SEGPublicKey)
|
||||
|
@ -1,5 +1,5 @@
|
||||
# Eos - Verifiable elections
|
||||
# Copyright © 2017-2019 RunasSudo (Yingtong Li)
|
||||
# Copyright © 2017-2021 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
|
||||
@ -255,7 +255,20 @@ def elections_batch():
|
||||
@using_election
|
||||
def election_api_json(election):
|
||||
is_full = 'full' in flask.request.args
|
||||
return flask.Response(EosObject.to_json(EosObject.serialise_and_wrap(election, None, SerialiseOptions(should_protect=True, for_hash=(not is_full), combine_related=True))), mimetype='application/json')
|
||||
|
||||
serialised = EosObject.serialise_and_wrap(election, None, SerialiseOptions(should_protect=True, for_hash=(not is_full), combine_related=True))
|
||||
|
||||
# Protect voters, votes if required
|
||||
if not election.is_voters_public:
|
||||
if 'voters' in serialised['value']:
|
||||
del serialised['value']['voters']
|
||||
if not election.is_votes_public:
|
||||
if 'voters' in serialised['value']:
|
||||
for voter in serialised['value']['voters']:
|
||||
if 'votes' in voter['value']:
|
||||
del voter['value']['votes']
|
||||
|
||||
return flask.Response(EosObject.to_json(serialised), mimetype='application/json')
|
||||
|
||||
@app.route('/election/<election_id>/view')
|
||||
@using_election
|
||||
@ -278,14 +291,20 @@ def election_view_questions(election):
|
||||
@app.route('/election/<election_id>/view/ballots')
|
||||
@using_election
|
||||
def election_view_ballots(election):
|
||||
return flask.render_template('election/view/ballots.html', election=election)
|
||||
if election.is_voters_public or ('user' in flask.session and flask.session['user'].is_admin()):
|
||||
return flask.render_template('election/view/ballots.html', election=election)
|
||||
|
||||
return flask.Response('Voters not public', 403)
|
||||
|
||||
@app.route('/election/<election_id>/voter/<voter_id>')
|
||||
@using_election
|
||||
def election_voter_view(election, voter_id):
|
||||
voter_id = uuid.UUID(voter_id)
|
||||
voter = next(voter for voter in election.voters if voter._id == voter_id)
|
||||
return flask.render_template('election/voter/view.html', election=election, voter=voter)
|
||||
if (election.is_voters_public and election.is_votes_public) or ('user' in flask.session and flask.session['user'].is_admin()):
|
||||
voter_id = uuid.UUID(voter_id)
|
||||
voter = next(voter for voter in election.voters if voter._id == voter_id)
|
||||
return flask.render_template('election/voter/view.html', election=election, voter=voter)
|
||||
|
||||
return flask.Response('Voters not public', 403)
|
||||
|
||||
@app.route('/election/<election_id>/view/trustees')
|
||||
@using_election
|
||||
|
@ -39,7 +39,11 @@
|
||||
{% endblock %}
|
||||
|
||||
{% block buttons %}
|
||||
<a href="{{ election_base_url }}view/ballots" class="ui right floated primary button">Finish</a>
|
||||
{% if election.is_votes_public %}
|
||||
<a href="{{ election_base_url }}view/ballots" class="ui right floated primary button">Finish</a>
|
||||
{% else %}
|
||||
<a href="{{ election_base_url }}view" class="ui right floated primary button">Finish</a>
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
||||
{% block after %}
|
||||
|
@ -1,6 +1,6 @@
|
||||
{#
|
||||
Eos - Verifiable elections
|
||||
Copyright © 2017 RunasSudo (Yingtong Li)
|
||||
Copyright © 2017-2021 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
|
||||
@ -19,5 +19,11 @@
|
||||
{% block tabs %}
|
||||
{{ tab('Overview', 'election_view') }}
|
||||
{{ tab('Questions', 'election_view_questions') }}
|
||||
{{ tab('Voters and ballots', 'election_view_ballots') }}
|
||||
{% if election.is_voters_public or (session.user and session.user.is_admin()) %}
|
||||
{% if election.is_votes_public or (session.user and session.user.is_admin()) %}
|
||||
{{ tab('Voters and ballots', 'election_view_ballots') }}
|
||||
{% else %}
|
||||
{{ tab('Voters', 'election_view_ballots') }}
|
||||
{% endif %}
|
||||
{% endif %}
|
||||
{% endblock %}
|
||||
|
@ -2,7 +2,7 @@
|
||||
|
||||
{#
|
||||
Eos - Verifiable elections
|
||||
Copyright © 2017-18 RunasSudo (Yingtong Li)
|
||||
Copyright © 2017-2021 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
|
||||
@ -23,21 +23,27 @@
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Voter</th>
|
||||
<th>Ballot fingerprint</th>
|
||||
{% if election.is_votes_public or (session.user and session.user.is_admin()) %}
|
||||
<th>Ballot fingerprint</th>
|
||||
{% endif %}
|
||||
</tr>
|
||||
</thead>
|
||||
<tbody>
|
||||
{% for voter in election.voters %}
|
||||
<tr>
|
||||
<td class="selectable"><a href="{{ url_for('election_voter_view', election_id=election._id, voter_id=voter._id) }}">{{ voter.name }}</a></td>
|
||||
{% set votes = voter.votes.get_all() %}
|
||||
<td class="selectable"><a href="{{ url_for('election_voter_view', election_id=election._id, voter_id=voter._id) }}">
|
||||
{% if votes|length > 0 %}
|
||||
<span class="hash">{{ SHA256().update_obj(votes[-1].ballot).hash_as_b64(True) }}</span>
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
</a></td>
|
||||
{% if election.is_votes_public or (session.user and session.user.is_admin()) %}
|
||||
<td class="selectable"><a href="{{ url_for('election_voter_view', election_id=election._id, voter_id=voter._id) }}">{{ voter.name }}</a></td>
|
||||
{% set votes = voter.votes.get_all() %}
|
||||
<td class="selectable"><a href="{{ url_for('election_voter_view', election_id=election._id, voter_id=voter._id) }}">
|
||||
{% if votes|length > 0 %}
|
||||
<span class="hash">{{ SHA256().update_obj(votes[-1].ballot).hash_as_b64(True) }}</span>
|
||||
{% else %}
|
||||
|
||||
{% endif %}
|
||||
</a></td>
|
||||
{% else %}
|
||||
<td>{{ voter.name }}</td>
|
||||
{% endif %}
|
||||
</tr>
|
||||
{% endfor %}
|
||||
</tbody>
|
||||
|
Loading…
Reference in New Issue
Block a user