diff --git a/.travis.yml b/.travis.yml index 6b93e8ab16e9d955e4a725263820f997c0ed30c5..1505fccb9e5bd689f6964ac911b32fa86dac2b92 100644 --- a/.travis.yml +++ b/.travis.yml @@ -2,16 +2,41 @@ sudo: false language: python python: - "2.7" -# command to install dependencies, e.g. pip install -r requirements.txt --use-mirrors + +os: linux + +before_install: + - export BOTO_CONFIG=/dev/null + install: - - pip install setuptools==24.3.1 + - pip install --upgrade pip - pip install -r requirements.txt -# command to run tests, e.g. python setup.py test -script: "python manage.py test" -addons: - postgresql: "9.3" + before_script: - psql -c 'create database helios;' -U postgres -before_install: - - export BOTO_CONFIG=/dev/null +script: "python -Wall manage.py test" + +jobs: + include: + - dist: trusty + addons: + postgresql: "9.3" + - dist: trusty + addons: + postgresql: "9.4" + - dist: trusty + addons: + postgresql: "9.5" + - dist: trusty + addons: + postgresql: "9.6" + - dist: xenial + addons: + postgresql: "9.4" + - dist: xenial + addons: + postgresql: "9.5" + - dist: xenial + addons: + postgresql: "9.6" diff --git a/CONTRIBUTORS.txt b/CONTRIBUTORS.txt index 61ac19608d9d2f4d2a54bf94b25ef65330682a43..e37f6e4a175408d6edea7843ccfea90942767fc6 100644 --- a/CONTRIBUTORS.txt +++ b/CONTRIBUTORS.txt @@ -7,3 +7,5 @@ Significant contributors: - Olivier de Marneffe - Emily Stark, Mike Hamburg, Tom Wu, and Dan Boneh for SJCL and integration of javascript crypto. - Nicholas Chang-Fong and Aleksander Essex for security reports and fixes. +- Shirley Chaves +- Marco Ciotola diff --git a/Procfile b/Procfile index 63d8d0cf6be1b07f29a15897a3f113b10c8355b3..608417dd038c618cda97dbc7f89e527ccea20dde 100644 --- a/Procfile +++ b/Procfile @@ -1,2 +1,2 @@ web: gunicorn wsgi:application -b 0.0.0.0:$PORT -w 8 -worker: python manage.py celeryd -E -B --beat --concurrency=1 \ No newline at end of file +worker: celery worker --app helios --events --beat --concurrency 1 --logfile celeryw.log --pidfile celeryw.pid \ No newline at end of file diff --git a/README.md b/README.md index 5c90a9c206ed2b2657284dc76cb00f11f98a62ab..9a5519bfc40a91c5f56a03198ea0d38f3d81e5e8 100644 --- a/README.md +++ b/README.md @@ -2,6 +2,6 @@ Helios is an end-to-end verifiable voting system. - +[](https://travis-ci.org/benadida/helios-server) [](https://waffle.io/benadida/helios-server) diff --git a/extract-passwords-for-email.py b/extract-passwords-for-email.py index d72705792a7691b2b26c863841e6c4bb01efeafc..7769d02557a621138e724e74d2a6200bfd5dea55 100644 --- a/extract-passwords-for-email.py +++ b/extract-passwords-for-email.py @@ -5,12 +5,16 @@ # python extract-passwords-for-email.py <election_uuid> <email_address> # -from django.core.management import setup_environ -import settings, sys, csv +import sys -setup_environ(settings) +import csv +import django +import os -from helios.models import * +from helios.models import Election + +os.environ.setdefault("DJANGO_SETTINGS_MODULE", "settings") +django.setup() election_uuid = sys.argv[1] email = sys.argv[2] diff --git a/helios/__init__.py b/helios/__init__.py index 3a516d7ce25e875c70086e5fa368e1af73eb6cd4..2f598298b565f3a883cf9365699a6911031e0120 100644 --- a/helios/__init__.py +++ b/helios/__init__.py @@ -1,5 +1,9 @@ from django.conf import settings -from django.core.urlresolvers import reverse +# This will make sure the app is always imported when +# Django starts so that shared_task will use this app. +from celery_app import app as celery_app + +__all__ = ('celery_app', 'TEMPLATE_BASE', 'ADMIN_ONLY', 'VOTERS_UPLOAD', 'VOTERS_EMAIL',) TEMPLATE_BASE = settings.HELIOS_TEMPLATE_BASE or "helios/templates/base.html" diff --git a/helios/apps.py b/helios/apps.py new file mode 100644 index 0000000000000000000000000000000000000000..90097432826dafdc8670f50a87eaa07403598c70 --- /dev/null +++ b/helios/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + +class HeliosConfig(AppConfig): + name = 'helios' + verbose_name = "Helios" diff --git a/helios/celery_app.py b/helios/celery_app.py new file mode 100644 index 0000000000000000000000000000000000000000..89f0ecb54d7f3f2cea1985ee8c5059a47866ca2a --- /dev/null +++ b/helios/celery_app.py @@ -0,0 +1,21 @@ +import os + +# set the default Django settings module for the 'celery' program. +from celery import Celery + +os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'settings') + +app = Celery() + +# Using a string here means the worker doesn't have to serialize +# the configuration object to child processes. +# - namespace='CELERY' means all celery-related configuration keys +# should have a `CELERY_` prefix. +app.config_from_object('django.conf:settings', namespace='CELERY') + +# Load task modules from all registered Django app configs. +app.autodiscover_tasks() + +@app.task(bind=True) +def debug_task(self): + print('Request: {0!r}'.format(self.request)) diff --git a/helios/datatypes/__init__.py b/helios/datatypes/__init__.py index b0ede25f2ed3569bc28d6bf414be7844b714b517..93bca2442f0dbe792bf879afd3e3c704c617a28d 100644 --- a/helios/datatypes/__init__.py +++ b/helios/datatypes/__init__.py @@ -33,7 +33,7 @@ from helios.crypto import utils as cryptoutils ## utility function ## def recursiveToDict(obj): - if obj == None: + if obj is None: return None if type(obj) == list: @@ -53,7 +53,7 @@ def get_class(datatype): dynamic_module = __import__(".".join(parsed_datatype[:-1]), globals(), locals(), [], level=-1) if not dynamic_module: - raise Exception("no module for %s" % datatpye) + raise Exception("no module for %s" % datatype) # go down the attributes to get to the class try: @@ -130,7 +130,7 @@ class LDObject(object): raise Exception("no datatype found") # nulls - if obj == None: + if obj is None: return None # the class @@ -171,7 +171,7 @@ class LDObject(object): self.structured_fields[f] = sub_ld_object # set the field on the wrapped object too - if sub_ld_object != None: + if sub_ld_object is not None: self._setattr_wrapped(f, sub_ld_object.wrapped_obj) else: self._setattr_wrapped(f, None) @@ -190,7 +190,7 @@ class LDObject(object): fields = self.FIELDS if not self.structured_fields: - if self.wrapped_obj.alias != None: + if self.wrapped_obj.alias is not None: fields = self.ALIASED_VOTER_FIELDS for f in (alternate_fields or fields): @@ -214,7 +214,7 @@ class LDObject(object): @classmethod def fromDict(cls, d, type_hint=None): # null objects - if d == None: + if d is None: return None # the LD type is either in d or in type_hint @@ -248,11 +248,11 @@ class LDObject(object): """ process some fields on the way into the object """ - if field_value == None: + if field_value is None: return None val = self._process_value_in(field_name, field_value) - if val != None: + if val is not None: return val else: return field_value @@ -264,11 +264,11 @@ class LDObject(object): """ process some fields on the way out of the object """ - if field_value == None: + if field_value is None: return None val = self._process_value_out(field_name, field_value) - if val != None: + if val is not None: return val else: return field_value @@ -278,9 +278,9 @@ class LDObject(object): def __eq__(self, other): if not hasattr(self, 'uuid'): - return super(LDObject,self) == other + return super(LDObject, self) == other - return other != None and self.uuid == other.uuid + return other is not None and self.uuid == other.uuid class BaseArrayOfObjects(LDObject): diff --git a/helios/datatypes/djangofield.py b/helios/datatypes/djangofield.py index e0eb1b4fbccbd437ac5d4d77a37bfaadabffba5d..05f8cf355845ddf0eed23d4efc93526a4a06e269 100644 --- a/helios/datatypes/djangofield.py +++ b/helios/datatypes/djangofield.py @@ -6,15 +6,12 @@ http://www.djangosnippets.org/snippets/377/ and adapted to LDObject """ -import datetime import json from django.db import models -from django.db.models import signals -from django.conf import settings -from django.core.serializers.json import DjangoJSONEncoder from . import LDObject + class LDObjectField(models.TextField): """ LDObject is a generic textfield that neatly serializes/unserializes @@ -23,9 +20,6 @@ class LDObjectField(models.TextField): deserialization_params added on 2011-01-09 to provide additional hints at deserialization time """ - # Used so to_python() is called - __metaclass__ = models.SubfieldBase - def __init__(self, type_hint=None, **kwargs): self.type_hint = type_hint super(LDObjectField, self).__init__(**kwargs) @@ -37,7 +31,11 @@ class LDObjectField(models.TextField): if not isinstance(value, basestring): return value - if value == None: + return self.from_db_value(value) + + # noinspection PyUnusedLocal + def from_db_value(self, value, *args, **kwargs): + if value is None: return None # in some cases, we're loading an existing array or dict, @@ -50,9 +48,9 @@ class LDObjectField(models.TextField): else: parsed_value = value - if parsed_value != None: - "we give the wrapped object back because we're not dealing with serialization types" - return_val = LDObject.fromDict(parsed_value, type_hint = self.type_hint).wrapped_obj + if parsed_value is not None: + # we give the wrapped object back because we're not dealing with serialization types + return_val = LDObject.fromDict(parsed_value, type_hint=self.type_hint).wrapped_obj return return_val else: return None @@ -62,7 +60,7 @@ class LDObjectField(models.TextField): if isinstance(value, basestring): return value - if value == None: + if value is None: return None # instantiate the proper LDObject to dump it appropriately @@ -71,4 +69,4 @@ class LDObjectField(models.TextField): def value_to_string(self, obj): value = self._get_val_from_obj(obj) - return self.get_db_prep_value(value) + return self.get_db_prep_value(value, None) diff --git a/helios/datatypes/legacy.py b/helios/datatypes/legacy.py index c0a24ffc2ab2d0540d2953adf7469cd2f7c98e66..d469b4418b663456b17b695e751799b3390e5af4 100644 --- a/helios/datatypes/legacy.py +++ b/helios/datatypes/legacy.py @@ -77,7 +77,7 @@ class Voter(LegacyObject): """ depending on whether the voter is aliased, use different fields """ - if self.wrapped_obj.alias != None: + if self.wrapped_obj.alias is not None: return super(Voter, self).toDict(self.ALIASED_VOTER_FIELDS, complete = complete) else: return super(Voter,self).toDict(complete = complete) diff --git a/helios/datetimewidget.py b/helios/datetimewidget.py index 5a9e0d40a3aa46066e1539cf207125a904372b9d..81d81e0172f7538df77a8d8be8f95774c8bd4e99 100644 --- a/helios/datetimewidget.py +++ b/helios/datetimewidget.py @@ -25,6 +25,8 @@ calbtn = u'''<img src="%smedia/admin/img/admin/icon_calendar.gif" alt="calendar" </script>''' class DateTimeWidget(forms.widgets.TextInput): + template_name = '' + class Media: css = { 'all': ( diff --git a/helios/election_url_names.py b/helios/election_url_names.py new file mode 100644 index 0000000000000000000000000000000000000000..eff9a5ea232956f1e613bac9126dc51e2b3519ac --- /dev/null +++ b/helios/election_url_names.py @@ -0,0 +1,62 @@ +ELECTION_HOME="election@home" +ELECTION_VIEW="election@view" +ELECTION_META="election@meta" +ELECTION_EDIT="election@edit" +ELECTION_SCHEDULE="election@schedule" +ELECTION_EXTEND="election@extend" +ELECTION_ARCHIVE="election@archive" +ELECTION_COPY="election@copy" +ELECTION_BADGE="election@badge" + +ELECTION_TRUSTEES_HOME="election@trustees" +ELECTION_TRUSTEES_VIEW="election@trustees@view" +ELECTION_TRUSTEES_NEW="election@trustees@new" +ELECTION_TRUSTEES_ADD_HELIOS="election@trustees@add-helios" +ELECTION_TRUSTEES_DELETE="election@trustees@delete" + +ELECTION_TRUSTEE_HOME="election@trustee" +ELECTION_TRUSTEE_SEND_URL="election@trustee@send-url" +ELECTION_TRUSTEE_KEY_GENERATOR="election@trustee@key-generator" +ELECTION_TRUSTEE_CHECK_SK="election@trustee@check-sk" +ELECTION_TRUSTEE_UPLOAD_PK="election@trustee@upload-pk" +ELECTION_TRUSTEE_DECRYPT_AND_PROVE="election@trustee@decrypt-and-prove" +ELECTION_TRUSTEE_UPLOAD_DECRYPTION="election@trustee@upload-decryption" + +ELECTION_RESULT="election@result" +ELECTION_RESULT_PROOF="election@result@proof" +ELECTION_BBOARD="election@bboard" +ELECTION_AUDITED_BALLOTS="election@audited-ballots" + +ELECTION_GET_RANDOMNESS="election@get-randomness" +ELECTION_ENCRYPT_BALLOT="election@encrypt-ballot" +ELECTION_QUESTIONS="election@questions" +ELECTION_SET_REG="election@set-reg" +ELECTION_SET_FEATURED="election@set-featured" +ELECTION_SAVE_QUESTIONS="election@save-questions" +ELECTION_REGISTER="election@register" +ELECTION_FREEZE="election@freeze" + +ELECTION_COMPUTE_TALLY="election@compute-tally" +ELECTION_COMBINE_DECRYPTIONS="election@combine-decryptions" +ELECTION_RELEASE_RESULT="election@release-result" + +ELECTION_CAST="election@cast" +ELECTION_CAST_CONFIRM="election@cast-confirm" +ELECTION_PASSWORD_VOTER_LOGIN="election@password-voter-login" +ELECTION_CAST_DONE="election@cast-done" + +ELECTION_POST_AUDITED_BALLOT="election@post-audited-ballot" + +ELECTION_VOTERS_HOME="election@voters" +ELECTION_VOTERS_UPLOAD="election@voters@upload" +ELECTION_VOTERS_UPLOAD_CANCEL="election@voters@upload-cancel" +ELECTION_VOTERS_LIST="election@voters@list" +ELECTION_VOTERS_LIST_PRETTY="election@voters@list-pretty" +ELECTION_VOTERS_ELIGIBILITY="election@voters@eligibility" +ELECTION_VOTERS_EMAIL="election@voters@email" +ELECTION_VOTER="election@voter" +ELECTION_VOTER_DELETE="election@voter@delete" + +ELECTION_BALLOTS_LIST="election@ballots@list" +ELECTION_BALLOTS_VOTER="election@ballots@voter" +ELECTION_BALLOTS_VOTER_LAST="election@ballots@voter@last" diff --git a/helios/election_urls.py b/helios/election_urls.py index 6622c5568a2564d986fdf916b401de7651281796..6fc07efaac9854557b8df6243b4ec1370fdd7a89 100644 --- a/helios/election_urls.py +++ b/helios/election_urls.py @@ -4,91 +4,99 @@ Helios URLs for Election related stuff Ben Adida (ben@adida.net) """ -from django.conf.urls import * +from django.conf.urls import url -from helios.views import * +from helios import views +from helios import election_url_names as names -urlpatterns = patterns('', +urlpatterns = [ # election data that is cryptographically verified - (r'^$', one_election), + url(r'^$', views.one_election, name=names.ELECTION_HOME), # metadata that need not be verified - (r'^/meta$', one_election_meta), + url(r'^/meta$', views.one_election_meta, name=names.ELECTION_META), # edit election params - (r'^/edit$', one_election_edit), - (r'^/schedule$', one_election_schedule), - (r'^/extend$', one_election_extend), - (r'^/archive$', one_election_archive), - (r'^/copy$', one_election_copy), + url(r'^/edit$', views.one_election_edit, name=names.ELECTION_EDIT), + url(r'^/schedule$', views.one_election_schedule, name=names.ELECTION_SCHEDULE), + url(r'^/extend$', views.one_election_extend, name=names.ELECTION_EXTEND), + url(r'^/archive$', views.one_election_archive, name=names.ELECTION_ARCHIVE), + url(r'^/copy$', views.one_election_copy, name=names.ELECTION_COPY), # badge - (r'^/badge$', election_badge), + url(r'^/badge$', views.election_badge, name=names.ELECTION_BADGE), # adding trustees - (r'^/trustees/$', list_trustees), - (r'^/trustees/view$', list_trustees_view), - (r'^/trustees/new$', new_trustee), - (r'^/trustees/add-helios$', new_trustee_helios), - (r'^/trustees/delete$', delete_trustee), + url(r'^/trustees/$', views.list_trustees, name=names.ELECTION_TRUSTEES_HOME), + url(r'^/trustees/view$', views.list_trustees_view, name=names.ELECTION_TRUSTEES_VIEW), + url(r'^/trustees/new$', views.new_trustee, name=names.ELECTION_TRUSTEES_NEW), + url(r'^/trustees/add-helios$', views.new_trustee_helios, name=names.ELECTION_TRUSTEES_ADD_HELIOS), + url(r'^/trustees/delete$', views.delete_trustee, name=names.ELECTION_TRUSTEES_DELETE), # trustee pages - (r'^/trustees/(?P<trustee_uuid>[^/]+)/home$', trustee_home), - (r'^/trustees/(?P<trustee_uuid>[^/]+)/sendurl$', trustee_send_url), - (r'^/trustees/(?P<trustee_uuid>[^/]+)/keygenerator$', trustee_keygenerator), - (r'^/trustees/(?P<trustee_uuid>[^/]+)/check-sk$', trustee_check_sk), - (r'^/trustees/(?P<trustee_uuid>[^/]+)/upoad-pk$', trustee_upload_pk), - (r'^/trustees/(?P<trustee_uuid>[^/]+)/decrypt-and-prove$', trustee_decrypt_and_prove), - (r'^/trustees/(?P<trustee_uuid>[^/]+)/upload-decryption$', trustee_upload_decryption), + url(r'^/trustees/(?P<trustee_uuid>[^/]+)/home$', + views.trustee_home, name=names.ELECTION_TRUSTEE_HOME), + url(r'^/trustees/(?P<trustee_uuid>[^/]+)/sendurl$', + views.trustee_send_url, name=names.ELECTION_TRUSTEE_SEND_URL), + url(r'^/trustees/(?P<trustee_uuid>[^/]+)/keygenerator$', + views.trustee_keygenerator, name=names.ELECTION_TRUSTEE_KEY_GENERATOR), + url(r'^/trustees/(?P<trustee_uuid>[^/]+)/check-sk$', + views.trustee_check_sk, name=names.ELECTION_TRUSTEE_CHECK_SK), + url(r'^/trustees/(?P<trustee_uuid>[^/]+)/upoad-pk$', + views.trustee_upload_pk, name=names.ELECTION_TRUSTEE_UPLOAD_PK), + url(r'^/trustees/(?P<trustee_uuid>[^/]+)/decrypt-and-prove$', + views.trustee_decrypt_and_prove, name=names.ELECTION_TRUSTEE_DECRYPT_AND_PROVE), + url(r'^/trustees/(?P<trustee_uuid>[^/]+)/upload-decryption$', + views.trustee_upload_decryption, name=names.ELECTION_TRUSTEE_UPLOAD_DECRYPTION), # election voting-process actions - (r'^/view$', one_election_view), - (r'^/result$', one_election_result), - (r'^/result_proof$', one_election_result_proof), - # (r'^/bboard$', one_election_bboard), - (r'^/audited-ballots/$', one_election_audited_ballots), + url(r'^/view$', views.one_election_view, name=names.ELECTION_VIEW), + url(r'^/result$', views.one_election_result, name=names.ELECTION_RESULT), + url(r'^/result_proof$', views.one_election_result_proof, name=names.ELECTION_RESULT_PROOF), + # url(r'^/bboard$', views.one_election_bboard, name=names.ELECTION_BBOARD), + url(r'^/audited-ballots/$', views.one_election_audited_ballots, name=names.ELECTION_AUDITED_BALLOTS), # get randomness - (r'^/get-randomness$', get_randomness), + url(r'^/get-randomness$', views.get_randomness, name=names.ELECTION_GET_RANDOMNESS), # server-side encryption - (r'^/encrypt-ballot$', encrypt_ballot), + url(r'^/encrypt-ballot$', views.encrypt_ballot, name=names.ELECTION_ENCRYPT_BALLOT), # construct election - (r'^/questions$', one_election_questions), - (r'^/set_reg$', one_election_set_reg), - (r'^/set_featured$', one_election_set_featured), - (r'^/save_questions$', one_election_save_questions), - (r'^/register$', one_election_register), - (r'^/freeze$', one_election_freeze), # includes freeze_2 as POST target + url(r'^/questions$', views.one_election_questions, name=names.ELECTION_QUESTIONS), + url(r'^/set_reg$', views.one_election_set_reg, name=names.ELECTION_SET_REG), + url(r'^/set_featured$', views.one_election_set_featured, name=names.ELECTION_SET_FEATURED), + url(r'^/save_questions$', views.one_election_save_questions, name=names.ELECTION_SAVE_QUESTIONS), + url(r'^/register$', views.one_election_register, name=names.ELECTION_REGISTER), + url(r'^/freeze$', views.one_election_freeze, name=names.ELECTION_FREEZE), # includes freeze_2 as POST target # computing tally - (r'^/compute_tally$', one_election_compute_tally), - (r'^/combine_decryptions$', combine_decryptions), - (r'^/release_result$', release_result), + url(r'^/compute_tally$', views.one_election_compute_tally, name=names.ELECTION_COMPUTE_TALLY), + url(r'^/combine_decryptions$', views.combine_decryptions, name=names.ELECTION_COMBINE_DECRYPTIONS), + url(r'^/release_result$', views.release_result, name=names.ELECTION_RELEASE_RESULT), # casting a ballot before we know who the voter is - (r'^/cast$', one_election_cast), - (r'^/cast_confirm$', one_election_cast_confirm), - (r'^/password_voter_login$', password_voter_login), - (r'^/cast_done$', one_election_cast_done), + url(r'^/cast$', views.one_election_cast, name=names.ELECTION_CAST), + url(r'^/cast_confirm$', views.one_election_cast_confirm, name=names.ELECTION_CAST_CONFIRM), + url(r'^/password_voter_login$', views.password_voter_login, name=names.ELECTION_PASSWORD_VOTER_LOGIN), + url(r'^/cast_done$', views.one_election_cast_done, name=names.ELECTION_CAST_DONE), # post audited ballot - (r'^/post-audited-ballot', post_audited_ballot), + url(r'^/post-audited-ballot', views.post_audited_ballot, name=names.ELECTION_POST_AUDITED_BALLOT), # managing voters - (r'^/voters/$', voter_list), - (r'^/voters/upload$', voters_upload), - (r'^/voters/upload-cancel$', voters_upload_cancel), - (r'^/voters/list$', voters_list_pretty), - (r'^/voters/eligibility$', voters_eligibility), - (r'^/voters/email$', voters_email), - (r'^/voters/(?P<voter_uuid>[^/]+)$', one_voter), - (r'^/voters/(?P<voter_uuid>[^/]+)/delete$', voter_delete), + url(r'^/voters/$', views.voter_list, name=names.ELECTION_VOTERS_LIST), + url(r'^/voters/upload$', views.voters_upload, name=names.ELECTION_VOTERS_UPLOAD), + url(r'^/voters/upload-cancel$', views.voters_upload_cancel, name=names.ELECTION_VOTERS_UPLOAD_CANCEL), + url(r'^/voters/list$', views.voters_list_pretty, name=names.ELECTION_VOTERS_LIST_PRETTY), + url(r'^/voters/eligibility$', views.voters_eligibility, name=names.ELECTION_VOTERS_ELIGIBILITY), + url(r'^/voters/email$', views.voters_email, name=names.ELECTION_VOTERS_EMAIL), + url(r'^/voters/(?P<voter_uuid>[^/]+)$', views.one_voter, name=names.ELECTION_VOTER), + url(r'^/voters/(?P<voter_uuid>[^/]+)/delete$', views.voter_delete, name=names.ELECTION_VOTER_DELETE), # ballots - (r'^/ballots/$', ballot_list), - (r'^/ballots/(?P<voter_uuid>[^/]+)/all$', voter_votes), - (r'^/ballots/(?P<voter_uuid>[^/]+)/last$', voter_last_vote), + url(r'^/ballots/$', views.ballot_list, name=names.ELECTION_BALLOTS_LIST), + url(r'^/ballots/(?P<voter_uuid>[^/]+)/all$', views.voter_votes, name=names.ELECTION_BALLOTS_VOTER), + url(r'^/ballots/(?P<voter_uuid>[^/]+)/last$', views.voter_last_vote, name=names.ELECTION_BALLOTS_VOTER_LAST), -) +] diff --git a/helios/fixtures/users.json b/helios/fixtures/users.json index c588ce47507d1f61348d614ee99640dcbf6bc66d..c6e18b53da75aa9efbf3db52560c1e5044a1394a 100644 --- a/helios/fixtures/users.json +++ b/helios/fixtures/users.json @@ -1 +1,40 @@ -[{"pk": 1, "model": "helios_auth.user", "fields": {"info": "{}", "user_id": "ben@adida.net", "name": "Ben Adida", "user_type": "google", "token": null, "admin_p": false}},{"pk": 2, "model": "helios_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 +[ + { + "pk": 1, + "model": "helios_auth.user", + "fields": { + "info": "{}", + "user_id": "ben@adida.net", + "name": "Ben Adida", + "user_type": "google", + "token": null, + "admin_p": false + } + }, + { + "pk": 2, + "model": "helios_auth.user", + "fields": { + "info": "{}", + "user_id": "12345", + "name": "Ben Adida", + "user_type": "facebook", + "token": { + "access_token": "1234" + }, + "admin_p": false + } + }, + { + "pk": 3, + "model": "helios_auth.user", + "fields": { + "info": "{}", + "user_id": "mccio@github.com", + "name": "Marco Ciotola", + "user_type": "google", + "token": null, + "admin_p": true + } + } +] \ No newline at end of file diff --git a/helios/forms.py b/helios/forms.py index cb10cfab8b7179b315f866de6ff1705dcb0d83f5..86fc18e5e3a0e88e4a65f32b62ef12b2bc1dea56 100644 --- a/helios/forms.py +++ b/helios/forms.py @@ -4,8 +4,8 @@ Forms for Helios from django import forms from models import Election -from widgets import * -from fields import * +from widgets import SplitSelectDateTimeWidget +from fields import SplitDateTimeField from django.conf import settings diff --git a/helios/management/commands/helios_trustee_decrypt.py b/helios/management/commands/helios_trustee_decrypt.py index 3dc75a4af8cd60562fed548483878603f7dd2875..4788330201a8d450a93be278d18506c86b32ff49 100644 --- a/helios/management/commands/helios_trustee_decrypt.py +++ b/helios/management/commands/helios_trustee_decrypt.py @@ -8,12 +8,10 @@ ben@adida.net 2010-05-22 """ -from django.core.management.base import BaseCommand, CommandError -import csv, datetime +from django.core.management.base import BaseCommand -from helios import utils as helios_utils +from helios.models import Trustee -from helios.models import * class Command(BaseCommand): args = '' diff --git a/helios/management/commands/load_voter_files.py b/helios/management/commands/load_voter_files.py index 5b82285a68650b1a06ae36c0f3bb3dd0cea236e7..c34e682aba306f9bd1380a5ed1dafa91cb247b8b 100644 --- a/helios/management/commands/load_voter_files.py +++ b/helios/management/commands/load_voter_files.py @@ -8,12 +8,15 @@ ben@adida.net 2010-05-22 """ -from django.core.management.base import BaseCommand, CommandError -import csv, datetime +import datetime + +import csv +import uuid +from django.core.management.base import BaseCommand from helios import utils as helios_utils +from helios.models import User, Voter, VoterFile -from helios.models import * ## ## UTF8 craziness for CSV @@ -27,42 +30,45 @@ def unicode_csv_reader(unicode_csv_data, dialect=csv.excel, **kwargs): # decode UTF-8 back to Unicode, cell by cell: yield [unicode(cell, 'utf-8') for cell in row] + def utf_8_encoder(unicode_csv_data): for line in unicode_csv_data: yield line.encode('utf-8') - + + def process_csv_file(election, f): reader = unicode_csv_reader(f) - + num_voters = 0 for voter in reader: - # bad line - if len(voter) < 1: - continue - - num_voters += 1 - voter_id = voter[0] - name = voter_id - email = voter_id - - if len(voter) > 1: - email = voter[1] - - if len(voter) > 2: - name = voter[2] - - # create the user - user = User.update_or_create(user_type='password', user_id=voter_id, info = {'password': helios_utils.random_string(10), 'email': email, 'name': name}) - user.save() - - # does voter for this user already exist - voter = Voter.get_by_election_and_user(election, user) - - # create the voter - if not voter: - voter_uuid = str(uuid.uuid1()) - voter = Voter(uuid= voter_uuid, voter_type = 'password', voter_id = voter_id, name = name, election = election) - voter.save() + # bad line + if len(voter) < 1: + continue + + num_voters += 1 + voter_id = voter[0] + name = voter_id + email = voter_id + + if len(voter) > 1: + email = voter[1] + + if len(voter) > 2: + name = voter[2] + + # create the user + user = User.update_or_create(user_type='password', user_id=voter_id, + info={'password': helios_utils.random_string(10), 'email': email, 'name': name}) + user.save() + + # does voter for this user already exist + voter = Voter.get_by_election_and_user(election, user) + + # create the voter + if not voter: + voter_uuid = str(uuid.uuid1()) + voter = Voter(uuid=voter_uuid, voter_type='password', voter_id=voter_id, name=name, election=election) + voter.save() return num_voters @@ -70,7 +76,7 @@ def process_csv_file(election, f): class Command(BaseCommand): args = '' help = 'load up voters from unprocessed voter files' - + def handle(self, *args, **options): # load up the voter files in order of last uploaded files_to_process = VoterFile.objects.filter(processing_started_at=None).order_by('uploaded_at') @@ -86,5 +92,3 @@ class Command(BaseCommand): file_to_process.processing_finished_at = datetime.datetime.utcnow() file_to_process.num_voters = num_voters file_to_process.save() - - diff --git a/helios/management/commands/verify_cast_votes.py b/helios/management/commands/verify_cast_votes.py index 5b7f39253615b82637937467db7fccf8b91c9e36..e2fab7186d318b4c67b500c345b93eb5d5d3dd79 100644 --- a/helios/management/commands/verify_cast_votes.py +++ b/helios/management/commands/verify_cast_votes.py @@ -6,12 +6,10 @@ ben@adida.net 2010-05-22 """ -from django.core.management.base import BaseCommand, CommandError -import csv, datetime +from django.core.management.base import BaseCommand -from helios import utils as helios_utils +from helios.models import CastVote -from helios.models import * def get_cast_vote_to_verify(): # fixme: add "select for update" functionality here diff --git a/helios/migrations/0001_initial.py b/helios/migrations/0001_initial.py index cb2a41e6779c24b6b4022ac951810fc0b1b978a5..8ba6efbb125a7b1c4e1e3ed6e74b831bedaf25f1 100644 --- a/helios/migrations/0001_initial.py +++ b/helios/migrations/0001_initial.py @@ -87,7 +87,7 @@ class Migration(migrations.Migration): ('result_proof', helios_auth.jsonfield.JSONField(null=True)), ('help_email', models.EmailField(max_length=75, null=True)), ('election_info_url', models.CharField(max_length=300, null=True)), - ('admin', models.ForeignKey(to='helios_auth.User')), + ('admin', models.ForeignKey(to='helios_auth.User', on_delete=models.CASCADE)), ], options={ 'abstract': False, @@ -100,7 +100,7 @@ class Migration(migrations.Migration): ('id', models.AutoField(verbose_name='ID', serialize=False, auto_created=True, primary_key=True)), ('log', models.CharField(max_length=500)), ('at', models.DateTimeField(auto_now_add=True)), - ('election', models.ForeignKey(to='helios.Election')), + ('election', models.ForeignKey(to='helios.Election', on_delete=models.CASCADE)), ], options={ }, @@ -120,7 +120,7 @@ class Migration(migrations.Migration): ('pok', helios.datatypes.djangofield.LDObjectField(null=True)), ('decryption_factors', helios.datatypes.djangofield.LDObjectField(null=True)), ('decryption_proofs', helios.datatypes.djangofield.LDObjectField(null=True)), - ('election', models.ForeignKey(to='helios.Election')), + ('election', models.ForeignKey(to='helios.Election', on_delete=models.CASCADE)), ], options={ }, @@ -139,8 +139,8 @@ class Migration(migrations.Migration): ('vote', helios.datatypes.djangofield.LDObjectField(null=True)), ('vote_hash', models.CharField(max_length=100, null=True)), ('cast_at', models.DateTimeField(null=True)), - ('election', models.ForeignKey(to='helios.Election')), - ('user', models.ForeignKey(to='helios_auth.User', null=True)), + ('election', models.ForeignKey(to='helios.Election', on_delete=models.CASCADE)), + ('user', models.ForeignKey(to='helios_auth.User', null=True, on_delete=models.CASCADE)), ], options={ }, @@ -156,7 +156,7 @@ class Migration(migrations.Migration): ('processing_started_at', models.DateTimeField(null=True)), ('processing_finished_at', models.DateTimeField(null=True)), ('num_voters', models.IntegerField(null=True)), - ('election', models.ForeignKey(to='helios.Election')), + ('election', models.ForeignKey(to='helios.Election', on_delete=models.CASCADE)), ], options={ }, @@ -173,13 +173,13 @@ class Migration(migrations.Migration): migrations.AddField( model_name='castvote', name='voter', - field=models.ForeignKey(to='helios.Voter'), + field=models.ForeignKey(to='helios.Voter', on_delete=models.CASCADE), preserve_default=True, ), migrations.AddField( model_name='auditedballot', name='election', - field=models.ForeignKey(to='helios.Election'), + field=models.ForeignKey(to='helios.Election', on_delete=models.CASCADE), preserve_default=True, ), ] diff --git a/helios/models.py b/helios/models.py index 96b6654184726d49157df5f8d651ad28cbe99d95..4252d1693e0c113c1007f22b69260851a9883bff 100644 --- a/helios/models.py +++ b/helios/models.py @@ -6,35 +6,33 @@ Ben Adida (ben@adida.net) """ -from django.db import models, transaction -import json -from django.conf import settings -from django.core.mail import send_mail +import datetime -import datetime, logging, uuid, random, io import bleach +import copy +import csv +import io +import random +import unicodecsv +import uuid +from django.conf import settings +from django.db import models, transaction -from crypto import electionalgs, algs, utils -from helios import utils as heliosutils -import helios.views - +from crypto import algs, utils from helios import datatypes - - +from helios import utils as heliosutils +from helios.datatypes.djangofield import LDObjectField # useful stuff in helios_auth -from helios_auth.models import User, AUTH_SYSTEMS from helios_auth.jsonfield import JSONField -from helios.datatypes.djangofield import LDObjectField +from helios_auth.models import User, AUTH_SYSTEMS -import csv, copy -import unicodecsv class HeliosModel(models.Model, datatypes.LDObjectContainer): class Meta: abstract = True class Election(HeliosModel): - admin = models.ForeignKey(User) + admin = models.ForeignKey(User, on_delete=models.CASCADE) uuid = models.CharField(max_length=50, null=False) @@ -145,6 +143,9 @@ class Election(HeliosModel): # downloadable election info election_info_url = models.CharField(max_length=300, null=True) + class Meta: + app_label = 'helios' + # metadata for the election @property def metadata(self): @@ -575,6 +576,7 @@ class Election(HeliosModel): @property def url(self): + import helios.views return helios.views.get_election_url(self) def init_tally(self): @@ -649,7 +651,8 @@ class Election(HeliosModel): prettified_result.append({'question': q['short_name'], 'answers': pretty_question}) return prettified_result - + + class ElectionLog(models.Model): """ a log of events for an election @@ -659,10 +662,13 @@ class ElectionLog(models.Model): VOTER_FILE_ADDED = "voter file added" DECRYPTIONS_COMBINED = "decryptions combined" - election = models.ForeignKey(Election) + election = models.ForeignKey(Election, on_delete=models.CASCADE) log = models.CharField(max_length=500) at = models.DateTimeField(auto_now_add=True) + class Meta: + app_label = 'helios' + ## ## UTF8 craziness for CSV ## @@ -691,7 +697,7 @@ class VoterFile(models.Model): # path where we store voter upload PATH = settings.VOTER_UPLOAD_REL_PATH - election = models.ForeignKey(Election) + election = models.ForeignKey(Election, on_delete=models.CASCADE) # we move to storing the content in the DB voter_file = models.FileField(upload_to=PATH, max_length=250,null=True) @@ -702,6 +708,9 @@ class VoterFile(models.Model): processing_finished_at = models.DateTimeField(auto_now_add=False, null=True) num_voters = models.IntegerField(null=True) + class Meta: + app_label = 'helios' + def itervoters(self): if self.voter_file_content: if type(self.voter_file_content) == unicode: @@ -779,10 +788,9 @@ class VoterFile(models.Model): return num_voters - class Voter(HeliosModel): - election = models.ForeignKey(Election) + election = models.ForeignKey(Election, on_delete=models.CASCADE) # let's link directly to the user now # FIXME: delete this as soon as migrations are set up @@ -794,7 +802,7 @@ class Voter(HeliosModel): # for users of type password, no user object is created # but a dynamic user object is created automatically - user = models.ForeignKey('helios_auth.User', null=True) + user = models.ForeignKey('helios_auth.User', null=True, on_delete=models.CASCADE) # if user is null, then you need a voter login ID and password voter_login_id = models.CharField(max_length = 100, null=True) @@ -813,6 +821,7 @@ class Voter(HeliosModel): class Meta: unique_together = (('election', 'voter_login_id')) + app_label = 'helios' def __init__(self, *args, **kwargs): super(Voter, self).__init__(*args, **kwargs) @@ -979,7 +988,7 @@ class Voter(HeliosModel): class CastVote(HeliosModel): # the reference to the voter provides the voter_uuid - voter = models.ForeignKey(Voter) + voter = models.ForeignKey(Voter, on_delete=models.CASCADE) # the actual encrypted vote vote = LDObjectField(type_hint = 'legacy/EncryptedVote') @@ -1003,6 +1012,9 @@ class CastVote(HeliosModel): # auditing purposes, like too many votes from the same IP, if it isn't expected cast_ip = models.GenericIPAddressField(null=True) + class Meta: + app_label = 'helios' + @property def datatype(self): return self.voter.datatype.replace('Voter', 'CastVote') @@ -1086,11 +1098,14 @@ class AuditedBallot(models.Model): """ ballots for auditing """ - election = models.ForeignKey(Election) + election = models.ForeignKey(Election, on_delete=models.CASCADE) raw_vote = models.TextField() vote_hash = models.CharField(max_length=100) added_at = models.DateTimeField(auto_now_add=True) + class Meta: + app_label = 'helios' + @classmethod def get(cls, election, vote_hash): return cls.objects.get(election = election, vote_hash = vote_hash) @@ -1107,9 +1122,10 @@ class AuditedBallot(models.Model): query = query[:limit] return query - + + class Trustee(HeliosModel): - election = models.ForeignKey(Election) + election = models.ForeignKey(Election, on_delete=models.CASCADE) uuid = models.CharField(max_length=50) name = models.CharField(max_length=200) @@ -1140,7 +1156,8 @@ class Trustee(HeliosModel): class Meta: unique_together = (('election', 'email')) - + app_label = 'helios' + def save(self, *args, **kwargs): """ override this just to get a hook diff --git a/helios/security.py b/helios/security.py index c0228213b3db56ff51a8e6e59c97b32ea38ce8c7..88dc6754d0bea4e046b6a3e2bb3f8e7c13bb63b5 100644 --- a/helios/security.py +++ b/helios/security.py @@ -7,12 +7,12 @@ 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.http import * +from django.urls import reverse +from django.core.exceptions import PermissionDenied +from django.http import Http404 from django.conf import settings -from models import * +from models import Voter, Trustee, Election from helios_auth.security import get_user from django.http import HttpResponseRedirect @@ -22,11 +22,23 @@ import helios class HSTSMiddleware: - def process_response(self, request, response): + def __init__(self, get_response): + self.get_response = get_response + # One-time configuration and initialization. + + def __call__(self, request): + # Code to be executed for each request before + # the view (and later middleware) are called. + + response = self.get_response(request) + + # Code to be executed for each request/response after + # the view is called. + if settings.STS: response['Strict-Transport-Security'] = "max-age=31536000; includeSubDomains; preload" return response - + # current voter def get_voter(request, user, election): """ diff --git a/helios/south_migrations/0001_initial.py b/helios/south_migrations/0001_initial.py deleted file mode 100644 index 4fa118cc427dc22993b9d8aba912c1bf778b51ac..0000000000000000000000000000000000000000 --- a/helios/south_migrations/0001_initial.py +++ /dev/null @@ -1,259 +0,0 @@ -# encoding: utf-8 -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - -class Migration(SchemaMigration): - - def forwards(self, orm): - - # Adding model 'Election' - db.create_table('helios_election', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('admin', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['helios_auth.User'])), - ('uuid', self.gf('django.db.models.fields.CharField')(max_length=50)), - ('short_name', self.gf('django.db.models.fields.CharField')(max_length=100)), - ('name', self.gf('django.db.models.fields.CharField')(max_length=250)), - ('description', self.gf('django.db.models.fields.TextField')()), - ('public_key', self.gf('helios_auth.jsonfield.JSONField')(null=True)), - ('private_key', self.gf('helios_auth.jsonfield.JSONField')(null=True)), - ('questions', self.gf('helios_auth.jsonfield.JSONField')(null=True)), - ('eligibility', self.gf('helios_auth.jsonfield.JSONField')(null=True)), - ('openreg', self.gf('django.db.models.fields.BooleanField')(default=False)), - ('featured_p', self.gf('django.db.models.fields.BooleanField')(default=False)), - ('use_voter_aliases', self.gf('django.db.models.fields.BooleanField')(default=False)), - ('cast_url', self.gf('django.db.models.fields.CharField')(max_length=500)), - ('created_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), - ('modified_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), - ('frozen_at', self.gf('django.db.models.fields.DateTimeField')(default=None, null=True)), - ('archived_at', self.gf('django.db.models.fields.DateTimeField')(default=None, null=True)), - ('registration_starts_at', self.gf('django.db.models.fields.DateTimeField')(default=None, null=True)), - ('voting_starts_at', self.gf('django.db.models.fields.DateTimeField')(default=None, null=True)), - ('voting_ends_at', self.gf('django.db.models.fields.DateTimeField')(default=None, null=True)), - ('tallying_starts_at', self.gf('django.db.models.fields.DateTimeField')(default=None, null=True)), - ('voting_started_at', self.gf('django.db.models.fields.DateTimeField')(default=None, null=True)), - ('voting_extended_until', self.gf('django.db.models.fields.DateTimeField')(default=None, null=True)), - ('voting_ended_at', self.gf('django.db.models.fields.DateTimeField')(default=None, null=True)), - ('tallying_started_at', self.gf('django.db.models.fields.DateTimeField')(default=None, null=True)), - ('tallying_finished_at', self.gf('django.db.models.fields.DateTimeField')(default=None, null=True)), - ('tallies_combined_at', self.gf('django.db.models.fields.DateTimeField')(default=None, null=True)), - ('voters_hash', self.gf('django.db.models.fields.CharField')(max_length=100, null=True)), - ('encrypted_tally', self.gf('helios_auth.jsonfield.JSONField')(null=True)), - ('result', self.gf('helios_auth.jsonfield.JSONField')(null=True)), - ('result_proof', self.gf('helios_auth.jsonfield.JSONField')(null=True)), - )) - db.send_create_signal('helios', ['Election']) - - # Adding model 'ElectionLog' - db.create_table('helios_electionlog', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('election', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['helios.Election'])), - ('log', self.gf('django.db.models.fields.CharField')(max_length=500)), - ('at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), - )) - db.send_create_signal('helios', ['ElectionLog']) - - # Adding model 'VoterFile' - db.create_table('helios_voterfile', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('election', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['helios.Election'])), - ('voter_file', self.gf('django.db.models.fields.files.FileField')(max_length=250)), - ('uploaded_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), - ('processing_started_at', self.gf('django.db.models.fields.DateTimeField')(null=True)), - ('processing_finished_at', self.gf('django.db.models.fields.DateTimeField')(null=True)), - ('num_voters', self.gf('django.db.models.fields.IntegerField')(null=True)), - )) - db.send_create_signal('helios', ['VoterFile']) - - # Adding model 'Voter' - db.create_table('helios_voter', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('election', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['helios.Election'])), - ('name', self.gf('django.db.models.fields.CharField')(max_length=200, null=True)), - ('voter_type', self.gf('django.db.models.fields.CharField')(max_length=100)), - ('voter_id', self.gf('django.db.models.fields.CharField')(max_length=100)), - ('uuid', self.gf('django.db.models.fields.CharField')(max_length=50)), - ('alias', self.gf('django.db.models.fields.CharField')(max_length=100, null=True)), - ('vote', self.gf('helios_auth.jsonfield.JSONField')(null=True)), - ('vote_hash', self.gf('django.db.models.fields.CharField')(max_length=100, null=True)), - ('cast_at', self.gf('django.db.models.fields.DateTimeField')(null=True)), - )) - db.send_create_signal('helios', ['Voter']) - - # Adding model 'CastVote' - db.create_table('helios_castvote', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('voter', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['helios.Voter'])), - ('vote', self.gf('helios_auth.jsonfield.JSONField')()), - ('vote_hash', self.gf('django.db.models.fields.CharField')(max_length=100)), - ('cast_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), - ('verified_at', self.gf('django.db.models.fields.DateTimeField')(null=True)), - ('invalidated_at', self.gf('django.db.models.fields.DateTimeField')(null=True)), - )) - db.send_create_signal('helios', ['CastVote']) - - # Adding model 'AuditedBallot' - db.create_table('helios_auditedballot', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('election', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['helios.Election'])), - ('raw_vote', self.gf('django.db.models.fields.TextField')()), - ('vote_hash', self.gf('django.db.models.fields.CharField')(max_length=100)), - ('added_at', self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, blank=True)), - )) - db.send_create_signal('helios', ['AuditedBallot']) - - # Adding model 'Trustee' - db.create_table('helios_trustee', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('election', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['helios.Election'])), - ('uuid', self.gf('django.db.models.fields.CharField')(max_length=50)), - ('name', self.gf('django.db.models.fields.CharField')(max_length=200)), - ('email', self.gf('django.db.models.fields.EmailField')(max_length=75)), - ('secret', self.gf('django.db.models.fields.CharField')(max_length=100)), - ('public_key', self.gf('helios_auth.jsonfield.JSONField')(null=True)), - ('public_key_hash', self.gf('django.db.models.fields.CharField')(max_length=100)), - ('secret_key', self.gf('helios_auth.jsonfield.JSONField')(null=True)), - ('pok', self.gf('helios_auth.jsonfield.JSONField')(null=True)), - ('decryption_factors', self.gf('helios_auth.jsonfield.JSONField')(null=True)), - ('decryption_proofs', self.gf('helios_auth.jsonfield.JSONField')(null=True)), - )) - db.send_create_signal('helios', ['Trustee']) - - - def backwards(self, orm): - - # Deleting model 'Election' - db.delete_table('helios_election') - - # Deleting model 'ElectionLog' - db.delete_table('helios_electionlog') - - # Deleting model 'VoterFile' - db.delete_table('helios_voterfile') - - # Deleting model 'Voter' - db.delete_table('helios_voter') - - # Deleting model 'CastVote' - db.delete_table('helios_castvote') - - # Deleting model 'AuditedBallot' - db.delete_table('helios_auditedballot') - - # Deleting model 'Trustee' - db.delete_table('helios_trustee') - - - models = { - 'helios_auth.user': { - 'Meta': {'unique_together': "(('user_type', 'user_id'),)", 'object_name': 'User'}, - 'admin_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'info': ('helios_auth.jsonfield.JSONField', [], {}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'token': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'user_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'user_type': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'helios.auditedballot': { - 'Meta': {'object_name': 'AuditedBallot'}, - 'added_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'raw_vote': ('django.db.models.fields.TextField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'helios.castvote': { - 'Meta': {'object_name': 'CastVote'}, - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'invalidated_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'verified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'vote': ('helios_auth.jsonfield.JSONField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'voter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Voter']"}) - }, - 'helios.election': { - 'Meta': {'object_name': 'Election'}, - 'admin': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios_auth.User']"}), - 'archived_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'cast_url': ('django.db.models.fields.CharField', [], {'max_length': '500'}), - 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'description': ('django.db.models.fields.TextField', [], {}), - 'eligibility': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'encrypted_tally': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'featured_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'frozen_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}), - 'openreg': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'private_key': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'public_key': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'questions': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'registration_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'result': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'result_proof': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'short_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'tallies_combined_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_finished_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'use_voter_aliases': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'voters_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voting_ended_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_ends_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_extended_until': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}) - }, - 'helios.electionlog': { - 'Meta': {'object_name': 'ElectionLog'}, - 'at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'log': ('django.db.models.fields.CharField', [], {'max_length': '500'}) - }, - 'helios.trustee': { - 'Meta': {'object_name': 'Trustee'}, - 'decryption_factors': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'decryption_proofs': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}), - 'pok': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'public_key': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'public_key_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret_key': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'helios.voter': { - 'Meta': {'object_name': 'Voter'}, - 'alias': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'vote': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'voter_type': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'helios.voterfile': { - 'Meta': {'object_name': 'VoterFile'}, - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'num_voters': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), - 'processing_finished_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'processing_started_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'voter_file': ('django.db.models.fields.files.FileField', [], {'max_length': '250'}) - } - } - - complete_apps = ['helios'] diff --git a/helios/south_migrations/0002_v3_1_new_election_and_voter_fields.py b/helios/south_migrations/0002_v3_1_new_election_and_voter_fields.py deleted file mode 100644 index a5d4e1d355477afbc53a5053fa0a0fd4acef0b8d..0000000000000000000000000000000000000000 --- a/helios/south_migrations/0002_v3_1_new_election_and_voter_fields.py +++ /dev/null @@ -1,196 +0,0 @@ -# encoding: utf-8 -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - -class Migration(SchemaMigration): - - def forwards(self, orm): - - # Adding field 'Voter.user' - db.add_column('helios_voter', 'user', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['helios_auth.User'], null=True), keep_default=False) - - # Adding field 'Voter.voter_login_id' - db.add_column('helios_voter', 'voter_login_id', self.gf('django.db.models.fields.CharField')(max_length=100, null=True), keep_default=False) - - # Adding field 'Voter.voter_password' - db.add_column('helios_voter', 'voter_password', self.gf('django.db.models.fields.CharField')(max_length=100, null=True), keep_default=False) - - # Adding field 'Voter.voter_name' - db.add_column('helios_voter', 'voter_name', self.gf('django.db.models.fields.CharField')(max_length=200, null=True), keep_default=False) - - # Adding field 'Voter.voter_email' - db.add_column('helios_voter', 'voter_email', self.gf('django.db.models.fields.CharField')(max_length=250, null=True), keep_default=False) - - # Adding field 'Election.datatype' - db.add_column('helios_election', 'datatype', self.gf('django.db.models.fields.CharField')(default='legacy/Election', max_length=250), keep_default=False) - - # Adding field 'Election.election_type' - db.add_column('helios_election', 'election_type', self.gf('django.db.models.fields.CharField')(default='election', max_length=250), keep_default=False) - - # Adding field 'Election.private_p' - db.add_column('helios_election', 'private_p', self.gf('django.db.models.fields.BooleanField')(default=False), keep_default=False) - - # Adding field 'Election.use_advanced_audit_features' - db.add_column('helios_election', 'use_advanced_audit_features', self.gf('django.db.models.fields.BooleanField')(default=True), keep_default=False) - - # Adding field 'CastVote.vote_tinyhash' - db.add_column('helios_castvote', 'vote_tinyhash', self.gf('django.db.models.fields.CharField')(max_length=50, unique=True, null=True), keep_default=False) - - - def backwards(self, orm): - - # Deleting field 'Voter.user' - db.delete_column('helios_voter', 'user_id') - - # Deleting field 'Voter.voter_login_id' - db.delete_column('helios_voter', 'voter_login_id') - - # Deleting field 'Voter.voter_password' - db.delete_column('helios_voter', 'voter_password') - - # Deleting field 'Voter.voter_name' - db.delete_column('helios_voter', 'voter_name') - - # Deleting field 'Voter.voter_email' - db.delete_column('helios_voter', 'voter_email') - - # Deleting field 'Election.datatype' - db.delete_column('helios_election', 'datatype') - - # Deleting field 'Election.election_type' - db.delete_column('helios_election', 'election_type') - - # Deleting field 'Election.private_p' - db.delete_column('helios_election', 'private_p') - - # Deleting field 'Election.use_advanced_audit_features' - db.delete_column('helios_election', 'use_advanced_audit_features') - - # Deleting field 'CastVote.vote_tinyhash' - db.delete_column('helios_castvote', 'vote_tinyhash') - - - models = { - 'helios_auth.user': { - 'Meta': {'unique_together': "(('user_type', 'user_id'),)", 'object_name': 'User'}, - 'admin_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'info': ('helios_auth.jsonfield.JSONField', [], {}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'token': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'user_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'user_type': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'helios.auditedballot': { - 'Meta': {'object_name': 'AuditedBallot'}, - 'added_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'raw_vote': ('django.db.models.fields.TextField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'helios.castvote': { - 'Meta': {'object_name': 'CastVote'}, - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'invalidated_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'verified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'vote': ('helios_auth.jsonfield.JSONField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'vote_tinyhash': ('django.db.models.fields.CharField', [], {'max_length': '50', 'unique': 'True', 'null': 'True'}), - 'voter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Voter']"}) - }, - 'helios.election': { - 'Meta': {'object_name': 'Election'}, - 'admin': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios_auth.User']"}), - 'archived_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'cast_url': ('django.db.models.fields.CharField', [], {'max_length': '500'}), - 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'datatype': ('django.db.models.fields.CharField', [], {'default': "'legacy/Election'", 'max_length': '250'}), - 'description': ('django.db.models.fields.TextField', [], {}), - 'election_type': ('django.db.models.fields.CharField', [], {'default': "'election'", 'max_length': '250'}), - 'eligibility': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'encrypted_tally': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'featured_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'frozen_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}), - 'openreg': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'private_key': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'private_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'public_key': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'questions': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'registration_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'result': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'result_proof': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'short_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'tallies_combined_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_finished_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'use_advanced_audit_features': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'use_voter_aliases': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'voters_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voting_ended_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_ends_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_extended_until': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}) - }, - 'helios.electionlog': { - 'Meta': {'object_name': 'ElectionLog'}, - 'at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'log': ('django.db.models.fields.CharField', [], {'max_length': '500'}) - }, - 'helios.trustee': { - 'Meta': {'object_name': 'Trustee'}, - 'decryption_factors': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'decryption_proofs': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}), - 'pok': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'public_key': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'public_key_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret_key': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'helios.voter': { - 'Meta': {'object_name': 'Voter'}, - 'alias': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios_auth.User']", 'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'vote': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_email': ('django.db.models.fields.CharField', [], {'max_length': '250', 'null': 'True'}), - 'voter_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'voter_login_id': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'voter_password': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_type': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'helios.voterfile': { - 'Meta': {'object_name': 'VoterFile'}, - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'num_voters': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), - 'processing_finished_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'processing_started_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'voter_file': ('django.db.models.fields.files.FileField', [], {'max_length': '250'}) - } - } - - complete_apps = ['helios'] diff --git a/helios/south_migrations/0003_v3_1_election_specific_voters_with_passwords.py b/helios/south_migrations/0003_v3_1_election_specific_voters_with_passwords.py deleted file mode 100644 index 573279f7c0576a403224c4b2f955140af36f00a9..0000000000000000000000000000000000000000 --- a/helios/south_migrations/0003_v3_1_election_specific_voters_with_passwords.py +++ /dev/null @@ -1,178 +0,0 @@ -# encoding: utf-8 -import datetime -from south.db import db -from south.v2 import DataMigration -from django.db import models - -class Migration(DataMigration): - - def forwards(self, orm): - """ - update the voters data objects to point to users when it makes sense, - and otherwise to copy the data needed from the users table. - make all elections legacy, because before now they are. - """ - for e in orm.Election.objects.all(): - e.datatype = 'legacy/Election' - e.save() - - # use the .iterator() call to reduce caching and make this more efficient - # so as not to trigger a memory error - for v in orm.Voter.objects.all().iterator(): - user = orm['helios_auth.User'].objects.get(user_type = v.voter_type, user_id = v.voter_id) - - if v.voter_type == 'password': - v.voter_login_id = v.voter_id - v.voter_name = v.name - - v.voter_email = user.info['email'] - v.voter_password = user.info['password'] - else: - v.user = user - - v.save() - - # also, update tinyhash for all votes - for cv in orm.CastVote.objects.all().iterator(): - safe_hash = cv.vote_hash - for c in ['/', '+']: - safe_hash = safe_hash.replace(c,'') - - length = 8 - while True: - vote_tinyhash = safe_hash[:length] - if orm.CastVote.objects.filter(vote_tinyhash = vote_tinyhash).count() == 0: - break - length += 1 - - cv.vote_tinyhash = vote_tinyhash - cv.save() - - - def backwards(self, orm): - "Write your backwards methods here." - raise Exception("can't revert to system-wide user passwords, rather than election specific") - - - models = { - 'helios_auth.user': { - 'Meta': {'unique_together': "(('user_type', 'user_id'),)", 'object_name': 'User'}, - 'admin_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'info': ('helios_auth.jsonfield.JSONField', [], {}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'token': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'user_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'user_type': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'helios.auditedballot': { - 'Meta': {'object_name': 'AuditedBallot'}, - 'added_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'raw_vote': ('django.db.models.fields.TextField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'helios.castvote': { - 'Meta': {'object_name': 'CastVote'}, - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'invalidated_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'verified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'vote': ('helios_auth.jsonfield.JSONField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'vote_tinyhash': ('django.db.models.fields.CharField', [], {'max_length': '50', 'unique': 'True', 'null': 'True'}), - 'voter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Voter']"}) - }, - 'helios.election': { - 'Meta': {'object_name': 'Election'}, - 'admin': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios_auth.User']"}), - 'archived_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'cast_url': ('django.db.models.fields.CharField', [], {'max_length': '500'}), - 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'datatype': ('django.db.models.fields.CharField', [], {'default': "'legacy/Election'", 'max_length': '250'}), - 'description': ('django.db.models.fields.TextField', [], {}), - 'election_type': ('django.db.models.fields.CharField', [], {'default': "'election'", 'max_length': '250'}), - 'eligibility': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'encrypted_tally': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'featured_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'frozen_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}), - 'openreg': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'private_key': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'private_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'public_key': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'questions': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'registration_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'result': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'result_proof': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'short_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'tallies_combined_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_finished_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'use_advanced_audit_features': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'use_voter_aliases': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'voters_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voting_ended_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_ends_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_extended_until': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}) - }, - 'helios.electionlog': { - 'Meta': {'object_name': 'ElectionLog'}, - 'at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'log': ('django.db.models.fields.CharField', [], {'max_length': '500'}) - }, - 'helios.trustee': { - 'Meta': {'object_name': 'Trustee'}, - 'decryption_factors': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'decryption_proofs': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}), - 'pok': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'public_key': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'public_key_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret_key': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'helios.voter': { - 'Meta': {'object_name': 'Voter'}, - 'alias': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios_auth.User']", 'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'vote': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_email': ('django.db.models.fields.CharField', [], {'max_length': '250', 'null': 'True'}), - 'voter_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'voter_login_id': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'voter_password': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_type': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'helios.voterfile': { - 'Meta': {'object_name': 'VoterFile'}, - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'num_voters': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), - 'processing_finished_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'processing_started_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'voter_file': ('django.db.models.fields.files.FileField', [], {'max_length': '250'}) - } - } - - complete_apps = ['helios'] diff --git a/helios/south_migrations/0004_v3_1_remove_voter_fields.py b/helios/south_migrations/0004_v3_1_remove_voter_fields.py deleted file mode 100644 index b934e945a081acbeab5da9054a16aafb793a9ee3..0000000000000000000000000000000000000000 --- a/helios/south_migrations/0004_v3_1_remove_voter_fields.py +++ /dev/null @@ -1,153 +0,0 @@ -# encoding: utf-8 -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - -class Migration(SchemaMigration): - - def forwards(self, orm): - - # Deleting field 'Voter.name' - db.delete_column('helios_voter', 'name') - - # Deleting field 'Voter.voter_id' - db.delete_column('helios_voter', 'voter_id') - - # Deleting field 'Voter.voter_type' - db.delete_column('helios_voter', 'voter_type') - - - def backwards(self, orm): - - # Adding field 'Voter.name' - db.add_column('helios_voter', 'name', self.gf('django.db.models.fields.CharField')(max_length=200, null=True), keep_default=False) - - # We cannot add back in field 'Voter.voter_id' - raise RuntimeError( - "Cannot reverse this migration. 'Voter.voter_id' and its values cannot be restored.") - - # We cannot add back in field 'Voter.voter_type' - raise RuntimeError( - "Cannot reverse this migration. 'Voter.voter_type' and its values cannot be restored.") - - - models = { - 'helios_auth.user': { - 'Meta': {'unique_together': "(('user_type', 'user_id'),)", 'object_name': 'User'}, - 'admin_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'info': ('helios_auth.jsonfield.JSONField', [], {}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'token': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'user_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'user_type': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'helios.auditedballot': { - 'Meta': {'object_name': 'AuditedBallot'}, - 'added_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'raw_vote': ('django.db.models.fields.TextField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'helios.castvote': { - 'Meta': {'object_name': 'CastVote'}, - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'invalidated_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'verified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'vote': ('helios_auth.jsonfield.JSONField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'vote_tinyhash': ('django.db.models.fields.CharField', [], {'max_length': '50', 'unique': 'True', 'null': 'True'}), - 'voter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Voter']"}) - }, - 'helios.election': { - 'Meta': {'object_name': 'Election'}, - 'admin': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios_auth.User']"}), - 'archived_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'cast_url': ('django.db.models.fields.CharField', [], {'max_length': '500'}), - 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'datatype': ('django.db.models.fields.CharField', [], {'default': "'legacy/Election'", 'max_length': '250'}), - 'description': ('django.db.models.fields.TextField', [], {}), - 'election_type': ('django.db.models.fields.CharField', [], {'default': "'election'", 'max_length': '250'}), - 'eligibility': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'encrypted_tally': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'featured_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'frozen_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}), - 'openreg': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'private_key': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'private_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'public_key': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'questions': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'registration_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'result': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'result_proof': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'short_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'tallies_combined_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_finished_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'use_advanced_audit_features': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'use_voter_aliases': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'voters_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voting_ended_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_ends_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_extended_until': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}) - }, - 'helios.electionlog': { - 'Meta': {'object_name': 'ElectionLog'}, - 'at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'log': ('django.db.models.fields.CharField', [], {'max_length': '500'}) - }, - 'helios.trustee': { - 'Meta': {'object_name': 'Trustee'}, - 'decryption_factors': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'decryption_proofs': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}), - 'pok': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'public_key': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'public_key_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret_key': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'helios.voter': { - 'Meta': {'object_name': 'Voter'}, - 'alias': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios_auth.User']", 'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'vote': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_email': ('django.db.models.fields.CharField', [], {'max_length': '250', 'null': 'True'}), - 'voter_login_id': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'voter_password': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}) - }, - 'helios.voterfile': { - 'Meta': {'object_name': 'VoterFile'}, - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'num_voters': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), - 'processing_finished_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'processing_started_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'voter_file': ('django.db.models.fields.files.FileField', [], {'max_length': '250'}) - } - } - - complete_apps = ['helios'] diff --git a/helios/south_migrations/0005_add_quarantine_fields.py b/helios/south_migrations/0005_add_quarantine_fields.py deleted file mode 100644 index b0f9f1dccd4bcaa4db810bbf5ab614eafe40fc28..0000000000000000000000000000000000000000 --- a/helios/south_migrations/0005_add_quarantine_fields.py +++ /dev/null @@ -1,154 +0,0 @@ -# encoding: utf-8 -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - -class Migration(SchemaMigration): - - def forwards(self, orm): - - # Adding field 'Election.complaint_period_ends_at' - db.add_column('helios_election', 'complaint_period_ends_at', self.gf('django.db.models.fields.DateTimeField')(default=None, null=True), keep_default=False) - - # Adding field 'CastVote.quarantined_p' - db.add_column('helios_castvote', 'quarantined_p', self.gf('django.db.models.fields.BooleanField')(default=False), keep_default=False) - - # Adding field 'CastVote.released_from_quarantine_at' - db.add_column('helios_castvote', 'released_from_quarantine_at', self.gf('django.db.models.fields.DateTimeField')(null=True), keep_default=False) - - - def backwards(self, orm): - - # Deleting field 'Election.complaint_period_ends_at' - db.delete_column('helios_election', 'complaint_period_ends_at') - - # Deleting field 'CastVote.quarantined_p' - db.delete_column('helios_castvote', 'quarantined_p') - - # Deleting field 'CastVote.released_from_quarantine_at' - db.delete_column('helios_castvote', 'released_from_quarantine_at') - - - models = { - 'helios_auth.user': { - 'Meta': {'unique_together': "(('user_type', 'user_id'),)", 'object_name': 'User'}, - 'admin_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'info': ('helios_auth.jsonfield.JSONField', [], {}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'token': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'user_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'user_type': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'helios.auditedballot': { - 'Meta': {'object_name': 'AuditedBallot'}, - 'added_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'raw_vote': ('django.db.models.fields.TextField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'helios.castvote': { - 'Meta': {'object_name': 'CastVote'}, - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'invalidated_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'quarantined_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'released_from_quarantine_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'verified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'vote': ('helios_auth.jsonfield.JSONField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'vote_tinyhash': ('django.db.models.fields.CharField', [], {'max_length': '50', 'unique': 'True', 'null': 'True'}), - 'voter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Voter']"}) - }, - 'helios.election': { - 'Meta': {'object_name': 'Election'}, - 'admin': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios_auth.User']"}), - 'archived_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'cast_url': ('django.db.models.fields.CharField', [], {'max_length': '500'}), - 'complaint_period_ends_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'datatype': ('django.db.models.fields.CharField', [], {'default': "'legacy/Election'", 'max_length': '250'}), - 'description': ('django.db.models.fields.TextField', [], {}), - 'election_type': ('django.db.models.fields.CharField', [], {'default': "'election'", 'max_length': '250'}), - 'eligibility': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'encrypted_tally': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'featured_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'frozen_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}), - 'openreg': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'private_key': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'private_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'public_key': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'questions': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'registration_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'result': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'result_proof': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'short_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'tallies_combined_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_finished_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'use_advanced_audit_features': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'use_voter_aliases': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'voters_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voting_ended_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_ends_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_extended_until': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}) - }, - 'helios.electionlog': { - 'Meta': {'object_name': 'ElectionLog'}, - 'at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'log': ('django.db.models.fields.CharField', [], {'max_length': '500'}) - }, - 'helios.trustee': { - 'Meta': {'object_name': 'Trustee'}, - 'decryption_factors': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'decryption_proofs': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}), - 'pok': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'public_key': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'public_key_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret_key': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'helios.voter': { - 'Meta': {'object_name': 'Voter'}, - 'alias': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios_auth.User']", 'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'vote': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_email': ('django.db.models.fields.CharField', [], {'max_length': '250', 'null': 'True'}), - 'voter_login_id': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'voter_password': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}) - }, - 'helios.voterfile': { - 'Meta': {'object_name': 'VoterFile'}, - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'num_voters': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), - 'processing_finished_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'processing_started_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'voter_file': ('django.db.models.fields.files.FileField', [], {'max_length': '250'}) - } - } - - complete_apps = ['helios'] diff --git a/helios/south_migrations/0006_auto__chg_field_voter_vote__add_unique_voter_voter_login_id_election__.py b/helios/south_migrations/0006_auto__chg_field_voter_vote__add_unique_voter_voter_login_id_election__.py deleted file mode 100644 index 2791e493af921dc4694966c0ce7ae973e281afbb..0000000000000000000000000000000000000000 --- a/helios/south_migrations/0006_auto__chg_field_voter_vote__add_unique_voter_voter_login_id_election__.py +++ /dev/null @@ -1,220 +0,0 @@ -# encoding: utf-8 -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - -class Migration(SchemaMigration): - - def forwards(self, orm): - - # Changing field 'Voter.vote' - db.alter_column('helios_voter', 'vote', self.gf('helios.datatypes.djangofield.LDObjectField')(null=True)) - - # Adding unique constraint on 'Voter', fields ['voter_login_id', 'election'] - db.create_unique('helios_voter', ['voter_login_id', 'election_id']) - - # Changing field 'Election.result' - db.alter_column('helios_election', 'result', self.gf('helios.datatypes.djangofield.LDObjectField')(null=True)) - - # Changing field 'Election.questions' - db.alter_column('helios_election', 'questions', self.gf('helios.datatypes.djangofield.LDObjectField')(null=True)) - - # Changing field 'Election.encrypted_tally' - db.alter_column('helios_election', 'encrypted_tally', self.gf('helios.datatypes.djangofield.LDObjectField')(null=True)) - - # Changing field 'Election.eligibility' - db.alter_column('helios_election', 'eligibility', self.gf('helios.datatypes.djangofield.LDObjectField')(null=True)) - - # Changing field 'Election.private_key' - db.alter_column('helios_election', 'private_key', self.gf('helios.datatypes.djangofield.LDObjectField')(null=True)) - - # Changing field 'Election.public_key' - db.alter_column('helios_election', 'public_key', self.gf('helios.datatypes.djangofield.LDObjectField')(null=True)) - - # Changing field 'Trustee.public_key' - db.alter_column('helios_trustee', 'public_key', self.gf('helios.datatypes.djangofield.LDObjectField')(null=True)) - - # Changing field 'Trustee.decryption_proofs' - db.alter_column('helios_trustee', 'decryption_proofs', self.gf('helios.datatypes.djangofield.LDObjectField')(null=True)) - - # Changing field 'Trustee.pok' - db.alter_column('helios_trustee', 'pok', self.gf('helios.datatypes.djangofield.LDObjectField')(null=True)) - - # Changing field 'Trustee.secret_key' - db.alter_column('helios_trustee', 'secret_key', self.gf('helios.datatypes.djangofield.LDObjectField')(null=True)) - - # Changing field 'Trustee.decryption_factors' - db.alter_column('helios_trustee', 'decryption_factors', self.gf('helios.datatypes.djangofield.LDObjectField')(null=True)) - - # Changing field 'CastVote.vote' - db.alter_column('helios_castvote', 'vote', self.gf('helios.datatypes.djangofield.LDObjectField')()) - - - def backwards(self, orm): - - # Removing unique constraint on 'Voter', fields ['voter_login_id', 'election'] - db.delete_unique('helios_voter', ['voter_login_id', 'election_id']) - - # Changing field 'Voter.vote' - db.alter_column('helios_voter', 'vote', self.gf('helios_auth.jsonfield.JSONField')(null=True)) - - # Changing field 'Election.result' - db.alter_column('helios_election', 'result', self.gf('helios_auth.jsonfield.JSONField')(null=True)) - - # Changing field 'Election.questions' - db.alter_column('helios_election', 'questions', self.gf('helios_auth.jsonfield.JSONField')(null=True)) - - # Changing field 'Election.encrypted_tally' - db.alter_column('helios_election', 'encrypted_tally', self.gf('helios_auth.jsonfield.JSONField')(null=True)) - - # Changing field 'Election.eligibility' - db.alter_column('helios_election', 'eligibility', self.gf('helios_auth.jsonfield.JSONField')(null=True)) - - # Changing field 'Election.private_key' - db.alter_column('helios_election', 'private_key', self.gf('helios_auth.jsonfield.JSONField')(null=True)) - - # Changing field 'Election.public_key' - db.alter_column('helios_election', 'public_key', self.gf('helios_auth.jsonfield.JSONField')(null=True)) - - # Changing field 'Trustee.public_key' - db.alter_column('helios_trustee', 'public_key', self.gf('helios_auth.jsonfield.JSONField')(null=True)) - - # Changing field 'Trustee.decryption_proofs' - db.alter_column('helios_trustee', 'decryption_proofs', self.gf('helios_auth.jsonfield.JSONField')(null=True)) - - # Changing field 'Trustee.pok' - db.alter_column('helios_trustee', 'pok', self.gf('helios_auth.jsonfield.JSONField')(null=True)) - - # Changing field 'Trustee.secret_key' - db.alter_column('helios_trustee', 'secret_key', self.gf('helios_auth.jsonfield.JSONField')(null=True)) - - # Changing field 'Trustee.decryption_factors' - db.alter_column('helios_trustee', 'decryption_factors', self.gf('helios_auth.jsonfield.JSONField')(null=True)) - - # Changing field 'CastVote.vote' - db.alter_column('helios_castvote', 'vote', self.gf('helios_auth.jsonfield.JSONField')()) - - - models = { - 'helios_auth.user': { - 'Meta': {'unique_together': "(('user_type', 'user_id'),)", 'object_name': 'User'}, - 'admin_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'info': ('helios_auth.jsonfield.JSONField', [], {}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'token': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'user_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'user_type': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'helios.auditedballot': { - 'Meta': {'object_name': 'AuditedBallot'}, - 'added_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'raw_vote': ('django.db.models.fields.TextField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'helios.castvote': { - 'Meta': {'object_name': 'CastVote'}, - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'invalidated_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'quarantined_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'released_from_quarantine_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'verified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'vote': ('helios.datatypes.djangofield.LDObjectField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'vote_tinyhash': ('django.db.models.fields.CharField', [], {'max_length': '50', 'unique': 'True', 'null': 'True'}), - 'voter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Voter']"}) - }, - 'helios.election': { - 'Meta': {'object_name': 'Election'}, - 'admin': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios_auth.User']"}), - 'archived_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'cast_url': ('django.db.models.fields.CharField', [], {'max_length': '500'}), - 'complaint_period_ends_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'datatype': ('django.db.models.fields.CharField', [], {'default': "'legacy/Election'", 'max_length': '250'}), - 'description': ('django.db.models.fields.TextField', [], {}), - 'election_type': ('django.db.models.fields.CharField', [], {'default': "'election'", 'max_length': '250'}), - 'eligibility': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'encrypted_tally': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'featured_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'frozen_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}), - 'openreg': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'private_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'private_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'public_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'questions': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'registration_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'result': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'result_proof': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'short_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'tallies_combined_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_finished_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'use_advanced_audit_features': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'use_voter_aliases': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'voters_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voting_ended_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_ends_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_extended_until': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}) - }, - 'helios.electionlog': { - 'Meta': {'object_name': 'ElectionLog'}, - 'at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'log': ('django.db.models.fields.CharField', [], {'max_length': '500'}) - }, - 'helios.trustee': { - 'Meta': {'object_name': 'Trustee'}, - 'decryption_factors': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'decryption_proofs': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}), - 'pok': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'public_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'public_key_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'helios.voter': { - 'Meta': {'unique_together': "(('election', 'voter_login_id'),)", 'object_name': 'Voter'}, - 'alias': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios_auth.User']", 'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'vote': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_email': ('django.db.models.fields.CharField', [], {'max_length': '250', 'null': 'True'}), - 'voter_login_id': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'voter_password': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}) - }, - 'helios.voterfile': { - 'Meta': {'object_name': 'VoterFile'}, - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'num_voters': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), - 'processing_finished_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'processing_started_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'voter_file': ('django.db.models.fields.files.FileField', [], {'max_length': '250'}) - } - } - - complete_apps = ['helios'] diff --git a/helios/south_migrations/0007_auto__add_field_voterfile_voter_file_content__chg_field_voterfile_vote.py b/helios/south_migrations/0007_auto__add_field_voterfile_voter_file_content__chg_field_voterfile_vote.py deleted file mode 100644 index 04a7f00b078c6d5954c11596a734feaf7afadad1..0000000000000000000000000000000000000000 --- a/helios/south_migrations/0007_auto__add_field_voterfile_voter_file_content__chg_field_voterfile_vote.py +++ /dev/null @@ -1,149 +0,0 @@ -# encoding: utf-8 -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - -class Migration(SchemaMigration): - - def forwards(self, orm): - - # Adding field 'VoterFile.voter_file_content' - db.add_column('helios_voterfile', 'voter_file_content', self.gf('django.db.models.fields.TextField')(null=True), keep_default=False) - - # Changing field 'VoterFile.voter_file' - db.alter_column('helios_voterfile', 'voter_file', self.gf('django.db.models.fields.files.FileField')(max_length=250, null=True)) - - - def backwards(self, orm): - - # Deleting field 'VoterFile.voter_file_content' - db.delete_column('helios_voterfile', 'voter_file_content') - - # User chose to not deal with backwards NULL issues for 'VoterFile.voter_file' - raise RuntimeError("Cannot reverse this migration. 'VoterFile.voter_file' and its values cannot be restored.") - - - models = { - 'helios_auth.user': { - 'Meta': {'unique_together': "(('user_type', 'user_id'),)", 'object_name': 'User'}, - 'admin_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'info': ('helios_auth.jsonfield.JSONField', [], {}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'token': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'user_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'user_type': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'helios.auditedballot': { - 'Meta': {'object_name': 'AuditedBallot'}, - 'added_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'raw_vote': ('django.db.models.fields.TextField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'helios.castvote': { - 'Meta': {'object_name': 'CastVote'}, - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'invalidated_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'quarantined_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'released_from_quarantine_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'verified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'vote': ('helios.datatypes.djangofield.LDObjectField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'vote_tinyhash': ('django.db.models.fields.CharField', [], {'max_length': '50', 'unique': 'True', 'null': 'True'}), - 'voter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Voter']"}) - }, - 'helios.election': { - 'Meta': {'object_name': 'Election'}, - 'admin': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios_auth.User']"}), - 'archived_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'cast_url': ('django.db.models.fields.CharField', [], {'max_length': '500'}), - 'complaint_period_ends_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'datatype': ('django.db.models.fields.CharField', [], {'default': "'legacy/Election'", 'max_length': '250'}), - 'description': ('django.db.models.fields.TextField', [], {}), - 'election_type': ('django.db.models.fields.CharField', [], {'default': "'election'", 'max_length': '250'}), - 'eligibility': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'encrypted_tally': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'featured_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'frozen_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}), - 'openreg': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'private_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'private_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'public_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'questions': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'registration_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'result': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'result_proof': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'short_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'tallies_combined_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_finished_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'use_advanced_audit_features': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'use_voter_aliases': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'voters_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voting_ended_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_ends_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_extended_until': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}) - }, - 'helios.electionlog': { - 'Meta': {'object_name': 'ElectionLog'}, - 'at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'log': ('django.db.models.fields.CharField', [], {'max_length': '500'}) - }, - 'helios.trustee': { - 'Meta': {'object_name': 'Trustee'}, - 'decryption_factors': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'decryption_proofs': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}), - 'pok': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'public_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'public_key_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'helios.voter': { - 'Meta': {'unique_together': "(('election', 'voter_login_id'),)", 'object_name': 'Voter'}, - 'alias': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios_auth.User']", 'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'vote': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_email': ('django.db.models.fields.CharField', [], {'max_length': '250', 'null': 'True'}), - 'voter_login_id': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'voter_password': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}) - }, - 'helios.voterfile': { - 'Meta': {'object_name': 'VoterFile'}, - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'num_voters': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), - 'processing_finished_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'processing_started_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'voter_file': ('django.db.models.fields.files.FileField', [], {'max_length': '250', 'null': 'True'}), - 'voter_file_content': ('django.db.models.fields.TextField', [], {'null': 'True'}) - } - } - - complete_apps = ['helios'] diff --git a/helios/south_migrations/0008_auto__add_unique_trustee_election_email.py b/helios/south_migrations/0008_auto__add_unique_trustee_election_email.py deleted file mode 100644 index 974dfd2db1c3e58fe78188645a8a54673d5febfb..0000000000000000000000000000000000000000 --- a/helios/south_migrations/0008_auto__add_unique_trustee_election_email.py +++ /dev/null @@ -1,143 +0,0 @@ -# encoding: utf-8 -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - -class Migration(SchemaMigration): - - def forwards(self, orm): - - # Adding unique constraint on 'Trustee', fields ['election', 'email'] - db.create_unique('helios_trustee', ['election_id', 'email']) - - - def backwards(self, orm): - - # Removing unique constraint on 'Trustee', fields ['election', 'email'] - db.delete_unique('helios_trustee', ['election_id', 'email']) - - - models = { - 'helios.auditedballot': { - 'Meta': {'object_name': 'AuditedBallot'}, - 'added_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'raw_vote': ('django.db.models.fields.TextField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'helios.castvote': { - 'Meta': {'object_name': 'CastVote'}, - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'invalidated_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'quarantined_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'released_from_quarantine_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'verified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'vote': ('helios.datatypes.djangofield.LDObjectField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'vote_tinyhash': ('django.db.models.fields.CharField', [], {'max_length': '50', 'unique': 'True', 'null': 'True'}), - 'voter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Voter']"}) - }, - 'helios.election': { - 'Meta': {'object_name': 'Election'}, - 'admin': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios_auth.User']"}), - 'archived_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'cast_url': ('django.db.models.fields.CharField', [], {'max_length': '500'}), - 'complaint_period_ends_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'datatype': ('django.db.models.fields.CharField', [], {'default': "'legacy/Election'", 'max_length': '250'}), - 'description': ('django.db.models.fields.TextField', [], {}), - 'election_type': ('django.db.models.fields.CharField', [], {'default': "'election'", 'max_length': '250'}), - 'eligibility': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'encrypted_tally': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'featured_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'frozen_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}), - 'openreg': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'private_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'private_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'public_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'questions': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'registration_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'result': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'result_proof': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'short_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'tallies_combined_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_finished_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'use_advanced_audit_features': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'use_voter_aliases': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'voters_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voting_ended_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_ends_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_extended_until': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}) - }, - 'helios.electionlog': { - 'Meta': {'object_name': 'ElectionLog'}, - 'at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'log': ('django.db.models.fields.CharField', [], {'max_length': '500'}) - }, - 'helios.trustee': { - 'Meta': {'unique_together': "(('election', 'email'),)", 'object_name': 'Trustee'}, - 'decryption_factors': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'decryption_proofs': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}), - 'pok': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'public_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'public_key_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'helios.voter': { - 'Meta': {'unique_together': "(('election', 'voter_login_id'),)", 'object_name': 'Voter'}, - 'alias': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios_auth.User']", 'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'vote': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_email': ('django.db.models.fields.CharField', [], {'max_length': '250', 'null': 'True'}), - 'voter_login_id': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'voter_password': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}) - }, - 'helios.voterfile': { - 'Meta': {'object_name': 'VoterFile'}, - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'num_voters': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), - 'processing_finished_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'processing_started_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'voter_file': ('django.db.models.fields.files.FileField', [], {'max_length': '250', 'null': 'True'}), - 'voter_file_content': ('django.db.models.fields.TextField', [], {'null': 'True'}) - }, - 'helios_auth.user': { - 'Meta': {'unique_together': "(('user_type', 'user_id'),)", 'object_name': 'User'}, - 'admin_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'info': ('helios_auth.jsonfield.JSONField', [], {}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'token': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'user_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'user_type': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - } - } - - complete_apps = ['helios'] diff --git a/helios/south_migrations/0009_auto__add_field_election_help_email.py b/helios/south_migrations/0009_auto__add_field_election_help_email.py deleted file mode 100644 index 1500f0e43d7fadd46bc702e1d9ac77aaa9dca60a..0000000000000000000000000000000000000000 --- a/helios/south_migrations/0009_auto__add_field_election_help_email.py +++ /dev/null @@ -1,144 +0,0 @@ -# encoding: utf-8 -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - -class Migration(SchemaMigration): - - def forwards(self, orm): - - # Adding field 'Election.help_email' - db.add_column('helios_election', 'help_email', self.gf('django.db.models.fields.EmailField')(max_length=75, null=True), keep_default=False) - - - def backwards(self, orm): - - # Deleting field 'Election.help_email' - db.delete_column('helios_election', 'help_email') - - - models = { - 'helios.auditedballot': { - 'Meta': {'object_name': 'AuditedBallot'}, - 'added_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'raw_vote': ('django.db.models.fields.TextField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'helios.castvote': { - 'Meta': {'object_name': 'CastVote'}, - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'invalidated_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'quarantined_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'released_from_quarantine_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'verified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'vote': ('helios.datatypes.djangofield.LDObjectField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'vote_tinyhash': ('django.db.models.fields.CharField', [], {'max_length': '50', 'unique': 'True', 'null': 'True'}), - 'voter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Voter']"}) - }, - 'helios.election': { - 'Meta': {'object_name': 'Election'}, - 'admin': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios_auth.User']"}), - 'archived_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'cast_url': ('django.db.models.fields.CharField', [], {'max_length': '500'}), - 'complaint_period_ends_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'datatype': ('django.db.models.fields.CharField', [], {'default': "'legacy/Election'", 'max_length': '250'}), - 'description': ('django.db.models.fields.TextField', [], {}), - 'election_type': ('django.db.models.fields.CharField', [], {'default': "'election'", 'max_length': '250'}), - 'eligibility': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'encrypted_tally': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'featured_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'frozen_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'help_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}), - 'openreg': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'private_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'private_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'public_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'questions': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'registration_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'result': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'result_proof': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'short_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'tallies_combined_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_finished_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'use_advanced_audit_features': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'use_voter_aliases': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'voters_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voting_ended_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_ends_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_extended_until': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}) - }, - 'helios.electionlog': { - 'Meta': {'object_name': 'ElectionLog'}, - 'at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'log': ('django.db.models.fields.CharField', [], {'max_length': '500'}) - }, - 'helios.trustee': { - 'Meta': {'unique_together': "(('election', 'email'),)", 'object_name': 'Trustee'}, - 'decryption_factors': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'decryption_proofs': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}), - 'pok': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'public_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'public_key_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'helios.voter': { - 'Meta': {'unique_together': "(('election', 'voter_login_id'),)", 'object_name': 'Voter'}, - 'alias': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios_auth.User']", 'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'vote': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_email': ('django.db.models.fields.CharField', [], {'max_length': '250', 'null': 'True'}), - 'voter_login_id': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'voter_password': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}) - }, - 'helios.voterfile': { - 'Meta': {'object_name': 'VoterFile'}, - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'num_voters': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), - 'processing_finished_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'processing_started_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'voter_file': ('django.db.models.fields.files.FileField', [], {'max_length': '250', 'null': 'True'}), - 'voter_file_content': ('django.db.models.fields.TextField', [], {'null': 'True'}) - }, - 'helios_auth.user': { - 'Meta': {'unique_together': "(('user_type', 'user_id'),)", 'object_name': 'User'}, - 'admin_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'info': ('helios_auth.jsonfield.JSONField', [], {}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'token': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'user_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'user_type': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - } - } - - complete_apps = ['helios'] diff --git a/helios/south_migrations/0010_auto__add_field_election_randomize_answer_order.py b/helios/south_migrations/0010_auto__add_field_election_randomize_answer_order.py deleted file mode 100644 index 96d1eb0662c93b3c1b2c77d1a34feefee5c4d526..0000000000000000000000000000000000000000 --- a/helios/south_migrations/0010_auto__add_field_election_randomize_answer_order.py +++ /dev/null @@ -1,146 +0,0 @@ -# -*- coding: utf-8 -*- -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - - -class Migration(SchemaMigration): - - def forwards(self, orm): - # Adding field 'Election.randomize_answer_order' - db.add_column('helios_election', 'randomize_answer_order', - self.gf('django.db.models.fields.BooleanField')(default=False), - keep_default=False) - - - def backwards(self, orm): - # Deleting field 'Election.randomize_answer_order' - db.delete_column('helios_election', 'randomize_answer_order') - - - models = { - 'helios.auditedballot': { - 'Meta': {'object_name': 'AuditedBallot'}, - 'added_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'raw_vote': ('django.db.models.fields.TextField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'helios.castvote': { - 'Meta': {'object_name': 'CastVote'}, - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'invalidated_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'quarantined_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'released_from_quarantine_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'verified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'vote': ('helios.datatypes.djangofield.LDObjectField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'vote_tinyhash': ('django.db.models.fields.CharField', [], {'max_length': '50', 'unique': 'True', 'null': 'True'}), - 'voter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Voter']"}) - }, - 'helios.election': { - 'Meta': {'object_name': 'Election'}, - 'admin': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios_auth.User']"}), - 'archived_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'cast_url': ('django.db.models.fields.CharField', [], {'max_length': '500'}), - 'complaint_period_ends_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'datatype': ('django.db.models.fields.CharField', [], {'default': "'legacy/Election'", 'max_length': '250'}), - 'description': ('django.db.models.fields.TextField', [], {}), - 'election_type': ('django.db.models.fields.CharField', [], {'default': "'election'", 'max_length': '250'}), - 'eligibility': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'encrypted_tally': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'featured_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'frozen_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'help_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}), - 'openreg': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'private_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'private_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'public_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'questions': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'randomize_answer_order': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'registration_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'result': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'result_proof': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'short_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'tallies_combined_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_finished_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'use_advanced_audit_features': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'use_voter_aliases': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'voters_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voting_ended_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_ends_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_extended_until': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}) - }, - 'helios.electionlog': { - 'Meta': {'object_name': 'ElectionLog'}, - 'at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'log': ('django.db.models.fields.CharField', [], {'max_length': '500'}) - }, - 'helios.trustee': { - 'Meta': {'unique_together': "(('election', 'email'),)", 'object_name': 'Trustee'}, - 'decryption_factors': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'decryption_proofs': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}), - 'pok': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'public_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'public_key_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'helios.voter': { - 'Meta': {'unique_together': "(('election', 'voter_login_id'),)", 'object_name': 'Voter'}, - 'alias': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios_auth.User']", 'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'vote': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_email': ('django.db.models.fields.CharField', [], {'max_length': '250', 'null': 'True'}), - 'voter_login_id': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'voter_password': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}) - }, - 'helios.voterfile': { - 'Meta': {'object_name': 'VoterFile'}, - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'num_voters': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), - 'processing_finished_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'processing_started_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'voter_file': ('django.db.models.fields.files.FileField', [], {'max_length': '250', 'null': 'True'}), - 'voter_file_content': ('django.db.models.fields.TextField', [], {'null': 'True'}) - }, - 'helios_auth.user': { - 'Meta': {'unique_together': "(('user_type', 'user_id'),)", 'object_name': 'User'}, - 'admin_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'info': ('helios_auth.jsonfield.JSONField', [], {}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'token': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'user_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'user_type': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - } - } - - complete_apps = ['helios'] \ No newline at end of file diff --git a/helios/south_migrations/0011_auto__add_field_election_election_info_url.py b/helios/south_migrations/0011_auto__add_field_election_election_info_url.py deleted file mode 100644 index 48c98fb14b0e962f86ca66326dee9687c4c7bdf9..0000000000000000000000000000000000000000 --- a/helios/south_migrations/0011_auto__add_field_election_election_info_url.py +++ /dev/null @@ -1,147 +0,0 @@ -# -*- coding: utf-8 -*- -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - - -class Migration(SchemaMigration): - - def forwards(self, orm): - # Adding field 'Election.election_info_url' - db.add_column('helios_election', 'election_info_url', - self.gf('django.db.models.fields.CharField')(max_length=300, null=True), - keep_default=False) - - - def backwards(self, orm): - # Deleting field 'Election.election_info_url' - db.delete_column('helios_election', 'election_info_url') - - - models = { - 'helios.auditedballot': { - 'Meta': {'object_name': 'AuditedBallot'}, - 'added_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'raw_vote': ('django.db.models.fields.TextField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'helios.castvote': { - 'Meta': {'object_name': 'CastVote'}, - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'invalidated_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'quarantined_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'released_from_quarantine_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'verified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'vote': ('helios.datatypes.djangofield.LDObjectField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'vote_tinyhash': ('django.db.models.fields.CharField', [], {'max_length': '50', 'unique': 'True', 'null': 'True'}), - 'voter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Voter']"}) - }, - 'helios.election': { - 'Meta': {'object_name': 'Election'}, - 'admin': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios_auth.User']"}), - 'archived_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'cast_url': ('django.db.models.fields.CharField', [], {'max_length': '500'}), - 'complaint_period_ends_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'datatype': ('django.db.models.fields.CharField', [], {'default': "'legacy/Election'", 'max_length': '250'}), - 'description': ('django.db.models.fields.TextField', [], {}), - 'election_info_url': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True'}), - 'election_type': ('django.db.models.fields.CharField', [], {'default': "'election'", 'max_length': '250'}), - 'eligibility': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'encrypted_tally': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'featured_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'frozen_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'help_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}), - 'openreg': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'private_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'private_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'public_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'questions': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'randomize_answer_order': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'registration_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'result': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'result_proof': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'short_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'tallies_combined_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_finished_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'use_advanced_audit_features': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'use_voter_aliases': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'voters_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voting_ended_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_ends_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_extended_until': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}) - }, - 'helios.electionlog': { - 'Meta': {'object_name': 'ElectionLog'}, - 'at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'log': ('django.db.models.fields.CharField', [], {'max_length': '500'}) - }, - 'helios.trustee': { - 'Meta': {'unique_together': "(('election', 'email'),)", 'object_name': 'Trustee'}, - 'decryption_factors': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'decryption_proofs': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}), - 'pok': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'public_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'public_key_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'helios.voter': { - 'Meta': {'unique_together': "(('election', 'voter_login_id'),)", 'object_name': 'Voter'}, - 'alias': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios_auth.User']", 'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'vote': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_email': ('django.db.models.fields.CharField', [], {'max_length': '250', 'null': 'True'}), - 'voter_login_id': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'voter_password': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}) - }, - 'helios.voterfile': { - 'Meta': {'object_name': 'VoterFile'}, - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'num_voters': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), - 'processing_finished_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'processing_started_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'voter_file': ('django.db.models.fields.files.FileField', [], {'max_length': '250', 'null': 'True'}), - 'voter_file_content': ('django.db.models.fields.TextField', [], {'null': 'True'}) - }, - 'helios_auth.user': { - 'Meta': {'unique_together': "(('user_type', 'user_id'),)", 'object_name': 'User'}, - 'admin_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'info': ('helios_auth.jsonfield.JSONField', [], {}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'token': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'user_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'user_type': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - } - } - - complete_apps = ['helios'] \ No newline at end of file diff --git a/helios/south_migrations/0012_auto__add_field_election_result_released_at.py b/helios/south_migrations/0012_auto__add_field_election_result_released_at.py deleted file mode 100644 index 0cc6853ee5188ff223a6c321abd332cf57c84765..0000000000000000000000000000000000000000 --- a/helios/south_migrations/0012_auto__add_field_election_result_released_at.py +++ /dev/null @@ -1,148 +0,0 @@ -# -*- coding: utf-8 -*- -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - - -class Migration(SchemaMigration): - - def forwards(self, orm): - # Adding field 'Election.result_released_at' - db.add_column('helios_election', 'result_released_at', - self.gf('django.db.models.fields.DateTimeField')(default=None, null=True), - keep_default=False) - - - def backwards(self, orm): - # Deleting field 'Election.result_released_at' - db.delete_column('helios_election', 'result_released_at') - - - models = { - 'helios.auditedballot': { - 'Meta': {'object_name': 'AuditedBallot'}, - 'added_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'raw_vote': ('django.db.models.fields.TextField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}) - }, - 'helios.castvote': { - 'Meta': {'object_name': 'CastVote'}, - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'invalidated_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'quarantined_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'released_from_quarantine_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'verified_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'vote': ('helios.datatypes.djangofield.LDObjectField', [], {}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'vote_tinyhash': ('django.db.models.fields.CharField', [], {'max_length': '50', 'unique': 'True', 'null': 'True'}), - 'voter': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Voter']"}) - }, - 'helios.election': { - 'Meta': {'object_name': 'Election'}, - 'admin': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios_auth.User']"}), - 'archived_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'cast_url': ('django.db.models.fields.CharField', [], {'max_length': '500'}), - 'complaint_period_ends_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'created_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'datatype': ('django.db.models.fields.CharField', [], {'default': "'legacy/Election'", 'max_length': '250'}), - 'description': ('django.db.models.fields.TextField', [], {}), - 'election_info_url': ('django.db.models.fields.CharField', [], {'max_length': '300', 'null': 'True'}), - 'election_type': ('django.db.models.fields.CharField', [], {'default': "'election'", 'max_length': '250'}), - 'eligibility': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'encrypted_tally': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'featured_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'frozen_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'help_email': ('django.db.models.fields.EmailField', [], {'max_length': '75', 'null': 'True'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'modified_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '250'}), - 'openreg': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'private_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'private_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'public_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'questions': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'randomize_answer_order': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'registration_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'result': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'result_proof': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'result_released_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'short_name': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'tallies_combined_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_finished_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'tallying_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'use_advanced_audit_features': ('django.db.models.fields.BooleanField', [], {'default': 'True'}), - 'use_voter_aliases': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'voters_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voting_ended_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_ends_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_extended_until': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_started_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}), - 'voting_starts_at': ('django.db.models.fields.DateTimeField', [], {'default': 'None', 'null': 'True'}) - }, - 'helios.electionlog': { - 'Meta': {'object_name': 'ElectionLog'}, - 'at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'log': ('django.db.models.fields.CharField', [], {'max_length': '500'}) - }, - 'helios.trustee': { - 'Meta': {'unique_together': "(('election', 'email'),)", 'object_name': 'Trustee'}, - 'decryption_factors': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'decryption_proofs': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200'}), - 'pok': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'public_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'public_key_hash': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'secret_key': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - }, - 'helios.voter': { - 'Meta': {'unique_together': "(('election', 'voter_login_id'),)", 'object_name': 'Voter'}, - 'alias': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'cast_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'user': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios_auth.User']", 'null': 'True'}), - 'uuid': ('django.db.models.fields.CharField', [], {'max_length': '50'}), - 'vote': ('helios.datatypes.djangofield.LDObjectField', [], {'null': 'True'}), - 'vote_hash': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_email': ('django.db.models.fields.CharField', [], {'max_length': '250', 'null': 'True'}), - 'voter_login_id': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}), - 'voter_name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'voter_password': ('django.db.models.fields.CharField', [], {'max_length': '100', 'null': 'True'}) - }, - 'helios.voterfile': { - 'Meta': {'object_name': 'VoterFile'}, - 'election': ('django.db.models.fields.related.ForeignKey', [], {'to': "orm['helios.Election']"}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'num_voters': ('django.db.models.fields.IntegerField', [], {'null': 'True'}), - 'processing_finished_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'processing_started_at': ('django.db.models.fields.DateTimeField', [], {'null': 'True'}), - 'uploaded_at': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}), - 'voter_file': ('django.db.models.fields.files.FileField', [], {'max_length': '250', 'null': 'True'}), - 'voter_file_content': ('django.db.models.fields.TextField', [], {'null': 'True'}) - }, - 'helios_auth.user': { - 'Meta': {'unique_together': "(('user_type', 'user_id'),)", 'object_name': 'User'}, - 'admin_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'info': ('helios_auth.jsonfield.JSONField', [], {}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'token': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'user_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'user_type': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - } - } - - complete_apps = ['helios'] \ No newline at end of file diff --git a/helios/south_migrations/__init__.py b/helios/south_migrations/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/helios/stats_url_names.py b/helios/stats_url_names.py new file mode 100644 index 0000000000000000000000000000000000000000..2b8ffe2cde27da4c9d8f21341a3c826ee9c4512f --- /dev/null +++ b/helios/stats_url_names.py @@ -0,0 +1,5 @@ +STATS_HOME="stats@home" +STATS_FORCE_QUEUE="stats@force-queue" +STATS_ELECTIONS="stats@elections" +STATS_ELECTIONS_PROBLEMS="stats@elections-problems" +STATS_RECENT_VOTES="stats@recent-votes" diff --git a/helios/stats_urls.py b/helios/stats_urls.py index 2d26d1961aabae3a75bef2e16117d9dd3eea7566..ac3b1439f9dae0acd8702b414772c691dbdc2c4f 100644 --- a/helios/stats_urls.py +++ b/helios/stats_urls.py @@ -4,15 +4,15 @@ Helios URLs for Election related stuff Ben Adida (ben@adida.net) """ -from django.conf.urls import * +from django.conf.urls import url -from helios.stats_views import * +from helios.stats_views import (home, force_queue, elections, recent_problem_elections, recent_votes) +import helios.stats_url_names as names -urlpatterns = patterns( - '', - (r'^$', home), - (r'^force-queue$', force_queue), - (r'^elections$', elections), - (r'^problem-elections$', recent_problem_elections), - (r'^recent-votes$', recent_votes), -) +urlpatterns = [ + url(r'^$', home, name=names.STATS_HOME), + url(r'^force-queue$', force_queue, name=names.STATS_FORCE_QUEUE), + url(r'^elections$', elections, name=names.STATS_ELECTIONS), + url(r'^problem-elections$', recent_problem_elections, name=names.STATS_ELECTIONS_PROBLEMS), + url(r'^recent-votes$', recent_votes, name=names.STATS_RECENT_VOTES), +] diff --git a/helios/stats_views.py b/helios/stats_views.py index 7d2a62ec6f4f7be47c01127dba95ba1013c167e3..5e71a32e8dca7cf20a191aeffe9cc8dc5bda3492 100644 --- a/helios/stats_views.py +++ b/helios/stats_views.py @@ -2,18 +2,19 @@ Helios stats views """ -from django.core.urlresolvers import reverse -from django.core.mail import send_mail +import datetime + from django.core.paginator import Paginator -from django.http import * -from django.db import transaction -from django.db.models import * +from django.urls import reverse +from django.db.models import Max, Count +from django.http import HttpResponseRedirect -from security import * -from helios_auth.security import get_user, save_in_session_across_logouts -from view_utils import * +from helios import tasks, url_names +from helios.models import CastVote, Election +from helios_auth.security import get_user +from security import PermissionDenied +from view_utils import render_template -from helios import tasks def require_admin(request): user = get_user(request) @@ -33,7 +34,7 @@ def force_queue(request): for cv in votes_in_queue: tasks.cast_vote_verify_and_store.delay(cv.id) - return HttpResponseRedirect(reverse(home)) + return HttpResponseRedirect(reverse(url_names.stats.STATS_HOME)) def elections(request): user = require_admin(request) @@ -42,8 +43,7 @@ def elections(request): limit = int(request.GET.get('limit', 25)) q = request.GET.get('q','') - elections = Election.objects.filter(name__icontains = q) - elections.all().order_by('-created_at') + elections = Election.objects.filter(name__icontains = q).order_by('-created_at') elections_paginator = Paginator(elections, limit) elections_page = elections_paginator.page(page) diff --git a/helios/tasks.py b/helios/tasks.py index 5f7bba8730120e732a48f7467314e05dcfd7b639..8610097182707b2aa40abc68e79c148fa664b19d 100644 --- a/helios/tasks.py +++ b/helios/tasks.py @@ -4,20 +4,18 @@ Celery queued tasks for Helios 2010-08-01 ben@adida.net """ +import copy +from celery import shared_task +from celery.utils.log import get_logger -from celery.decorators import task - -from models import * -from view_utils import render_template_raw import signals +from models import CastVote, Election, Voter, VoterFile +from view_utils import render_template_raw -import copy - -from django.conf import settings -@task() +@shared_task def cast_vote_verify_and_store(cast_vote_id, status_update_message=None, **kwargs): - cast_vote = CastVote.objects.get(id = cast_vote_id) + cast_vote = CastVote.objects.get(id=cast_vote_id) result = cast_vote.verify_and_store() voter = cast_vote.voter @@ -27,23 +25,22 @@ def cast_vote_verify_and_store(cast_vote_id, status_update_message=None, **kwarg if result: # send the signal signals.vote_cast.send(sender=election, election=election, user=user, voter=voter, cast_vote=cast_vote) - - if status_update_message and user.can_update_status(): - from views import get_election_url + if status_update_message and user.can_update_status(): user.update_status(status_update_message) else: - logger = cast_vote_verify_and_store.get_logger(**kwargs) + logger = get_logger(cast_vote_verify_and_store.__name__) logger.error("Failed to verify and store %d" % cast_vote_id) - -@task() + + +@shared_task def voters_email(election_id, subject_template, body_template, extra_vars={}, voter_constraints_include=None, voter_constraints_exclude=None): """ voter_constraints_include are conditions on including voters voter_constraints_exclude are conditions on excluding voters """ - election = Election.objects.get(id = election_id) + election = Election.objects.get(id=election_id) # select the right list of voters voters = election.voter_set.all() @@ -53,61 +50,66 @@ def voters_email(election_id, subject_template, body_template, extra_vars={}, voters = voters.exclude(**voter_constraints_exclude) for voter in voters: - single_voter_email.delay(voter.uuid, subject_template, body_template, extra_vars) + single_voter_email.delay(voter.uuid, subject_template, body_template, extra_vars) + -@task() +@shared_task def voters_notify(election_id, notification_template, extra_vars={}): - election = Election.objects.get(id = election_id) + election = Election.objects.get(id=election_id) for voter in election.voter_set.all(): single_voter_notify.delay(voter.uuid, notification_template, extra_vars) -@task() + +@shared_task def single_voter_email(voter_uuid, subject_template, body_template, extra_vars={}): - voter = Voter.objects.get(uuid = voter_uuid) + voter = Voter.objects.get(uuid=voter_uuid) the_vars = copy.copy(extra_vars) - the_vars.update({'voter' : voter}) + the_vars.update({'voter': voter}) subject = render_template_raw(None, subject_template, the_vars) body = render_template_raw(None, body_template, the_vars) voter.send_message(subject, body) -@task() + +@shared_task def single_voter_notify(voter_uuid, notification_template, extra_vars={}): - voter = Voter.objects.get(uuid = voter_uuid) + voter = Voter.objects.get(uuid=voter_uuid) the_vars = copy.copy(extra_vars) - the_vars.update({'voter' : voter}) + the_vars.update({'voter': voter}) notification = render_template_raw(None, notification_template, the_vars) voter.send_notification(notification) -@task() + +@shared_task def election_compute_tally(election_id): - election = Election.objects.get(id = election_id) + election = Election.objects.get(id=election_id) election.compute_tally() - election_notify_admin.delay(election_id = election_id, - subject = "encrypted tally computed", - body = """ + election_notify_admin.delay(election_id=election_id, + subject="encrypted tally computed", + body=""" The encrypted tally for election %s has been computed. -- Helios """ % election.name) - + if election.has_helios_trustee(): - tally_helios_decrypt.delay(election_id = election.id) + tally_helios_decrypt.delay(election_id=election.id) + -@task() +@shared_task def tally_helios_decrypt(election_id): - election = Election.objects.get(id = election_id) + election = Election.objects.get(id=election_id) election.helios_trustee_decrypt() - election_notify_admin.delay(election_id = election_id, - subject = 'Helios Decrypt', - body = """ + election_notify_admin.delay(election_id=election_id, + subject='Helios Decrypt', + body=""" Helios has decrypted its portion of the tally for election %s. @@ -115,13 +117,14 @@ for election %s. Helios """ % election.name) -@task() + +@shared_task def voter_file_process(voter_file_id): - voter_file = VoterFile.objects.get(id = voter_file_id) + voter_file = VoterFile.objects.get(id=voter_file_id) voter_file.process() - election_notify_admin.delay(election_id = voter_file.election.id, - subject = 'voter file processed', - body = """ + election_notify_admin.delay(election_id=voter_file.election.id, + subject='voter file processed', + body=""" Your voter file upload for election %s has been processed. @@ -131,7 +134,8 @@ has been processed. Helios """ % (voter_file.election.name, voter_file.num_voters)) -@task() + +@shared_task def election_notify_admin(election_id, subject, body): - election = Election.objects.get(id = election_id) + election = Election.objects.get(id=election_id) election.admin.send_message(subject, body) diff --git a/helios/templates/_castconfirm_docast.html b/helios/templates/_castconfirm_docast.html index fa6b3e70a48f53299dfa4215c3e6577f1effd014..1a91b213767ad733344124fe487ddc3ec67cfe14 100644 --- a/helios/templates/_castconfirm_docast.html +++ b/helios/templates/_castconfirm_docast.html @@ -23,7 +23,7 @@ You are logged in as <u>{{voter.display_html_big|safe}}</u><br /><br /> </form> <p> - <button class="tiny" onclick="document.location='./view';">cancel</button><br /> + <button class="tiny" onclick="document.location='{% url "election@view" election.uuid %}';">cancel</button><br /> <span style="font-size:0.8em;">If you cancel now, your ballot will <em>NOT</em> be recorded.<br /> You can start the voting process over again, of course.</span> </p> diff --git a/helios/templates/_castconfirm_password.html b/helios/templates/_castconfirm_password.html index 25e31de2145cfba6ca39ffb009667ea14993cac8..03e698af7800a10ffae24aec3bd5eacc032d1162 100644 --- a/helios/templates/_castconfirm_password.html +++ b/helios/templates/_castconfirm_password.html @@ -1,5 +1,5 @@ Please provide the voter ID and password you received by email.<br /><br /> -<form method="post" action="{% url "helios.views.password_voter_login" election.uuid %}" onsubmit="show_waiting()"> +<form method="post" action="{% url "election@password-voter-login" election.uuid %}" onsubmit="show_waiting()"> <input type="hidden" name="csrf_token" value="{{csrf_token}}" /> <input type="hidden" name="return_url" value="{{return_url}}" /> <input type="hidden" name="cast_ballot" value="{{cast_ballot}}" /> diff --git a/helios/templates/cast_done.html b/helios/templates/cast_done.html index 75265abb060e5c9b3e0582330e1261e09efaedf8..dc40805d268b492561f02f036bc64a13970cbbcc 100644 --- a/helios/templates/cast_done.html +++ b/helios/templates/cast_done.html @@ -15,12 +15,12 @@ {% if logout %} <p><b>For your safety, we have logged you out.</b></p> -<iframe width="0" height="0" border="0" frameborder="0" src="/auth/logout"> +<iframe width="0" height="0" border="0" frameborder="0" src="{% url "auth@logout" %}"> </iframe> {% endif %} <p style="font-size: 1.4em;"> -[ <a href="{% url "helios.views.one_election_view" election.uuid %}">return to election info</a> ] +[ <a href="{% url "election@view" election.uuid %}">return to election info</a> ] </p> {% endblock %} diff --git a/helios/templates/castvote.html b/helios/templates/castvote.html index 1c21d73f50e12e267c2ffbe247600813f12fb40d..21b5fa72fa719c811a449dd881c5e6d33dec3232 100644 --- a/helios/templates/castvote.html +++ b/helios/templates/castvote.html @@ -3,7 +3,7 @@ {% block title %}{{cast_vote.vote_tinyhash}} — {{election.name}}{% endblock %} {% block content %} <h2 class="title">Cast Vote {{cast_vote.vote_tinyhash}}</h2> -cast in <a href="{% url "helios.views.one_election_view" election.uuid %}">{{election.name}}</a><br /> +cast in <a href="{% url "election@view" election.uuid %}">{{election.name}}</a><br /> Fingerprint: <tt>{{cast_vote.vote_hash}}</tt><br /> by <b><u> {% if the_voter.alias %} diff --git a/helios/templates/combine_decryptions.html b/helios/templates/combine_decryptions.html index 3530867df835c5fbeb0d9d591b50d0842be7eb95..89d60f120b61cc4c70976d1f74f52a641890f2a7 100644 --- a/helios/templates/combine_decryptions.html +++ b/helios/templates/combine_decryptions.html @@ -2,7 +2,7 @@ {% block title %}Compute Tally — {{election.name}}{% endblock %} {% block content %} - <h2 class="title">{{election.name}} — Compute Tally <span style="font-size:0.7em;">[<a href="{% url "helios.views.one_election_view" election.uuid %}">cancel</a>]</span></h2> + <h2 class="title">{{election.name}} — Compute Tally <span style="font-size:0.7em;">[<a href="{% url "election@view" election.uuid %}">cancel</a>]</span></h2> <p> You are about to compute the tally for this election. You only will then see the results. diff --git a/helios/templates/election_audited_ballots.html b/helios/templates/election_audited_ballots.html index 2e01f9b3254d46ad750322e1996baa5c99bb3d60..8225c1bc03a8ccf3f58da8d26572bbf454d4dbed 100644 --- a/helios/templates/election_audited_ballots.html +++ b/helios/templates/election_audited_ballots.html @@ -3,7 +3,7 @@ {% block title %}Audited Ballots for {{election.name}}{% endblock %} {% block content %} - <h2 class="title">{{election.name}} — Audited Ballots <span style="font-size:0.7em;">[<a href="{% url "helios.views.one_election_view" election_uuid=election.uuid %}">back to election</a>]</span></h2> + <h2 class="title">{{election.name}} — Audited Ballots <span style="font-size:0.7em;">[<a href="{% url "election@view" election_uuid=election.uuid %}">back to election</a>]</span></h2> <p> When you prepare a ballot with Helios, you immediately receive a smart ballot tracker. Before you choose to cast that ballot, you have the option to ask Helios to "break open" that encrypted ballot and verify that Helios encrypted your ballot correctly. Once that's done, you can post that opened ballot here, on the audited ballots' list, for everyone to verify (your identity is not included). Once you've done this, you have to re-encrypt your choices and obtain a different smart ballot tracker. This helps reduce the chance that someone might coerce you to vote differently from your true choice. @@ -14,7 +14,7 @@ These ballots are <em>not cast</em>, and they will not be counted. They are just </p> <p> - To verify an audited ballot, copy its entire content and paste it in the <a target="_new" href="/booth/single-ballot-verify.html?election_url={% url "helios.views.one_election" election.uuid %}">single ballot verifier</a>. + To verify an audited ballot, copy its entire content and paste it in the <a target="_new" href="/booth/single-ballot-verify.html?election_url={% url "election@home" election.uuid %}">single ballot verifier</a>. </p> {% if audited_ballots %} diff --git a/helios/templates/election_bboard.html b/helios/templates/election_bboard.html index a5fd7e7d9dd14bf16f26373bb97c4c277906707a..25821934c5227c7a9695d5552c6018787a8afdf4 100644 --- a/helios/templates/election_bboard.html +++ b/helios/templates/election_bboard.html @@ -3,7 +3,7 @@ {% block title %}Ballot Tracking Center for {{election.name}}{% endblock %} {% block content %} - <h2 class="title">{{election.name}} — Ballot Tracking Center <span style="font-size:0.7em;">[<a href="{% url "helios.views.one_election_view" election_uuid=election.uuid %}">back to election</a>]</span></h2> + <h2 class="title">{{election.name}} — Ballot Tracking Center <span style="font-size:0.7em;">[<a href="{% url "election@view" election_uuid=election.uuid %}">back to election</a>]</span></h2> <p> This is the ballot tracking center, which displays the tracking numbers of all cast ballots in this election. @@ -16,15 +16,15 @@ Voters {{offset_plus_one}} - {{offset_plus_limit}} {% if next_after %} -<a href="./bboard?after={{next_after}}&offset={{offset_plus_limit}}">next {{limit}}</a> +<a href="{% url "election@bboard" election.uuid %}?after={{next_after}}&offset={{offset_plus_limit}}">next {{limit}}</a> {% endif %} {% ifequal offset 0 %} {% else %} -<a href="./bboard">back to start</a> +<a href="{% url "election@bboard" election.uuid %}">back to start</a> {% endifequal %} {% if more_p %} -<a href="./bboard?after={{next_after}}&offset={{next_offset}}">next {{limit}}</a> +<a href="{% url "election@bboard" election.uuid %}?after={{next_after}}&offset={{next_offset}}">next {{limit}}</a> {% endif %} <table class="pretty"> <tr><th> @@ -40,7 +40,7 @@ Name {{voter.alias}} {% else %} <img border="0" height="20" src="/static/auth/login-icons/{{voter.voter_type}}.png" alt="{{voter.voter_type}}" /> {% if voter.name %}{{voter.name}}{% else %}{{voter.voter_id}}{% endif %} -{% endif %}</td><td><tt style="font-size: 1.4em;;">{% if voter.vote_hash %}{{voter.vote_hash}} <span style="font-size:0.8em;">[<a href="{% url "helios.views.voter_last_vote" election_uuid=election.uuid voter_uuid=voter.uuid %}">view</a>]</span>{% else %}—{% endif %}</tt></td></tr> +{% endif %}</td><td><tt style="font-size: 1.4em;;">{% if voter.vote_hash %}{{voter.vote_hash}} <span style="font-size:0.8em;">[<a href="{% url "election@ballots@voter@last" election_uuid=election.uuid voter_uuid=voter.uuid %}">view</a>]</span>{% else %}—{% endif %}</tt></td></tr> {% endfor %} </table> diff --git a/helios/templates/election_build.html b/helios/templates/election_build.html index 4526d6a05fa75ff5c2b194b8c85ace21635f4335..8f56185fcb93e2c5092168794bfae0cb4c15df72 100644 --- a/helios/templates/election_build.html +++ b/helios/templates/election_build.html @@ -1,7 +1,7 @@ {% extends "helios/templates/cryptobase.html" %} {% block content %} - <h2 class="title">{{election.name}} — Questions <span style="font-size:0.7em;">[<a href="{% url "helios.views.one_election_view" election.uuid %}">back to election</a>]</span></h2> + <h2 class="title">{{election.name}} — Questions <span style="font-size:0.7em;">[<a href="{% url "election@view" election.uuid %}">back to election</a>]</span></h2> <script language="javascript"> {% if election.questions %} diff --git a/helios/templates/election_cast_confirm.html b/helios/templates/election_cast_confirm.html index 346284c6b9670de2e8968a9ed9a6c24cdb733d28..173d729c62997569d22c4b20fbcf081e775cc8c5 100644 --- a/helios/templates/election_cast_confirm.html +++ b/helios/templates/election_cast_confirm.html @@ -73,7 +73,7 @@ requires election-specific credentials. {% endif %} </b><br /></p> <p> - [<a href="{% url "helios.views.one_election_view" election.uuid %}">return to the main election page</a>] + [<a href="{% url "election@view" election.uuid %}">return to the main election page</a>] </p> {% else %} <p> diff --git a/helios/templates/election_compute_tally.html b/helios/templates/election_compute_tally.html index fd98440e3466bdd0d5b1cbfbf8dcdaa263514289..2ad050a0286f6787f84c9349a0b4b3b7170bf8e4 100644 --- a/helios/templates/election_compute_tally.html +++ b/helios/templates/election_compute_tally.html @@ -19,12 +19,12 @@ <input type="hidden" name="csrf_token" value="{{csrf_token}}" /> <input class="button" type="submit" value="compute encrypted tally!" /> -<button onclick="document.location='./view'; return false;">never mind</button> +<button onclick="document.location='{% url "election@view" election.uuid %}'; return false;">never mind</button> </form> {% else %} <p> No votes have been cast in this election. At least one vote must be cast before you compute the tally.<br /><br /> -<a href="./view">back to election</a> +<a href="{% url "election@view" election.uuid %}">back to election</a> </p> {% endif %} </div> diff --git a/helios/templates/election_edit.html b/helios/templates/election_edit.html index 2519fb704d4e74a821a43cd792505179961cd8f4..025b2585513d0240f0005e58de3b80e88f24f375 100644 --- a/helios/templates/election_edit.html +++ b/helios/templates/election_edit.html @@ -2,7 +2,7 @@ {% block content %} - <h2 class="title">{{election.name}} — Update <span style="font-size:0.7em;">[<a href="{% url "helios.views.one_election_view" election.uuid %}">cancel</a>]</span></h2> + <h2 class="title">{{election.name}} — Update <span style="font-size:0.7em;">[<a href="{% url "election@view" election.uuid %}">cancel</a>]</span></h2> {% if error %} <p style="color: red;"> diff --git a/helios/templates/election_extend.html b/helios/templates/election_extend.html index 0db2c448ba96143d1f11d709f6ff924e4da8c46a..813afe7fd8309d449a63f505ef0327d3be23bef1 100644 --- a/helios/templates/election_extend.html +++ b/helios/templates/election_extend.html @@ -2,7 +2,7 @@ {% block content %} - <h2 class="title">{{election.name}} — Extend Voting <span style="font-size:0.7em;">[<a href="{% url "helios.views.one_election_view" election.uuid %}">cancel</a>]</span></h2> + <h2 class="title">{{election.name}} — Extend Voting <span style="font-size:0.7em;">[<a href="{% url "election@view" election.uuid %}">cancel</a>]</span></h2> <form class="prettyform" action="" method="POST" id="edit_election_form"> <input type="hidden" name="csrf_token" value="{{csrf_token}}" /> diff --git a/helios/templates/election_freeze.html b/helios/templates/election_freeze.html index a0aad4dd0eb5b03443c166a996efdf84269f1811..f0229be99638b268af28613b7fc0e83a302f799c 100644 --- a/helios/templates/election_freeze.html +++ b/helios/templates/election_freeze.html @@ -29,14 +29,14 @@ You must freeze the ballot before you can contact voters. <li>{{issue.action}}</li> {% endfor %} </ul> - <a href="{% url "helios.views.one_election_view" election.uuid %}">go back to the election</a> + <a href="{% url "election@view" election.uuid %}">go back to the election</a> </p> {% else %} <form method="post" action=""> <input type="hidden" name="csrf_token" value="{{csrf_token}}" /> <input class="button" type="submit" value="Freeze the ballot" /> -<button onclick="document.location='./view'; return false;">never mind</button> +<button onclick="document.location='{% url "election@view" election.uuid %}'; return false;">never mind</button> </form> {% endif %} diff --git a/helios/templates/election_keygenerator.html b/helios/templates/election_keygenerator.html index 4521fc9393185cf177f5e4cba6d3f69b2193ef46..bce34b8755bce301212faba9ce284908a1d495b6 100644 --- a/helios/templates/election_keygenerator.html +++ b/helios/templates/election_keygenerator.html @@ -35,7 +35,7 @@ $(document).ready(function() { $('#generator').hide(); // get some more server-side randomness for keygen - $.getJSON('../../get-randomness', function(result) { + $.getJSON('{% url "election@get-randomness" election.uuid %}', function(result) { sjcl.random.addEntropy(result.randomness); BigInt.setup(function() { ELGAMAL_PARAMS = ElGamal.Params.fromJSONObject({{eg_params_json|safe}}); @@ -159,7 +159,7 @@ Your key has been generated, but you may choose to<br /><a href="javascript:clea </p> </div> -<form method="post" id="pk_form" action="{% url "helios.views.trustee_upload_pk" election.uuid trustee.uuid %}"> +<form method="post" id="pk_form" action="{% url "election@trustee@upload-pk" election.uuid trustee.uuid %}"> <h3>Your Public Key</h3> <p> It's time to upload the public key to the server. diff --git a/helios/templates/election_not_started.html b/helios/templates/election_not_started.html index 4ba944e1a8a3b1ab9eb8351b5a2347f46e58c28f..5fba613a3aef9c42fac05fadf9f6985df5e608df 100644 --- a/helios/templates/election_not_started.html +++ b/helios/templates/election_not_started.html @@ -9,6 +9,6 @@ </p> <p> - <a href="{% url "helios.views.one_election_view" election.uuid %}">back to the election</a> + <a href="{% url "election@view" election.uuid %}">back to the election</a> </p> {% endblock %} diff --git a/helios/templates/election_questions.html b/helios/templates/election_questions.html index d7b8f7353c69025b2c4d04d2f7318b3bdeede240..468c65ecf751335f11968aabc5f2e0e9dd8a45d8 100644 --- a/helios/templates/election_questions.html +++ b/helios/templates/election_questions.html @@ -2,7 +2,7 @@ {% block title %}Questions for {{election.name}}{% endblock %} {% block content %} - <h3 class="title">{{election.name}} — Questions <span style="font-size:0.7em;">[<a href="{% url "helios.views.one_election_view" election.uuid %}">back to election</a>]</span></h3> + <h3 class="title">{{election.name}} — Questions <span style="font-size:0.7em;">[<a href="{% url "election@view" election.uuid %}">back to election</a>]</span></h3> <script language="javascript"> {% if election.questions %} diff --git a/helios/templates/election_register.html b/helios/templates/election_register.html index e1c731e0ca219ede8118caddb3fb0bca29dd1333..96a6004559183e637159bf056f614f1ef9da47be 100644 --- a/helios/templates/election_register.html +++ b/helios/templates/election_register.html @@ -16,7 +16,7 @@ You are <em>not</em> registered for this election. </p> -<form method="post" action="{% url "helios.views.one_election_register" election.uuid %}"> +<form method="post" action="{% url "election@register" election.uuid %}"> <input type="submit" value="register!" /> </form> {% endif %} diff --git a/helios/templates/election_tallied.html b/helios/templates/election_tallied.html index 9b00b636e94be8bcd05bfbe8d1a2a37412947b40..b7116822c5b31bb96c300cc2219a43e3782e32eb 100644 --- a/helios/templates/election_tallied.html +++ b/helios/templates/election_tallied.html @@ -9,6 +9,6 @@ </p> <p> - <a href="{% url "helios.views.one_election_view" election.uuid %}">view the election tally</a> + <a href="{% url "election@view" election.uuid %}">view the election tally</a> </p> {% endblock %} \ No newline at end of file diff --git a/helios/templates/election_view.html b/helios/templates/election_view.html index 5973c20292f9323cbaa5a3abe427e047e7796d89..fcb71210ab90582c5bac3d3a21bbf4ad322b506a 100644 --- a/helios/templates/election_view.html +++ b/helios/templates/election_view.html @@ -5,7 +5,7 @@ <h3 class="title">{{ election.name }} {% if admin_p %} {% if not election.frozen_at %} -<small><a class="small button" href="{% url "helios.views.one_election_edit" election.uuid %}">edit</a></small> +<small><a class="small button" href="{% url "election@edit" election.uuid %}">edit</a></small> {% endif %} {% endif %}</h3> <p style="padding-top:0px; margin-top:0px"> @@ -14,8 +14,8 @@ [archived] {% endif %} {% if admin_p %} - {% if election.is_archived %}<a class="small button" href="{% url "helios.views.one_election_archive" election_uuid=election.uuid %}?archive_p=0">unarchive it</a>{% else %}<a class="small button" href="{% url "helios.views.one_election_archive" election_uuid=election.uuid %}?archive_p=1">archive it</a>{% endif %} -<a class="small button" onclick="return window.confirm('Are you sure you want to copy this election?');" href="{% url "helios.views.one_election_copy" election_uuid=election.uuid %}">copy</a> + {% if election.is_archived %}<a class="small button" href="{% url "election@archive" election_uuid=election.uuid %}?archive_p=0">unarchive it</a>{% else %}<a class="small button" href="{% url "election@archive" election_uuid=election.uuid %}?archive_p=1">archive it</a>{% endif %} +<a class="small button" onclick="return window.confirm('Are you sure you want to copy this election?');" href="{% url "election@copy" election_uuid=election.uuid %}">copy</a> {% endif %} <br /> {% if admin_p %} @@ -23,12 +23,12 @@ {% if election.featured_p %} this {{election.election_type}} is featured on the front page. {% if can_feature_p %} -[<a href="{% url "helios.views.one_election_set_featured" election.uuid %}?featured_p=0">unfeature it</a>] +[<a href="{% url "election@set-featured" election.uuid %}?featured_p=0">unfeature it</a>] {% endif %} {% else %} this {{election.election_type}} is <u>not</u> featured on the front page. {% if can_feature_p %} -[<a href="{% url "helios.views.one_election_set_featured" election.uuid %}?featured_p=1">feature it</a>] +[<a href="{% url "election@set-featured" election.uuid %}?featured_p=1">feature it</a>] {% endif %} {% endif %} {% endif %} @@ -51,11 +51,11 @@ this {{election.election_type}} is <u>not</u> featured on the front page. {% endif %} <p align="center" style="font-size: 1.5em;"> -<a href="{% url "helios.views.one_election_questions" election.uuid %}">questions ({% if election.questions %}{{election.questions|length}}{% else %}0{% endif %})</a> +<a href="{% url "election@questions" election.uuid %}">questions ({% if election.questions %}{{election.questions|length}}{% else %}0{% endif %})</a> | -<a href="{% url "helios.views.voters_list_pretty" election.uuid %}">voters & ballots</a> +<a href="{% url "election@voters@list-pretty" election.uuid %}">voters & ballots</a> | -<a href="{% url "helios.views.list_trustees_view" election.uuid %}">trustees ({{trustees|length}})</a> +<a href="{% url "election@trustees@view" election.uuid %}">trustees ({{trustees|length}})</a> </p> {% if admin_p %} @@ -87,7 +87,7 @@ this {{election.election_type}} is <u>not</u> featured on the front page. {{issue.action}}{% if forloop.last %}{% else %}, and{% endif %}<br /> {% endfor %} {% else %} -<a href="{% url "helios.views.one_election_freeze" election.uuid %}">freeze ballot and open election.</a> +<a href="{% url "election@freeze" election.uuid %}">freeze ballot and open election.</a> <br /> {% if election.voting_starts_at %} once you do this, the election will be ready for voting and will open automatically<br /> @@ -104,20 +104,20 @@ once you do this, the election will be immediately open for voting. Tally computation is under way.<br /> Reload this page in a couple of minutes. {% else %} -<a href="{% url "helios.views.one_election_compute_tally" election.uuid %}">compute encrypted tally</a><br /> +<a href="{% url "election@compute-tally" election.uuid %}">compute encrypted tally</a><br /> The encrypted votes will be combined into an encrypted tally. Once this is done,<br /> trustees will be asked to provide their share of the decryption. {% endif %} {% else %} {% if election.result %} -<a href="{% url "helios.views.release_result" election.uuid %}">release result</a><br /> +<a href="{% url "election@release-result" election.uuid %}">release result</a><br /> The result displayed below is visible only to you.<br /> Once you release the result, it will be visible to everyone. {% else %} {% if election.ready_for_decryption_combination %} -<a href="{% url "helios.views.combine_decryptions" election.uuid %}"> +<a href="{% url "election@combine-decryptions" election.uuid %}"> {% if election.num_trustees == 1 %} compute results {% else %} @@ -131,7 +131,7 @@ The decryption shares from the trustees will be combined and the tally computed. Once you do this, the tally will visible to you, the administrator, only. {% endif %} {% else %} -<a href="{% url "helios.views.list_trustees_view" election.uuid %}">trustees (for decryption)</a> +<a href="{% url "election@trustees@view" election.uuid %}">trustees (for decryption)</a> {% endif %} {% endif %} @@ -236,7 +236,7 @@ You are <em>not eligible</em> to vote in this {{election.election_type}}. {% if election.openreg %} {% if election.eligibility %} This election is open to: {{election.pretty_eligibility|safe}} -<a href="{{settings.SECURE_URL_HOST}}{% url "helios_auth.views.index" %}?return_url={{CURRENT_URL}}">Log in</a> to check your eligibility. +<a href="{{settings.SECURE_URL_HOST}}{% url "auth@index" %}?return_url={{CURRENT_URL}}">Log in</a> to check your eligibility. {% else %} Anyone can vote in this election. {% endif %} @@ -249,7 +249,7 @@ Anyone can vote in this election. {% endif %} {% if admin_p and election.voting_ends_at and not election.tallying_started_at %} -<br /><a href="{% url "helios.views.one_election_extend" election.uuid %}">extend voting</a><br /> +<br /><a href="{% url "election@extend" election.uuid %}">extend voting</a><br /> {% endif %} <div style="background: lightyellow; padding:5px; padding-left: 10px; margin-top: 15px; border: 1px solid #aaa; width: 720px;" class="round"> @@ -271,22 +271,22 @@ Anyone can vote in this election. {% endif %} <p style="font-size: 1.3em;"> -<a href="{% url "helios.views.voters_list_pretty" election.uuid %}">Ballot Tracking Center</a> | -<a href="{% url "helios.views.one_election_audited_ballots" election.uuid %}">Audited Ballots</a> +<a href="{% url "election@voters@list-pretty" election.uuid %}">Ballot Tracking Center</a> | +<a href="{% url "election@audited-ballots" election.uuid %}">Audited Ballots</a> </p> {% endif %} {% if not election.voting_has_started %} <p style="font-size: 1.2em;"> - <a href="{{SECURE_URL_HOST}}/booth/vote.html?election_url={% url "helios.views.one_election" election.uuid %}">preview booth</a> + <a href="{{SECURE_URL_HOST}}/booth/vote.html?election_url={% url "election@home" election.uuid %}">preview booth</a> </p> {% endif %} {% if election.voting_has_stopped %} <p style="font-size: 1.2em;"> {% if election.result %} -verify <a target="_blank" href="/verifier/verify.html?election_url={% url "helios.views.one_election" election.uuid %}">election tally</a>. +verify <a target="_blank" href="/verifier/verify.html?election_url={% url "election@home" election.uuid %}">election tally</a>. {% endif %} review the <a href="{{vote_url}}">voting booth</a>. diff --git a/helios/templates/elections_administered.html b/helios/templates/elections_administered.html index 03bc226c6583e2ab94b516b05bd16efbf1128b30..563ecc9fe5450e42a2b2ae9ed144648b4eb5e9bb 100644 --- a/helios/templates/elections_administered.html +++ b/helios/templates/elections_administered.html @@ -5,7 +5,7 @@ <ul> {% for election in elections %} -<li> <a href="{% url "helios.views.one_election_view" election.uuid %}">{{election.name}}</a><em> - {{election.num_voters}} voters / {{election.num_cast_votes}} cast votes</em></li> +<li> <a href="{% url "election@view" election.uuid %}">{{election.name}}</a><em> - {{election.num_voters}} voters / {{election.num_cast_votes}} cast votes</em></li> {% endfor %} </ul> {% endblock %} \ No newline at end of file diff --git a/helios/templates/elections_voted.html b/helios/templates/elections_voted.html index 7447eb09f63ef179d5e9afa0166b8f5736cf2b05..f013a983b72c4991f9d4a6a353747a55b5708193 100644 --- a/helios/templates/elections_voted.html +++ b/helios/templates/elections_voted.html @@ -5,7 +5,7 @@ <ul> {% for election in elections %} -<li> <a href="{% url "helios.views.one_election_view" election.uuid %}">{{election.name}}</a></li> +<li> <a href="{% url "election@view" election.uuid %}">{{election.name}}</a></li> {% endfor %} </ul> {% endblock %} diff --git a/helios/templates/list_trustees.html b/helios/templates/list_trustees.html index 39ddd5553f74b66896be55c57693f5449df41305..47032c4d1c5e65cf2b476003edba3d24069968b6 100644 --- a/helios/templates/list_trustees.html +++ b/helios/templates/list_trustees.html @@ -3,7 +3,7 @@ {% block title %}Trustees for {{election.name}}{% endblock %} {% block content %} - <h3 class="title">{{election.name}} — Trustees <span style="font-size:0.7em;">[<a href="{% url "helios.views.one_election_view" election.uuid %}">back to election</a>]</span></h3> + <h3 class="title">{{election.name}} — Trustees <span style="font-size:0.7em;">[<a href="{% url "election@view" election.uuid %}">back to election</a>]</span></h3> <p> Trustees are responsible for decrypting the election result.<br /> @@ -21,11 +21,11 @@ {% if admin_p %} <p> - [ <a onclick="return(confirm('Adding your own trustee requires a good bit more work to tally the election.\nYou will need to have trustees generate keypairs and safeguard their secret key.\n\nIf you are not sure what that means, we strongly recommend\nclicking Cancel and letting Helios tally the election for you.'));" href="{% url "helios.views.new_trustee" election.uuid %}">add a trustee</a> ] + [ <a onclick="return(confirm('Adding your own trustee requires a good bit more work to tally the election.\nYou will need to have trustees generate keypairs and safeguard their secret key.\n\nIf you are not sure what that means, we strongly recommend\nclicking Cancel and letting Helios tally the election for you.'));" href="{% url "election@trustees@new" election.uuid %}">add a trustee</a> ] </p> {% if not election.has_helios_trustee %} <p> - <a href="{% url "helios.views.new_trustee_helios" election.uuid %}">add Helios as a trustee</a> + <a href="{% url "election@trustees@add-helios" election.uuid %}">add Helios as a trustee</a> </p> {% endif %} {% endif %} @@ -39,11 +39,11 @@ <h5> Trustee #{{forloop.counter}}: {{t.name}} {% if admin_p %} {% 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 %} +{% if not election.frozen_at %}[<a onclick="return confirm('Are you sure you want to remove Helios as a trustee?');" href="{% url "election@trustees@delete" election.uuid %}?uuid={{t.uuid}}">x</a>]{% endif %} {% else %} ({{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 %} -[<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>] +{% if not election.frozen_at %}[<a onclick="return confirm('Are you sure you want to remove this Trustee?');" href="{% url "election@trustees@delete" 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 "election@trustee@send-url" election.uuid t.uuid %}">send login</a>] {% endif %} {% endif %} </h5> diff --git a/helios/templates/new_trustee.html b/helios/templates/new_trustee.html index 0df1a27c287fcb2a8a960315604ea7e94ec37370..75af0545bd60262c22a9349ea8ae33581cf73a22 100644 --- a/helios/templates/new_trustee.html +++ b/helios/templates/new_trustee.html @@ -1,7 +1,7 @@ {% extends "helios/templates/cryptobase.html" %} {% block content %} - <h2 class="title">{{election.name}} — New Trustee <span style="font-size:0.7em;">[<a href="{% url "helios.views.list_trustees_view" election.uuid %}">cancel</a>]</span></h2> + <h2 class="title">{{election.name}} — New Trustee <span style="font-size:0.7em;">[<a href="{% url "election@trustees@view" election.uuid %}">cancel</a>]</span></h2> <form method="post" action=""> <input type="hidden" name="csrf_token" value="{{csrf_token}}" /> diff --git a/helios/templates/release_result.html b/helios/templates/release_result.html index cac6c64a7a6e62d07691ecbf877d09780607c495..5e467e471cb58ccee1319e362109a96d461946a5 100644 --- a/helios/templates/release_result.html +++ b/helios/templates/release_result.html @@ -2,7 +2,7 @@ {% block title %}Release Result — {{election.name}}{% endblock %} {% block content %} - <h2 class="title">{{election.name}} — Release Result <span style="font-size:0.7em;">[<a href="{% url "helios.views.one_election_view" election.uuid %}">cancel</a>]</span></h2> + <h2 class="title">{{election.name}} — Release Result <span style="font-size:0.7em;">[<a href="{% url "election@view" election.uuid %}">cancel</a>]</span></h2> <p> You are about to release the result for this election. diff --git a/helios/templates/stats.html b/helios/templates/stats.html index 37468b7150a3e90bf27c1ea7c89028c8a089d231..3f2bffe2b415bf3148bcd716640cbfa7199b9a45 100644 --- a/helios/templates/stats.html +++ b/helios/templates/stats.html @@ -5,11 +5,11 @@ <h1>Admin</h1> <ul> -<li> <a href="{% url "helios.stats_views.elections" %}">elections</a></li> -<li> <a href="{% url "helios.stats_views.recent_votes" %}">recent votes</a></li> -<li> <a href="{% url "helios.stats_views.recent_problem_elections" %}">recent problem elections</a></li> +<li> <a href="{% url "stats@elections" %}">elections</a></li> +<li> <a href="{% url "stats@recent-votes" %}">recent votes</a></li> +<li> <a href="{% url "stats@elections-problems" %}">recent problem elections</a></li> </ul> -<p><b>{{num_votes_in_queue}}</b> votes in queue. {% if num_votes_in_queue %}[<a href="{% url "helios.stats_views.force_queue" %}">force it</a>]{% endif %}</p> +<p><b>{{num_votes_in_queue}}</b> votes in queue. {% if num_votes_in_queue %}[<a href="{% url "stats@force-queue" %}">force it</a>]{% endif %}</p> {% endblock %} diff --git a/helios/templates/stats_elections.html b/helios/templates/stats_elections.html index 7179698334bbaecfc80f458b9b5061d560ddd9ea..e9a498ef8e9a5a21d5069eb3ac5861ff4726dd41 100644 --- a/helios/templates/stats_elections.html +++ b/helios/templates/stats_elections.html @@ -5,7 +5,7 @@ <h1>Elections</h1> <p> -<form method="get" action="{% url "helios.stats_views.elections" %}"> +<form method="get" action="{% url "stats@elections" %}"> <b>search</b>: <input type="text" name="q" value="{{q}}"/> <input class="small button" type="submit" value="search" /> <a class="small button" href="?">clear search</a> </form> @@ -26,7 +26,7 @@ Elections {{elections_page.start_index}} - {{elections_page.end_index}} (of {{to {% for election in elections %} <p> -<b><a href="{% url "helios.views.one_election_view" election.uuid %}">{{election.name}}</a></b> by <a href="mailto:{{election.admin.info.email}}">{{election.admin.pretty_name}}</a> -- {{election.num_voters}} voters / {{election.num_cast_votes}} cast votes +<b><a href="{% url "election@view" election.uuid %}">{{election.name}}</a></b> by <a href="mailto:{{election.admin.info.email}}">{{election.admin.pretty_name}}</a> -- {{election.num_voters}} voters / {{election.num_cast_votes}} cast votes </p> {% endfor %} diff --git a/helios/templates/stats_problem_elections.html b/helios/templates/stats_problem_elections.html index 9f8c1dadd43bf52905d1c844088443ea72da07b0..2f82f74b92050540ce84ab43f4e522d87ea0f92d 100644 --- a/helios/templates/stats_problem_elections.html +++ b/helios/templates/stats_problem_elections.html @@ -8,7 +8,7 @@ Unfrozen for more than a day. {% for election in elections %} <p> -<b><a href="{% url "helios.views.one_election_view" election.uuid %}">{{election.name}}</a></b> -- {{election.num_voters}} voters +<b><a href="{% url "election@view" election.uuid %}">{{election.name}}</a></b> -- {{election.num_voters}} voters </p> {% endfor %} diff --git a/helios/templates/stats_recent_votes.html b/helios/templates/stats_recent_votes.html index 37c074161f3f973c4bab1d9c4f2d2118c79f327c..bf360a28482a477bcecfb0766045f39563167f71 100644 --- a/helios/templates/stats_recent_votes.html +++ b/helios/templates/stats_recent_votes.html @@ -8,7 +8,7 @@ Last 24 hours {% for election in elections %} <p> -<b><a href="{% url "helios.views.one_election_view" election.uuid %}">{{election.name}}</a></b> -- {{election.last_cast_vote}} {{election.num_recent_cast_votes}} recently cast votes +<b><a href="{% url "election@view" election.uuid %}">{{election.name}}</a></b> -- {{election.last_cast_vote}} {{election.num_recent_cast_votes}} recently cast votes </p> {% endfor %} diff --git a/helios/templates/trustee_check_sk.html b/helios/templates/trustee_check_sk.html index 81afe42d4945f3b9856dc31a1eab792d3647c6db..99380d31c5e8024fab0c51edbbb785c233d3c73c 100644 --- a/helios/templates/trustee_check_sk.html +++ b/helios/templates/trustee_check_sk.html @@ -43,7 +43,7 @@ function check_sk(sk_value) { } } </script> - <h2 class="title">{{election.name}} — Trustee {{trustee.name}} — Check Secret Key <span style="font-size:0.7em;">[<a href="./home">back to trustee home</a>]</span></h2> + <h2 class="title">{{election.name}} — Trustee {{trustee.name}} — Check Secret Key <span style="font-size:0.7em;">[<a href="{% url "election@trustee" election_uuid=election.uuid trustee_uuid=trustee.uuid %}">back to trustee home</a>]</span></h2> <p> Your public key fingerprint is: <b>{{trustee.public_key_hash}}</b> diff --git a/helios/templates/trustee_decrypt_and_prove.html b/helios/templates/trustee_decrypt_and_prove.html index 05153b8a349b2ae8b91b5de283f2bc850ab89f63..cb4c2e68caa5b627ffdd12284ba1805105a1f5a8 100644 --- a/helios/templates/trustee_decrypt_and_prove.html +++ b/helios/templates/trustee_decrypt_and_prove.html @@ -195,7 +195,7 @@ function reset() { </div> <div id="done_div"> - Done! <a href="{% url "helios.views.one_election_view" election.uuid %}">Back to election</a> + Done! <a href="{% url "election@view" election.uuid %}">Back to election</a> </div> <div id="error_div"> diff --git a/helios/templates/trustee_home.html b/helios/templates/trustee_home.html index 5f6ee9c54e66c1884114827b208f518888c96bc8..8d6dd115179c563bd90cb2886813e6285dd97d71 100644 --- a/helios/templates/trustee_home.html +++ b/helios/templates/trustee_home.html @@ -7,9 +7,9 @@ {% if trustee.public_key_hash %} You have successfully uploaded your public key.<br /> Your public key fingerprint is: <b>{{trustee.public_key_hash}}</b>.<br /> -You can <a href="{% url "helios.views.trustee_check_sk" election.uuid trustee.uuid %}">verify that you have the right secret key</a>. +You can <a href="{% url "election@trustee@check-sk" election.uuid trustee.uuid %}">verify that you have the right secret key</a>. {% else %} -<a href="{% url "helios.views.trustee_keygenerator" election.uuid trustee.uuid %}">setup your key</a> +<a href="{% url "election@trustee@key-generator" election.uuid trustee.uuid %}">setup your key</a> {% endif %} </p> @@ -19,7 +19,7 @@ You can <a href="{% url "helios.views.trustee_check_sk" election.uuid trustee.uu You have successfully uploaded your decryption. {% else %} The encrypted tally for this election is ready.<br /> - <a href="{% url "helios.views.trustee_decrypt_and_prove" election.uuid trustee.uuid %}">decrypt with your key</a> + <a href="{% url "election@trustee@decrypt-and-prove" election.uuid trustee.uuid %}">decrypt with your key</a> {% endif %} {% else %} Once the tally is computed, come back here to provide your secret key for decryption purposes.<br /> diff --git a/helios/templates/voters_eligibility.html b/helios/templates/voters_eligibility.html index 51343befd47591e0b937a484a32b4a3dfe7675ea..0baa6f7f968ddf5067580f18e75c28d69c353730 100644 --- a/helios/templates/voters_eligibility.html +++ b/helios/templates/voters_eligibility.html @@ -2,7 +2,7 @@ {% block title %}Voter Eligibility for {{election.name}}{% endblock %} {% block content %} - <h2 class="title">{{election.name}} — Voter Eligibility <span style="font-size:0.7em;">[<a href="{% url "helios.views.voters_list_pretty" election.uuid %}">back to voters</a>]</span></h2> + <h2 class="title">{{election.name}} — Voter Eligibility <span style="font-size:0.7em;">[<a href="{% url "election@voters@list-pretty" election.uuid %}">back to voters</a>]</span></h2> <p> <em>{{election.pretty_eligibility|safe}}</em> diff --git a/helios/templates/voters_email.html b/helios/templates/voters_email.html index 535f7533fbeaf6cd87753c2f5f0c8788f03f4a95..62a6c7d63bc52eb57da0c0353a1151ba193b0938 100644 --- a/helios/templates/voters_email.html +++ b/helios/templates/voters_email.html @@ -9,7 +9,7 @@ voter_id = '{{voter.voter_id}}'; {% endif %} </script> - <h2 class="title">{{election.name}} — Contact Voters <span style="font-size:0.7em;">[<a href="{% url "helios.views.one_election_view" election.uuid %}">back to election</a>]</span></h2> + <h2 class="title">{{election.name}} — Contact Voters <span style="font-size:0.7em;">[<a href="{% url "election@view" election.uuid %}">back to election</a>]</span></h2> {% if voter %} <p> @@ -55,7 +55,7 @@ You may tweak the subject and add a custom message using the form below. </div> <div id="done" style="display:none;"> - Done, go <a href="{% url "helios.views.one_election_view" election.uuid %}">back to election</a>. + Done, go <a href="{% url "election@view" election.uuid %}">back to election</a>. </div> <div id="error" style="display:none;"> diff --git a/helios/templates/voters_list.html b/helios/templates/voters_list.html index fffe57fdbc717c6c97cb39f4527938bccdacf811..3b345a06bc4f0d05eed048bf76cf17c333be897d 100644 --- a/helios/templates/voters_list.html +++ b/helios/templates/voters_list.html @@ -2,7 +2,7 @@ {% block title %}Voters & Ballot Tracking Center for {{election.name}}{% endblock %} {% block content %} - <h3 class="title">{{election.name}} — 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></h3> + <h3 class="title">{{election.name}} — Voters and Ballot Tracking Center <span style="font-size:0.7em;">[<a href="{% url "election@view" election.uuid %}">back to election</a>]</span></h3> <p> <b>Who can vote?</b> @@ -18,7 +18,7 @@ <em>Your election is marked private, which means you cannot open registration up more widely</em>.<br /> {% else %} You can change this setting: -<form method="post" action="{% url "helios.views.voters_eligibility" election.uuid %}"> +<form method="post" action="{% url "election@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 /> @@ -37,7 +37,7 @@ You can change this setting: {% endif %} {% if email_voters and election.frozen_at and admin_p %} -<p><a class="button" href="{% url "helios.views.voters_email" election.uuid %}">email voters</a></p> +<p><a class="button" href="{% url "election@voters@email" election.uuid %}">email voters</a></p> {% endif %} {% if election.num_voters > 20 %} @@ -45,7 +45,7 @@ You can change this setting: {% if q %} <p><em>searching for <u>{{q}}</u>.</em> [<a href="?">clear search</a>]</p> {% else %} -<form method="get" action="{% url "helios.views.voters_list_pretty" election.uuid %}"><b>search</b>: <input type="text" name="q" /> <input type="submit" value="search" /></form> +<form method="get" action="{% url "election@voters@list-pretty" election.uuid %}"><b>search</b>: <input type="text" name="q" /> <input type="submit" value="search" /></form> {% endif %} </p> {% endif %} @@ -54,7 +54,7 @@ You can change this setting: <!-- Add a Voter: WORK HERE--> {% if upload_p and not election.openreg %} <p> -<a class="button" href="{% url "helios.views.voters_upload" election_uuid=election.uuid %}">bulk upload voters</a> +<a class="button" href="{% url "election@voters@upload" election_uuid=election.uuid %}">bulk upload voters</a> </p> {% if voter_files %} @@ -99,14 +99,14 @@ no votes yet </p> {% if voters_page.has_previous %} -<a href="./list?page={{voters_page.previous_page_number}}&limit={{limit}}&q={{q|urlencode}}">previous {{limit}}</a> +<a href="{% url "election@voters@list-pretty" election.uuid %}?page={{voters_page.previous_page_number}}&limit={{limit}}&q={{q|urlencode}}">previous {{limit}}</a> {% endif %} Voters {{voters_page.start_index}} - {{voters_page.end_index}} (of {{total_voters}}) {% if voters_page.has_next %} -<a href="./list?page={{voters_page.next_page_number}}&limit={{limit}}&q={{q|urlencode}}">next {{limit}}</a> +<a href="{% url "election@voters@list-pretty" election.uuid %}?page={{voters_page.next_page_number}}&limit={{limit}}&q={{q|urlencode}}">next {{limit}}</a> {% endif %} <table class="pretty"> @@ -131,9 +131,9 @@ Voters {{voters_page.start_index}} - {{voters_page.end_index}} (of {{total_voter {% if admin_p %} <td style="white-space: nowrap;"> {% if election.frozen_at %} -[<a href="{% url "helios.views.voters_email" election.uuid %}?voter_id={{voter.voter_login_id}}">email</a>] +[<a href="{% url "election@voters@email" election.uuid %}?voter_id={{voter.voter_login_id}}">email</a>] {% endif %} -[<a onclick="return confirm('are you sure you want to remove {{voter.name}} ?');" href="{% url "helios.views.voter_delete" election.uuid voter.uuid %}">x</a>] +[<a onclick="return confirm('are you sure you want to remove {{voter.name}} ?');" href="{% url "election@voter@delete" election.uuid voter.uuid %}">x</a>] </td> <td>{{voter.voter_login_id}}</td> <td>{{voter.voter_email}}</td> @@ -143,7 +143,7 @@ Voters {{voters_page.start_index}} - {{voters_page.end_index}} (of {{total_voter {% if election.use_voter_aliases %} <td>{{voter.alias}}</td> {% endif %} -<td><tt style="font-size: 1.4em;">{% if voter.vote_hash %}{{voter.vote_hash}} <span style="font-size:0.8em;">[<a href="{% url "helios.views.castvote_shortcut" vote_tinyhash=voter.vote_tinyhash %}">view</a>]</span>{% else %}—{% endif %}</tt></td> +<td><tt style="font-size: 1.4em;">{% if voter.vote_hash %}{{voter.vote_hash}} <span style="font-size:0.8em;">[<a href="{% url "shortcut@vote" vote_tinyhash=voter.vote_tinyhash %}">view</a>]</span>{% else %}—{% endif %}</tt></td> </tr> {% endfor %} </table> diff --git a/helios/templates/voters_manage.html b/helios/templates/voters_manage.html index ccd54906ab945a00ec8b8cb5b57fd59ae71523a5..f2a83c794091be3b5268ad0734f9a8135d61cb1c 100644 --- a/helios/templates/voters_manage.html +++ b/helios/templates/voters_manage.html @@ -1,12 +1,12 @@ {% extends TEMPLATE_BASE %} {% block content %} - <h2 class="title">{{election.name}} — Manage Voters <span style="font-size:0.7em;">[<a href="{% url "helios.views.one_election_view" election.uuid %}">back to election</a>]</span></h2> + <h2 class="title">{{election.name}} — Manage Voters <span style="font-size:0.7em;">[<a href="{% url "election@view" election.uuid %}">back to election</a>]</span></h2> <form method="get" action="{% url "helios.views.voters_search" election.uuid %}"><b>search</b>: <input type="text" name="q" /> <input type="submit" value="search" /></form> {% if upload_p %} -<p><a href="{% url "helios.views.voters_upload" election_uuid=election.uuid %}">bulk upload voters</a></p> +<p><a href="{% url "election@voters@upload" election_uuid=election.uuid %}">bulk upload voters</a></p> {% endif %} Voters {{offset_plus_one}} - {{offset_plus_limit}} @@ -29,7 +29,7 @@ Voters {{offset_plus_one}} - {{offset_plus_limit}} <tr><td>{{voter.alias}}</td><td>{{voter.name}}</td><td>{{voter.voter_id}} {% if election.frozen_at %} {% else %} -[<a onclick="return confirm('are you sure you want to remove {{voter.name}} ?');" href="{% url "helios.views.voter_delete" election.uuid voter.uuid %}">x</a>] +[<a onclick="return confirm('are you sure you want to remove {{voter.name}} ?');" href="{% url "election@voter@delete" election.uuid voter.uuid %}">x</a>] {% endif %} </td></tr> {% endfor %} diff --git a/helios/templates/voters_search.html b/helios/templates/voters_search.html index 1adfb33fe1bf5123a30bae6eb03915644a23740b..162051f7095b9af671faa20000246c592968b673 100644 --- a/helios/templates/voters_search.html +++ b/helios/templates/voters_search.html @@ -1,12 +1,12 @@ {% extends TEMPLATE_BASE %} {% block content %} - <h2 class="title">{{election.name}} — Search Voters for '{{search_term}}' <span style="font-size:0.7em;">[<a href="{% url "helios.views.one_election_view" election.uuid %}">back to election</a>]</span></h2> + <h2 class="title">{{election.name}} — Search Voters for '{{search_term}}' <span style="font-size:0.7em;">[<a href="{% url "election@view" election.uuid %}">back to election</a>]</span></h2> {% if voter %} Voter Found: {{voter.name}} ({{voter.voter_id}})<br /><br /> {% if election.frozen_at %} -<a href="{% url "helios.views.voters_email" election.uuid %}?voter_id={{voter.voter_id}}">email this voter</a> +<a href="{% url "election@voters@email" election.uuid %}?voter_id={{voter.voter_id}}">email this voter</a> {% else %} once this election is frozen, you'll be able to email this voter. {% endif %} diff --git a/helios/templates/voters_upload.html b/helios/templates/voters_upload.html index a38956d019d1d02b90f43c184239e072f38353cd..908c147f124f4c342b034b6845bd406f3e5b8048 100644 --- a/helios/templates/voters_upload.html +++ b/helios/templates/voters_upload.html @@ -1,7 +1,7 @@ {% extends TEMPLATE_BASE %} {% block content %} - <h2 class="title">{{election.name}} — Bulk Upload Voters <span style="font-size:0.7em;">[<a href="{% url "helios.views.one_election_view" election.uuid %}">back to election</a>]</span></h2> + <h2 class="title">{{election.name}} — Bulk Upload Voters <span style="font-size:0.7em;">[<a href="{% url "election@view" election.uuid %}">back to election</a>]</span></h2> <form method="post" action="" id="upload_form" enctype="multipart/form-data"> <p> diff --git a/helios/templates/voters_upload_confirm.html b/helios/templates/voters_upload_confirm.html index c3d7c084b58b285b09959d3e72fc48ef28309cf6..911cb259d9d321e6bd0cc69ddc9cde95acb7320c 100644 --- a/helios/templates/voters_upload_confirm.html +++ b/helios/templates/voters_upload_confirm.html @@ -1,7 +1,7 @@ {% extends TEMPLATE_BASE %} {% block content %} - <h2 class="title">{{election.name}} — Bulk Upload Voters — Confirm<span style="font-size:0.7em;">[<a href="{% url "helios.views.one_election_view" election.uuid %}">back to election</a>]</span></h2> + <h2 class="title">{{election.name}} — Bulk Upload Voters — Confirm<span style="font-size:0.7em;">[<a href="{% url "election@view" election.uuid %}">back to election</a>]</span></h2> <p> You have uploaded a file of voters. The first few rows of this file are: @@ -23,7 +23,7 @@ HOLD ON:<br /> </p> <br /> -<a href="{% url "helios.views.voters_upload_cancel" election.uuid %}">never mind, upload a different file</a> +<a href="{% url "election@voters@upload-cancel" election.uuid %}">never mind, upload a different file</a> </p> {% else %} @@ -34,7 +34,7 @@ HOLD ON:<br /> <input type="submit" value="Yes, let's go" /> </form> -<a href="{% url "helios.views.voters_upload_cancel" election.uuid %}">no, let me upload a different file</a> +<a href="{% url "election@voters@upload-cancel" election.uuid %}">no, let me upload a different file</a> {% endif %} diff --git a/helios/test.py b/helios/test.py index 086f117c139e3bc4a88a518bfe999a07d3527ec7..11fde1c1799c63e07d7f4ea3a8f279ff78a9fd03 100644 --- a/helios/test.py +++ b/helios/test.py @@ -2,18 +2,21 @@ Testing Helios Features """ -from helios.models import * -from helios_auth.models import * import uuid -def generate_voters(election, num_voters = 1000, start_with = 1): - # generate the user - for v_num in range(start_with, start_with + num_voters): - user = User(user_type='password', user_id='testuser%s' % v_num, name='Test User %s' % v_num) - user.put() - voter = Voter(uuid=str(uuid.uuid1()), election = election, voter_type=user.user_type, voter_id = user.user_id) - voter.put() +from helios.models import Voter +from helios_auth.models import User + + +def generate_voters(election, num_voters=1000, start_with=1): + # generate the user + for v_num in range(start_with, start_with + num_voters): + user = User(user_type='password', user_id='testuser%s' % v_num, name='Test User %s' % v_num) + user.save() + voter = Voter(uuid=str(uuid.uuid1()), election=election, voter_type=user.user_type, voter_id=user.user_id) + voter.save() + def delete_voters(election): - for v in Voter.get_by_election(election): - v.delete() \ No newline at end of file + for v in Voter.get_by_election(election): + v.delete() diff --git a/helios/tests.py b/helios/tests.py index 3bd573197b062287d6dd34896d03c8f904156f66..157ce2823da9cc332790cea5561cd11d8704730d 100644 --- a/helios/tests.py +++ b/helios/tests.py @@ -2,32 +2,28 @@ Unit Tests for Helios """ -import unittest, datetime, re, urllib -import django_webtest - -import models -import datatypes - -from helios_auth import models as auth_models -from views import ELGAMAL_PARAMS -import views -import utils +import datetime +import re +import urllib -from django.db import IntegrityError, transaction -from django.test.client import Client +import django_webtest +import uuid +from django.conf import settings +from django.core import mail +from django.core.files import File from django.test import TestCase from django.utils.html import escape as html_escape -from django.core import mail -from django.core.files import File -from django.core.urlresolvers import reverse -from django.conf import settings -from django.core.exceptions import PermissionDenied +import helios.datatypes as datatypes +import helios.models as models +import helios.utils as utils +import helios.views as views +from helios_auth import models as auth_models -import uuid class ElectionModelTests(TestCase): fixtures = ['users.json'] + allow_database_queries = True def create_election(self): return models.Election.get_or_create( @@ -41,7 +37,7 @@ class ElectionModelTests(TestCase): self.election.questions = QUESTIONS def setup_trustee(self): - self.election.generate_trustee(ELGAMAL_PARAMS) + self.election.generate_trustee(views.ELGAMAL_PARAMS) def setup_openreg(self): self.election.openreg=True @@ -114,7 +110,7 @@ class ElectionModelTests(TestCase): self.assertEquals(len(issues), 0) def test_helios_trustee(self): - self.election.generate_trustee(ELGAMAL_PARAMS) + self.election.generate_trustee(views.ELGAMAL_PARAMS) self.assertTrue(self.election.has_helios_trustee()) @@ -198,15 +194,15 @@ class ElectionModelTests(TestCase): def test_voter_registration(self): # before adding a voter voters = models.Voter.get_by_election(self.election) - self.assertTrue(len(voters) == 0) + self.assertEquals(0, len(voters)) # make sure no voter yet voter = models.Voter.get_by_election_and_user(self.election, self.user) - self.assertTrue(voter == None) + self.assertIsNone(voter) # make sure no voter at all across all elections voters = models.Voter.get_by_user(self.user) - self.assertTrue(len(voters) == 0) + self.assertEquals(0, len(voters)) # register the voter voter = models.Voter.register_user_in_election(self.user, self.election) @@ -214,13 +210,13 @@ 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.assertIsNotNone(voter) + self.assertIsNotNone(voter_2) self.assertEquals(voter, voter_2) # make sure voter is there in this call too voters = models.Voter.get_by_user(self.user) - self.assertTrue(len(voters) == 1) + self.assertEquals(1, len(voters)) self.assertEquals(voter, voters[0]) voter_2 = models.Voter.get_by_election_and_uuid(self.election, voter.uuid) @@ -232,6 +228,7 @@ class ElectionModelTests(TestCase): class VoterModelTests(TestCase): fixtures = ['users.json', 'election.json'] + allow_database_queries = True def setUp(self): self.election = models.Election.objects.get(short_name='test') @@ -255,6 +252,7 @@ class VoterModelTests(TestCase): class CastVoteModelTests(TestCase): fixtures = ['users.json', 'election.json'] + allow_database_queries = True def setUp(self): self.election = models.Election.objects.get(short_name='test') @@ -268,10 +266,11 @@ class CastVoteModelTests(TestCase): class DatatypeTests(TestCase): fixtures = ['users.json', 'election.json'] + allow_database_queries = True def setUp(self): self.election = models.Election.objects.all()[0] - self.election.generate_trustee(ELGAMAL_PARAMS) + self.election.generate_trustee(views.ELGAMAL_PARAMS) def test_instantiate(self): ld_obj = datatypes.LDObject.instantiate(self.election.get_helios_trustee(), '2011/01/Trustee') @@ -334,6 +333,7 @@ class DataFormatBlackboxTests(object): class LegacyElectionBlackboxTests(DataFormatBlackboxTests, TestCase): fixtures = ['legacy-data.json'] + allow_database_queries = True EXPECTED_ELECTION_FILE = 'helios/fixtures/legacy-election-expected.json' EXPECTED_ELECTION_METADATA_FILE = 'helios/fixtures/legacy-election-metadata-expected.json' EXPECTED_VOTERS_FILE = 'helios/fixtures/legacy-election-voters-expected.json' @@ -348,6 +348,13 @@ class LegacyElectionBlackboxTests(DataFormatBlackboxTests, TestCase): # EXPECTED_BALLOTS_FILE = 'helios/fixtures/v3.1-ballots-expected.json' class WebTest(django_webtest.WebTest): + def assertStatusCode(self, response, status_code): + if hasattr(response, 'status_code'): + assert response.status_code == status_code, response.status_code + else: + assert response.status_int == status_code, response.status_int + + def assertRedirects(self, response, url): """ reimplement this in case it's a WebOp response @@ -355,38 +362,23 @@ class WebTest(django_webtest.WebTest): thus the localhost exception """ if hasattr(response, 'location'): - assert url in response.location + assert url in response.location, response.location else: - assert url in response._headers['location'][1] - - if hasattr(response, 'status_code'): - assert response.status_code == 302 - else: - assert response.status_int == 302 - - #self.assertEqual(response.status_code, 302) - + assert url in response['location'], response['location'] + self.assertStatusCode(response, 302) #return super(django_webtest.WebTest, self).assertRedirects(response, url) - #if hasattr(response, 'status_code') and hasattr(response, 'location'): - - #assert url in response.location, "redirected to %s instead of %s" % (response.location, url) + def assertContains(self, response, text): - if hasattr(response, 'status_code'): - assert response.status_code == 200 -# return super(django_webtest.WebTest, self).assertContains(response, text) - else: - assert response.status_int == 200 + self.assertStatusCode(response, 200) - if hasattr(response, "testbody"): assert text in response.testbody, "missing text %s" % text + elif hasattr(response, "body"): + assert text in response.body, "missing text %s" % text else: - if hasattr(response, "body"): - assert text in response.body, "missing text %s" % text - else: - assert text in response.content, "missing text %s" % text + assert text in response.content, "missing text %s" % text ## @@ -395,31 +387,23 @@ class WebTest(django_webtest.WebTest): class ElectionBlackboxTests(WebTest): fixtures = ['users.json', 'election.json'] + allow_database_queries = True def setUp(self): self.election = models.Election.objects.all()[0] self.user = auth_models.User.objects.get(user_id='ben@adida.net', user_type='google') - def assertContains(self, response, text): - if hasattr(response, 'status_code'): - assert response.status_code == 200 -# return super(django_webtest.WebTest, self).assertContains(response, text) - else: - assert response.status_int == 200 - - - if hasattr(response, "testbody"): - assert text in response.testbody, "missing text %s" % text - else: - if hasattr(response, "body"): - assert text in response.body, "missing text %s" % text - else: - assert text in response.content, "missing text %s" % text - - def setup_login(self): + def setup_login(self, from_scratch=False, **kwargs): + if from_scratch: + # a bogus call to set up the session + self.client.get("/") # set up the session session = self.client.session - session['user'] = {'type': self.user.user_type, 'user_id': self.user.user_id} + if kwargs: + user = auth_models.User.objects.get(**kwargs) + else: + user = self.user + session['user'] = {'type': user.user_type, 'user_id': user.user_id} session.save() # set up the app, too @@ -438,11 +422,11 @@ class ElectionBlackboxTests(WebTest): def test_election_404(self): response = self.client.get("/helios/elections/foobar") - self.assertEquals(response.status_code, 404) + self.assertStatusCode(response, 404) def test_election_bad_trustee(self): response = self.client.get("/helios/t/%s/foobar@bar.com/badsecret" % self.election.short_name) - self.assertEquals(response.status_code, 404) + self.assertStatusCode(response, 404) def test_get_election_shortcut(self): response = self.client.get("/helios/e/%s" % self.election.short_name, follow=True) @@ -491,10 +475,7 @@ class ElectionBlackboxTests(WebTest): self.assertRedirects(response, "/auth/?return_url=/helios/elections/new") def test_election_edit(self): - # a bogus call to set up the session - self.client.get("/") - - self.setup_login() + self.setup_login(from_scratch=True) response = self.client.get("/helios/elections/%s/edit" % self.election.uuid) response = self.client.post("/helios/elections/%s/edit" % self.election.uuid, { "short_name" : self.election.short_name + "-2", @@ -510,14 +491,31 @@ class ElectionBlackboxTests(WebTest): new_election = models.Election.objects.get(uuid = self.election.uuid) self.assertEquals(new_election.short_name, self.election.short_name + "-2") - def _setup_complete_election(self, election_params={}): - "do the setup part of a whole election" + def test_get_election_stats(self): + self.setup_login(from_scratch=True, user_id='mccio@github.com', user_type='google') + response = self.client.get("/helios/stats/", follow=False) + self.assertStatusCode(response, 200) + response = self.client.get("/helios/stats/force-queue", follow=False) + self.assertRedirects(response, "/helios/stats/") + response = self.client.get("/helios/stats/elections", follow=False) + self.assertStatusCode(response, 200) + response = self.client.get("/helios/stats/problem-elections", follow=False) + self.assertStatusCode(response, 200) + response = self.client.get("/helios/stats/recent-votes", follow=False) + self.assertStatusCode(response, 200) + self.clear_login() + response = self.client.get("/helios/stats/", follow=False) + self.assertStatusCode(response, 403) + self.setup_login() + response = self.client.get("/helios/stats/", follow=False) + self.assertStatusCode(response, 403) + self.clear_login() - # a bogus call to set up the session - self.client.get("/") + def _setup_complete_election(self, election_params=None): + "do the setup part of a whole election" # REPLACE with params? - self.setup_login() + self.setup_login(from_scratch=True) # create the election full_election_params = { @@ -532,12 +530,14 @@ class ElectionBlackboxTests(WebTest): } # override with the given - full_election_params.update(election_params) + full_election_params.update(election_params or {}) response = self.client.post("/helios/elections/new", full_election_params) # we are redirected to the election, let's extract the ID out of the URL - election_id = re.search('/elections/([^/]+)/', str(response['Location'])).group(1) + election_id = re.search('/elections/([^/]+)/', str(response['Location'])) + self.assertIsNotNone(election_id, "Election id not found in redirect: %s" % str(response['Location'])) + election_id = election_id.group(1) # helios is automatically added as a trustee @@ -577,7 +577,7 @@ class ElectionBlackboxTests(WebTest): self.assertContains(response, '"uuid": "%s"' % single_voter.uuid) response = self.client.get("/helios/elections/%s/voters/foobar" % election_id) - self.assertEquals(response.status_code, 404) + self.assertStatusCode(response, 404) # add questions response = self.client.post("/helios/elections/%s/save_questions" % election_id, { @@ -670,7 +670,7 @@ class ElectionBlackboxTests(WebTest): # at this point an email should have gone out to the user # at position num_messages after, since that was the len() before we cast this ballot email_message = mail.outbox[len(mail.outbox) - 1] - url = re.search('http://[^/]+(/[^ \n]*)', email_message.body).group(1) + url = re.search('https?://[^/]+(/[^ \n]*)', email_message.body).group(1) # check that we can get at that URL if not need_login: @@ -690,7 +690,7 @@ class ElectionBlackboxTests(WebTest): login_form['password'] = ' ' + password + ' ' login_form.submit() - response = self.app.get(url) + response = self.app.get(url, auto_follow=True) self.assertContains(response, ballot.hash) self.assertContains(response, html_escape(encrypted_vote)) @@ -723,7 +723,7 @@ class ElectionBlackboxTests(WebTest): # check that we can't get the tally yet response = self.client.get("/helios/elections/%s/result" % election_id) - self.assertEquals(response.status_code, 403) + self.assertStatusCode(response, 403) # release response = self.client.post("/helios/elections/%s/release_result" % election_id, { @@ -776,8 +776,7 @@ class ElectionBlackboxTests(WebTest): def test_election_voters_eligibility(self): # create the election - self.client.get("/") - self.setup_login() + self.setup_login(from_scratch=True) response = self.client.post("/helios/elections/new", { "short_name" : "test-eligibility", "name" : "Test Eligibility", @@ -788,7 +787,9 @@ class ElectionBlackboxTests(WebTest): "private_p" : "False", 'csrf_token': self.client.session['csrf_token']}) - election_id = re.match("(.*)/elections/(.*)/view", response['Location']).group(2) + election_id = re.match("(.*)/elections/(.*)/view", str(response['Location'])) + self.assertIsNotNone(election_id, "Election id not found in redirect: %s" % str(response['Location'])) + election_id = election_id.group(2) # update eligiblity response = self.client.post("/helios/elections/%s/voters/eligibility" % election_id, { diff --git a/helios/url_names.py b/helios/url_names.py new file mode 100644 index 0000000000000000000000000000000000000000..319a9be5bd72a11144e4917823e3433b378d405a --- /dev/null +++ b/helios/url_names.py @@ -0,0 +1,27 @@ +from helios import election_url_names as election, stats_url_names as stats + +__all__ = [ + "election", "stats", + "COOKIE_TEST", "COOKIE_TEST_2", "COOKIE_NO", + "ELECTION_SHORTCUT", "ELECTION_SHORTCUT_VOTE", "CAST_VOTE_SHORTCUT", + "TRUSTEE_LOGIN", + "ELECTIONS_PARAMS", "ELECTIONS_VERIFIER", "ELECTIONS_VERIFIER_SINGLE_BALLOT", + "ELECTIONS_NEW", "ELECTIONS_ADMINISTERED", "ELECTIONS_VOTED", +] + +COOKIE_TEST="cookie@test" +COOKIE_TEST_2="cookie@test2" +COOKIE_NO="cookie@no" + +ELECTION_SHORTCUT="shortcut@election" +ELECTION_SHORTCUT_VOTE="shortcut@election@vote" +CAST_VOTE_SHORTCUT="shortcut@vote" + +TRUSTEE_LOGIN="trustee@login" + +ELECTIONS_PARAMS="elections@params" +ELECTIONS_VERIFIER="elections@verifier" +ELECTIONS_VERIFIER_SINGLE_BALLOT="elections@verifier@single-ballot" +ELECTIONS_NEW="elections@new" +ELECTIONS_ADMINISTERED="elections@administered" +ELECTIONS_VOTED="elections@voted" diff --git a/helios/urls.py b/helios/urls.py index 8effba1727a9bbd7623471c2c70f00ae43dff62e..6d278a9d195f17b169f4d7f126ef32ed3c012c61 100644 --- a/helios/urls.py +++ b/helios/urls.py @@ -1,35 +1,34 @@ # -*- coding: utf-8 -*- -from django.conf.urls import patterns, include +from django.conf.urls import url, include -from views import * +import url_names as names +import views -urlpatterns = patterns('', - (r'^autologin$', admin_autologin), - (r'^testcookie$', test_cookie), - (r'^testcookie_2$', test_cookie_2), - (r'^nocookies$', nocookies), - (r'^stats/', include('helios.stats_urls')), +urlpatterns = [ + url(r'^autologin$', views.admin_autologin), + url(r'^testcookie$', views.test_cookie, name=names.COOKIE_TEST), + url(r'^testcookie_2$', views.test_cookie_2, name=names.COOKIE_TEST_2), + url(r'^nocookies$', views.nocookies, name=names.COOKIE_NO), + url(r'^stats/', include('helios.stats_urls')), # election shortcut by shortname - (r'^e/(?P<election_short_name>[^/]+)$', election_shortcut), - (r'^e/(?P<election_short_name>[^/]+)/vote$', election_vote_shortcut), + url(r'^e/(?P<election_short_name>[^/]+)$', views.election_shortcut, name=names.ELECTION_SHORTCUT), + url(r'^e/(?P<election_short_name>[^/]+)/vote$', views.election_vote_shortcut, name=names.ELECTION_SHORTCUT_VOTE), # vote shortcut - (r'^v/(?P<vote_tinyhash>[^/]+)$', castvote_shortcut), + url(r'^v/(?P<vote_tinyhash>[^/]+)$', views.castvote_shortcut, name=names.CAST_VOTE_SHORTCUT), # trustee login - (r'^t/(?P<election_short_name>[^/]+)/(?P<trustee_email>[^/]+)/(?P<trustee_secret>[^/]+)$', trustee_login), + url(r'^t/(?P<election_short_name>[^/]+)/(?P<trustee_email>[^/]+)/(?P<trustee_secret>[^/]+)$', views.trustee_login, + name=names.TRUSTEE_LOGIN), # election - (r'^elections/params$', election_params), - (r'^elections/verifier$', election_verifier), - (r'^elections/single_ballot_verifier$', election_single_ballot_verifier), - (r'^elections/new$', election_new), - (r'^elections/administered$', elections_administered), - (r'^elections/voted$', elections_voted), + url(r'^elections/params$', views.election_params, name=names.ELECTIONS_PARAMS), + url(r'^elections/verifier$', views.election_verifier, name=names.ELECTIONS_VERIFIER), + url(r'^elections/single_ballot_verifier$', views.election_single_ballot_verifier, name=names.ELECTIONS_VERIFIER_SINGLE_BALLOT), + url(r'^elections/new$', views.election_new, name=names.ELECTIONS_NEW), + url(r'^elections/administered$', views.elections_administered, name=names.ELECTIONS_ADMINISTERED), + url(r'^elections/voted$', views.elections_voted, name=names.ELECTIONS_VOTED), - (r'^elections/(?P<election_uuid>[^/]+)', include('helios.election_urls')), - -) - - + url(r'^elections/(?P<election_uuid>[^/]+)', include('helios.election_urls')), +] diff --git a/helios/view_utils.py b/helios/view_utils.py index 3e3fb5a81461e0616af9b9ac2b937b2196071924..26da7046c50d1f6c8d62e256cd67175f76cf141f 100644 --- a/helios/view_utils.py +++ b/helios/view_utils.py @@ -4,22 +4,16 @@ Utilities for all views Ben Adida (12-30-2008) """ -from django.template import Context, Template, loader -from django.http import HttpResponse, Http404 +from django.conf import settings +from django.http import HttpResponse from django.shortcuts import render_to_response - -import utils - -from helios import datatypes - +from django.template import loader # nicely update the wrapper function from functools import update_wrapper -from helios_auth.security import get_user - import helios - -from django.conf import settings +import utils +from helios_auth.security import get_user ## ## BASICS @@ -33,14 +27,14 @@ FAILURE = HttpResponse("FAILURE") ## ## template abstraction ## -def prepare_vars(request, vars): - vars_with_user = vars.copy() +def prepare_vars(request, values): + vars_with_user = values.copy() if values is not None else {} vars_with_user['user'] = get_user(request) - + # csrf protection if request.session.has_key('csrf_token'): vars_with_user['csrf_token'] = request.session['csrf_token'] - + vars_with_user['utils'] = utils vars_with_user['settings'] = settings vars_with_user['HELIOS_STATIC'] = '/static/helios/helios' @@ -50,32 +44,32 @@ def prepare_vars(request, vars): return vars_with_user -def render_template(request, template_name, vars = {}, include_user=True): - t = loader.get_template(template_name + '.html') - - vars_with_user = prepare_vars(request, vars) - + +def render_template(request, template_name, values = None, include_user=True): + vars_with_user = prepare_vars(request, values) + if not include_user: del vars_with_user['user'] - + return render_to_response('helios/templates/%s.html' % template_name, vars_with_user) - -def render_template_raw(request, template_name, vars={}): + + +def render_template_raw(request, template_name, values=None): t = loader.get_template(template_name) - + # if there's a request, prep the vars, otherwise can't do it. if request: - full_vars = prepare_vars(request, vars) + full_vars = prepare_vars(request, values) else: - full_vars = vars + full_vars = values or {} - c = Context(full_vars) - return t.render(c) + return t.render(context=full_vars, request=request) def render_json(json_txt): return HttpResponse(json_txt, "application/json") + # decorator def return_json(func): """ @@ -92,4 +86,3 @@ def return_json(func): raise e return update_wrapper(convert_to_json,func) - diff --git a/helios/views.py b/helios/views.py index 3337459fae6dd93048807f7982f194873a2cc552..b62f6eebf73f14a748fdcd84a61d109394fb263d 100644 --- a/helios/views.py +++ b/helios/views.py @@ -5,7 +5,7 @@ Helios Django Views Ben Adida (ben@adida.net) """ -from django.core.urlresolvers import reverse +from django.urls import reverse from django.core.paginator import Paginator from django.core.exceptions import PermissionDenied from django.http import HttpResponse, Http404, HttpResponseRedirect, HttpResponseForbidden @@ -18,12 +18,13 @@ import urllib, os, base64 from crypto import algs, electionalgs, elgamal from crypto import utils as cryptoutils from workflows import homomorphic -from helios import utils, VOTERS_EMAIL, VOTERS_UPLOAD +from helios import utils, VOTERS_EMAIL, VOTERS_UPLOAD, url_names from view_utils import SUCCESS, FAILURE, return_json, render_template, render_template_raw from helios_auth.security import check_csrf, login_required, get_user, save_in_session_across_logouts from helios_auth.auth_systems import AUTH_SYSTEMS, can_list_categories from helios_auth.models import AuthenticationExpired +import helios_auth.url_names as helios_auth_urls from helios_auth import views as auth_views @@ -57,16 +58,16 @@ ELGAMAL_PARAMS_LD_OBJECT = datatypes.LDObject.instantiate(ELGAMAL_PARAMS, dataty from django.conf import settings def get_election_url(election): - return settings.URL_HOST + reverse(election_shortcut, args=[election.short_name]) + return settings.URL_HOST + reverse(url_names.ELECTION_SHORTCUT, args=[election.short_name]) def get_election_badge_url(election): - return settings.URL_HOST + reverse(election_badge, args=[election.uuid]) + return settings.URL_HOST + reverse(url_names.election.ELECTION_BADGE, args=[election.uuid]) def get_election_govote_url(election): - return settings.URL_HOST + reverse(election_vote_shortcut, args=[election.short_name]) + return settings.URL_HOST + reverse(url_names.ELECTION_SHORTCUT_VOTE, args=[election.short_name]) def get_castvote_url(cast_vote): - return settings.URL_HOST + reverse(castvote_shortcut, args=[cast_vote.vote_tinyhash]) + return settings.URL_HOST + reverse(url_names.CAST_VOTE_SHORTCUT, args=[cast_vote.vote_tinyhash]) ## @@ -76,7 +77,7 @@ def user_reauth(request, user): # FIXME: should we be wary of infinite redirects here, and # add a parameter to prevent it? Maybe. login_url = "%s%s?%s" % (settings.SECURE_URL_HOST, - reverse(auth_views.start, args=[user.user_type]), + reverse(helios_auth_urls.AUTH_START, args=[user.user_type]), urllib.urlencode({'return_url': request.get_full_path()})) return HttpResponseRedirect(login_url) @@ -116,16 +117,16 @@ def election_single_ballot_verifier(request): def election_shortcut(request, election_short_name): election = Election.get_by_short_name(election_short_name) if election: - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(one_election_view, args=[election.uuid])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_VIEW, args=[election.uuid])) else: raise Http404 # a hidden view behind the shortcut that performs the actual perm check @election_view() def _election_vote_shortcut(request, election): - vote_url = "%s/booth/vote.html?%s" % (settings.SECURE_URL_HOST, urllib.urlencode({'election_url' : reverse(one_election, args=[election.uuid])})) + vote_url = "%s/booth/vote.html?%s" % (settings.SECURE_URL_HOST, urllib.urlencode({'election_url' : reverse(url_names.election.ELECTION_HOME, args=[election.uuid])})) - test_cookie_url = "%s?%s" % (reverse(test_cookie), urllib.urlencode({'continue_url' : vote_url})) + test_cookie_url = "%s?%s" % (reverse(url_names.COOKIE_TEST), urllib.urlencode({'continue_url' : vote_url})) return HttpResponseRedirect(test_cookie_url) @@ -208,7 +209,7 @@ def election_new(request): try: election = Election.objects.create(**election_params) election.generate_trustee(ELGAMAL_PARAMS) - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(one_election_view, args=[election.uuid])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_VIEW, args=[election.uuid])) except IntegrityError: error = "An election with short name %s already exists" % election_params['short_name'] else: @@ -241,7 +242,7 @@ def one_election_edit(request, election): setattr(election, attr_name, clean_data[attr_name]) try: election.save() - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(one_election_view, args=[election.uuid])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_VIEW, args=[election.uuid])) except IntegrityError: error = "An election with short name %s already exists" % clean_data['short_name'] @@ -264,7 +265,7 @@ def one_election_extend(request, election): election.voting_extended_until = clean_data['voting_extended_until'] election.save() - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(one_election_view, args=[election.uuid])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_VIEW, args=[election.uuid])) return render_template(request, "election_extend", {'election_form' : election_form, 'election' : election}) @@ -303,9 +304,9 @@ def one_election_view(request, election): election_badge_url = get_election_badge_url(election) status_update_message = None - vote_url = "%s/booth/vote.html?%s" % (settings.SECURE_URL_HOST, urllib.urlencode({'election_url' : reverse(one_election, args=[election.uuid])})) + vote_url = "%s/booth/vote.html?%s" % (settings.SECURE_URL_HOST, urllib.urlencode({'election_url' : reverse(url_names.election.ELECTION_HOME, args=[election.uuid])})) - test_cookie_url = "%s?%s" % (reverse(test_cookie), urllib.urlencode({'continue_url' : vote_url})) + test_cookie_url = "%s?%s" % (reverse(url_names.COOKIE_TEST), urllib.urlencode({'continue_url' : vote_url})) if user: voter = Voter.get_by_election_and_user(election, user) @@ -352,20 +353,20 @@ def one_election_view(request, election): def test_cookie(request): continue_url = request.GET['continue_url'] request.session.set_test_cookie() - next_url = "%s?%s" % (reverse(test_cookie_2), urllib.urlencode({'continue_url': continue_url})) + next_url = "%s?%s" % (reverse(url_names.COOKIE_TEST_2), urllib.urlencode({'continue_url': continue_url})) return HttpResponseRedirect(settings.SECURE_URL_HOST + next_url) def test_cookie_2(request): continue_url = request.GET['continue_url'] if not request.session.test_cookie_worked(): - return HttpResponseRedirect(settings.SECURE_URL_HOST + ("%s?%s" % (reverse(nocookies), urllib.urlencode({'continue_url': continue_url})))) + return HttpResponseRedirect(settings.SECURE_URL_HOST + ("%s?%s" % (reverse(url_names.COOKIE_NO), urllib.urlencode({'continue_url': continue_url})))) request.session.delete_test_cookie() return HttpResponseRedirect(continue_url) def nocookies(request): - retest_url = "%s?%s" % (reverse(test_cookie), urllib.urlencode({'continue_url' : request.GET['continue_url']})) + retest_url = "%s?%s" % (reverse(url_names.COOKIE_TEST), urllib.urlencode({'continue_url' : request.GET['continue_url']})) return render_template(request, 'nocookies', {'retest_url': retest_url}) ## @@ -399,7 +400,7 @@ def new_trustee(request, election): trustee = Trustee(uuid = str(uuid.uuid1()), election = election, name=name, email=email) trustee.save() - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(list_trustees_view, args=[election.uuid])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_TRUSTEES_VIEW, args=[election.uuid])) @election_admin(frozen=False) def new_trustee_helios(request, election): @@ -407,13 +408,13 @@ def new_trustee_helios(request, election): Make Helios a trustee of the election """ election.generate_trustee(ELGAMAL_PARAMS) - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(list_trustees_view, args=[election.uuid])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_TRUSTEES_VIEW, args=[election.uuid])) @election_admin(frozen=False) def delete_trustee(request, election): trustee = Trustee.get_by_election_and_uuid(election, request.GET['uuid']) trustee.delete() - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(list_trustees_view, args=[election.uuid])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_TRUSTEES_VIEW, args=[election.uuid])) def trustee_login(request, election_short_name, trustee_email, trustee_secret): election = Election.get_by_short_name(election_short_name) @@ -423,7 +424,7 @@ def trustee_login(request, election_short_name, trustee_email, trustee_secret): if trustee: if trustee.secret == trustee_secret: set_logged_in_trustee(request, trustee) - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(trustee_home, args=[election.uuid, trustee.uuid])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_TRUSTEE_HOME, args=[election.uuid, trustee.uuid])) # bad secret or no such trustee raise Http404("Trustee not recognized.") raise Http404("No election {} found.".format(election_short_name)) @@ -432,7 +433,7 @@ def trustee_login(request, election_short_name, trustee_email, trustee_secret): def trustee_send_url(request, election, trustee_uuid): trustee = Trustee.get_by_election_and_uuid(election, trustee_uuid) - url = settings.SECURE_URL_HOST + reverse(trustee_login, args=[election.short_name, trustee.email, trustee.secret]) + url = settings.SECURE_URL_HOST + reverse(url_names.TRUSTEE_LOGIN, args=[election.short_name, trustee.email, trustee.secret]) body = """ @@ -449,7 +450,7 @@ Helios utils.send_email(settings.SERVER_EMAIL, ["%s <%s>" % (trustee.name, trustee.email)], 'your trustee homepage for %s' % election.name, body) logging.info("URL %s " % url) - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(list_trustees_view, args = [election.uuid])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_TRUSTEES_VIEW, args = [election.uuid])) @trustee_check def trustee_home(request, election, trustee): @@ -482,7 +483,7 @@ def trustee_upload_pk(request, election, trustee): # oh well, no message sent pass - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(trustee_home, args=[election.uuid, trustee.uuid])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_TRUSTEE_HOME, args=[election.uuid, trustee.uuid])) ## ## Ballot Management @@ -530,14 +531,14 @@ def one_election_cast(request, election): on a GET, this is a cancellation, on a POST it's a cast """ if request.method == "GET": - return HttpResponseRedirect("%s%s" % (settings.SECURE_URL_HOST, reverse(one_election_view, args = [election.uuid]))) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_VIEW, args = [election.uuid])) user = get_user(request) encrypted_vote = request.POST['encrypted_vote'] save_in_session_across_logouts(request, 'encrypted_vote', encrypted_vote) - return HttpResponseRedirect("%s%s" % (settings.SECURE_URL_HOST, reverse(one_election_cast_confirm, args=[election.uuid]))) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(one_election_cast_confirm, args=[election.uuid])) @election_view(allow_logins=True) def password_voter_login(request, election): @@ -559,7 +560,7 @@ def password_voter_login(request, election): # if user logged in somehow in the interim, e.g. using the login link for administration, # then go! if user_can_see_election(request, election): - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(one_election_view, args = [election.uuid])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_VIEW, args = [election.uuid])) password_login_form = forms.VoterPasswordForm() return render_template(request, 'password_voter_login', @@ -574,7 +575,7 @@ def password_voter_login(request, election): # login depending on whether this is a private election # cause if it's private the login is happening on the front page if election.private_p: - login_url = reverse(password_voter_login, args=[election.uuid]) + login_url = reverse(url_names.election.ELECTION_PASSWORD_VOTER_LOGIN, args=[election.uuid]) else: login_url = reverse(one_election_cast_confirm, args=[election.uuid]) @@ -742,7 +743,7 @@ def one_election_cast_confirm(request, election): # remove the vote from the store del request.session['encrypted_vote'] - return HttpResponseRedirect("%s%s" % (settings.URL_HOST, reverse(one_election_cast_done, args=[election.uuid]))) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(one_election_cast_done, args=[election.uuid])) @election_view() def one_election_cast_done(request, election): @@ -930,7 +931,7 @@ def one_election_set_featured(request, election): election.featured_p = featured_p election.save() - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(one_election_view, args=[election.uuid])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_VIEW, args=[election.uuid])) @election_admin() def one_election_archive(request, election): @@ -944,7 +945,7 @@ def one_election_archive(request, election): election.save() - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(one_election_view, args=[election.uuid])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_VIEW, args=[election.uuid])) @election_admin() def one_election_copy(request, election): @@ -978,7 +979,7 @@ def one_election_copy(request, election): new_election.generate_trustee(ELGAMAL_PARAMS) - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(one_election_view, args=[new_election.uuid])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_VIEW, args=[new_election.uuid])) # changed from admin to view because # anyone can see the questions, the administration aspect is now @@ -1017,7 +1018,7 @@ def one_election_register(request, election): if not voter: voter = _register_voter(election, user) - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(one_election_view, args=[election.uuid])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_VIEW, args=[election.uuid])) @election_admin(frozen=False) def one_election_save_questions(request, election): @@ -1046,7 +1047,7 @@ def one_election_freeze(request, election): election.freeze() if get_user(request): - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(one_election_view, args=[election.uuid])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_VIEW, args=[election.uuid])) else: return SUCCESS @@ -1062,7 +1063,7 @@ def one_election_compute_tally(request, election): tallying is done all at a time now """ if not _check_election_tally_type(election): - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(one_election_view,args=[election.election_id])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_VIEW,args=[election.election_id])) if request.method == "GET": return render_template(request, 'election_compute_tally', {'election': election}) @@ -1077,12 +1078,12 @@ def one_election_compute_tally(request, election): tasks.election_compute_tally.delay(election_id = election.id) - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(one_election_view,args=[election.uuid])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_VIEW,args=[election.uuid])) @trustee_check def trustee_decrypt_and_prove(request, election, trustee): if not _check_election_tally_type(election) or election.encrypted_tally == None: - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(one_election_view,args=[election.uuid])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_VIEW,args=[election.uuid])) return render_template(request, 'trustee_decrypt_and_prove', {'election': election, 'trustee': trustee}) @@ -1131,7 +1132,7 @@ def release_result(request, election): if request.POST.get('send_email', ''): return HttpResponseRedirect("%s?%s" % (settings.SECURE_URL_HOST + reverse(voters_email, args=[election.uuid]),urllib.urlencode({'template': 'result'}))) else: - return HttpResponseRedirect("%s" % (settings.SECURE_URL_HOST + reverse(one_election_view, args=[election.uuid]))) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_VIEW, args=[election.uuid])) # if just viewing the form or the form is not valid return render_template(request, 'release_result', {'election': election}) @@ -1150,7 +1151,7 @@ def combine_decryptions(request, election): election.combine_decryptions() election.save() - return HttpResponseRedirect("%s" % (settings.SECURE_URL_HOST + reverse(one_election_view, args=[election.uuid]))) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_VIEW, args=[election.uuid])) # if just viewing the form or the form is not valid return render_template(request, 'combine_decryptions', {'election': election}) @@ -1158,7 +1159,7 @@ def combine_decryptions(request, election): @election_admin(frozen=True) def one_election_set_result_and_proof(request, election): if election.tally_type != "homomorphic" or election.encrypted_tally == None: - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(one_election_view,args=[election.election_id])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_VIEW, args=[election.election_id])) # FIXME: check csrf @@ -1167,7 +1168,7 @@ def one_election_set_result_and_proof(request, election): election.save() if get_user(request): - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(one_election_view, args=[election.uuid])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_VIEW, args=[election.uuid])) else: return SUCCESS @@ -1326,12 +1327,12 @@ def voters_upload_cancel(request, election): vf.delete() del request.session['voter_file_id'] - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(one_election_view, args=[election.uuid])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_VIEW, args=[election.uuid])) @election_admin(frozen=True) def voters_email(request, election): if not VOTERS_EMAIL: - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(one_election_view, args=[election.uuid])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_VIEW, args=[election.uuid])) TEMPLATES = [ ('vote', 'Time to Vote'), ('simple', 'Simple'), @@ -1408,7 +1409,7 @@ def voters_email(request, election): tasks.voters_email.delay(election_id = election.id, subject_template = subject_template, body_template = body_template, extra_vars = extra_vars, voter_constraints_include = voter_constraints_include, voter_constraints_exclude = voter_constraints_exclude) # this batch process is all async, so we can return a nice note - return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(one_election_view, args=[election.uuid])) + return HttpResponseRedirect(settings.SECURE_URL_HOST + reverse(url_names.election.ELECTION_VIEW, args=[election.uuid])) return render_template(request, "voters_email", { 'email_form': email_form, 'election': election, diff --git a/helios/widgets.py b/helios/widgets.py index 7eff891c13b6601a9bd77c78185e25415463a094..9eff2f435bc1bf7e37cb8174a5bc1a6db12272f1 100644 --- a/helios/widgets.py +++ b/helios/widgets.py @@ -5,8 +5,7 @@ Widget for datetime split, with calendar for date, and drop-downs for times. from django import forms from django.db import models from django.template.loader import render_to_string -from django.forms.widgets import Select, MultiWidget, DateInput, TextInput, Widget -from django.forms.extras.widgets import SelectDateWidget +from django.forms.widgets import Select, MultiWidget, DateInput, TextInput, Widget, SelectDateWidget from time import strftime import re @@ -36,19 +35,20 @@ class SelectTimeWidget(Widget): Also allows user-defined increments for minutes/seconds """ + template_name = '' hour_field = '%s_hour' minute_field = '%s_minute' meridiem_field = '%s_meridiem' twelve_hr = False # Default to 24hr. - + def __init__(self, attrs=None, hour_step=None, minute_step=None, twelve_hr=False): """ hour_step, minute_step, second_step are optional step values for for the range of values for the associated select element twelve_hr: If True, forces the output to be in 12-hr format (rather than 24-hr) """ - self.attrs = attrs or {} - + super(SelectTimeWidget, self).__init__(attrs) + if twelve_hr: self.twelve_hr = True # Do 12hr (rather than 24hr) self.meridiem_val = 'a.m.' # Default to Morning (A.M.) @@ -67,7 +67,7 @@ class SelectTimeWidget(Widget): else: self.minutes = range(0,60) - def render(self, name, value, attrs=None): + def render(self, name, value, attrs=None, renderer=None): try: # try to get time values from a datetime.time object (value) hour_val, minute_val = value.hour, value.minute if self.twelve_hr: @@ -80,7 +80,7 @@ class SelectTimeWidget(Widget): if isinstance(value, basestring): match = RE_TIME.match(value) if match: - time_groups = match.groups(); + time_groups = match.groups() hour_val = int(time_groups[HOURS]) % 24 # force to range(0-24) minute_val = int(time_groups[MINUTES]) @@ -117,7 +117,7 @@ class SelectTimeWidget(Widget): minute_val = u"%.2d" % minute_val hour_choices = [("%.2d"%i, "%.2d"%i) for i in self.hours] - local_attrs = self.build_attrs(id=self.hour_field % id_) + local_attrs = self.build_attrs({'id': self.hour_field % id_}) select_html = Select(choices=hour_choices).render(self.hour_field % name, hour_val, local_attrs) output.append(select_html) @@ -169,6 +169,8 @@ class SplitSelectDateTimeWidget(MultiWidget): This class combines SelectTimeWidget and SelectDateWidget so we have something like SpliteDateTimeWidget (in django.forms.widgets), but with Select elements. """ + template_name = '' + def __init__(self, attrs=None, hour_step=None, minute_step=None, twelve_hr=None, years=None): """ pass all these parameters to their respective widget constructors...""" widgets = (SelectDateWidget(attrs=attrs, years=years), SelectTimeWidget(attrs=attrs, hour_step=hour_step, minute_step=minute_step, twelve_hr=twelve_hr)) @@ -185,13 +187,6 @@ class SplitSelectDateTimeWidget(MultiWidget): return [value.date(), value.time().replace(microsecond=0)] return [None, None] - def format_output(self, rendered_widgets): - """ - Given a list of rendered widgets (as strings), it inserts an HTML - linebreak between them. - - Returns a Unicode string representing the HTML for the whole lot. - """ - rendered_widgets.insert(-1, '<br/>') - return u''.join(rendered_widgets) - + def render(self, name, value, attrs=None, renderer=None): + rendered_widgets = list(widget.render(name, value, attrs=attrs, renderer=renderer) for widget in self.widgets) + return u'<br/>'.join(rendered_widgets) diff --git a/helios/workflows/homomorphic.py b/helios/workflows/homomorphic.py index 63e2d0c42ec1153afac7a6304e3824975be8a646..c3c98eb715482af7421a90e42f3c23c74c71e12f 100644 --- a/helios/workflows/homomorphic.py +++ b/helios/workflows/homomorphic.py @@ -6,11 +6,7 @@ Ben Adida reworked 2011-01-09 """ -from helios.crypto import algs, utils -import logging -import uuid -import datetime -from helios import models +from helios.crypto import algs from . import WorkflowObject class EncryptedAnswer(WorkflowObject): diff --git a/helios_auth/apps.py b/helios_auth/apps.py new file mode 100644 index 0000000000000000000000000000000000000000..7d1472ae311ac4ed3066ab8c76f5603ada1f4814 --- /dev/null +++ b/helios_auth/apps.py @@ -0,0 +1,5 @@ +from django.apps import AppConfig + +class HeliosAuthConfig(AppConfig): + name = 'helios_auth' + verbose_name = "Helios Authentication" diff --git a/helios_auth/auth_systems/cas.py b/helios_auth/auth_systems/cas.py index 8202ad262712f527b8f8896b02b7a2b47b445917..dd4216b5ecc2c3953892332fa49ae8a51b13eeff 100644 --- a/helios_auth/auth_systems/cas.py +++ b/helios_auth/auth_systems/cas.py @@ -5,11 +5,14 @@ Some code borrowed from https://sp.princeton.edu/oit/sdp/CAS/Wiki%20Pages/Python.aspx """ -from django.http import * -from django.core.mail import send_mail +import datetime +import re +import urllib +import urllib2 +import uuid from django.conf import settings - -import sys, os, cgi, urllib, urllib2, re, uuid, datetime +from django.core.mail import send_mail +from django.http import HttpResponseRedirect from xml.etree import ElementTree CAS_EMAIL_DOMAIN = "princeton.edu" @@ -31,11 +34,11 @@ STATUS_UPDATES = False def _get_service_url(): # FIXME current URL - from helios_auth.views import after + from helios_auth import url_names from django.conf import settings - from django.core.urlresolvers import reverse + from django.urls import reverse - return settings.SECURE_URL_HOST + reverse(after) + return settings.SECURE_URL_HOST + reverse(url_names.AUTH_AFTER) def get_auth_url(request, redirect_url): request.session['cas_redirect_url'] = redirect_url diff --git a/helios_auth/auth_systems/clever.py b/helios_auth/auth_systems/clever.py index dcd52d0e522b4bf2039a6d5752dca26090eefa9c..498951f8dbf0e3d60f2460c83d580be0b703bb64 100644 --- a/helios_auth/auth_systems/clever.py +++ b/helios_auth/auth_systems/clever.py @@ -3,14 +3,11 @@ Clever Authentication """ -from django.http import * -from django.core.mail import send_mail +import base64 +import httplib2 +import json +import urllib from django.conf import settings - -import httplib2,json,base64 - -import sys, os, cgi, urllib, urllib2, re - from oauth2client.client import OAuth2WebServerFlow, OAuth2Credentials # some parameters to indicate that status updating is not possible diff --git a/helios_auth/auth_systems/facebookclient/djangofb/default_app/urls.py b/helios_auth/auth_systems/facebookclient/djangofb/default_app/urls.py index 5e793a6ae4a68e8662f45546b6475e5e7eb7a92c..f75d8d258360fc43e12b2343182d89f14a01ef8c 100644 --- a/helios_auth/auth_systems/facebookclient/djangofb/default_app/urls.py +++ b/helios_auth/auth_systems/facebookclient/djangofb/default_app/urls.py @@ -1,7 +1,7 @@ -from django.conf.urls import * +from django.conf.urls import url -urlpatterns = patterns('{{ project }}.{{ app }}.views', - (r'^$', 'canvas'), - # Define other pages you want to create here -) +from views import canvas +urlpatterns = [ + url(r'^$', canvas), +] diff --git a/helios_auth/auth_systems/google.py b/helios_auth/auth_systems/google.py index 7caa32fc2f03e810f2f675b587d37ea01d41cf40..03419915600fe58636ce9e2098a0219075fa804d 100644 --- a/helios_auth/auth_systems/google.py +++ b/helios_auth/auth_systems/google.py @@ -3,14 +3,10 @@ Google Authentication """ -from django.http import * -from django.core.mail import send_mail +import httplib2 +import json from django.conf import settings - -import httplib2,json - -import sys, os, cgi, urllib, urllib2, re - +from django.core.mail import send_mail from oauth2client.client import OAuth2WebServerFlow # some parameters to indicate that status updating is not possible diff --git a/helios_auth/auth_systems/linkedin.py b/helios_auth/auth_systems/linkedin.py index 32b0033c14fc0c3277671470055d91dbd1271556..696eda9836f0c141360d24f00739d8ed66fca95e 100644 --- a/helios_auth/auth_systems/linkedin.py +++ b/helios_auth/auth_systems/linkedin.py @@ -4,7 +4,7 @@ LinkedIn Authentication from oauthclient import client -from django.core.urlresolvers import reverse +from django.urls import reverse from django.http import HttpResponseRedirect from helios_auth import utils diff --git a/helios_auth/auth_systems/openid/util.py b/helios_auth/auth_systems/openid/util.py index 277b92ca18f21b5c9f465701217fe82fdea94c28..1ed33f3be0f82de0f2f9d545a79ccf8b972bd878 100644 --- a/helios_auth/auth_systems/openid/util.py +++ b/helios_auth/auth_systems/openid/util.py @@ -10,7 +10,7 @@ from django.template.context import RequestContext from django.template import loader from django import http from django.core.exceptions import ImproperlyConfigured -from django.core.urlresolvers import reverse as reverseURL +from django.urls import reverse as reverseURL from django.conf import settings diff --git a/helios_auth/auth_systems/password.py b/helios_auth/auth_systems/password.py index f78d9f6a1fffe679570b5f4e3a83837b14e082a5..aadb03fb05e52d9bbe4e9b2d5e8e02933b89590f 100644 --- a/helios_auth/auth_systems/password.py +++ b/helios_auth/auth_systems/password.py @@ -2,17 +2,21 @@ Username/Password Authentication """ -from django.core.urlresolvers import reverse +from django.urls import reverse from django import forms from django.core.mail import send_mail from django.conf import settings from django.http import HttpResponseRedirect +from django.conf.urls import url + +from helios_auth import url_names import logging # some parameters to indicate that status updating is possible STATUS_UPDATES = False - +PASSWORD_LOGIN_URL_NAME = "auth@password@login" +PASSWORD_FORGOTTEN_URL_NAME = "auth@password@forgotten" def create_user(username, password, name = None): from helios_auth.models import User @@ -58,7 +62,7 @@ def password_login_view(request): user = User.get_by_type_and_id('password', username) if password_check(user, password): request.session['password_user_id'] = user.user_id - return HttpResponseRedirect(reverse(after)) + return HttpResponseRedirect(reverse(url_names.AUTH_AFTER)) except User.DoesNotExist: pass error = 'Bad Username or Password' @@ -101,7 +105,7 @@ Your password: %s return HttpResponseRedirect(return_url) def get_auth_url(request, redirect_url = None): - return reverse(password_login_view) + return reverse(PASSWORD_LOGIN_URL_NAME) def get_user_info_after_auth(request): from helios_auth.models import User @@ -125,3 +129,9 @@ def send_message(user_id, user_name, user_info, subject, body): def can_create_election(user_id, user_info): return True + + +urlpatterns = [ + url(r'^password/login', password_login_view, name=PASSWORD_LOGIN_URL_NAME), + url(r'^password/forgot', password_forgotten_view, name=PASSWORD_FORGOTTEN_URL_NAME) +] diff --git a/helios_auth/auth_systems/twitter.py b/helios_auth/auth_systems/twitter.py index 9963f9121d42b3c53edaac0c128f67499d98c761..8739d607ebcb1d85b0b539c8f85eb34cceaa4ce8 100644 --- a/helios_auth/auth_systems/twitter.py +++ b/helios_auth/auth_systems/twitter.py @@ -4,7 +4,8 @@ Twitter Authentication from oauthclient import client -from django.core.urlresolvers import reverse +from django.conf.urls import url +from django.urls import reverse from django.http import HttpResponseRedirect from helios_auth import utils @@ -21,6 +22,7 @@ DM_TOKEN = settings.TWITTER_DM_TOKEN # some parameters to indicate that status updating is possible STATUS_UPDATES = True STATUS_UPDATE_WORDING_TEMPLATE = "Tweet %s" +FOLLOW_VIEW_URL_NAME = "auth@twitter@follow" OAUTH_PARAMS = { 'root_url' : 'https://twitter.com', @@ -70,7 +72,7 @@ def user_needs_intervention(user_id, user_info, token): if friendship: return None - return HttpResponseRedirect(reverse(follow_view)) + return HttpResponseRedirect(reverse(FOLLOW_VIEW_URL_NAME)) def _get_client_by_request(request): access_token = request.session['access_token'] @@ -114,8 +116,8 @@ def follow_view(request): twitter_client = _get_client_by_token(user.token) result = twitter_client.oauth_request('http://api.twitter.com/1/friendships/create.json', args={'screen_name': USER_TO_FOLLOW}, method='POST') - from helios_auth.views import after_intervention - return HttpResponseRedirect(reverse(after_intervention)) + from helios_auth.url_names import AUTH_AFTER_INTERVENTION + return HttpResponseRedirect(reverse(AUTH_AFTER_INTERVENTION)) @@ -125,3 +127,6 @@ def follow_view(request): def can_create_election(user_id, user_info): return True + + +urlpatterns = [url(r'^twitter/follow', follow_view, name=FOLLOW_VIEW_URL_NAME)] \ No newline at end of file diff --git a/helios_auth/auth_systems/yahoo.py b/helios_auth/auth_systems/yahoo.py index 16bc0343cd40b78386a95fb0279c05c02b23f317..5131a19be520301ab4ea6643e88d97015d186d0f 100644 --- a/helios_auth/auth_systems/yahoo.py +++ b/helios_auth/auth_systems/yahoo.py @@ -3,12 +3,8 @@ Yahoo Authentication """ -from django.http import * -from django.core.mail import send_mail from django.conf import settings - -import sys, os, cgi, urllib, urllib2, re -from xml.etree import ElementTree +from django.core.mail import send_mail from openid import view_helpers diff --git a/helios_auth/jsonfield.py b/helios_auth/jsonfield.py index 0104ce496758988f891bf4c29dce64661473507e..34cecf7894487c1141388abe13d5a0934a4ab9dc 100644 --- a/helios_auth/jsonfield.py +++ b/helios_auth/jsonfield.py @@ -4,11 +4,11 @@ taken from http://www.djangosnippets.org/snippets/377/ """ -import datetime, json -from django.db import models -from django.db.models import signals -from django.conf import settings +import json +from django.core.exceptions import ValidationError from django.core.serializers.json import DjangoJSONEncoder +from django.db import models + class JSONField(models.TextField): """ @@ -18,9 +18,6 @@ class JSONField(models.TextField): deserialization_params added on 2011-01-09 to provide additional hints at deserialization time """ - # Used so to_python() is called - __metaclass__ = models.SubfieldBase - def __init__(self, json_type=None, deserialization_params=None, **kwargs): self.json_type = json_type self.deserialization_params = deserialization_params @@ -36,17 +33,21 @@ class JSONField(models.TextField): if isinstance(value, dict) or isinstance(value, list): return value - if value == "" or value == None: + return self.from_db_value(value) + + # noinspection PyUnusedLocal + def from_db_value(self, value, *args, **kwargs): + if value == "" or value is None: return None try: parsed_value = json.loads(value) - except: - raise Exception("not JSON") + except Exception as e: + raise ValidationError("Received value is not JSON", e) if self.json_type and parsed_value: parsed_value = self.json_type.fromJSONDict(parsed_value, **self.deserialization_params) - + return parsed_value # we should never look up by JSON field anyways. @@ -57,7 +58,7 @@ class JSONField(models.TextField): if isinstance(value, basestring): return value - if value == None: + if value is None: return None if self.json_type and isinstance(value, self.json_type): @@ -70,5 +71,4 @@ class JSONField(models.TextField): def value_to_string(self, obj): value = self._get_val_from_obj(obj) - return self.get_db_prep_value(value) - + return self.get_db_prep_value(value, None) diff --git a/helios_auth/models.py b/helios_auth/models.py index b9179958e5bbca1ad7d9eacc4c2264c020fecf4b..fb050d225808599e95459e057f7ff0489e5c1ecf 100644 --- a/helios_auth/models.py +++ b/helios_auth/models.py @@ -6,13 +6,11 @@ GAE Ben Adida (ben@adida.net) """ - from django.db import models -from jsonfield import JSONField -import datetime, logging +from auth_systems import AUTH_SYSTEMS +from jsonfield import JSONField -from auth_systems import AUTH_SYSTEMS, can_check_constraint, can_list_categories # an exception to catch when a user is no longer authenticated class AuthenticationExpired(Exception): @@ -35,7 +33,8 @@ class User(models.Model): class Meta: unique_together = (('user_type', 'user_id'),) - + app_label = 'helios_auth' + @classmethod def _get_type_and_id(cls, user_type, user_id): return "%s:%s" % (user_type, user_id) diff --git a/helios_auth/security/__init__.py b/helios_auth/security/__init__.py index facc0c32d73b225997acb529de57b501de2f8aad..d3c5ac184a160d6790b1f04e8584341919dd3ef5 100644 --- a/helios_auth/security/__init__.py +++ b/helios_auth/security/__init__.py @@ -4,19 +4,16 @@ Generic Security -- for the auth system Ben Adida (ben@adida.net) """ -# nicely update the wrapper function -from functools import update_wrapper - -from django.http import HttpResponse, Http404, HttpResponseRedirect -from django.core.exceptions import * +import uuid from django.conf import settings +from django.core.exceptions import PermissionDenied from django.http import HttpResponseNotAllowed +from django.http import HttpResponseRedirect +# nicely update the wrapper function +from functools import update_wrapper import oauth - -import uuid - -from helios_auth.models import * +from helios_auth.models import User FIELDS_TO_SAVE = 'FIELDS_TO_SAVE' diff --git a/helios_auth/security/oauth.py b/helios_auth/security/oauth.py index 4addf22677a22f19bdc350497ab1fab3746689a1..71676c89f039eebadbb1129081e8e96d2f638ee7 100644 --- a/helios_auth/security/oauth.py +++ b/helios_auth/security/oauth.py @@ -6,7 +6,6 @@ Hacked a bit by Ben Adida (ben@adida.net) so that: - access tokens are looked up with an extra param of consumer """ -import cgi import urllib import time import random @@ -55,7 +54,7 @@ class OAuthConsumer(object): self.secret = secret # OAuthToken is a data type that represents an End User via either an access -# or request token. +# or request token. class OAuthToken(object): # access tokens and request tokens key = None @@ -74,9 +73,9 @@ class OAuthToken(object): # return a token from something like: # oauth_token_secret=digg&oauth_token=digg - @staticmethod + @staticmethod def from_string(s): - params = cgi.parse_qs(s, keep_blank_values=False) + params = urlparse.parse_qs(s, keep_blank_values=False) key = params['oauth_token'][0] secret = params['oauth_token_secret'][0] return OAuthToken(key, secret) @@ -88,11 +87,11 @@ class OAuthToken(object): class OAuthRequest(object): ''' OAuth parameters: - - oauth_consumer_key + - oauth_consumer_key - oauth_token - oauth_signature_method - - oauth_signature - - oauth_timestamp + - oauth_signature + - oauth_timestamp - oauth_nonce - oauth_version ... any additional parameters, as defined by the Service Provider. @@ -101,7 +100,7 @@ class OAuthRequest(object): http_method = HTTP_METHOD http_url = None version = VERSION - + # added by Ben to filter out extra params from header OAUTH_PARAMS = ['oauth_consumer_key', 'oauth_token', 'oauth_signature_method', 'oauth_signature', 'oauth_timestamp', 'oauth_nonce', 'oauth_version'] @@ -173,7 +172,7 @@ class OAuthRequest(object): parts = urlparse.urlparse(self.http_url) url_string = '%s://%s%s' % (parts[0], parts[1], parts[2]) # scheme, netloc, path return url_string - + # set the signature parameter to the result of build_signature def sign_request(self, signature_method, consumer, token): # set the signature method @@ -266,11 +265,11 @@ class OAuthRequest(object): # remove quotes and unescape the value params[param_parts[0]] = urllib.unquote(param_parts[1].strip('\"')) return params - + # util function: turn url string into parameters, has to do some unescaping @staticmethod def _split_url_string(param_str): - parameters = cgi.parse_qs(param_str, keep_blank_values=False) + parameters = urlparse.parse_qs(param_str, keep_blank_values=False) for k, v in parameters.iteritems(): parameters[k] = urllib.unquote(v[0]) return parameters @@ -287,7 +286,7 @@ class OAuthServer(object): self.signature_methods = signature_methods or {} def set_data_store(self, oauth_data_store): - self.data_store = data_store + self.data_store = oauth_data_store def get_data_store(self): return self.data_store @@ -336,12 +335,12 @@ class OAuthServer(object): # authorize a request token def authorize_token(self, token, user): return self.data_store.authorize_request_token(token, user) - + # get the callback url def get_callback(self, oauth_request): return oauth_request.get_parameter('oauth_callback') - # optional support for the authenticate header + # optional support for the authenticate header def build_authenticate_header(self, realm=''): return {'WWW-Authenticate': 'OAuth realm="%s"' % realm} @@ -495,7 +494,7 @@ class OAuthSignatureMethod_HMAC_SHA1(OAuthSignatureMethod): def get_name(self): return 'HMAC-SHA1' - + def build_signature_base_string(self, oauth_request, consumer, token): sig = ( escape(oauth_request.get_normalized_http_method()), diff --git a/helios_auth/south_migrations/0001_initial.py b/helios_auth/south_migrations/0001_initial.py deleted file mode 100644 index 4ba2a3a2b5cfe08fe055f0dd0d5534a798d43f1e..0000000000000000000000000000000000000000 --- a/helios_auth/south_migrations/0001_initial.py +++ /dev/null @@ -1,49 +0,0 @@ -# encoding: utf-8 -import datetime -from south.db import db -from south.v2 import SchemaMigration -from django.db import models - -class Migration(SchemaMigration): - - def forwards(self, orm): - - # Adding model 'User' - db.create_table('helios_auth_user', ( - ('id', self.gf('django.db.models.fields.AutoField')(primary_key=True)), - ('user_type', self.gf('django.db.models.fields.CharField')(max_length=50)), - ('user_id', self.gf('django.db.models.fields.CharField')(max_length=100)), - ('name', self.gf('django.db.models.fields.CharField')(max_length=200, null=True)), - ('info', self.gf('helios_auth.jsonfield.JSONField')()), - ('token', self.gf('helios_auth.jsonfield.JSONField')(null=True)), - ('admin_p', self.gf('django.db.models.fields.BooleanField')(default=False)), - )) - db.send_create_signal('helios_auth', ['User']) - - # Adding unique constraint on 'User', fields ['user_type', 'user_id'] - db.create_unique('helios_auth_user', ['user_type', 'user_id']) - - - def backwards(self, orm): - - # Removing unique constraint on 'User', fields ['user_type', 'user_id'] - db.delete_unique('helios_auth_user', ['user_type', 'user_id']) - - # Deleting model 'User' - db.delete_table('helios_auth_user') - - - models = { - 'helios_auth.user': { - 'Meta': {'unique_together': "(('user_type', 'user_id'),)", 'object_name': 'User'}, - 'admin_p': ('django.db.models.fields.BooleanField', [], {'default': 'False'}), - 'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), - 'info': ('helios_auth.jsonfield.JSONField', [], {}), - 'name': ('django.db.models.fields.CharField', [], {'max_length': '200', 'null': 'True'}), - 'token': ('helios_auth.jsonfield.JSONField', [], {'null': 'True'}), - 'user_id': ('django.db.models.fields.CharField', [], {'max_length': '100'}), - 'user_type': ('django.db.models.fields.CharField', [], {'max_length': '50'}) - } - } - - complete_apps = ['helios_auth'] diff --git a/helios_auth/south_migrations/__init__.py b/helios_auth/south_migrations/__init__.py deleted file mode 100644 index e69de29bb2d1d6434b8b29ae775ad8c2e48c5391..0000000000000000000000000000000000000000 diff --git a/helios_auth/templates/index.html b/helios_auth/templates/index.html index f16a7b80cf80e6362c2b70b5ce264f278cc0934f..3c2e9f8d73595f83e9d61c42cd9cf37145735079 100644 --- a/helios_auth/templates/index.html +++ b/helios_auth/templates/index.html @@ -8,7 +8,7 @@ You are currently logged in as<br /><b>{{user.user_id}}</b> via <b>{{user.user_type}}</b>. </p> <p> - <a href="{% url "helios_auth.views.logout" %}">logout</a> + <a href="{% url "auth@logout" %}">logout</a> </p> {% else %} diff --git a/helios_auth/templates/login_box.html b/helios_auth/templates/login_box.html index 2e89e94e49fb8384d97fe81a8ffed94aa2204f85..27ca7da17aa80df0367db54adc7bf4d4336365f8 100644 --- a/helios_auth/templates/login_box.html +++ b/helios_auth/templates/login_box.html @@ -1,12 +1,12 @@ {% if default_auth_system %} <p> -<a class="small button" href="{% url "helios_auth.views.start" system_name=default_auth_system %}?return_url={{return_url}}">Log in</a></p> +<a class="small button" href="{% url "auth@start" system_name=default_auth_system %}?return_url={{return_url}}">Log in</a></p> {% else %} {% for auth_system in enabled_auth_systems %} {% ifequal auth_system "password" %} {% else %} <p> - <a href="{{SECURE_URL_HOST}}{% url "helios_auth.views.start" system_name=auth_system %}?return_url={{return_url}}" style="font-size: 1.4em;"> + <a href="{{SECURE_URL_HOST}}{% url "auth@start" system_name=auth_system %}?return_url={{return_url}}" style="font-size: 1.4em;"> <img style="height: 35px; border: 0px;" src="/static/auth/login-icons/{{auth_system}}.png" alt="{{auth_system}}" /> {{auth_system}} {% endifequal %} </a> diff --git a/helios_auth/templates/perms_why.html b/helios_auth/templates/perms_why.html index 179d103c27153c17bf45f59e39af2658532d2090..3f38fd18d0b87ac528ee27852730bddf42c4e2e9 100644 --- a/helios_auth/templates/perms_why.html +++ b/helios_auth/templates/perms_why.html @@ -13,7 +13,7 @@ this information, we unfortunately cannot help you vote. </p> <form method="POST" action=""> -<input type="hidden" value="{{csrf_token}}" /> +<input type="hidden" name="csrf_token" value="{{csrf_token}}" /> <input type="submit" value="OK, I understand, let's do this login thing." /><br /><br /> <a href="http://google.com">nope, get me out of here</a>. </form> diff --git a/helios_auth/tests.py b/helios_auth/tests.py index f07f309fb5176007ca67a25ce14c712efc33af35..de21e3b09c600084194a47bd5cd0f73522a74daa 100644 --- a/helios_auth/tests.py +++ b/helios_auth/tests.py @@ -91,7 +91,7 @@ class UserModelTests(unittest.TestCase): import views import auth_systems.password as password_views -from django.core.urlresolvers import reverse +from django.urls import reverse # FIXME: login CSRF should make these tests more complicated # and should be tested for @@ -116,7 +116,7 @@ class UserBlackboxTests(TestCase): # self.assertContains(response, "Foobar User") def test_logout(self): - response = self.client.post(reverse(views.logout), follow=True) + response = self.client.post(reverse("auth@logout"), follow=True) self.assertContains(response, "not logged in") self.assertNotContains(response, "Foobar User") diff --git a/helios_auth/url_names.py b/helios_auth/url_names.py new file mode 100644 index 0000000000000000000000000000000000000000..29f7b228f8363f090f44cf21225a5f6e2595caf1 --- /dev/null +++ b/helios_auth/url_names.py @@ -0,0 +1,6 @@ +AUTH_INDEX="auth@index" +AUTH_LOGOUT="auth@logout" +AUTH_START="auth@start" +AUTH_AFTER="auth@after" +AUTH_WHY="auth@why" +AUTH_AFTER_INTERVENTION="auth@after-intervention" diff --git a/helios_auth/urls.py b/helios_auth/urls.py index 11d10139530db6f84becb2cf5f55326641fb2163..5244e10b8a1e2f07f8ab712c3b8f3997e58bedfa 100644 --- a/helios_auth/urls.py +++ b/helios_auth/urls.py @@ -7,27 +7,27 @@ Ben Adida (ben@adida.net) from django.conf.urls import url +import url_names import views from settings import AUTH_ENABLED_AUTH_SYSTEMS urlpatterns = [ # basic static stuff - url(r'^$', views.index), - url(r'^logout$', views.logout), - url(r'^start/(?P<system_name>.*)$', views.start), + url(r'^$', views.index, name=url_names.AUTH_INDEX), + url(r'^logout$', views.logout, name=url_names.AUTH_LOGOUT), + url(r'^start/(?P<system_name>.*)$', views.start, name=url_names.AUTH_START), # weird facebook constraint for trailing slash - url(r'^after/$', views.after), - url(r'^why$', views.perms_why), - url(r'^after_intervention$', views.after_intervention), + url(r'^after/$', views.after, name=url_names.AUTH_AFTER), + url(r'^why$', views.perms_why, name=url_names.AUTH_WHY), + url(r'^after_intervention$', views.after_intervention, name=url_names.AUTH_AFTER_INTERVENTION), ] # password auth if 'password' in AUTH_ENABLED_AUTH_SYSTEMS: - from auth_systems.password import password_login_view, password_forgotten_view - urlpatterns.append(url(r'^password/login', password_login_view)) - urlpatterns.append(url(r'^password/forgot', password_forgotten_view)) + from auth_systems.password import urlpatterns as password_patterns + urlpatterns.extend(password_patterns) # twitter if 'twitter' in AUTH_ENABLED_AUTH_SYSTEMS: - from auth_systems.twitter import follow_view - urlpatterns.append(url(r'^twitter/follow', follow_view)) + from auth_systems.twitter import urlpatterns as twitter_patterns + urlpatterns.extend(twitter_patterns) diff --git a/helios_auth/view_utils.py b/helios_auth/view_utils.py index 1355ba450b75ff40c0122b42b860751852225479..6699ab28ab5030b4b8703ea4868f5ef1edd22a14 100644 --- a/helios_auth/view_utils.py +++ b/helios_auth/view_utils.py @@ -4,15 +4,13 @@ Utilities for all views Ben Adida (12-30-2008) """ -from django.template import Context, Template, loader -from django.http import HttpResponse, Http404 +from django.conf import settings +from django.http import HttpResponse from django.shortcuts import render_to_response - -from helios_auth.security import get_user +from django.template import loader import helios_auth - -from django.conf import settings +from helios_auth.security import get_user ## ## BASICS @@ -24,37 +22,37 @@ SUCCESS = HttpResponse("SUCCESS") ## template abstraction ## -def prepare_vars(request, vars): - vars_with_user = vars.copy() - +def prepare_vars(request, values): + vars_with_user = values.copy() + if request: vars_with_user['user'] = get_user(request) vars_with_user['csrf_token'] = request.session['csrf_token'] vars_with_user['SECURE_URL_HOST'] = settings.SECURE_URL_HOST - + vars_with_user['STATIC'] = '/static/auth' vars_with_user['MEDIA_URL'] = '/static/auth/' vars_with_user['TEMPLATE_BASE'] = helios_auth.TEMPLATE_BASE - + vars_with_user['settings'] = settings - + return vars_with_user - -def render_template(request, template_name, vars = {}): - t = loader.get_template(template_name + '.html') - - vars_with_user = prepare_vars(request, vars) - + + +def render_template(request, template_name, values=None): + vars_with_user = prepare_vars(request, values or {}) + return render_to_response('helios_auth/templates/%s.html' % template_name, vars_with_user) -def render_template_raw(request, template_name, vars={}): + +def render_template_raw(request, template_name, values=None): t = loader.get_template(template_name + '.html') - - vars_with_user = prepare_vars(request, vars) - c = Context(vars_with_user) - return t.render(c) + values = values or {} -def render_json(json_txt): - return HttpResponse(json_txt) + vars_with_user = prepare_vars(request, values) + + return t.render(context=vars_with_user, request=request) +def render_json(json_txt): + return HttpResponse(json_txt) diff --git a/helios_auth/views.py b/helios_auth/views.py index b85f82e797192295cc9118dff36000b8ed6010cf..f246dafd582ef696d6ba2351fad93d507f7924eb 100644 --- a/helios_auth/views.py +++ b/helios_auth/views.py @@ -5,22 +5,20 @@ Ben Adida 2009-07-05 """ -from django.http import * -from django.core.urlresolvers import reverse +import urllib +from django.urls import reverse +from django.http import HttpResponseRedirect, HttpResponse -from view_utils import * -from helios_auth.security import get_user - -import auth_systems +import helios_auth +import settings from auth_systems import AUTH_SYSTEMS from auth_systems import password -import helios_auth - -import copy, urllib - +from helios_auth.security import get_user +from helios_auth.url_names import AUTH_INDEX, AUTH_START, AUTH_AFTER, AUTH_WHY, AUTH_AFTER_INTERVENTION from models import User - from security import FIELDS_TO_SAVE +from view_utils import render_template, render_template_raw + def index(request): """ @@ -31,7 +29,7 @@ def index(request): # single auth system? if len(helios_auth.ENABLED_AUTH_SYSTEMS) == 1 and not user: - return HttpResponseRedirect(reverse(start, args=[helios_auth.ENABLED_AUTH_SYSTEMS[0]])+ '?return_url=' + request.GET.get('return_url', '')) + return HttpResponseRedirect(reverse(AUTH_START, args=[helios_auth.ENABLED_AUTH_SYSTEMS[0]])+ '?return_url=' + request.GET.get('return_url', '')) #if helios_auth.DEFAULT_AUTH_SYSTEM and not user: # return HttpResponseRedirect(reverse(start, args=[helios_auth.DEFAULT_AUTH_SYSTEM])+ '?return_url=' + request.GET.get('return_url', '')) @@ -42,10 +40,10 @@ def index(request): #form = password.LoginForm() - return render_template(request,'index', {'return_url' : request.GET.get('return_url', '/'), - 'enabled_auth_systems' : helios_auth.ENABLED_AUTH_SYSTEMS, - 'default_auth_system': helios_auth.DEFAULT_AUTH_SYSTEM, - 'default_auth_system_obj': default_auth_system_obj}) + return render_template(request, 'index', {'return_url' : request.GET.get('return_url', '/'), + 'enabled_auth_systems' : helios_auth.ENABLED_AUTH_SYSTEMS, + 'default_auth_system': helios_auth.DEFAULT_AUTH_SYSTEM, + 'default_auth_system_obj': default_auth_system_obj}) def login_box_raw(request, return_url='/', auth_systems = None): """ @@ -56,7 +54,7 @@ def login_box_raw(request, return_url='/', auth_systems = None): default_auth_system_obj = AUTH_SYSTEMS[helios_auth.DEFAULT_AUTH_SYSTEM] # make sure that auth_systems includes only available and enabled auth systems - if auth_systems != None: + if auth_systems is not None: enabled_auth_systems = set(auth_systems).intersection(set(helios_auth.ENABLED_AUTH_SYSTEMS)).intersection(set(AUTH_SYSTEMS.keys())) else: enabled_auth_systems = set(helios_auth.ENABLED_AUTH_SYSTEMS).intersection(set(AUTH_SYSTEMS.keys())) @@ -87,7 +85,7 @@ def do_local_logout(request): # let's clean up the self-referential issue: field_names_to_save = set(field_names_to_save) - field_names_to_save = field_names_to_save - set([FIELDS_TO_SAVE]) + field_names_to_save = field_names_to_save - {FIELDS_TO_SAVE} field_names_to_save = list(field_names_to_save) fields_to_save = dict([(name, request.session.get(name, None)) for name in field_names_to_save]) @@ -144,7 +142,7 @@ def _do_auth(request): system = AUTH_SYSTEMS[system_name] # where to send the user to? - redirect_url = "%s%s" % (settings.SECURE_URL_HOST,reverse(after)) + redirect_url = settings.SECURE_URL_HOST + reverse(AUTH_AFTER) auth_url = system.get_auth_url(request, redirect_url=redirect_url) if auth_url: @@ -154,7 +152,7 @@ def _do_auth(request): def start(request, system_name): if not (system_name in helios_auth.ENABLED_AUTH_SYSTEMS): - return HttpResponseRedirect(reverse(index)) + return HttpResponseRedirect(reverse(AUTH_INDEX)) # why is this here? Let's try without it # request.session.save() @@ -190,7 +188,7 @@ def after(request): request.session['user'] = user else: - return HttpResponseRedirect("%s?%s" % (reverse(perms_why), urllib.urlencode({'system_name' : request.session['auth_system_name']}))) + return HttpResponseRedirect("%s?%s" % (reverse(AUTH_WHY), urllib.urlencode({'system_name' : request.session['auth_system_name']}))) # does the auth system want to present an additional view? # this is, for example, to prompt the user to follow @heliosvoting @@ -201,12 +199,12 @@ def after(request): return intervention_response # go to the after intervention page. This is for modularity - return HttpResponseRedirect(reverse(after_intervention)) + return HttpResponseRedirect(reverse(AUTH_AFTER_INTERVENTION)) def after_intervention(request): return_url = "/" if request.session.has_key('auth_return_url'): return_url = request.session['auth_return_url'] del request.session['auth_return_url'] - return HttpResponseRedirect("%s%s" % (settings.URL_HOST, return_url)) + return HttpResponseRedirect(settings.URL_HOST + return_url) diff --git a/requirements.txt b/requirements.txt index 237e75c98c2c3ecb7659d3d44a4c079030515fbc..8e69fb261c4417d9c3c41cdd8a10c8911ecb4713 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,9 +1,8 @@ -Django==1.8.19 +Django==1.11.28 anyjson==0.3.3 -celery==3.1.18 -django-celery==3.1.16 +celery==4.2.1 django-picklefield==0.3.0 -kombu==3.0.30 +kombu==4.2.0 html5lib==0.999 psycopg2==2.7.3.2 pyparsing==1.5.7 @@ -14,10 +13,8 @@ gunicorn==19.9 requests==2.21.0 unicodecsv==0.9.0 dj_database_url==0.3.0 -django-sslify==0.2.7 django_webtest>=1.9 webtest==2.0.18 -django-secure==1.0.1 bleach==1.4.1 boto==2.27.0 django-ses==0.6.0 diff --git a/reset.sh b/reset.sh index 52141e13601899518420a971142f26d30f772ab2..8192723eefa08a4af0b4092f341e7bf3e6cd758e 100755 --- a/reset.sh +++ b/reset.sh @@ -2,6 +2,6 @@ set -e # Exit immediately if a command exits with a non-zero status. dropdb helios createdb helios -python manage.py syncdb +python manage.py makemigrations python manage.py migrate echo "from helios_auth.models import User; User.objects.create(user_type='google',user_id='ben@adida.net', info={'name':'Ben Adida'})" | python manage.py shell \ No newline at end of file diff --git a/server_ui/__init__.py b/server_ui/__init__.py index bb89b654f886d6c945b7212738cfa15717e54ea3..3f1966c404ae56875aebbb86b13e1d65e43788f6 100644 --- a/server_ui/__init__.py +++ b/server_ui/__init__.py @@ -1,5 +1,3 @@ """ This django app is meant only to connect the pieces of Helios and Auth to present a clean UI """ - -import glue diff --git a/server_ui/glue.py b/server_ui/glue.py index 9b3b5b37ba54c7de399c820d274e131374029184..12b64b1ec35bfc3a777d2fdb4f03b5ce2ec191ff 100644 --- a/server_ui/glue.py +++ b/server_ui/glue.py @@ -2,36 +2,35 @@ Glue some events together """ -from django.conf import settings -from django.core.urlresolvers import reverse -from django.conf import settings +import helios.signals +import helios.views from helios.view_utils import render_template_raw -import helios.views, helios.signals -import views def vote_cast_send_message(user, voter, election, cast_vote, **kwargs): - ## FIXME: this doesn't work for voters that are not also users - # prepare the message - subject_template = 'email/cast_vote_subject.txt' - body_template = 'email/cast_vote_body.txt' - - extra_vars = { - 'election' : election, - 'voter': voter, - 'cast_vote': cast_vote, - 'cast_vote_url': helios.views.get_castvote_url(cast_vote), - 'custom_subject' : "%s - vote cast" % election.name - } - subject = render_template_raw(None, subject_template, extra_vars) - body = render_template_raw(None, body_template, extra_vars) - - # send it via the notification system associated with the auth system - user.send_message(subject, body) - -helios.signals.vote_cast.connect(vote_cast_send_message) + ## FIXME: this doesn't work for voters that are not also users + # prepare the message + subject_template = 'email/cast_vote_subject.txt' + body_template = 'email/cast_vote_body.txt' + + extra_vars = { + 'election': election, + 'voter': voter, + 'cast_vote': cast_vote, + 'cast_vote_url': helios.views.get_castvote_url(cast_vote), + 'custom_subject': "%s - vote cast" % election.name + } + subject = render_template_raw(None, subject_template, extra_vars) + body = render_template_raw(None, body_template, extra_vars) + + # send it via the notification system associated with the auth system + user.send_message(subject, body) + def election_tallied(election, **kwargs): - pass + pass + -helios.signals.election_tallied.connect(election_tallied) +def glue(): + helios.signals.vote_cast.connect(vote_cast_send_message) + helios.signals.election_tallied.connect(election_tallied) diff --git a/server_ui/templates/base.html b/server_ui/templates/base.html index ac5f2d13cc11ccd1a60456482fe5199d985e7476..8357be2aaa31636509e32c51609ce92f8d0b3801 100644 --- a/server_ui/templates/base.html +++ b/server_ui/templates/base.html @@ -42,7 +42,7 @@ <!-- Right Nav Section --> <ul class="right"> {% if user and user.admin_p %} - <li><a href="{% url "helios.stats_views.home" %}">Admin</a></li> + <li><a href="{% url "stats@home" %}">Admin</a></li> <li class="divider"></li> {% endif %} {% if not settings.MASTER_HELIOS %} @@ -88,13 +88,13 @@ </span>--> {% if user %} logged in as <b>{{user.display_html_small|safe}}</b> - <a class="tiny button" href="{% url "helios_auth.views.logout" %}?return_url={{CURRENT_URL}}">logout</a><br /> + <a class="tiny button" href="{% url "auth@logout" %}?return_url={{CURRENT_URL}}">logout</a><br /> {% else %} {% if voter %} - You are signed in as voter <u>{% if voter.alias %}{{voter.alias}}{% else %}{{voter.name}}{% endif %}</u> in election <u>{{voter.election.name}}</u>. [<a href="{{settings.SECURE_URL_HOST}}{% url "helios_auth.views.logout" %}?return_url={{CURRENT_URL}}">sign out</a>] + You are signed in as voter <u>{% if voter.alias %}{{voter.alias}}{% else %}{{voter.name}}{% endif %}</u> in election <u>{{voter.election.name}}</u>. [<a href="{{settings.SECURE_URL_HOST}}{% url "auth@logout" %}?return_url={{CURRENT_URL}}">sign out</a>] {% else %} {% if settings.SHOW_LOGIN_OPTIONS %} - not logged in. <a class="tiny button" href="{{settings.SECURE_URL_HOST}}{% url "helios_auth.views.index" %}?return_url={{CURRENT_URL}}">log in</a> + not logged in. <a class="tiny button" href="{{settings.SECURE_URL_HOST}}{% url "auth@index" %}?return_url={{CURRENT_URL}}">log in</a> {% else %} powered by <a href="http://heliosvoting.org">Helios Voting</a>. {% endif %} diff --git a/server_ui/templates/confirm.html b/server_ui/templates/confirm.html index d98f65fef5c7e46b9e480cb206ea8dd6408a06b6..2f24a807a0ae1854a5f2b8207c037d3b8a6c74d0 100644 --- a/server_ui/templates/confirm.html +++ b/server_ui/templates/confirm.html @@ -38,7 +38,7 @@ function show_waiting() { </form> <p> - Forgot your password? <a href="{% url "helios_auth.auth_systems.password.password_forgotten_view" %}?return_url={% url "server_ui.views.cast_confirm" %}">Have it emailed to you</a>.<br />(don't worry, we won't forget your vote). + Forgot your password? <a href="{% url "auth@password@forgotten" %}?return_url={% url "election@cast-confirm" %}">Have it emailed to you</a>.<br />(don't worry, we won't forget your vote). </p> </div> diff --git a/server_ui/templates/done.html b/server_ui/templates/done.html index 47ff73fa6023c847ea8fb2425c5bfc56b01d36d2..d4281060f7f16cef56798f82a06788da99467ddb 100644 --- a/server_ui/templates/done.html +++ b/server_ui/templates/done.html @@ -11,7 +11,7 @@ </p> <p> - Visit the <a href="{% url "helios.views.one_election_view" election.uuid %}">election homepage</a>. + Visit the <a href="{% url "election@view" election.uuid %}">election homepage</a>. </p> {% endblock %} diff --git a/server_ui/templates/election_tallied.html b/server_ui/templates/election_tallied.html index 747e083fc3d4ed3433000fd8b1edf5f41bd7364d..42d44410f9b298eecc3c429b7eca9bcf98aaaf69 100644 --- a/server_ui/templates/election_tallied.html +++ b/server_ui/templates/election_tallied.html @@ -9,6 +9,6 @@ </p> <p> - <a href="{% url "helios.views.one_election_view" election.uuid %}">view the election</a> + <a href="{% url "election@view" election.uuid %}">view the election</a> </p> {% endblock %} \ No newline at end of file diff --git a/server_ui/templates/index.html b/server_ui/templates/index.html index e31ac19e9c3fa5bc425c623c5e5fe6d7b946cc38..4b1fcec8f7cb672a02569e02a01ff4efefa99d90 100644 --- a/server_ui/templates/index.html +++ b/server_ui/templates/index.html @@ -28,7 +28,7 @@ More than <b>2,000,000 votes</b> have been cast using Helios. </p> {% if create_p %} -<a class="button" href="{% url "helios.views.election_new" %}">create an election</a> +<a class="button" href="{% url "elections@new" %}">create an election</a> {% endif %} {% else %} @@ -40,7 +40,7 @@ More than <b>2,000,000 votes</b> have been cast using Helios. <p> {% for election in elections %} <div class="panel"> - <a style="font-size: 1.4em;" href="{% url "helios.views.election_shortcut" election.short_name %}">{{election.name}}</a>{% if settings.SHOW_USER_INFO %}<br /> by {{election.admin.display_html_small|safe}}{% endif %} + <a style="font-size: 1.4em;" href="{% url "shortcut@election" election.short_name %}">{{election.name}}</a>{% if settings.SHOW_USER_INFO %}<br /> by {{election.admin.display_html_small|safe}}{% endif %} </div> <br /> {% endfor %} @@ -58,19 +58,19 @@ More than <b>2,000,000 votes</b> have been cast using Helios. {% if user %} <!--<div class="row right">{{user.display_html_big|safe}}</div>--> {% if create_p %} -<a class="small button" href="{% url "helios.views.election_new" %}">create election</a> +<a class="small button" href="{% url "elections@new" %}">create election</a> <h5 class="subheader">Administration</h5> {% if elections_administered %} <ul> {% for election in elections_administered %} -<li> <a href="{% url "helios.views.one_election_view" election.uuid %}">{{election.name}}</a></li> +<li> <a href="{% url "election@view" election.uuid %}">{{election.name}}</a></li> {% endfor %} </ul> {% else %} <em>none yet</em> {% endif %} <div class="row right"> -<a class="tiny button" href="{% url "helios.views.elections_administered" %}">see all</a> +<a class="tiny button" href="{% url "elections@administered" %}">see all</a> </div> <div class="row"></div> {% endif %} @@ -79,13 +79,13 @@ More than <b>2,000,000 votes</b> have been cast using Helios. {% if elections_voted %} <ul> {% for election in elections_voted %} -<li><a href="{% url "helios.views.one_election_view" election.uuid %}">{{election.name}}</a></li> +<li><a href="{% url "election@view" election.uuid %}">{{election.name}}</a></li> {% endfor %} </ul> {% else %} <em>none yet</em> {% endif %} -<div class="row right"><a class="tiny button" href="{% url "helios.views.elections_voted" %}">see all</a></div> +<div class="row right"><a class="tiny button" href="{% url "elections@voted" %}">see all</a></div> <div class="row"></div> {% else %} {% if settings.SHOW_LOGIN_OPTIONS %} diff --git a/server_ui/urls.py b/server_ui/urls.py index 0711bd7c15047d880c8d3d18926aceea00e338b4..e691c07afe7b29c0b347e5bde5ea75e9addd65c7 100644 --- a/server_ui/urls.py +++ b/server_ui/urls.py @@ -1,12 +1,12 @@ # -*- coding: utf-8 -*- -from django.conf.urls import patterns +from django.conf.urls import url from views import home, about, docs, faq, privacy -urlpatterns = patterns('', - (r'^$', home), - (r'^about$', about), - (r'^docs$', docs), - (r'^faq$', faq), - (r'^privacy$', privacy), -) +urlpatterns = [ + url(r'^$', home), + url(r'^about$', about), + url(r'^docs$', docs), + url(r'^faq$', faq), + url(r'^privacy$', privacy), +] diff --git a/server_ui/view_utils.py b/server_ui/view_utils.py index e22fcd5bc6beae9bef9e10eb6accf402b3998b7b..df947214620fc0169b9569767a84e633cd0e7615 100644 --- a/server_ui/view_utils.py +++ b/server_ui/view_utils.py @@ -4,21 +4,17 @@ Utilities for single election views Ben Adida (2009-07-18) """ -from django.template import Context, Template, loader -from django.http import HttpResponse, Http404 +from django.conf import settings from django.shortcuts import render_to_response from helios_auth.security import get_user -from django.conf import settings ## ## template abstraction ## -def render_template(request, template_name, vars = {}): - t = loader.get_template(template_name + '.html') - - vars_with_user = vars.copy() +def render_template(request, template_name, values = None): + vars_with_user = values.copy() if values is not None else {} vars_with_user['user'] = get_user(request) vars_with_user['settings'] = settings vars_with_user['CURRENT_URL'] = request.path diff --git a/server_ui/views.py b/server_ui/views.py index a4fe09513b9e07972fdf3ae286e463f130174580..190d902aa71f4c0722ed68a787055a4f978ba7c8 100644 --- a/server_ui/views.py +++ b/server_ui/views.py @@ -2,23 +2,19 @@ server_ui specific views """ -from helios.models import * -from helios_auth.security import * -from view_utils import * +import copy +from django.conf import settings -import helios.views -import helios -from helios.crypto import utils as cryptoutils -from helios_auth.security import * +import helios_auth.views as auth_views +from helios.models import Election from helios.security import can_create_election +from helios_auth.security import get_user +from view_utils import render_template +import glue -from django.core.urlresolvers import reverse -from django.http import HttpResponse, HttpResponseRedirect, Http404, HttpResponseNotAllowed -from django.conf import settings +glue.glue() # actually apply glue helios.view <-> helios.signals -import copy -import helios_auth.views as auth_views def get_election(): return None diff --git a/settings.py b/settings.py index 2cf2d8fd00371a05e68df28fb0e29cb14b9d182b..1a4a08a9d822061df049285ee5abe68c3b364b57 100644 --- a/settings.py +++ b/settings.py @@ -1,8 +1,10 @@ -import os, json - # a massive hack to see if we're testing, in which case we use different settings import sys + +import json +import os + TESTING = 'test' in sys.argv # go through environment variables and override them @@ -13,7 +15,6 @@ def get_from_env(var, default): return default DEBUG = (get_from_env('DEBUG', '1') == '1') -TEMPLATE_DEBUG = DEBUG # add admins of the form: # ('Ben Adida', 'ben@adida.net'), @@ -40,14 +41,12 @@ DATABASES = { } } -SOUTH_DATABASE_ADAPTERS = {'default':'south.db.postgresql_psycopg2'} - # override if we have an env variable if get_from_env('DATABASE_URL', None): import dj_database_url DATABASES['default'] = dj_database_url.config() DATABASES['default']['ENGINE'] = 'django.db.backends.postgresql_psycopg2' - DATABASES['default']['CONN_MAX_AGE'] = 600 + DATABASES['default']['CONN_MAX_AGE'] = '600' # require SSL DATABASES['default']['OPTIONS'] = {'sslmode': 'require'} @@ -93,7 +92,7 @@ SECRET_KEY = get_from_env('SECRET_KEY', 'replaceme') ALLOWED_HOSTS = get_from_env('ALLOWED_HOSTS', 'localhost').split(",") # Secure Stuff -if (get_from_env('SSL', '0') == '1'): +if get_from_env('SSL', '0') == '1': SECURE_SSL_REDIRECT = True SESSION_COOKIE_SECURE = True @@ -104,7 +103,7 @@ SESSION_COOKIE_HTTPONLY = True # let's go with one year because that's the way to do it now STS = False -if (get_from_env('HSTS', '0') == '1'): +if get_from_env('HSTS', '0') == '1': STS = True # we're using our own custom middleware now # SECURE_HSTS_SECONDS = 31536000 @@ -114,45 +113,46 @@ if (get_from_env('HSTS', '0') == '1'): SECURE_BROWSER_XSS_FILTER = True SECURE_CONTENT_TYPE_NOSNIFF = True -# List of callables that know how to import templates from various sources. -TEMPLATE_LOADERS = ( - 'django.template.loaders.filesystem.Loader', - 'django.template.loaders.app_directories.Loader' -) - -MIDDLEWARE_CLASSES = ( - # make all things SSL - #'sslify.middleware.SSLifyMiddleware', +SILENCED_SYSTEM_CHECKS = ['urls.W002'] +MIDDLEWARE = [ # secure a bunch of things - 'djangosecure.middleware.SecurityMiddleware', + 'django.middleware.security.SecurityMiddleware', 'helios.security.HSTSMiddleware', 'django.middleware.clickjacking.XFrameOptionsMiddleware', + # 'django.middleware.csrf.CsrfViewMiddleware', 'django.middleware.common.CommonMiddleware', 'django.contrib.sessions.middleware.SessionMiddleware', - 'django.contrib.auth.middleware.AuthenticationMiddleware' -) + 'django.contrib.auth.middleware.AuthenticationMiddleware', +] ROOT_URLCONF = 'urls' ROOT_PATH = os.path.dirname(__file__) -TEMPLATE_DIRS = ( - ROOT_PATH, - os.path.join(ROOT_PATH, 'templates') -) + +TEMPLATES = [ + { + 'BACKEND': 'django.template.backends.django.DjangoTemplates', + 'APP_DIRS': True, + 'DIRS': [ + ROOT_PATH, + os.path.join(ROOT_PATH, 'templates'), + # os.path.join(ROOT_PATH, 'helios/templates'), # covered by APP_DIRS:True + # os.path.join(ROOT_PATH, 'helios_auth/templates'), # covered by APP_DIRS:True + # os.path.join(ROOT_PATH, 'server_ui/templates'), # covered by APP_DIRS:True + ], + 'OPTIONS': { + 'debug': DEBUG + } + }, +] INSTALLED_APPS = ( -# 'django.contrib.auth', -# 'django.contrib.contenttypes', - 'djangosecure', + 'django.contrib.auth', + 'django.contrib.contenttypes', 'django.contrib.sessions', - #'django.contrib.sites', - ## needed for queues - 'djcelery', - 'kombu.transport.django', - ## in Django 1.7 we now use built-in migrations, no more south - ## 'south', + 'django.contrib.sites', ## HELIOS stuff 'helios_auth', 'helios', @@ -267,23 +267,17 @@ logging.basicConfig( ) -# set up django-celery -# BROKER_BACKEND = "kombu.transport.DatabaseTransport" -BROKER_URL = "django://" -CELERY_RESULT_DBURI = DATABASES['default'] -import djcelery -djcelery.setup_loader() - - -# for testing -TEST_RUNNER = 'djcelery.contrib.test_runner.CeleryTestSuiteRunner' -# this effectively does CELERY_ALWAYS_EAGER = True +# set up celery +CELERY_BROKER_URL = get_from_env('CELERY_BROKER_URL', 'amqp://localhost') +if TESTING: + CELERY_TASK_ALWAYS_EAGER = True +#database_url = DATABASES['default'] # Rollbar Error Logging ROLLBAR_ACCESS_TOKEN = get_from_env('ROLLBAR_ACCESS_TOKEN', None) if ROLLBAR_ACCESS_TOKEN: print "setting up rollbar" - MIDDLEWARE_CLASSES += ('rollbar.contrib.django.middleware.RollbarNotifierMiddleware',) + MIDDLEWARE += ['rollbar.contrib.django.middleware.RollbarNotifierMiddleware',] ROLLBAR = { 'access_token': ROLLBAR_ACCESS_TOKEN, 'environment': 'development' if DEBUG else 'production', diff --git a/urls.py b/urls.py index d4674991451a72c154ae6d91bfdf5a0dd0bee8a1..8c29e83ea1a7b309247f81caf3dc6a423d6e6cd7 100644 --- a/urls.py +++ b/urls.py @@ -1,21 +1,19 @@ # -*- coding: utf-8 -*- -from django.conf.urls import * -from django.contrib import admin from django.conf import settings +from django.conf.urls import url, include +from django.views.static import serve -urlpatterns = patterns( - '', - (r'^auth/', include('helios_auth.urls')), - (r'^helios/', include('helios.urls')), +urlpatterns = [ + url(r'^auth/', include('helios_auth.urls')), + url(r'^helios/', include('helios.urls')), # SHOULD BE REPLACED BY APACHE STATIC PATH - (r'booth/(?P<path>.*)$', 'django.views.static.serve', {'document_root' : settings.ROOT_PATH + '/heliosbooth'}), - (r'verifier/(?P<path>.*)$', 'django.views.static.serve', {'document_root' : settings.ROOT_PATH + '/heliosverifier'}), + url(r'booth/(?P<path>.*)$', serve, {'document_root' : settings.ROOT_PATH + '/heliosbooth'}), + url(r'verifier/(?P<path>.*)$', serve, {'document_root' : settings.ROOT_PATH + '/heliosverifier'}), - (r'static/auth/(?P<path>.*)$', 'django.views.static.serve', {'document_root' : settings.ROOT_PATH + '/helios_auth/media'}), - (r'static/helios/(?P<path>.*)$', 'django.views.static.serve', {'document_root' : settings.ROOT_PATH + '/helios/media'}), - (r'static/(?P<path>.*)$', 'django.views.static.serve', {'document_root' : settings.ROOT_PATH + '/server_ui/media'}), + url(r'static/auth/(?P<path>.*)$', serve, {'document_root' : settings.ROOT_PATH + '/helios_auth/media'}), + url(r'static/helios/(?P<path>.*)$', serve, {'document_root' : settings.ROOT_PATH + '/helios/media'}), + url(r'static/(?P<path>.*)$', serve, {'document_root' : settings.ROOT_PATH + '/server_ui/media'}), - (r'^', include('server_ui.urls')), - - ) + url(r'^', include('server_ui.urls')), +]