Skip to content
Snippets Groups Projects
Commit 071d5307 authored by Ben Adida's avatar Ben Adida
Browse files

merged v3.0 maintenance changes

parents 10e736b4 705802da
No related branches found
No related tags found
No related merge requests found
...@@ -9,12 +9,13 @@ from django.http import * ...@@ -9,12 +9,13 @@ from django.http import *
from django.core.mail import send_mail from django.core.mail import send_mail
from django.conf import settings from django.conf import settings
import sys, os, cgi, urllib, urllib2, re import sys, os, cgi, urllib, urllib2, re, uuid, datetime
from xml.etree import ElementTree from xml.etree import ElementTree
CAS_EMAIL_DOMAIN = "princeton.edu" CAS_EMAIL_DOMAIN = "princeton.edu"
CAS_URL= 'https://fed.princeton.edu/cas/' CAS_URL= 'https://fed.princeton.edu/cas/'
CAS_LOGOUT_URL = 'https://fed.princeton.edu/cas/logout?service=%s' CAS_LOGOUT_URL = 'https://fed.princeton.edu/cas/logout?service=%s'
CAS_SAML_VALIDATE_URL = 'https://fed.princeton.edu/cas/samlValidate?TARGET=%s'
# eligibility checking # eligibility checking
if hasattr(settings, 'CAS_USERNAME'): if hasattr(settings, 'CAS_USERNAME'):
...@@ -34,7 +35,7 @@ def _get_service_url(): ...@@ -34,7 +35,7 @@ def _get_service_url():
from django.conf import settings from django.conf import settings
from django.core.urlresolvers import reverse from django.core.urlresolvers import reverse
return settings.URL_HOST + reverse(after) return settings.SECURE_URL_HOST + reverse(after)
def get_auth_url(request, redirect_url): def get_auth_url(request, redirect_url):
request.session['cas_redirect_url'] = redirect_url request.session['cas_redirect_url'] = redirect_url
...@@ -52,6 +53,47 @@ def get_user_category(user_id): ...@@ -52,6 +53,47 @@ def get_user_category(user_id):
parsed_result = ElementTree.fromstring(result) parsed_result = ElementTree.fromstring(result)
return parsed_result.text return parsed_result.text
def get_saml_info(ticket):
"""
Using SAML, get all of the information needed
"""
import logging
saml_request = """<?xml version='1.0' encoding='UTF-8'?>
<soap-env:Envelope
xmlns:soap-env='http://schemas.xmlsoap.org/soap/envelope/'>
<soap-env:Header />
<soap-env:Body>
<samlp:Request xmlns:samlp="urn:oasis:names:tc:SAML:1.0:protocol"
MajorVersion="1" MinorVersion="1"
RequestID="%s"
IssueInstant="%sZ">
<samlp:AssertionArtifact>%s</samlp:AssertionArtifact>
</samlp:Request>
</soap-env:Body>
</soap-env:Envelope>
""" % (uuid.uuid1(), datetime.datetime.utcnow().isoformat(), ticket)
url = CAS_SAML_VALIDATE_URL % urllib.quote(_get_service_url())
# by virtue of having a body, this is a POST
req = urllib2.Request(url, saml_request)
raw_response = urllib2.urlopen(req).read()
logging.info("RESP:\n%s\n\n" % raw_response)
response = ElementTree.fromstring(raw_response)
# ugly path down the tree of attributes
attributes = response.findall('{http://schemas.xmlsoap.org/soap/envelope/}Body/{urn:oasis:names:tc:SAML:1.0:protocol}Response/{urn:oasis:names:tc:SAML:1.0:assertion}Assertion/{urn:oasis:names:tc:SAML:1.0:assertion}AttributeStatement/{urn:oasis:names:tc:SAML:1.0:assertion}Attribute')
values = {}
for attribute in attributes:
values[str(attribute.attrib['AttributeName'])] = attribute.findtext('{urn:oasis:names:tc:SAML:1.0:assertion}AttributeValue')
# parse response for netid, display name, and employee type (category)
return {'user_id': values.get('mail',None), 'name': values.get('displayName', None), 'category': values.get('employeeType',None)}
def get_user_info(user_id): def get_user_info(user_id):
url = 'http://dsml.princeton.edu/' url = 'http://dsml.princeton.edu/'
...@@ -101,13 +143,7 @@ def get_user_info(user_id): ...@@ -101,13 +143,7 @@ def get_user_info(user_id):
else: else:
return None return None
def get_user_info_after_auth(request): def get_user_info_special(ticket):
ticket = request.GET.get('ticket', None)
# if no ticket, this is a logout
if not ticket:
return None
# fetch the information from the CAS server # fetch the information from the CAS server
val_url = CAS_URL + "validate" + \ val_url = CAS_URL + "validate" + \
'?service=' + urllib.quote(_get_service_url()) + \ '?service=' + urllib.quote(_get_service_url()) + \
...@@ -119,17 +155,38 @@ def get_user_info_after_auth(request): ...@@ -119,17 +155,38 @@ def get_user_info_after_auth(request):
netid = r[1].strip() netid = r[1].strip()
category = get_user_category(netid) category = get_user_category(netid)
user_info = get_user_info(netid)
#try:
# user_info = get_user_info(netid)
#except:
# user_info = None
# for now, no need to wait for this request to finish
user_info = None
if user_info: if user_info:
info = {'name': user_info['name'], 'category': category} info = {'name': user_info['name'], 'category': category}
else: else:
info = {'name': netid, 'category': category} info = {'name': netid, 'category': category}
return {'type': 'cas', 'user_id': netid, 'name': info['name'], 'info': info, 'token': None} return {'user_id': netid, 'name': info['name'], 'info': info, 'token': None}
else: else:
return None return None
def get_user_info_after_auth(request):
ticket = request.GET.get('ticket', None)
# if no ticket, this is a logout
if not ticket:
return None
#user_info = get_saml_info(ticket)
user_info = get_user_info_special(ticket)
user_info['type'] = 'cas'
return user_info
def do_logout(user): def do_logout(user):
""" """
Perform logout of CAS by redirecting to the CAS logout URL Perform logout of CAS by redirecting to the CAS logout URL
......
...@@ -33,8 +33,8 @@ class EmailVotersForm(forms.Form): ...@@ -33,8 +33,8 @@ class EmailVotersForm(forms.Form):
class TallyNotificationEmailForm(forms.Form): class TallyNotificationEmailForm(forms.Form):
subject = forms.CharField(max_length=80) subject = forms.CharField(max_length=80)
body = forms.CharField(max_length=2000, widget=forms.Textarea) body = forms.CharField(max_length=2000, widget=forms.Textarea, required=False)
send_to = forms.ChoiceField(label="Send To", choices= [('all', 'all voters'), ('voted', 'only voters who cast a ballot')]) send_to = forms.ChoiceField(label="Send To", choices= [('all', 'all voters'), ('voted', 'only voters who cast a ballot'), ('none', 'no one -- are you sure about this?')])
class VoterPasswordForm(forms.Form): class VoterPasswordForm(forms.Form):
voter_id = forms.CharField(max_length=50) voter_id = forms.CharField(max_length=50)
......
...@@ -27,7 +27,9 @@ ...@@ -27,7 +27,9 @@
{% for t in trustees %} {% for t in trustees %}
<h3> Trustee #{{forloop.counter}}: {{t.name}} <h3> Trustee #{{forloop.counter}}: {{t.name}}
{% if admin_p %} {% if admin_p %}
{% if not t.secret_key %} {% if t.secret_key %}
{% if not election.frozen_at %}[<a onclick="return confirm('Are you sure you want to remove Helios as a trustee?');" href="{% url helios.views.delete_trustee election.uuid %}?uuid={{t.uuid}}">x</a>]{% endif %}
{% else %}
({{t.email}}) ({{t.email}})
{% if not election.frozen_at %}[<a onclick="return confirm('Are you sure you want to remove this Trustee?');" href="{% url helios.views.delete_trustee election.uuid %}?uuid={{t.uuid}}">x</a>]{% endif %} {% if not election.frozen_at %}[<a onclick="return confirm('Are you sure you want to remove this Trustee?');" href="{% url helios.views.delete_trustee election.uuid %}?uuid={{t.uuid}}">x</a>]{% endif %}
[<a onclick="return confirm('Are you sure you want to send this trustee his/her admin URL?');" href="{% url helios.views.trustee_send_url election.uuid t.uuid %}">send login</a>] [<a onclick="return confirm('Are you sure you want to send this trustee his/her admin URL?');" href="{% url helios.views.trustee_send_url election.uuid t.uuid %}">send login</a>]
......
...@@ -353,7 +353,7 @@ def new_trustee_helios(request, election): ...@@ -353,7 +353,7 @@ def new_trustee_helios(request, election):
election.generate_trustee(ELGAMAL_PARAMS) election.generate_trustee(ELGAMAL_PARAMS)
return HttpResponseRedirect(reverse(list_trustees_view, args=[election.uuid])) return HttpResponseRedirect(reverse(list_trustees_view, args=[election.uuid]))
@election_admin() @election_admin(frozen=False)
def delete_trustee(request, election): def delete_trustee(request, election):
trustee = Trustee.get_by_election_and_uuid(election, request.GET['uuid']) trustee = Trustee.get_by_election_and_uuid(election, request.GET['uuid'])
trustee.delete() trustee.delete()
...@@ -538,7 +538,7 @@ def one_election_cast_confirm(request, election): ...@@ -538,7 +538,7 @@ def one_election_cast_confirm(request, election):
# status update this vote # status update this vote
if voter and user and user.can_update_status(): if voter and user and user.can_update_status():
status_update_label = voter.user.update_status_template() % "your smart ballot tracker" status_update_label = voter.user.update_status_template() % "your smart ballot tracker"
status_update_message = "I voted in %s, my smart tracker is %s.. -- %s" % (election.name, cast_vote.vote_hash[:10], get_election_url(election)) status_update_message = "I voted in %s - my smart tracker is %s.. #heliosvoting" % (get_election_url(election),cast_vote.vote_hash[:10])
else: else:
status_update_label = None status_update_label = None
status_update_message = None status_update_message = None
...@@ -929,6 +929,8 @@ def combine_decryptions(request, election): ...@@ -929,6 +929,8 @@ def combine_decryptions(request, election):
'election' : election 'election' : election
} }
# if the user opted for notifying no one, then we skip this step
if email_form.cleaned_data['send_to'] != 'none':
# exclude those who have not voted # exclude those who have not voted
if email_form.cleaned_data['send_to'] == 'voted': if email_form.cleaned_data['send_to'] == 'voted':
voter_constraints_exclude = {'vote_hash' : None} voter_constraints_exclude = {'vote_hash' : None}
...@@ -944,6 +946,7 @@ def combine_decryptions(request, election): ...@@ -944,6 +946,7 @@ def combine_decryptions(request, election):
# rapid short-message notification # rapid short-message notification
# this inherently only applies to those who have voted (for the most part) # this inherently only applies to those who have voted (for the most part)
# and this is not configurable, this is ALWAYS sent
tasks.voters_notify.delay(election_id = election.id, tasks.voters_notify.delay(election_id = election.id,
notification_template = 'notification/result.txt', notification_template = 'notification/result.txt',
extra_vars = extra_vars) extra_vars = extra_vars)
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment