Allow hiding voters and/or votes
This commit is contained in:
parent
d44c21cbd7
commit
fc4366c028
@ -214,6 +214,8 @@ class STVResult(Result):
|
|||||||
random = BlobField()
|
random = BlobField()
|
||||||
|
|
||||||
class Election(TopLevelObject):
|
class Election(TopLevelObject):
|
||||||
|
_ver = StringField(default='0.9')
|
||||||
|
|
||||||
_id = UUIDField()
|
_id = UUIDField()
|
||||||
workflow = EmbeddedObjectField(Workflow) # Once saved, we don't care what kind of workflow it is
|
workflow = EmbeddedObjectField(Workflow) # Once saved, we don't care what kind of workflow it is
|
||||||
name = StringField()
|
name = StringField()
|
||||||
@ -222,6 +224,9 @@ class Election(TopLevelObject):
|
|||||||
questions = EmbeddedObjectListField()
|
questions = EmbeddedObjectListField()
|
||||||
results = EmbeddedObjectListField(is_hashed=False)
|
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):
|
def can_audit(self):
|
||||||
"""Can prepared votes be audited?"""
|
"""Can prepared votes be audited?"""
|
||||||
return False
|
return False
|
||||||
|
@ -225,6 +225,9 @@ class InternalMixingTrustee(MixingTrustee):
|
|||||||
return True
|
return True
|
||||||
|
|
||||||
class PSRElection(Election):
|
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
|
sk = EmbeddedObjectField(SEGPrivateKey, is_protected=True) # TODO: Threshold
|
||||||
|
|
||||||
public_key = EmbeddedObjectField(SEGPublicKey)
|
public_key = EmbeddedObjectField(SEGPublicKey)
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
# Eos - Verifiable elections
|
# 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
|
# 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
|
# it under the terms of the GNU Affero General Public License as published by
|
||||||
@ -255,7 +255,20 @@ def elections_batch():
|
|||||||
@using_election
|
@using_election
|
||||||
def election_api_json(election):
|
def election_api_json(election):
|
||||||
is_full = 'full' in flask.request.args
|
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')
|
@app.route('/election/<election_id>/view')
|
||||||
@using_election
|
@using_election
|
||||||
@ -278,14 +291,20 @@ def election_view_questions(election):
|
|||||||
@app.route('/election/<election_id>/view/ballots')
|
@app.route('/election/<election_id>/view/ballots')
|
||||||
@using_election
|
@using_election
|
||||||
def election_view_ballots(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>')
|
@app.route('/election/<election_id>/voter/<voter_id>')
|
||||||
@using_election
|
@using_election
|
||||||
def election_voter_view(election, voter_id):
|
def election_voter_view(election, voter_id):
|
||||||
voter_id = uuid.UUID(voter_id)
|
if (election.is_voters_public and election.is_votes_public) or ('user' in flask.session and flask.session['user'].is_admin()):
|
||||||
voter = next(voter for voter in election.voters if voter._id == voter_id)
|
voter_id = uuid.UUID(voter_id)
|
||||||
return flask.render_template('election/voter/view.html', election=election, voter=voter)
|
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')
|
@app.route('/election/<election_id>/view/trustees')
|
||||||
@using_election
|
@using_election
|
||||||
|
@ -39,7 +39,11 @@
|
|||||||
{% endblock %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block buttons %}
|
{% 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 %}
|
{% endblock %}
|
||||||
|
|
||||||
{% block after %}
|
{% block after %}
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
{#
|
{#
|
||||||
Eos - Verifiable elections
|
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
|
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
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
@ -19,5 +19,11 @@
|
|||||||
{% block tabs %}
|
{% block tabs %}
|
||||||
{{ tab('Overview', 'election_view') }}
|
{{ tab('Overview', 'election_view') }}
|
||||||
{{ tab('Questions', 'election_view_questions') }}
|
{{ 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 %}
|
{% endblock %}
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
{#
|
{#
|
||||||
Eos - Verifiable elections
|
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
|
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
|
it under the terms of the GNU Affero General Public License as published by
|
||||||
@ -23,21 +23,27 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Voter</th>
|
<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>
|
</tr>
|
||||||
</thead>
|
</thead>
|
||||||
<tbody>
|
<tbody>
|
||||||
{% for voter in election.voters %}
|
{% for voter in election.voters %}
|
||||||
<tr>
|
<tr>
|
||||||
<td class="selectable"><a href="{{ url_for('election_voter_view', election_id=election._id, voter_id=voter._id) }}">{{ voter.name }}</a></td>
|
{% if election.is_votes_public or (session.user and session.user.is_admin()) %}
|
||||||
{% set votes = voter.votes.get_all() %}
|
<td class="selectable"><a href="{{ url_for('election_voter_view', election_id=election._id, voter_id=voter._id) }}">{{ voter.name }}</a></td>
|
||||||
<td class="selectable"><a href="{{ url_for('election_voter_view', election_id=election._id, voter_id=voter._id) }}">
|
{% set votes = voter.votes.get_all() %}
|
||||||
{% if votes|length > 0 %}
|
<td class="selectable"><a href="{{ url_for('election_voter_view', election_id=election._id, voter_id=voter._id) }}">
|
||||||
<span class="hash">{{ SHA256().update_obj(votes[-1].ballot).hash_as_b64(True) }}</span>
|
{% if votes|length > 0 %}
|
||||||
{% else %}
|
<span class="hash">{{ SHA256().update_obj(votes[-1].ballot).hash_as_b64(True) }}</span>
|
||||||
|
{% else %}
|
||||||
{% endif %}
|
|
||||||
</a></td>
|
{% endif %}
|
||||||
|
</a></td>
|
||||||
|
{% else %}
|
||||||
|
<td>{{ voter.name }}</td>
|
||||||
|
{% endif %}
|
||||||
</tr>
|
</tr>
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
</tbody>
|
</tbody>
|
||||||
|
Loading…
Reference in New Issue
Block a user