From 431a6b3317b55b026da5e4ed80f3235664e30950 Mon Sep 17 00:00:00 2001
From: Ben Adida <ben@adida.net>
Date: Sun, 13 Mar 2011 19:15:39 -0700
Subject: [PATCH] added logic for private elections, but widget still hidden as
 need to think about how to do / disallow private elections for
 facebook/google/twitter users

---
 helios/security.py                         |  7 ++++---
 helios/templates/password_voter_login.html | 12 ++++++++++++
 helios/tests.py                            | 19 +++++++++++--------
 helios/views.py                            |  7 ++++++-
 4 files changed, 33 insertions(+), 12 deletions(-)
 create mode 100644 helios/templates/password_voter_login.html

diff --git a/helios/security.py b/helios/security.py
index 73115e0..7abbf32 100644
--- a/helios/security.py
+++ b/helios/security.py
@@ -7,6 +7,7 @@ Ben Adida (ben@adida.net)
 # nicely update the wrapper function
 from functools import update_wrapper
 
+from django.core.urlresolvers import reverse
 from django.core.exceptions import *
 from django.conf import settings
 
@@ -72,17 +73,17 @@ def election_view(**checks):
   def election_view_decorator(func):
     def election_view_wrapper(request, election_uuid=None, *args, **kw):
       election = get_election_by_uuid(election_uuid)
-    
+
       # do checks
       do_election_checks(election, checks)
 
       # if private election, only logged in voters
       if election.private_p and not checks.get('allow_logins',False):
-        from views import get_voter, get_user
+        from views import get_voter, get_user, password_voter_login
         user = get_user(request)
         if not user_can_admin_election(user, election) and not get_voter(request, user, election):
           # FIXME: should be a nice redirect
-          raise PermissionDenied()
+          return HttpResponseRedirect(reverse(password_voter_login, args=[election.uuid]))
     
       return func(request, election, *args, **kw)
 
diff --git a/helios/templates/password_voter_login.html b/helios/templates/password_voter_login.html
new file mode 100644
index 0000000..dd92a32
--- /dev/null
+++ b/helios/templates/password_voter_login.html
@@ -0,0 +1,12 @@
+{% extends TEMPLATE_BASE %}
+
+{% block title %}Log In to View Election{% endblock %}
+{% block content %}
+<h2>Private Election - Please Log In</h2>
+
+<p>
+This election, with fingerprint <tt>{{election.hash}}</tt>, is private, and can only be viewed by eligible voters.
+</p>
+
+{% include "_castconfirm_password.html" %}
+{% endblock %}
diff --git a/helios/tests.py b/helios/tests.py
index 760c8de..70bdabe 100644
--- a/helios/tests.py
+++ b/helios/tests.py
@@ -492,7 +492,7 @@ class ElectionBlackboxTests(TestCase):
         # return the voter username and password to vote
         return election_id, username, password
 
-    def _cast_ballot(self, election_id, username, password):
+    def _cast_ballot(self, election_id, username, password, need_login=True):
         # vote by preparing a ballot via the server-side encryption
         response = self.client.post("/helios/elections/%s/encrypt-ballot" % election_id, {
                 'answers_json': utils.to_json([[1]])})
@@ -507,12 +507,15 @@ class ElectionBlackboxTests(TestCase):
                 'encrypted_vote': encrypted_vote})
         self.assertRedirects(response, "%s/helios/elections/%s/cast_confirm" % (settings.SECURE_URL_HOST, election_id))        
 
-        # log in
-        response = self.client.post("/helios/elections/%s/password_voter_login" % election_id, {
-                'voter_id' : username,
-                'password' : password
-                })
-        self.assertRedirects(response, "/helios/elections/%s/cast_confirm" % election_id)
+        if need_login:
+            response = self.client.post("/helios/elections/%s/password_voter_login" % election_id, {
+                    'voter_id' : username,
+                    'password' : password
+                    })
+            self.assertRedirects(response, "/helios/elections/%s/cast_confirm" % election_id)
+        else:
+            response = self.client.get("/helios/elections/%s/cast_confirm" % election_id)
+            self.assertContains(response, "I am ")
 
         # confirm the vote
         response = self.client.post("/helios/elections/%s/cast_confirm" % election_id, {
@@ -576,5 +579,5 @@ class ElectionBlackboxTests(TestCase):
                 })
         self.assertRedirects(response, "/helios/elections/%s/view" % election_id)
 
-        self._cast_ballot(election_id, username, password)
+        self._cast_ballot(election_id, username, password, need_login = False)
         self._do_tally(election_id)
diff --git a/helios/views.py b/helios/views.py
index e2b3776..fbad7ba 100644
--- a/helios/views.py
+++ b/helios/views.py
@@ -499,11 +499,16 @@ def one_election_cast(request, election):
 
   return HttpResponseRedirect("%s%s" % (settings.SECURE_URL_HOST, reverse(one_election_cast_confirm, args=[election.uuid])))
 
-@election_view(frozen=True, allow_logins=True)
+@election_view(allow_logins=True)
 def password_voter_login(request, election):
   """
   This is used to log in as a voter for a particular election
   """
+
+  if request.method == "GET":
+    password_login_form = forms.VoterPasswordForm()
+    return render_template(request, 'password_voter_login', {'election': election, 'password_login_form': password_login_form})
+
   password_login_form = forms.VoterPasswordForm(request.POST)
 
   # redirect base depending on whether this is a private election
-- 
GitLab