When an authenticated user votes on a poll, it will be recorded without a timestamp and for anonymous users votes will generate a SQL "integrity constraint violation, duplicate entry" because the IP address is being saved as ''.
Before the DBTNG conversion, we had in poll_vote():
if ($user->uid) {
db_query('INSERT INTO {poll_vote} (nid, chid, uid, timestamp) VALUES (%d, %d, %d, %d)', $node->nid, $choice, $user->uid, REQUEST_TIME);
}
else {
db_query("INSERT INTO {poll_vote} (nid, chid, hostname, timestamp) VALUES (%d, %d, '%s', %d)", $node->nid, $choice, ip_address(), REQUEST_TIME);
}
currently we have:
db_insert('poll_vote')
->fields(array(
'nid' => $node->nid,
'chid' => $choice,
'uid' => $user->uid,
'hostname' => $user->uid ? ip_address() : '',
))
->execute();
The ip_address() : '' part needs to be reversed, and the timestamp field value of REQUEST_TIME is missing.
Comments
Comment #1
sivaji_ganesh_jojodae commentedThis patch looks okay and ready to mark it as RTBC.
Comment #2
kscheirerIs REQUEST_TIME defined here? If so, this seems like a good fix.
Comment #3
kscheirerpatch works for me, thanks!
Bumping this up to critical since this patch also fixes : recording the IP for logged in users will actually prevent an anonymous user from the same IP from being able to vote.
(To test that, open browser A, log in and vote. Then on the same computer open a new browser B, stay anonymous and go to the poll node page. You will be shown the current vote tally, since your IP will already be recorded as having voted.)
Comment #4
webchickIs there a way to add a test for this? Perhaps by force-setting $_SERVER['REMOTE_ADDR'] to something?
Comment #5
grndlvl commentedCurrently working on tests for this one.
Comment #6
grndlvl commentedAlright I have written a test for this.
I was unable to spoof the ip for testing but instead changed the hostname of the poll votes for ones that have a host name.
Test sequence
- User 1(hostname1) Vote
- Check User 1(hostname1) cannot vote again.
- Anonymous(hostname1) Vote
- Check Anonymous(hostname1) cannot vote again.
- User 2(hostname1) Vote
- Change hostname of previous votes.(Simulate user coming from another hostname)
- Anonymous(hostname2) Vote
- Check Anonymous(hostname2) cannot vote again.
- Check User 1(hostname2) cannot vote again.
Not really sure what to call this test... would like some suggestions there.
Comment #7
dawehnerIndentation is broken. It should be always 2 spaces
I think we should use t() here, because the messages could be translated, too.
Powered by Dreditor.
The rest looks fine and rtbc
Comment #8
grndlvl commented- Fixing asserts to include t().
- Fixing tabbing of db_update('poll_vote')
Changes applied (#7) from http://drupal.org/node/602998#comment-2511150.
Comment #9
grndlvl commentedComment #10
grndlvl commentedIt is weird but the Status is "Test request sent" but if you click on the "View details" link it says pass. So it does seem that this patch does pass all the tests.
Thanks,
Jonathan
Comment #11
catchLooks fine.
Comment #12
dries commentedAny reason we don't always store the IP address?
Comment #13
JacobSingh commentedAlthough it is not the greatest for data retrieval, we do store that info in watchdog when someone logs in.
I agree though, the inconsistency isn't needed. I'd vote for creating a new issue though so that this critical error doesn't get held up.
-J
Comment #14
dries commentedI created #702134: Always store IP address for poll votes to track the IP address issue so we can make progress with this critical bug.
Comment #15
dries commentedCommitted to CVS HEAD.