Ejemplo n.º 1
0
def voter_exclude(request, election, voter_uuid):

  user = get_user(request)
  admin_p = security.user_can_admin_election(user, election)

  if not election.frozen_at or datetime.datetime.now() <= election.voting_starts_at:
    raise PermissionDenied('20')

  # admin requested mixing to start
  if election.mixing_started:
    raise PermissionDenied('21')

  voter = Voter.get_by_election_and_uuid(election, voter_uuid)
  if not voter:
    raise PermissionDenied('22')

  if voter.excluded_at:
    raise PermissionDenied('23')

  if request.method == 'POST' and request.POST.get('confirm') == '1':
    election.zeus_election.exclude_voter(voter.uuid,
                                         request.POST.get('reason', ''))
    return HttpResponseRedirect(reverse(voters_list_pretty,
                                        args=[election.uuid]))

  return render_template(request, 'voter_exclude', {
      'election': election,
      'voter_o': voter,
      'menu_active': 'voters',
      'admin_p': admin_p
  })
Ejemplo n.º 2
0
def one_election_view(request, election):
  user = get_user(request)
  admin_p = security.user_can_admin_election(user, election)
  can_feature_p = security.user_can_feature_election(user, election)

  notregistered = False
  eligible_p = True

  election_url = get_election_url(election)
  status_update_message = None

  vote_url = "%s/booth/vote.html?%s" % (settings.SECURE_URL_HOST, urllib.urlencode({
    'token': request.session.get('csrf_token'),
    'election_url' : reverse(one_election, args=[election.uuid])}))

  test_cookie_url = "%s?%s" % (reverse(test_cookie), urllib.urlencode({'continue_url' : vote_url}))

  voter = get_voter(request, user, election)

  if voter:
    # cast any votes?
    votes = CastVote.get_by_voter(voter)
    if election.frozen_at:
        voter.last_visit = datetime.datetime.now()
        voter.save()
  else:
    votes = None

  trustee = None
  if request.session.get('helios_trustee_uuid', None):
    try:
        trustee = Trustee.objects.get(election=election,
                    uuid=request.session.get('helios_trustee_uuid', None))
    except:
        raise PermissionDenied('15')

  if not voter and not user and not trustee:
    raise PermissionDenied('16')

  # status update message?
  if election.openreg:
    if election.voting_has_started:
      status_update_message = u"Vote in %s" % election.name
    else:
      status_update_message = u"Register to vote in %s" % election.name

  # result!
  if election.result:
    status_update_message = u"Results are in for %s" % election.name

  trustees = Trustee.get_by_election(election)

  return render_template(request, 'election_view',
                         {'election' : election, 'trustees': trustees, 'admin_p': admin_p, 'user': user,
                          'voter': voter, 'votes': votes, 'notregistered': notregistered, 'eligible_p': eligible_p,
                          'can_feature_p': can_feature_p, 'election_url' : election_url,
                          'vote_url': vote_url,
                          'menu_active': 'overview',
                          'trustee': trustee,
                          'test_cookie_url': test_cookie_url})
Ejemplo n.º 3
0
def one_election_stats(request, election):
  user = get_user(request)
  admin_p = security.user_can_admin_election(user, election) or user.superadmin_p

  stats_data = {'stats': {'election': list(reports.election_report([election]))[0],
                          'votes': list(reports.election_votes_report([election],
                                                                 False))}}

  if request.GET.get('json', None):
    def handler(obj):
      if hasattr(obj, 'isoformat'):
        return obj.isoformat()
      raise TypeError

    return HttpResponse(jsonlib.dumps(stats_data, default=handler),
                        mimetype="application/json")

  return render_template(request, "election_stats", {
      'election': election,
      'admin_p': admin_p,
      'user': user,
      'menu_active': 'stats',
      'STATS_UPDATE_INTERVAL': getattr(settings, 'HELIOS_STATS_UPDATE_INTERVAL',
                                      2000)
  })
Ejemplo n.º 4
0
def list_trustees_view(request, election):
  trustees = Trustee.get_by_election(election)
  user = get_user(request)
  admin_p = security.user_can_admin_election(user, election)

  return render_template(request, 'list_trustees', {
      'election': election,
      'trustees': trustees,
      'menu_active': 'trustees',
      'admin_p':admin_p})
