Skip to content
This repository has been archived by the owner on Apr 5, 2018. It is now read-only.

Commit

Permalink
Added honeypot module.
Browse files Browse the repository at this point in the history
  • Loading branch information
xendk committed Feb 13, 2015
1 parent 3fd0dfc commit a63ccbf
Show file tree
Hide file tree
Showing 8 changed files with 1,410 additions and 0 deletions.
339 changes: 339 additions & 0 deletions sites/all/modules/honeypot/LICENSE.txt

Large diffs are not rendered by default.

43 changes: 43 additions & 0 deletions sites/all/modules/honeypot/README.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@

Honeypot Module Readme
----------------------


Installation
------------

To install this module, place it in your sites/all/modules folder and enable it
on the modules page.


Configuration
-------------

All settings for this module are on the Honeypot configuration page, under the
Configuration section, in the Content authoring settings. You can visit the
configuration page directly at admin/config/content/honeypot.

Note that, when testing Honeypot on your website, make sure you're not logged in
as an administrative user or user 1; Honeypot allows administrative users to
bypass Honeypot protection, so by default, Honeypot will not be added to forms
accessed by site administrators.


Use in Your Own Forms
---------------------

If you want to add honeypot to your own forms, or to any form through your own
module's hook_form_alter's, you can simply place the following function call
inside your form builder function (or inside a hook_form_alter):

honeypot_add_form_protection($form, $form_state, array('honeypot', 'time_restriction'));

Note that you can enable or disable either the honeypot field, or the time
restriction on the form by including or not including the option in the array.


Credit
------

The Honeypot module was originally developed by Jeff Geerling of Midwestern Mac,
LLC (midwesternmac.com), and sponsored by flockNote (flocknote.com).
180 changes: 180 additions & 0 deletions sites/all/modules/honeypot/honeypot.admin.inc
Original file line number Diff line number Diff line change
@@ -0,0 +1,180 @@
<?php

/**
* @file
* Honeypot administration forms.
*/

