function security_questions_require_question in Security Questions 6.2
Same name and namespace in other branches
- 7.2 security_questions.module \security_questions_require_question()
Denies access if an answerable question cannot be found for a given user.
This function should be used any time the user is required to answer a security question in order to proceed. It first checks for failed attempts by the visitor (as identified by IP address) to answer questions as the given user and removes those questions from consideration; this impedes brute force attempts to guess a user's answers, and also prevents the same question from being presented repeatedly. It then randomly selects a question from those that remain in consideration. Finally, if no question can be found, it aborts the request with an access denied message.
Parameters
$uid: The user's ID.
Return value
A security question.
1 call to security_questions_require_question()
- security_questions_challenge in ./
security_questions.module - Generates the form elements for a security question challenge.
File
- ./
security_questions.module, line 600 - Main module file for security_questions.
Code
function security_questions_require_question($uid) {
// Get a list of questions that this visitor has already failed to answer.
$result = db_query("SELECT sqid FROM {security_questions_incorrect} WHERE uid = %d AND ip = '%s' AND expiration > %d", $uid, ip_address(), time());
$failed = array();
while ($row = db_fetch_object($result)) {
$failed[] = $row->sqid;
}
// Get a random question from the database where the user has an answer,
// excluding those where the visitor has logged a failed attempt.
$query = "SELECT q.sqid FROM {security_questions} q";
$query .= " INNER JOIN {security_questions_answers} a ON q.sqid = a.sqid AND a.uid = %d";
$args = array(
$uid,
);
if (!empty($failed)) {
$query .= " WHERE q.sqid NOT IN (" . db_placeholders($failed) . ")";
$args = array_merge($args, $failed);
}
$query .= " ORDER BY RAND() LIMIT 1";
$qid = db_result(db_query($query, $args));
$question = empty($qid) ? FALSE : security_questions_question_load($qid);
// If no question could be selected, we need to abort.
if (empty($question)) {
// Rather than using drupal_set_message(), we overwrite the messages array
// directly to prevent any other messages from being displayed.
$_SESSION['messages'] = array();
$_SESSION['messages']['error'][] = t('Too many failed attempts to answer security questions in @interval. Try again later.', array(
'@interval' => format_interval(variable_get('security_questions_flood_expire', 3600)),
));
drupal_access_denied();
exit;
}
return $question;
}