Ejemplo n.º 5
0
def one_election_set_completed(request, election):
  user = get_user(request)
  admin_p = security.user_can_admin_election(user, election) or user.superadmin_p
  if not user.superadmin_p:
    raise PermissionDenied('11')

  election.is_completed = not election.is_completed
  election.save()

  return HttpResponseRedirect('/admin/')
Ejemplo n.º 6
0
def one_election_audited_ballots(request, election):
  """
  UI to show election audited ballots
  """

  user = get_user(request)
  admin_p = security.user_can_admin_election(user, election)
  voter = get_voter(request, user, election)

  if request.GET.has_key('vote_hash'):
    b = AuditedBallot.get(election, request.GET['vote_hash'])
    return HttpResponse(b.raw_vote, mimetype="text/plain")

  after = request.GET.get('after', None)
  offset= int(request.GET.get('offset', 0))
  limit = int(request.GET.get('limit', 100))

  audited_ballots = AuditedBallot.get_by_election(election, after=after, limit=limit+1)
  voter_audited_ballots = AuditedBallot.get_by_election(election,
                                                        extra={'voter':voter})

  more_p = len(audited_ballots) > limit
  if more_p:
    audited_ballots = audited_ballots[0:limit]
    next_after = audited_ballots[limit-1].vote_hash
  else:
    next_after = None

  return render_template(request, 'election_audited_ballots', {
    'menu_active': 'audits',
    'election': election, 'audited_ballots': audited_ballots,
    'voter_audited_ballots': voter_audited_ballots,
    'admin_p': admin_p,
    'next_after': next_after,
    'offset': offset,
    'limit': limit,
    'offset_plus_one': offset+1,
    'offset_plus_limit': offset+limit})
Ejemplo n.º 7
0
def one_election_candidates(request, election):
  questions_json = utils.to_json(election.questions)
  user = get_user(request)
  admin_p = security.user_can_admin_election(user, election)
  candidates = [] if not election.questions or len(election.questions) == 0 else\
      election.questions[0]['answers']

  if admin_p and request.method == "POST":
    if not election.can_change_candidates():
        raise PermissionDenied('26')

    questions = []

    fields = ['surname', 'name', 'father_name', 'department']

    surnames = request.POST.getlist('candidates_lastname')
    names = request.POST.getlist('candidates_name')
    fathernames = request.POST.getlist('candidates_fathers_name')
    departments = request.POST.getlist('candidates_department')

    def filled(c):
      return c['name'] or c['surname'] or c['father_name']

    candidates_data = zip(surnames, names, fathernames, departments)
    candidates = filter(filled, [dict(zip(fields, d)) for d in candidates_data])

    error = None
    errors = []
    for cand in candidates:
      for key in cand.keys():
        if not cand[key]:
          error = "Invalid entry"
          errors.append(cand)

    empty_inputs = range(5) if len(candidates) else range(15)

    if error:
      return render_template(request, 'election_candidates', {
        'election': election, 'questions_json' : questions_json,
        'candidates': candidates,
        'error': error,
        'departments': election.departments,
        'empty_inputs': empty_inputs,
        'menu_active': 'candidates',
        'admin_p': admin_p})

    candidates = sorted(candidates, key=lambda c: c['surname'])
    question = {}
    question['answer_urls'] = [None for x in range(len(candidates))]
    question['choice_type'] = 'stv'
    question['question'] = 'Candidates choice'
    question['answers'] = []
    question['result_type'] = 'absolute'
    question['tally_type'] = 'stv'
    questions.append(question)
    election.questions = questions
    election.candidates = candidates
    election.sort_candidates()
    election.save()
    election.update_answers()

    if election.voter_set.count() == 0:
      return HttpResponseRedirect(reverse(voters_upload,
                                        args=[election.uuid]))

    return HttpResponseRedirect(reverse(one_election_view,
                                        args=[election.uuid]))

  empty_inputs = range(5) if len(candidates) else range(15)
  return render_template(request, 'election_candidates', {
    'election': election, 'questions_json' : questions_json,
    'candidates': election.candidates,
    'departments': election.departments,
    'empty_inputs': empty_inputs,
    'menu_active': 'candidates',
    'admin_p': admin_p})
