This repository has been archived on 2023-02-21. You can view files and clone it, but cannot push or open issues or pull requests.
asec/extra/modules/anonymity.py

136 lines
4.3 KiB
Python

# w.c.s. (asec) - w.c.s. extension for poll & survey service
# Copyright (C) 2010-2011 Entr'ouvert
#
# This program is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at your
# option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
# or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
# License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
import fcntl
import os
import cPickle
from quixote import get_response
from qommon.ident.password import make_password
from qommon.admin.texts import TextsDirectory
from wcs.workflows import WorkflowStatusItem, register_item_class
class AnonymiseStatusItem(WorkflowStatusItem):
description = N_('Anonymise submitted questionnaire')
key = 'anonymise'
def perform(self, formdata):
objects_dir = formdata.get_objects_dir()
box_filename = os.path.join(objects_dir, '.result')
try:
f = open(box_filename, 'rw+')
rc = fcntl.flock(f, fcntl.LOCK_EX)
d = cPickle.load(f)
except IOError:
f = open(box_filename, 'w')
rc = fcntl.flock(f, fcntl.LOCK_EX)
d = {'voters':[], 'tokens':[]}
user_id = formdata.user_id
formdata.user_id = None
formdata.receipt_time = None
formdata.verification_code = None
# make sure the form gets an unique verification code
while formdata.verification_code is None or formdata.verification_code in d.get('tokens'):
formdata.verification_code = make_password(20, 20)
formdata.store()
if user_id in d['voters']:
formdata.verification_code = None # passing this info to get_message()
formdata.remove_self()
else:
d['voters'].append(user_id)
d['voters'].sort()
d['tokens'].append(formdata.verification_code)
d['tokens'].sort()
f.seek(0)
f.truncate()
cPickle.dump(d, f)
f.close()
def get_message(self, formdata):
if not formdata.verification_code:
return TextsDirectory.get_html_text('asec-already-voted')
return TextsDirectory.get_html_text('asec-recorded-vote',
vars={'verification_code': formdata.verification_code})
register_item_class(AnonymiseStatusItem)
def has_voted(formdef, user_id):
objects_dir = formdef.data_class().get_objects_dir()
box_filename = os.path.join(objects_dir, '.result')
try:
f = open(box_filename, 'r')
d = cPickle.load(f)
if user_id in d['voters']:
return True
f.close()
except:
pass
return False
def get_voters(formdef):
objects_dir = formdef.data_class().get_objects_dir()
box_filename = os.path.join(objects_dir, '.result')
try:
f = open(box_filename, 'r')
d = cPickle.load(f)
t = sorted(d['voters'])
f.close()
return t
except:
pass
return []
def get_verification_codes(formdef):
objects_dir = formdef.data_class().get_objects_dir()
box_filename = os.path.join(objects_dir, '.result')
try:
f = open(box_filename, 'r')
d = cPickle.load(f)
t = sorted(d['tokens'])
f.close()
return t
except:
pass
return []
TextsDirectory.register('asec-recorded-vote',
N_('Message when a response has been recorded.'),
hint=N_('Available variable: verification_code'),
default=N_('''<p>
Your response has been recorded. Its verification code is
<strong>[verification_code]</strong>.
</p>
<p>
This verification code is a unique identifier which will allow you to
verify after the election that your response was counted correctly. To ensure
anonymity, no link is kept between this code and your identifiers,
so please keep this code safe.
</p>
<p>
Nobody except you knows that this code is associated with you and only you
will be able to verify your response. It is not possible to request this anonymous
code later.
</p>
'''))