diff --git a/auth/auth_systems/facebook.py b/auth/auth_systems/facebook.py
index 7ace5cb0900150a47a40f99362ec0a6784483932..7951197f051fbabf6900653c6f42204fdc6f2f91 100644
--- a/auth/auth_systems/facebook.py
+++ b/auth/auth_systems/facebook.py
@@ -85,7 +85,7 @@ def get_user_groups(user):
 
 def check_constraint(constraint, user):
   # get the groups for the user
-  groups = [group['id'] for group in get_user_groups(user.token)]
+  groups = [group['id'] for group in get_user_groups(user)]
 
   # check if one of them is the group in the constraint
   try:
diff --git a/helios/fixtures/users.json b/helios/fixtures/users.json
index e66e46d1db2b33cdf3ca21b0db6a00e4fde07b26..62f2a32e72d41064841bb3cf221e154bb820e873 100644
--- a/helios/fixtures/users.json
+++ b/helios/fixtures/users.json
@@ -1 +1 @@
-[{"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
+[{"pk": 1, "model": "auth.user", "fields": {"info": "{}", "user_id": "ben@adida.net", "name": "Ben Adida", "user_type": "google", "token": null, "admin_p": false}},{"pk": 2, "model": "auth.user", "fields": {"info": "{}", "user_id": "12345", "name": "Ben Adida", "user_type": "facebook", "token": {"access_token":"1234"}, "admin_p": false}}]
\ No newline at end of file
diff --git a/helios/models.py b/helios/models.py
index f0ca2468eebae6411b159cc0b929a0a8f9e43313..9841a773e566981d01fda3222ff2cb4713646535 100644
--- a/helios/models.py
+++ b/helios/models.py
@@ -255,7 +255,7 @@ class Election(HeliosModel):
     if not self.eligibility:
       return "Everyone can vote."
     else:
-      return_val = "Only the following users can vote:<ul>"
+      return_val = "<ul>"
       
       for constraint in self.eligibility:
         for one_constraint in constraint['constraint']:
diff --git a/helios/templates/election_view.html b/helios/templates/election_view.html
index f0d856e060dfefad2050b3e57130e6a08e2c8805..78beb63402a03d3725a46858636a9b9ee80a8c5a 100644
--- a/helios/templates/election_view.html
+++ b/helios/templates/election_view.html
@@ -229,27 +229,24 @@ Your voter alias is {{voter.alias}}.
 {% else %}
 {% if election.openreg %}
 {% if eligible_p %}
-{% if election.voting_has_started %}
-This {{election.election_type}} is open to anyone.
-{% else %}
-You are <em>not</em> registered to vote in this {{election.election_type}}.<br />
-<form method="post" action="{% url helios.views.one_election_register election.uuid %}">
-<input type="hidden" name="csrf_token" value="{{csrf_token}}" />
-<input type="submit" value="register!" />
-</form>
-{% endif %}
+You are eligible to vote in this election.
 {% else %}
-Registration for this {{election.election_type}} is open, but You are <em>not eligible</em>.
+You are <em>not eligible</em> to vote in this {{election.election_type}}.
 {% endif %}
 {% else %}
-You are <em>not eligible</em> to vote in this {{election.election_type}}, because registration is closed and you are not registered.<br />
+You are <em>not eligible</em> to vote in this {{election.election_type}}.
+<br />
 {% endif %}
 {% endif %}
 {% endif %}
 {% else %}
 
 {% if election.openreg %}
-Anyone can register for this election. <a href="{{settings.SECURE_URL_HOST}}{% url auth.views.index %}?return_url={{CURRENT_URL}}">Log in</a> and register!
+{% if election.eligibility %}
+This election is open to: {{election.pretty_eligibility|safe}}.  <a href="{{settings.SECURE_URL_HOST}}{% url auth.views.index %}?return_url={{CURRENT_URL}}">Log in</a> to check your eligibility.
+{% else %}
+Anyone can vote in this election.
+{% endif %}
 {% endif %}
 
 {% endif %}
diff --git a/helios/templates/voters_list.html b/helios/templates/voters_list.html
index 6bdd14fa7f259a6033d260a46edc49e172c68e3c..fba557f6ebcbd2ed72f76627ab6aa31b0dcd09ba 100644
--- a/helios/templates/voters_list.html
+++ b/helios/templates/voters_list.html
@@ -5,30 +5,36 @@
   <h2 class="title">{{election.name}} &mdash; Voters and Ballot Tracking Center <span style="font-size:0.7em;">[<a href="{% url helios.views.one_election_view election.uuid %}">back to election</a>]</span></h2>
 
 <p>
-<u>Registration</u> is {% if not election.frozen_at %}currently{% endif %} <b>{{ election.registration_status_pretty }}</b>.
-{% if admin_p and not election.frozen_at %}
+<b>Who can vote?</b>
 {% if election.openreg %}
-[<a href="{% url helios.views.one_election_set_reg election.uuid %}?open_p=0">switch to closed</a>]
-
-{% if can_set_eligibility %}
-<p>
-<em>{{election.pretty_eligibility|safe}}</em>
-<br />
-You can <a href="{% url helios.views.voters_eligibility election.uuid %}">limit the eligibility</a> of voters based on their {{user.user_type}} credentials.
-</p>
+{{election.pretty_eligibility|safe}}
+{% else %}
+<em>Only the voters listed here</em>.
 {% endif %}
+</p>
 
-
-{% else %}
+{% if admin_p and not election.frozen_at %}
 {% if election.private_p %}
-<br />
-Your election is marked private: registration can be opened to the public only for public elections.
+<em>Your election is marked private, which means you cannot open registration up more widely</em>.<br />
 {% else %}
-[<a href="{% url helios.views.one_election_set_reg election.uuid %}?open_p=1">switch to open</a>]
+You can change this setting:
+<form method="post" action="{% url helios.views.voters_eligibility election.uuid %}">
+<input type="hidden" name="csrf_token" value="{{csrf_token}}" />
+<input type="radio" name="eligibility" value="openreg" {% if election.openreg and not election.eligibility %}CHECKED{% endif %} /> anyone can vote<br />
+<input type="radio" name="eligibility" value="closedreg" {% if not election.openreg %}CHECKED{% endif %} /> only voters listed explicitly below can vote<br />
+{% if categories %}
+<input type="radio" name="eligibility" value="limitedreg" {% if election.eligibility %}CHECKED{% endif %} /> only voters who are members of 
+<select name="category_id">
+{% for category in categories %}
+<option value="{{category.id}}"> {{category.name}}</option>
+{% endfor %}
+</select>
+<br />
 {% endif %}
+<input type="submit" value="update" />
+</form>
 {% endif %}
 {% endif %}
-</p>
 
 {% if email_voters and election.frozen_at and admin_p %}
 <p><a href="{% url helios.views.voters_email election.uuid %}">email voters</a></p>
@@ -46,7 +52,7 @@ Your election is marked private: registration can be opened to the public only f
 
 {% if admin_p %}
 <!-- Add a Voter: WORK HERE-->
-{% if upload_p %}
+{% if upload_p and not election.openreg %}
 <p>
 <a href="{% url helios.views.voters_upload election_uuid=election.uuid %}">bulk upload voters</a>
 </p>
@@ -125,6 +131,7 @@ Voters {{voters_page.start_index}} - {{voters_page.end_index}} (of {{total_voter
 </table>
 
 {% else %}
+<br /><br />
 <em>no voters.</em>
 {% endif %}
 
diff --git a/helios/tests.py b/helios/tests.py
index 91a414f29ec7b76dcff8835ce607f3e6e7dac24d..61ccfa6debd9ebd05d23b2a6de819e4c5e6da86f 100644
--- a/helios/tests.py
+++ b/helios/tests.py
@@ -49,6 +49,7 @@ class ElectionModelTests(TestCase):
     
     def setUp(self):
         self.user = auth_models.User.objects.get(user_id='ben@adida.net', user_type='google')
+        self.fb_user = auth_models.User.objects.get(user_type='facebook')
         self.election, self.created_p = self.create_election()
 
     def test_create_election(self):
@@ -147,6 +148,24 @@ class ElectionModelTests(TestCase):
         # without openreg, and now true
         self.assertTrue(self.election.user_eligible_p(self.user))
 
+    def test_facebook_eligibility(self):
+        self.election.eligibility = [{'auth_system': 'facebook', 'constraint':[{'group': {'id': '123', 'name':'Fake Group'}}]}]
+
+        # without openreg, this should be false
+        self.assertFalse(self.election.user_eligible_p(self.fb_user))
+        
+        self.election.openreg = True
+
+        # fake out the facebook constraint checking, since
+        # our access_token is obviously wrong
+        from auth.auth_systems import facebook
+
+        def fake_check_constraint(constraint, user):
+            return constraint == {'group': {'id': '123', 'name':'Fake Group'}} and user == self.fb_user                
+        facebook.check_constraint = fake_check_constraint
+
+        self.assertTrue(self.election.user_eligible_p(self.fb_user))
+
     def test_freeze(self):
         # freezing without trustees and questions, no good
         def try_freeze():
@@ -670,6 +689,36 @@ class ElectionBlackboxTests(WebTest):
         self._cast_ballot(election_id, username, password, need_login = False)
         self._do_tally(election_id)
 
+    def test_election_voters_eligibility(self):
+        # create the election
+        self.client.get("/")
+        self.setup_login()
+        response = self.app.post("/helios/elections/new", {
+                "short_name" : "test-eligibility",
+                "name" : "Test Eligibility",
+                "description" : "An election test for voter eligibility",
+                "election_type" : "election",
+                "use_voter_aliases": "0",
+                "use_advanced_audit_features": "1",
+                "private_p" : "0"})
+
+        election_id = re.match("(.*)/elections/(.*)/view", response.location).group(2)
+        
+        # get the eligibility page
+        eligibility_page = self.app.get("/helios/elections/%s/voters/list" % election_id)
+
+        elig_form = eligibility_page.form
+        elig_form['eligibility'] = 'openreg'
+        elig_page = elig_form.submit().follow()
+
+        self.assertContains(elig_page, "Everyone can vote")
+
+        elig_form = elig_page.form
+        elig_form['eligibility'] = 'closedreg'
+        elig_page = elig_form.submit().follow()
+
+        self.assertContains(elig_page, "Only the voters listed here")
+
     def test_do_complete_election_with_trustees(self):
         """
         FIXME: do the this test
diff --git a/helios/views.py b/helios/views.py
index 2a82eae8de22d6dcd982774d8d2280b6134a7bd6..169d9c43d46012ee798d4d5eca2c1e3ae4657b32 100644
--- a/helios/views.py
+++ b/helios/views.py
@@ -1114,10 +1114,9 @@ def voters_list_pretty(request, election):
   user = get_user(request)
   admin_p = security.user_can_admin_election(user, election)
 
-  if admin_p and election.openreg:
-    can_set_eligibility = can_list_categories(user.user_type)
-  else:
-    can_set_eligibility = False
+  categories = None
+  if admin_p and can_list_categories(user.user_type):
+      categories = AUTH_SYSTEMS[user.user_type].list_categories(user)
   
   # files being processed
   voter_files = election.voterfile_set.all()
@@ -1144,34 +1143,43 @@ def voters_list_pretty(request, election):
                           'limit': limit, 'total_voters': total_voters,
                           'upload_p': helios.VOTERS_UPLOAD, 'q' : q,
                           'voter_files': voter_files,
-                          'can_set_eligibility': can_set_eligibility})
+                          'categories': categories})
 
 @election_admin()
 def voters_eligibility(request, election):
+  """
+  set eligibility for voters
+  """
   user = get_user(request)
 
-  if not can_list_categories(user.user_type):
+  if request.method == "GET":
+    # this shouldn't happen, only POSTs
+    return HttpResponseRedirect("/")
+
+  # for now, private elections cannot change eligibility
+  if election.private_p:
     return HttpResponseRedirect(reverse(voters_list_pretty, args=[election.uuid]))
 
-  if request.method == "GET":
-    categories = AUTH_SYSTEMS[user.user_type].list_categories(user)
+  # eligibility
+  eligibility = request.POST['eligibility']
+
+  if eligibility in ['openreg', 'limitedreg']:
+    election.openreg= True
 
-    return render_template(request, 'voters_eligibility',
-                           {'categories' : categories, 'election': election})
+  if eligibility == 'closedreg':
+    election.openreg= False
 
-  # now process the constraint
-  category_id = request.POST['category_id']
-  if category_id == "":
-    category_id = None
+  if eligibility == 'limitedreg':
+    # now process the constraint
+    category_id = request.POST['category_id']
 
-  if category_id:
     constraint = AUTH_SYSTEMS[user.user_type].generate_constraint(category_id, user)
     election.eligibility = [{'auth_system': user.user_type, 'constraint': [constraint]}]
   else:
     election.eligibility = None
-  
+
   election.save()
-  return HttpResponseRedirect(reverse(voters_eligibility, args=[election.uuid]))
+  return HttpResponseRedirect(reverse(voters_list_pretty, args=[election.uuid]))
   
 @election_admin()
 def voters_upload(request, election):