Ejemplo n.º 8
0
def one_election_questions(request, election):
  from zeus.forms import QuestionForm, DEFAULT_ANSWERS_COUNT, MAX_QUESTIONS_LIMIT
  if election.election_type == 'election_parties':
      from zeus.forms import PartyForm as QuestionForm

  extra = 1
  if election.questions_data:
    extra = 0

  questions_formset = formset_factory(QuestionForm, extra=extra, can_delete=True,
                                      can_order=True)

  user = get_user(request)
  admin_p = security.user_can_admin_election(user, election)

  if request.method == "POST":
      if not election.can_change_questions():
        raise PermissionDenied('26')

      formset = questions_formset(request.POST)
      if formset.is_valid():
        questions_data = []
        for question in formset.cleaned_data:
          if not question:
              continue

          # force sort of answers by extracting index from answer key.
          # cast answer index to integer, otherwise answer_10 would be placed
          # before answer_2
          answer_index = lambda a: int(a[0].replace('answer_', ''))
          isanswer = lambda a: a[0].startswith('answer_')
          answer_values = filter(isanswer, question.iteritems())
          sorted_answers = sorted(answer_values, key=answer_index)

          answers = [x[1] for x in sorted_answers]
          question['answers'] = answers
          for k in question.keys():
            if k in ['DELETE', 'ORDER']:
              del question[k]

          questions_data.append(question)

        election.questions_data = questions_data
        election.update_answers()
        election.save()

        if election.voter_set.count() == 0:
          return HttpResponseRedirect(reverse(voters_upload,
                                            args=[election.uuid]))
        return HttpResponseRedirect(reverse(one_election_questions,
                                            args=[election.uuid])+"#q1")

  else:
      data = election.questions_data or None
      formset = questions_formset(initial=election.questions_data)

  return render_template(request, 'election_questions', {
    'menu_active': 'candidates',
    'default_answers_count': DEFAULT_ANSWERS_COUNT,
    'formset': formset,
    'max_questions_limit': MAX_QUESTIONS_LIMIT,
    'election': election,
    'admin_p': admin_p})
Ejemplo n.º 9
0
def voters_email(request, election):

  user = get_user(request)
  admin_p = security.user_can_admin_election(user, election)

  if not helios.VOTERS_EMAIL:
    return HttpResponseRedirect(reverse(one_election_view, args=[election.uuid]))

  TEMPLATES = [
    ('vote', _('Time to Vote')),
    ('info', _('Additional Info'))
  ]

  default_template = 'vote'
  if not election.frozen_at:
    TEMPLATES.pop(0)
    default_template = 'info'

  template = request.REQUEST.get('template', default_template)

  if not template in [t[0] for t in TEMPLATES]:
    raise Exception("bad template")

  voter_id = request.REQUEST.get('voter_id', None)

  if voter_id:
    voter = Voter.get_by_election_and_voter_id(election, voter_id)
    if not voter:
      return HttpResponseRedirect(reverse(one_election_view, args=[election.uuid]))
  else:
    voter = None

  election_url = get_election_url(election)

  default_subject = render_template_raw(None, 'email/%s_subject.txt' % template, {
      'custom_subject': "&lt;SUBJECT&gt;"
})
  default_body = render_template_raw(None, 'email/%s_body.txt' % template, {
      'election' : election,
      'election_url' : election_url,
      'custom_subject' : default_subject,
      'custom_message': '&lt;BODY&gt;',
      'voter': {'vote_hash' : '<SMART_TRACKER>',
                'name': '<VOTER_NAME>',
                'voter_name': '<VOTER_NAME>',
                'voter_surname': '<VOTER_SURNAME>',
                'voter_login_id': '<VOTER_LOGIN_ID>',
                'voter_password': '******',
                'audit_passwords': '1',
                'get_audit_passwords': ['pass1', 'pass2', '...'],
                'get_quick_login_url': '<VOTER_LOGIN_URL>',
                'voter_type' : election.voter_set.all()[0].voter_type,
                'election' : election}
      })

  if request.method == "GET":
    email_form = forms.EmailVotersForm()
    email_form.fields['subject'].initial = dict(TEMPLATES)[template]
    if voter:
      email_form.fields['send_to'].widget = email_form.fields['send_to'].hidden_widget()
  else:
    email_form = forms.EmailVotersForm(request.POST)

    if email_form.is_valid():

      # the client knows to submit only once with a specific voter_id
      subject_template = 'email/%s_subject.txt' % template
      body_template = 'email/%s_body.txt' % template

      extra_vars = {
        'custom_subject' : email_form.cleaned_data['subject'],
        'custom_message' : email_form.cleaned_data['body'],
        'election_url' : election_url,
        'election' : election,
        }

      voter_constraints_include = None
      voter_constraints_exclude = None

      if voter:
        tasks.single_voter_email.delay(voter_uuid=voter.uuid,
                                       subject_template=subject_template,
                                       body_template=body_template,
                                       extra_vars=extra_vars)
      else:
        # exclude those who have not voted
        if email_form.cleaned_data['send_to'] == 'voted':
          voter_constraints_exclude = {'vote_hash' : None}

        # include only those who have not voted
        if email_form.cleaned_data['send_to'] == 'not-voted':
          voter_constraints_include = {'vote_hash': None}

        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
      messages.info(request, "Η αποστολή των email έχει ξεκινήσει.")

      return HttpResponseRedirect(reverse(one_election_view, args=[election.uuid]))

  return render_template(request, "voters_email", {
      'email_form': email_form, 'election': election,
      'voter_o': voter,
      'admin_p': admin_p,
      'default_subject': default_subject,
      'default_body' : default_body,
      'template' : template,
      'menu_active': 'voters',
      'templates' : TEMPLATES})
