Hi pjcdawkins,
Thanks for this great module.
As I need a voting platform with really secret ballots (ie. no possibility to track the votes in the database), I need to develop an "anonymizer module" (called "election_vote_anonymize").
And it's not that easy as I first need to understand the way the modules interact.
My ideas:
- Creating each time a user votes, two different ballots: one that tracks the user (has already voted or not) and one to which the vote is assigned (secret ballot which I think could be assigned to uid 1 with blank values for request time, ip and so on).
- Assigning the vote to the secret ballot.
- Removing the ability to undo a vote if the module is enabled.
I tried this:
- I created a election_vote_anonymize module
- I added the following functions in my .module file:
function election_vote_anonymize_vote_form($form, &$form_state) {
$form['buttons']['submit']['#submit'] = array('election_vote_anonymize_form_vote', 'election_vote_form_vote');
if (!empty($post->allow_abstention)) {
$form['buttons']['abstain']['#submit'] = array('election_vote_anonymize_form_abstain', 'election_vote_form_abstain');
}
}
And the two following functions: election_vote_anonymize_form_vote and election_vote_anonymize_form_abstain().
In these two functions I create a ballot (I almost copied the similar ones from election_vote.forms.inc).
My problem concerns the election_vote_anonymize_form_vote, which invokes the 'election_vote_' . $election->type . '_save'... If I want to build a separate submodule, it should alter every 'election_vote_' . $election->type . '_save' function, which seems impossible.
Same problem to prevent the "undo vote" link from appearing (but it seems easier to solve).
What do you think of my idea?
Do you think it's possible?
Thanks in advance for your help and advice!
| Comment | File | Size | Author |
|---|---|---|---|
| #15 | election-anon_ballots-2006326-15-D7.patch | 6.61 KB | liam morland |
| #4 | election-2006326.patch | 3.01 KB | pjcdawkins |
Comments
Comment #1
pjcdawkins commentedHi Antoine_k
Quite busy now - I'll be able to respond to this in more detail later.
I thought I'd just post some fairly relevant facts:
There's already a bit of separation in place:- "Ballots" record that the person has voted (necessary for preventing multiple votes). Stored in the election_ballot database table.
- "Votes" are how someone has voted (the politically sensitive part). Stored in the election_vote database table.
The feature you propose should be accomplished as a setting in election_vote.module. It would not really be possible in a separate module.
Regarding the use case, I can see why you might want completely anonymous votes. There are disadvantages though:
BTW a colleague of mine suggested an exotic solution a while ago: you could encrypt the "ballot_id" with the user password, or with a separate password set by the voter. That would be extra effort while voting of course.
Comment #2
Antoine_k commentedThanks for your answer and your ideas!
I completely understand that you already have much to do with the other feature requests.
I'm going to try to hack the election_vote module to enable this possibility. If I succeed it, I'll post a patch.
My main problem at the moment is that the field "ballot_id" is indexed in the database (which is a good thing when deleting the votes/ballots), which prevents from filling it with a password or anything else than a real ballot_id (or I misunderstood the concept of indexed db fields).
Comment #3
pjcdawkins commentedThe column
{election_vote}.ballot_idcan be left NULL.Comment #4
pjcdawkins commentedHere's how you might do it (clear caches after applying the patch).
Quite simple really.
By the way, the statistics (as they currently are) break if you use this. And any other DB query that uses a JOIN between the election_vote and election_ballot tables will no longer be reliable.
Comment #5
Antoine_k commentedThanks for your help!
It works perfectly well even if I still think of your colleague's idea (encrypting the ballot_id with the user pwd as hash salt).
As I understand the way the module is implemented in the DB, it would require altering the election_vote db scheme to change the ballot_id into a varchar(128) (to be able to record a hashed ballot_id).
Comment #6
Antoine_k commentedThanks for your help!
It works perfectly well even if I still think of your colleague's idea (encrypting the ballot_id with the user pwd as hash salt).
As I understand the way the module is implemented in the DB, it would require altering the election_vote db scheme to change the ballot_id into a varchar(128) (to be able to record a hashed ballot_id).
Comment #7
pjcdawkins commentedYes that would be how you'd do it.
Meanwhile, I'm not sure about whether this should be added to Election.
It's quite a strange feature, and it adds a bit of confusion (votes are kept anonymous anyway, just not from those with database access and a bit of SQL knowledge).
Those with admin + database access will normally be able to see a whole lot of personal/sensitive information about a website's users - thus usually this kind of access should be highly restricted at that level. Beyond that, sometimes encryption is used (with credit card numbers or user passwords) but it seems over the top to do it with other information.
Votes are peculiar in that nearly all the information needs to be read very easily - the main bit that's sensitive is the relationship between a vote and the voter. Encrypting a relationship seems to be quite exotic to me. And who should be allowed to decrypt this? Just the voter? Or administrators/developers too?
Comment #8
Antoine_k commentedYou're right, it's not worth and a bit extravagant... I'm happy with your solution!
Just a small add-on to your patch: it's worth to add the
to the election_vote_form_abstain function (in election_vote.forms.inc).
Thanks again for your time.
Comment #9
bircherHello
I was looking for the exact same option.
And I had pretty much the same idea as Antoine_k for the implementation.
Although I agree that the administrator and whoever has access to the database, already has access to all sorts of sensitive data, it is not truly a secret vote if it is possible to check the relationship.
On the other hand, even i you hide the relation is is not "secret" for someone monitoring the database. (all you would have to do is track changes in the two tables with some other dirty script and there you go knowing who voted for what)
So acknowledging this limitation I think it would be a nice compromise to "anonymize" the election after the election has been closed and then disallow reopening it. This would solve the issue with the changing the minds while the election is ongoing. Yet afterwards it is not possible any more to track the voters.
Its just an idea...
Comment #10
liam morlandComment #11
pjcdawkins commentedIndeed - actually, knowing the time someone voted could reveal their identity, if you were also watching something else, like "Session opened for @name" watchdog messages. That's why the election_vote table doesn't store timestamps.
I think we can aim to add extra protection or anonymizing to cover the case of people who might have accessed a copy of the database (maliciously or otherwise). To protect properly against actual site admins would be pretty much impossible.
Comment #12
liam morlandThe site could be monitored outside of Drupal for admin access during an election and any such access would raise an alarm.
Comment #13
liam morlandThe column election_ballot.value can currently cause a vote to not be counted. This needs to be taken into consideration if election_vote.ballot_id is to be allowed to be null.
Comment #14
liam morlandComment #15
liam morlandThis does FPTP and referendum, but not STV, which requires more elaborate changes to make it work.
@#8: $ballot_id is not used again in the function, so I don't see why that extra code is needed.
Comment #17
liam morlandThis is fixed for all built-in types except STV, which will be done in #2834454: Make election_vote records anonymous for STV.