/**
* Honeypot administration page.
*/
function honeypot_admin_form($form, &$form_state) {
// Honeypot Configuration.
$form['configuration'] = array(
'#type' => 'fieldset',
'#title' => t('Honeypot Configuration'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
);
$form['configuration']['honeypot_protect_all_forms'] = array(
'#type' => 'checkbox',
'#title' => t('Protect all forms with Honeypot'),
'#description' => t('Enable Honeypot protection for ALL forms on this site (it is best to only enable Honeypot for the forms you need below).'),
'#default_value' => variable_get('honeypot_protect_all_forms', 0),
);
$form['configuration']['honeypot_protect_all_forms']['#description'] .= '<br />' . t('<strong>Page caching will be disabled on any page where a form is present if the Honeypot time limit is not set to 0.</strong>');
$form['configuration']['honeypot_log'] = array(
'#type' => 'checkbox',
'#title' => t('Log blocked form submissions'),
'#description' => t('Log submissions that are blocked due to Honeypot protection.'),
'#default_value' => variable_get('honeypot_log', 0),
);
$form['configuration']['honeypot_element_name'] = array(
'#type' => 'textfield',
'#title' => t('Honeypot element name'),
'#description' => t("The name of the Honeypot form field. It's usually most effective to use a generic name like email, homepage, or name, but this should be changed if it interferes with fields that are already in your forms. Must not contain spaces or special characters."),
'#default_value' => variable_get('honeypot_element_name', 'url'),
'#required' => TRUE,
'#size' => 30,
);
$form['configuration']['honeypot_time_limit'] = array(
'#type' => 'textfield',
'#title' => t('Honeypot time limit'),
'#description' => t('Minimum time required before form should be considered entered by a human instead of a bot. Set to 0 to disable.'),
'#default_value' => variable_get('honeypot_time_limit', 5),
'#required' => TRUE,
'#size' => 5,
'#field_suffix' => t('seconds'),
);
$form['configuration']['honeypot_time_limit']['#description'] .= '<br />' . t('<strong>Page caching will be disabled if there is a form protected by time limit on the page.</strong>');

// Honeypot Enabled forms.
$form['enabled_forms'] = array(
'#type' => 'fieldset',
'#title' => t('Honeypot Enabled Forms'),
'#description' => t("Check the boxes next to individual forms on which you'd like Honeypot protection enabled."),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#states' => array(
// Hide this fieldset when all forms are protected.
'invisible' => array(
'input[name="honeypot_protect_all_forms"]' => array('checked' => TRUE),
),
),
);

// Generic forms.
$form['enabled_forms']['general_forms'] = array('#markup' => '<h5>' . t('General Forms') . '</h5>');
// User register form.
$form['enabled_forms']['honeypot_form_user_register_form'] = array(
'#type' => 'checkbox',
'#title' => t('User Registration form'),
'#default_value' => variable_get('honeypot_form_user_register_form', 0),
);
// User password form.
$form['enabled_forms']['honeypot_form_user_pass'] = array(
'#type' => 'checkbox',
'#title' => t('User Password Reset form'),
'#default_value' => variable_get('honeypot_form_user_pass', 0),
);

// If webform.module enabled, add webforms.
if (module_exists('webform')) {
$form['enabled_forms']['honeypot_form_webforms'] = array(
'#type' => 'checkbox',
'#title' => t('Webforms (all)'),
'#default_value' => variable_get('honeypot_form_webforms', 0),
);
}

// If contact.module enabled, add contact forms.
if (module_exists('contact')) {
$form['enabled_forms']['contact_forms'] = array('#markup' => '<h5>' . t('Contact Forms') . '</h5>');
// Sitewide contact form.
$form['enabled_forms']['honeypot_form_contact_site_form'] = array(
'#type' => 'checkbox',
'#title' => t('Sitewide Contact form'),
'#default_value' => variable_get('honeypot_form_contact_site_form', 0),
);
// Sitewide personal form.
$form['enabled_forms']['honeypot_form_contact_personal_form'] = array(
'#type' => 'checkbox',
'#title' => t('Personal Contact forms'),
'#default_value' => variable_get('honeypot_form_contact_personal_form', 0),
);
}

// If profile.module enabled, add profile forms.
if (module_exists('profile')) {
$form['enabled_forms']['profile_forms'] = array('#value' => '<h5>' . t('Profile Forms') . '</h5>');
$form['enabled_forms']['honeypot_form_user_profile_form'] = array(
'#type' => 'checkbox',
'#title' => t('Profile forms (all)'),
'#default_value' => variable_get('honeypot_form_user_profile_form', 0),
);
}

// Get node types for node forms and node comment forms.
$types = node_type_get_types();
if (!empty($types)) {
// Node forms.
$form['enabled_forms']['node_forms'] = array('#markup' => '<h5>' . t('Node Forms') . '</h5>');
foreach ($types as $type) {
$id = 'honeypot_form_' . $type->type . '_node_form';
$form['enabled_forms'][$id] = array(
'#type' => 'checkbox',
'#title' => t('@name node form', array('@name' => $type->name)),
'#default_value' => variable_get($id, 0),
);
}

// Comment forms.
if (module_exists('comment')) {
$form['enabled_forms']['comment_forms'] = array('#markup' => '<h5>' . t('Comment Forms') . '</h5>');
foreach ($types as $type) {
$id = 'honeypot_form_comment_node_' . $type->type . '_form';
$form['enabled_forms'][$id] = array(
'#type' => 'checkbox',
'#title' => t('@name comment form', array('@name' => $type->name)),
'#default_value' => variable_get($id, 0),
);
}
}
}

// Add our own submit handler to clear honeypot's form cache on save.
$form['#submit'][] = 'honeypot_admin_form_submit';

return system_settings_form($form);
}

/**
* Validate the admin form.
*/
function honeypot_admin_form_validate($form, &$form_state) {
// Make sure the time limit is a positive integer or 0.
$time_limit = $form_state['values']['honeypot_time_limit'];
if ((is_numeric($time_limit) && $time_limit > 0) || $time_limit === '0') {
if (ctype_digit($time_limit)) {
// Good to go.
}
else {
form_set_error('honeypot_time_limit', t("The time limit must be a positive integer or 0."));
}
}
else {
form_set_error('honeypot_time_limit', t("The time limit must be a positive integer or 0."));
}

// Make sure Honeypot element name only contains A-Z, 0-9.
if (!preg_match("/^[-_a-zA-Z0-9]+$/", $form_state['values']['honeypot_element_name'])) {
form_set_error('honeypot_element_name', t("The element name cannot contain spaces or other special characters."));
}
}