Ejemplo n.º 10
0
def voters_list_pretty(request, election):
  """
  Show the list of voters
  now using Django pagination
  """

  # for django pagination support
  page = int(request.GET.get('page', 1))
  limit = int(request.GET.get('limit', 50))
  q = request.GET.get('q','')

  validate_hash = request.GET.get('vote_hash', "").strip()
  hash_invalid = None
  hash_valid = None

  if validate_hash:
    try:
      cast = CastVote.objects.get(verified_at__isnull=False,
                   voter__election=election, vote_hash=validate_hash)
      hash_valid = "1"
    except CastVote.DoesNotExist:
      hash_invalid = "1"


  order_by = 'user__user_id'

  # unless it's by alias, in which case we better go by UUID
  if election.use_voter_aliases:
    order_by = 'alias'

  user = get_user(request)
  admin_p = security.user_can_admin_election(user, election)

  categories = None
  eligibility_category_id = None

  try:
    if admin_p and can_list_categories(user.user_type):
      categories = AUTH_SYSTEMS[user.user_type].list_categories(user)
      eligibility_category_id = election.eligibility_category_id(user.user_type)
  except AuthenticationExpired:
    return user_reauth(request, user)

  # files being processed
  voter_files = election.voterfile_set.all()

  # load a bunch of voters
  # voters = Voter.get_by_election(election, order_by=order_by)
  voters = Voter.objects.filter(election = election).order_by('voter_surname')

  if q != '':
    if election.use_voter_aliases:
      voters = voters.filter(alias__icontains = q)
    else:
      voters = voters.filter(voter_name__icontains = q)

  total_voters = voters.count()
  voters_voted = election.voted_count()

  return render_template(request, 'voters_list',
                         {'election': election,
                          'voters': voters, 'admin_p': admin_p,
                          'request': request,
                          'email_voters': helios.VOTERS_EMAIL,
                          'limit': limit, 'total_voters': total_voters,
                          'upload_p': helios.VOTERS_UPLOAD, 'q' : q,
                          'menu_active': 'voters',
                          'voter_files': voter_files,
                          'voted_count': voters_voted,
                          'hash_valid': hash_valid,
                          'validate_hash': validate_hash,
                          'hash_invalid': hash_invalid,
                          'categories': categories,
                          'eligibility_category_id' : eligibility_category_id})