Esempio n. 1
0
    def test_encryption_roundtrip(self):
        """Ensure that we can pass information through an encrypt/decrypt cycle."""
        from nuvavaalit.crypto import encrypt
        from nuvavaalit.crypto import decrypt

        for value in '1', 'foo', 'fööbär':
            self.assertEquals(value, decrypt(encrypt(value, 'secret'), 'secret'))
Esempio n. 2
0
def vote(request):
    """Renders the voting form for the selected candidate and processes the
    vote.

    A valid vote must meet all of the following criteria:

        * The voter must be authenticated.

        * The voter must not have voted previously.

        * The candidate must be the one chosen in the previous step (See
          :py:func:`select`).

        * The CSRF token included in the form must be valid.

    :param request: The currently active request.
    :type request: :py:class:`pyramid.request.Request`

    :rtype: dict
    """
    error = False
    session = DBSession()
    voter = authenticated_user(request)
    log = logging.getLogger('nuvavaalit')
    request.add_response_callback(disable_caching)
    localizer = get_localizer(request)

    # The user must be authenticated at this time
    if voter is None:
        log.warn('Unauthenticated attempt to vote.')
        raise HTTPForbidden()

    # The user may vote only once
    if voter.has_voted():
        log.warn('User "{}" attempted to vote a second time.'.format(voter.username))
        return exit_voting(request)

    # Find the selected candidate
    try:
        number = int(decrypt(request.matchdict['id'], request.session['encryption_key']))
    except (ValueError, TypeError):
        log.warn('Candidate number decryption failed')
        raise HTTPNotFound

    candidate = session.query(Candidate)\
            .filter(Candidate.number == number)\
            .first()

    if candidate is None:
        log.warn('User "{}" attempted to vote for a non-existing candidate "{}".'.format(
            voter.username, number))
        raise HTTPNotFound

    # Handle voting
    if 'vote' in request.POST:

        if request.session.get_csrf_token() != request.POST.get('csrf_token'):
            log.warn('CSRF attempt at: {0}.'.format(request.url))
            error = True
        elif request.POST['vote'].strip() == str(number):

            session.add(Vote(candidate))
            session.add(VotingLog(voter))

            log.info('Stored vote cast by "{}".'.format(voter.username))
            if request.statsd:
                statsd.increment('vote.success')
            return exit_voting(request)
        else:
            error = True

    if request.statsd and error:
        statsd.increment('vote.error')

    options = {
        'action_url': request.path_url,
        'select_url': route_url('select', request),
        'candidate': {
            'number': candidate.number,
            'name': candidate.fullname() if not candidate.is_empty() else _(u'Tyhjä'),
            },
        'voter': {
            'fullname': voter.fullname(),
        },
        'error': error,
        'csrf_token': request.session.get_csrf_token(),
        'unload_confirmation': localizer.translate(
            _(u'Et ole vielä äänestänyt. Oletko varma, että haluat poistua sivulta?')),
    }

    return options