From e7ec6f161d0cfe7d13364751412d652036b1773d Mon Sep 17 00:00:00 2001 From: Ben Adida <ben@adida.net> Date: Wed, 8 Dec 2010 18:43:42 -0800 Subject: [PATCH] added private_p field to election, more tests, and continued election-specific voter passwords port --- helios/fixtures/election.json | 23 +++++++++++++++++++++ helios/fixtures/users.json | 2 +- helios/forms.py | 1 + helios/models.py | 17 ++++++++++------ helios/templates/election_view.html | 2 +- helios/tests.py | 31 ++++++++++++++++++++++++----- helios/views.py | 2 +- heliosbooth | 2 +- 8 files changed, 65 insertions(+), 15 deletions(-) create mode 100644 helios/fixtures/election.json diff --git a/helios/fixtures/election.json b/helios/fixtures/election.json new file mode 100644 index 0000000..6159a99 --- /dev/null +++ b/helios/fixtures/election.json @@ -0,0 +1,23 @@ +[{"pk": 1000, + "model": "helios.election", + "fields": + { + "admin": 1, + "uuid" : "206ef039-05c9-4e9c-bb8f-963da50c08d4", + "short_name" : "test", + "name" : "Test Election", + "election_type" : "election", + "advanced_audit_features" : true, + "private_p" : false, + "description" : "test descriptoin", + "public_key" : null, + "private_key" : null, + "questions" : [], + "eligibility": null, + "openreg": true, + "featured_p": false, + "use_voter_aliases" : false, + "cast_url" : "/helios/elections/206ef039-05c9-4e9c-bb8f-963da50c08d4/cast" + } + } + ] diff --git a/helios/fixtures/users.json b/helios/fixtures/users.json index f764ccb..e66e46d 100644 --- a/helios/fixtures/users.json +++ b/helios/fixtures/users.json @@ -1 +1 @@ -[{"pk": 1, "model": "auth.user", "fields": {"info": "{u'password': u'test'}", "user_id": "foobar", "name": "Foo Bar", "user_type": "password", "token": null, "admin_p": false}}] \ No newline at end of file +[{"pk": 1, "model": "auth.user", "fields": {"info": "{}", "user_id": "ben@adida.net", "name": "Ben Adida", "user_type": "google", "token": null, "admin_p": false}}] \ No newline at end of file diff --git a/helios/forms.py b/helios/forms.py index 83f05d8..3ac8951 100644 --- a/helios/forms.py +++ b/helios/forms.py @@ -14,6 +14,7 @@ class ElectionForm(forms.Form): election_type = forms.ChoiceField(label="type", choices = Election.ELECTION_TYPES) use_voter_aliases = forms.BooleanField(required=False, initial=False, help_text='if selected, voter identities will be replaced with aliases, e.g. "V12", in the ballot tracking center') advanced_audit_features = forms.BooleanField(required=False, initial=True, help_text='disable this only if you want a simple election with reduced security but a simpler user interface') + private_p = forms.BooleanField(required=False, initial=False, label="Private?", help_text='a private election is only visible to registered/eligible voters') class ElectionTimesForm(forms.Form): diff --git a/helios/models.py b/helios/models.py index 673dae2..0de508e 100644 --- a/helios/models.py +++ b/helios/models.py @@ -42,6 +42,7 @@ class Election(models.Model, electionalgs.Election): election_type = models.CharField(max_length=250, null=False, default='election', choices = ELECTION_TYPES) advanced_audit_features = models.BooleanField(default=True, null=False) + private_p = models.BooleanField(default=False, null=False) description = models.TextField() public_key = JSONField(algs.EGPublicKey, null=True) @@ -520,6 +521,7 @@ class VoterFile(models.Model): if not voter: voter_uuid = str(uuid.uuid4()) voter = Voter(uuid= voter_uuid, user = None, voter_login_id = voter_id, voter_name = name, election = election) + voter.generate_password() new_voters.append(voter) voter.save() @@ -577,7 +579,7 @@ class Voter(models.Model, electionalgs.Voter): return voter @classmethod - def get_by_election(cls, election, cast=None, order_by='voter_id', after=None, limit=None): + def get_by_election(cls, election, cast=None, order_by='voter_login_id', after=None, limit=None): """ FIXME: review this for non-GAE? """ @@ -624,11 +626,9 @@ class Voter(models.Model, electionalgs.Voter): @classmethod def get_by_election_and_user(cls, election, user): - query = cls.objects.filter(election = election, user = user) - try: - return query[0] - except: + return cls.objects.get(election = election, user = user) + except cls.DoesNotExist: return None @classmethod @@ -668,7 +668,7 @@ class Voter(models.Model, electionalgs.Voter): return self.user.user_type else: return 'password' - + @property def display_html_big(self): if self.user: @@ -676,6 +676,11 @@ class Voter(models.Model, electionalgs.Voter): else: return """<img border="0" height="25" src="/static/auth/login-icons/password.png" alt="password" /> %s""" % self.name + def generate_password(self, length=10): + if self.voter_password: + raise Exception("password already exists") + + self.voter_password = heliosutils.random_string(length) def store_vote(self, cast_vote): # only store the vote if it's cast later than the current one diff --git a/helios/templates/election_view.html b/helios/templates/election_view.html index 1a007f4..abf42ed 100644 --- a/helios/templates/election_view.html +++ b/helios/templates/election_view.html @@ -24,7 +24,7 @@ if (!navigator.javaEnabled()) { {% endif %} {% endif %}</h2> <p style="padding-top:0px; margin-top:0px"> -{{ election.election_type }} created by <u><b>{{election.admin.display_html_small|safe}}</b></u> +<em>{% if election.private_p %}private{%else%}public{% endif %}</em> {{ election.election_type }} created by <u><b>{{election.admin.display_html_small|safe}}</b></u> {% if election.is_archived %} [archived] {% endif %} diff --git a/helios/tests.py b/helios/tests.py index 3130d88..12b99ce 100644 --- a/helios/tests.py +++ b/helios/tests.py @@ -15,6 +15,8 @@ from django.test import TestCase from django.core import mail +import uuid + class ElectionModelTests(TestCase): fixtures = ['users.json'] @@ -33,7 +35,7 @@ class ElectionModelTests(TestCase): self.election.generate_trustee(ELGAMAL_PARAMS) def setUp(self): - self.user = auth_models.User.objects.get(user_id='foobar') + self.user = auth_models.User.objects.get(user_id='ben@adida.net', user_type='google') self.election, self.created_p = self.create_election() def test_create_election(self): @@ -101,7 +103,7 @@ class ElectionModelTests(TestCase): self.assertEquals(LOGS,pulled_logs) def test_eligibility(self): - self.election.eligibility = [{'auth_system': 'password'}] + self.election.eligibility = [{'auth_system': self.user.user_type}] # without openreg, this should be false self.assertFalse(self.election.user_eligible_p(self.user)) @@ -151,7 +153,9 @@ class ElectionModelTests(TestCase): # make sure voter is there now voter_2 = models.Voter.get_by_election_and_user(self.election, self.user) + self.assertFalse(voter == None) + self.assertFalse(voter_2 == None) self.assertEquals(voter, voter_2) # make sure voter is there in this call too @@ -159,10 +163,27 @@ class ElectionModelTests(TestCase): self.assertTrue(len(voters) == 1) self.assertEquals(voter, voters[0]) - voter_2 = models.Voter.get_by_election_and_voter_id(self.election, voter.voter_id) - self.assertEquals(voter, voter_2) - voter_2 = models.Voter.get_by_election_and_uuid(self.election, voter.uuid) self.assertEquals(voter, voter_2) self.assertEquals(voter.user, self.user) + + +class VoterModelTests(TestCase): + fixtures = ['users.json', 'election.json'] + + def setUp(self): + self.election = models.Election.objects.get(short_name='test') + + def test_create_password_voter(self): + v = models.Voter(uuid = uuid.uuid1(), election = self.election, voter_login_id = 'voter_test_1', voter_name = 'Voter Test 1') + v.generate_password() + + v.save() + + # password has been generated! + self.assertFalse(v.voter_password == None) + + # can't generate passwords twice + self.assertRaises(Exception, lambda: v.generate_password()) + diff --git a/helios/views.py b/helios/views.py index 1069861..5a2b560 100644 --- a/helios/views.py +++ b/helios/views.py @@ -170,7 +170,7 @@ def election_new(request): def one_election_edit(request, election): error = None - RELEVANT_FIELDS = ['short_name', 'name', 'description', 'use_voter_aliases', 'election_type', 'advanced_audit_features'] + RELEVANT_FIELDS = ['short_name', 'name', 'description', 'use_voter_aliases', 'election_type', 'advanced_audit_features', 'private_p'] if request.method == "GET": values = {} diff --git a/heliosbooth b/heliosbooth index c5ce1b4..8686477 160000 --- a/heliosbooth +++ b/heliosbooth @@ -1 +1 @@ -Subproject commit c5ce1b4a5e9cbd93a4e39a738a6ca39db046d5f3 +Subproject commit 868647746ac7033b77afc1ee5e09baddbe57ce20 -- GitLab