/**
* Clear the honeypot form cache on submit.
*/
function honeypot_admin_form_submit($form, &$form_state) {
cache_clear_all('honeypot_protected_forms', 'cache');
}
100 changes: 100 additions & 0 deletions sites/all/modules/honeypot/honeypot.api.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
<?php

/**
* @file
* API Functionality for Honeypot module.
*/

/**
* @addtogroup hooks
* @{
*/

/**
* Alter the honeypot protections added to a particular form.
*
* @param array $options
* Protections that will be applied to the form. May be empty, or may include
* 'honeypot' and/or 'time_restriction'.
* @param array $form
* The Form API form to which protections will be added.
*/
function hook_honeypot_form_protections_alter(&$options, $form) {
// Add 'time_restriction' protection to 'mymodule-form' if it's not set.
if ($form['form_id']['#value'] == 'mymodule_form' && !in_array('time_restriction', $options)) {
$options[] = 'time_restriction';
}
}

/**
* React to an addition of honeypot form protections for a given form_id.
*
* After honeypot has added its protections to a form, this hook will be called.
* You can use this hook to track when and how many times certain protected
* forms are displayed to certain users, or for other tracking purposes.
*
* @param array $options
* Protections that were applied to the form. Includes 'honeypot' and/or
* 'time_restriction'.
* @param array $form
* The Form API form to which protections were added.
*/
function hook_honeypot_add_form_protection($options, $form) {
if ($form['form_id']['#value'] == 'mymodule_form') {
// Do something...
}
}

/**
* React to the rejection of a form submission.
*
* When honeypot rejects a form submission, it calls this hook with the form ID,
* the user ID (0 if anonymous) of the user that was disallowed from submitting
* the form, and the reason (type) for the rejection of the form submission.
*
* @param string $form_id
* Form ID of the form the user was disallowed from submitting.
* @param int $uid
* 0 for anonymous users, otherwise the user ID of the user.
* @param string $type
* String indicating the reason the submission was blocked. Allowed values:
* - honeypot: If honeypot field was filled in.
* - honeypot_time: If form was completed before the configured time limit.
*/
function hook_honeypot_reject($form_id, $uid, $type) {
if ($form_id == 'mymodule_form') {
// Do something...
}
}

/**
* Add time to the Honeypot time limit.
*
* In certain circumstances (for example, on forms routinely targeted by
* spammers), you may want to add an additional time delay. You can use this
* hook to return additional time (in seconds) to honeypot when it is calculates
* the time limit for a particular form.
*
* @param int $honeypot_time_limit
* The current honeypot time limit (in seconds), to which any additions you
* return will be added.
* @param array $form_values
* Array of form values (may be empty).
* @param int $number
* Number of times the current user has already fallen into the honeypot trap.
*
* @return int
* Additional time to add to the honeypot_time_limit, in seconds (integer).
*/
function hook_honeypot_time_limit($honeypot_time_limit, $form_values, $number) {
$additions = 0;
// If 'some_interesting_value' is set in your form, add 10 seconds to limit.
if (!empty($form_values['some_interesting_value']) && $form_values['some_interesting_value']) {
$additions = 10;
}
return $additions;
}

/**
* @} End of "addtogroup hooks".
*/
14 changes: 14 additions & 0 deletions sites/all/modules/honeypot/honeypot.info
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
name = Honeypot
description = "Mitigates spam form submissions using the honeypot method."
core = 7.x
configure = admin/config/content/honeypot
package = "Spam control"

files[] = honeypot.test

; Information added by Drupal.org packaging script on 2014-05-30
version = "7.x-1.17"
core = "7.x"
project = "honeypot"
datestamp = "1401478128"

Loading

0 comments on commit a63ccbf

Please sign in to comment.