Revision a8cee257
Added by Assos Assos almost 5 years ago
drupal7/sites/all/modules/captcha/captcha.module | ||
---|---|---|
184 | 184 |
// Add JavaScript for general CAPTCHA functionality. |
185 | 185 |
drupal_add_js(drupal_get_path('module', 'captcha') . '/captcha.js'); |
186 | 186 |
|
187 |
// Prevent caching of the page with CAPTCHA elements. |
|
188 |
// This needs to be done even if the CAPTCHA will be ommitted later: |
|
189 |
// other untrusted users should not get a cached page when |
|
190 |
// the current untrusted user can skip the current CAPTCHA. |
|
191 |
drupal_page_is_cacheable(FALSE); |
|
192 |
|
|
193 | 187 |
// Get the form ID of the form we are currently processing (which is not |
194 | 188 |
// necessary the same form that is submitted (if any). |
195 | 189 |
$this_form_id = $complete_form['form_id']['#value']; |
... | ... | |
296 | 290 |
// Store the solution in the #captcha_info array. |
297 | 291 |
$element['#captcha_info']['solution'] = $captcha['solution']; |
298 | 292 |
|
293 |
// Store if this captcha type is cacheable: |
|
294 |
// A cacheable captcha must not depend on the sid or solution, but be |
|
295 |
// independent - like for example recaptcha. |
|
296 |
$element['#captcha_info']['cacheable'] = !empty($captcha['cacheable']); |
|
297 |
|
|
298 |
if (!empty($element['#captcha_info']['cacheable']) && drupal_page_is_cacheable()) { |
|
299 |
// This is only used to avoid the re-use message. |
|
300 |
$element['captcha_cacheable'] = array( |
|
301 |
'#type' => 'hidden', |
|
302 |
'#value' => TRUE, |
|
303 |
); |
|
304 |
} |
|
305 |
|
|
299 | 306 |
// Make sure we can use a top level form value $form_state['values']['captcha_response'], even if the form has #tree=true. |
300 | 307 |
$element['#tree'] = FALSE; |
301 | 308 |
|
... | ... | |
360 | 367 |
*/ |
361 | 368 |
function theme_captcha($variables) { |
362 | 369 |
$element = $variables['element']; |
370 |
|
|
371 |
if (empty($element['#description']) && !empty($element['#attributes']['title'])) { |
|
372 |
// Fix for Bootstrap-based themes. |
|
373 |
$element['#description'] = $element['#attributes']['title']; |
|
374 |
} |
|
375 |
|
|
363 | 376 |
if (!empty($element['#description']) && isset($element['captcha_widgets'])) { |
364 | 377 |
$fieldset = array( |
365 | 378 |
'#type' => 'fieldset', |
... | ... | |
383 | 396 |
*/ |
384 | 397 |
function captcha_form_alter(&$form, &$form_state, $form_id) { |
385 | 398 |
|
399 |
// If user has skip CAPTCHA permission, doesn't do anything. |
|
386 | 400 |
if (!user_access('skip CAPTCHA')) { |
387 | 401 |
// Visitor does not have permission to skip CAPTCHAs. |
388 | 402 |
module_load_include('inc', 'captcha'); |
... | ... | |
406 | 420 |
_captcha_insert_captcha_element($form, $captcha_placement, $captcha_element); |
407 | 421 |
} |
408 | 422 |
} |
409 |
elseif ( |
|
423 |
|
|
424 |
// If user has access to administer CAPTCHA settings and |
|
425 |
// 'Add CAPTCHA administration links to forms' is enabled, display the |
|
426 |
// helper widget. |
|
427 |
if ( |
|
410 | 428 |
variable_get('captcha_administration_mode', FALSE) |
411 | 429 |
&& user_access('administer CAPTCHA settings') |
412 | 430 |
&& (arg(0) != 'admin' || variable_get('captcha_allow_on_admin_pages', FALSE)) |
... | ... | |
423 | 441 |
'#collapsed' => TRUE, |
424 | 442 |
'#attributes' => array('class' => array('captcha-admin-links')), |
425 | 443 |
); |
444 |
|
|
426 | 445 |
if ($captcha_point !== NULL && $captcha_point->captcha_type) { |
427 | 446 |
$captcha_element['#title'] = t('CAPTCHA: challenge "@type" enabled', array('@type' => $captcha_point->captcha_type)); |
428 | 447 |
$captcha_element['#description'] = t('Untrusted users will see a CAPTCHA here (<a href="@settings">general CAPTCHA settings</a>).', |
... | ... | |
438 | 457 |
'@disable' => url("admin/config/people/captcha/captcha/captcha_point/$form_id/disable", array('query' => drupal_get_destination())), |
439 | 458 |
)), |
440 | 459 |
); |
460 |
|
|
441 | 461 |
// Add an example challenge with solution. |
442 | 462 |
// This does not work with the reCAPTCHA and Egglue challenges as |
443 | 463 |
// discussed in http://drupal.org/node/487032 and |
... | ... | |
464 | 484 |
$captcha_element['add_captcha'] = array( |
465 | 485 |
'#markup' => l(t('Place a CAPTCHA here for untrusted users.'), "admin/config/people/captcha/captcha/captcha_point/$form_id", array('query' => drupal_get_destination())) |
466 | 486 |
); |
467 |
|
|
468 | 487 |
} |
488 |
|
|
469 | 489 |
// Get placement in form and insert in form. |
470 | 490 |
$captcha_placement = _captcha_get_captcha_placement($form_id, $form); |
471 | 491 |
_captcha_insert_captcha_element($form, $captcha_placement, $captcha_element); |
472 |
|
|
473 | 492 |
} |
474 | 493 |
|
475 | 494 |
// Add a warning about caching on the Perfomance settings page. |
... | ... | |
637 | 656 |
)->fetchField(); |
638 | 657 |
|
639 | 658 |
if ($expected_captcha_token !== $posted_captcha_token) { |
640 |
drupal_set_message(t('CAPTCHA session reuse attack detected.'), 'error'); |
|
659 |
if (empty($form_state['input']['captcha_cacheable'])) { |
|
660 |
drupal_set_message(t('CAPTCHA session reuse attack detected.'), 'error'); |
|
661 |
} |
|
641 | 662 |
// Invalidate the CAPTCHA session. |
642 | 663 |
$posted_captcha_sid = NULL; |
643 | 664 |
} |
... | ... | |
731 | 752 |
->expression('attempts', 'attempts + 1') |
732 | 753 |
->execute(); |
733 | 754 |
// Set form error. |
734 |
form_set_error('captcha_response', t('The answer you entered for the CAPTCHA was not correct.'));
|
|
755 |
form_set_error('captcha_response', _captcha_get_error_message());
|
|
735 | 756 |
// Update wrong response counter. |
736 | 757 |
if (variable_get('captcha_enable_stats', FALSE)) { |
737 | 758 |
variable_set('captcha_wrong_response_counter', variable_get('captcha_wrong_response_counter', 0) + 1); |
... | ... | |
777 | 798 |
// when the challenge is solved correctely on preview, the form is still |
778 | 799 |
// not completely submitted, but the CAPTCHA can be skipped. |
779 | 800 |
if (_captcha_required_for_user($captcha_sid, $form_id) || $element['#captcha_admin_mode'] || $element['#captcha_always']) { |
801 |
// Prevent caching of the page with CAPTCHA elements. |
|
802 |
// This needs to be done only if the captcha is actually displayed. |
|
803 |
// The captcha display will be skipped only in 2 cases: |
|
804 |
// - The captcha sid has a solution already. |
|
805 |
// - The user has a SESSION. |
|
806 |
// For a page to be cacheable, the user MUST not have a SESSION. |
|
807 |
// For a SID to be solved already, it must be a POST request as else |
|
808 |
// a new unsolved SID is generated. |
|
809 |
// Therefore it is fine to disable the cache at this late stage here. |
|
810 |
if (empty($captcha_info['cacheable'])) { |
|
811 |
// The cache is only disabled if the captcha itself is not cacheable. |
|
812 |
drupal_page_is_cacheable(FALSE); |
|
813 |
} |
|
814 |
|
|
780 | 815 |
// Update captcha_sessions table: store the solution of the generated CAPTCHA. |
781 | 816 |
_captcha_update_captcha_session($captcha_sid, $captcha_info['solution']); |
782 | 817 |
|
Also available in: Unified diff
Weekly update of contrib modules