diff --git a/helios/fixtures/voter-badfile.csv b/helios/fixtures/voter-badfile.csv new file mode 100644 index 0000000000000000000000000000000000000000..fd674a999ad12a6043390c33c630dc5dd3bb2f1c --- /dev/null +++ b/helios/fixtures/voter-badfile.csv @@ -0,0 +1,5 @@ +Ben78@adida.net,Ben78 Adida + benadida5,ben5@adida.net , Ben5 Adida +benadida6,ben6@adida.net,Ben6 Adida +benadida7,ben7@adida.net,Ben7 Adida +ernesto,helios-testing-ernesto@adida.net,Erñesto Testing Helios \ No newline at end of file diff --git a/helios/models.py b/helios/models.py index c59a08969eb868ba04f586d78399dcf051e8a1e8..3df75bb6c037cc1c317a81a3e0c5c7b4f4fa9280 100644 --- a/helios/models.py +++ b/helios/models.py @@ -703,9 +703,14 @@ class VoterFile(models.Model): if len(voter_fields) > 1: return_dict['email'] = voter_fields[1].strip() + else: + # assume single field means the email is the same field + return_dict['email'] = voter_fields[0].strip() if len(voter_fields) > 2: return_dict['name'] = voter_fields[2].strip() + else: + return_dict['name'] = return_dict['email'] yield return_dict diff --git a/helios/templates/voters_upload_confirm.html b/helios/templates/voters_upload_confirm.html index 18d5e0964270b41f7700c09781cd377fbd7a846e..4f5d2adae032cde21bf32ad697abd11f1a03649c 100644 --- a/helios/templates/voters_upload_confirm.html +++ b/helios/templates/voters_upload_confirm.html @@ -14,6 +14,14 @@ You have uploaded a file of voters. The first few rows of this file are: {% endfor %} </table> +{% if email_problem %} +<p style="font-size: 1.5em;"> +<b>HOLD ON</b>: those don't look like correct email addresses. Are you sure you uploaded a file with email address as second field?<br /> + +<a href="{% url helios.views.voters_upload_cancel election.uuid %}">no, let me upload a different file</a> +</p> + +{% else %} <p></p> <form method="post" action="" id="upload_form"> Does this look right to you? @@ -23,4 +31,6 @@ You have uploaded a file of voters. The first few rows of this file are: <a href="{% url helios.views.voters_upload_cancel election.uuid %}">no, let me upload a different file</a> +{% endif %} + {% endblock %} diff --git a/helios/tests.py b/helios/tests.py index f04114a784be63fc6d1d2ad975019da394b4425b..eeb9caca6740f8f570f6b800efe06ae2918c0ff7 100644 --- a/helios/tests.py +++ b/helios/tests.py @@ -543,6 +543,13 @@ class ElectionBlackboxTests(WebTest): response = self.client.get("/helios/elections/%s/trustees/view" % election_id) self.assertContains(response, "Trustee #1") + # add a few voters with an improperly placed email address + FILE = "helios/fixtures/voter-badfile.csv" + voters_file = open(FILE) + response = self.client.post("/helios/elections/%s/voters/upload" % election_id, {'voters_file': voters_file}) + voters_file.close() + self.assertContains(response, "HOLD ON") + # add a few voters, via file upload # this file now includes a UTF-8 encoded unicode character # yes I know that's not how you spell Ernesto. @@ -652,7 +659,7 @@ class ElectionBlackboxTests(WebTest): # cast_confirm_page = cast_confirm_page.follow() else: # here we should be at the cast-confirm page and logged in - self.assertContains(cast_confirm_page, "I am ") + self.assertContains(cast_confirm_page, "CAST this ballot") # confirm the vote, now with the actual form cast_form = cast_confirm_page.form diff --git a/helios/views.py b/helios/views.py index 44002dafc68765e60dcbf2164eb144ce33d7b841..2c2775054071aed0d49115648850acd830ec3ee3 100644 --- a/helios/views.py +++ b/helios/views.py @@ -13,6 +13,8 @@ from django.db import transaction from mimetypes import guess_type +from validate_email import validate_email + import csv, urllib, os, base64 from crypto import algs, electionalgs, elgamal @@ -1204,7 +1206,10 @@ def voters_upload(request, election): # import the first few lines to check voters = [v for v in voter_file_obj.itervoters()][:5] - return render_template(request, 'voters_upload_confirm', {'election': election, 'voters': voters}) + # check if voter emails look like emails + email_problem = False in [validate_email(v['email']) for v in voters] + + return render_template(request, 'voters_upload_confirm', {'election': election, 'voters': voters, 'email_problem': email_problem}) else: return HttpResponseRedirect("%s?%s" % (settings.SECURE_URL_HOST + reverse(voters_upload, args=[election.uuid]), urllib.urlencode({'e':'no voter file specified, try again'}))) diff --git a/requirements.txt b/requirements.txt index fa99dcffc067dfcf93370f7f9dd67d72167c7f45..0ee4a32c1e05758b8243c4c687a2a8f1ca3eba03 100644 --- a/requirements.txt +++ b/requirements.txt @@ -22,3 +22,4 @@ django-secure==0.1.2 bleach==1.4 boto==2.27.0 django-ses==0.6.0 +validate_email==1.2