updated mailgun, mailsystem, honeypot, googleanalitycs, features, content_taxonomy
This commit is contained in:
58
sites/all/modules/contrib/form/honeypot/README.md
Normal file
58
sites/all/modules/contrib/form/honeypot/README.md
Normal file
@@ -0,0 +1,58 @@
|
||||
|
||||
# Honeypot
|
||||
|
||||
[](https://travis-ci.org/geerlingguy/drupal-honeypot)
|
||||
|
||||
|
||||
## 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.
|
||||
|
||||
|
||||
## Testing
|
||||
|
||||
Honeypot includes a `docker-compose.yml` file that can be used for testing purposes. To build a Drupal 8 environment for local testing, do the following:
|
||||
|
||||
1. Make sure you have Docker for Mac (or for whatever OS you're using) installed.
|
||||
2. Add the following entry to your `/etc/hosts` file: `192.168.22.33 local.drupalhoneypot.com`
|
||||
3. Run `docker-compose up -d` in this directory.
|
||||
4. Install Drupal: `docker exec honeypot install-drupal 7.x` (optionally provide a version after `install-drupal`).
|
||||
5. Link the honeypot module directory into the Drupal modules directory: `docker exec honeypot ln -s /opt/honeypot/ /var/www/drupalvm/drupal/web/sites/all/modules/honeypot`
|
||||
6. Visit `http://local.drupalhoneypot.com/user` and log in using the admin credentials Drush displayed.
|
||||
|
||||
> Note: If you're using a Mac, you may also need to perform additional steps to get the hostname working; see [Managing your hosts file](http://docs.drupalvm.com/en/latest/other/docker/#managing-your-hosts-file) in the Drupal VM documentation.
|
||||
|
||||
|
||||
## Credit
|
||||
|
||||
The Honeypot module was originally developed by Jeff Geerling of Midwestern Mac,
|
||||
LLC (midwesternmac.com), and sponsored by Flocknote (flocknote.com).
|
@@ -1,43 +0,0 @@
|
||||
|
||||
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).
|
32
sites/all/modules/contrib/form/honeypot/docker-compose.yml
Normal file
32
sites/all/modules/contrib/form/honeypot/docker-compose.yml
Normal file
@@ -0,0 +1,32 @@
|
||||
version: "3"
|
||||
|
||||
services:
|
||||
|
||||
honeypot:
|
||||
image: geerlingguy/drupal-vm
|
||||
container_name: honeypot
|
||||
ports:
|
||||
- 80:80
|
||||
- 443:443
|
||||
privileged: true
|
||||
extra_hosts:
|
||||
local.drupalhoneypot.com: 127.0.0.1
|
||||
dns:
|
||||
- 8.8.8.8
|
||||
- 8.8.4.4
|
||||
volumes:
|
||||
- ./:/opt/honeypot/:rw,delegated
|
||||
command: /lib/systemd/systemd
|
||||
networks:
|
||||
honeypot:
|
||||
ipv4_address: 192.168.22.33
|
||||
|
||||
networks:
|
||||
|
||||
honeypot:
|
||||
driver: bridge
|
||||
driver_opts:
|
||||
ip: 192.168.22.1
|
||||
ipam:
|
||||
config:
|
||||
- subnet: "192.168.22.0/16"
|
@@ -22,7 +22,9 @@ function honeypot_admin_form($form, &$form_state) {
|
||||
'#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>');
|
||||
if (!variable_get('honeypot_use_js_for_cached_pages', FALSE)) {
|
||||
$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'),
|
||||
@@ -46,7 +48,23 @@ function honeypot_admin_form($form, &$form_state) {
|
||||
'#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>');
|
||||
if (!variable_get('honeypot_use_js_for_cached_pages', FALSE)) {
|
||||
$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>');
|
||||
}
|
||||
|
||||
$form['configuration']['honeypot_use_js_for_cached_pages'] = array(
|
||||
'#type' => 'checkbox',
|
||||
'#title' => t('Use Javascript protection for cacheable pages. (experimental)'),
|
||||
'#description' => t('Uses Javascript to preserve Page caching.'),
|
||||
'#default_value' => variable_get('honeypot_use_js_for_cached_pages', FALSE),
|
||||
'#states' => array(
|
||||
// Hide this when time limit is disabled.
|
||||
'invisible' => array(
|
||||
'input[name="honeypot_time_limit"]' => array('value' => 0),
|
||||
),
|
||||
),
|
||||
);
|
||||
$form['configuration']['honeypot_use_js_for_cached_pages']['#description'] .= '<br />' . t('<strong>Warning: Users who have javascript disabled will need to confirm their form submission on the next page (if the Honeypot-enabled form is on a cacheable page).</strong>');
|
||||
|
||||
// Honeypot Enabled forms.
|
||||
$form['enabled_forms'] = array(
|
||||
|
@@ -6,9 +6,8 @@ package = "Spam control"
|
||||
|
||||
files[] = honeypot.test
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-03-11
|
||||
version = "7.x-1.22"
|
||||
; Information added by Drupal.org packaging script on 2018-08-09
|
||||
version = "7.x-1.25"
|
||||
core = "7.x"
|
||||
project = "honeypot"
|
||||
datestamp = "1457672041"
|
||||
|
||||
datestamp = "1533849190"
|
||||
|
@@ -68,8 +68,8 @@ function honeypot_uninstall() {
|
||||
}
|
||||
}
|
||||
|
||||
// Delete 'honeypot' directory from public file directory.
|
||||
file_unmanaged_delete_recursive('public://honeypot');
|
||||
// Delete 'honeypot' directory from files directory.
|
||||
file_unmanaged_delete_recursive(honeypot_file_default_scheme() . '://honeypot');
|
||||
}
|
||||
|
||||
/**
|
||||
|
@@ -78,7 +78,7 @@ function honeypot_form_alter(&$form, &$form_state, $form_id) {
|
||||
if (variable_get('honeypot_protect_all_forms', 0) && !in_array($form_id, $unprotected_forms)) {
|
||||
// Don't protect system forms - only admins should have access, and system
|
||||
// forms may be programmatically submitted by drush and other modules.
|
||||
if (strpos($form_id, 'system_') === FALSE && strpos($form_id, 'search_') === FALSE && strpos($form_id, 'views_exposed_form_') === FALSE) {
|
||||
if (preg_match('/[^a-zA-Z]system_/', $form_id) === 0 && preg_match('/[^a-zA-Z]search_/', $form_id) === 0 && preg_match('/[^a-zA-Z]views_exposed_form_/', $form_id) === 0) {
|
||||
honeypot_add_form_protection($form, $form_state, array('honeypot', 'time_restriction'));
|
||||
}
|
||||
}
|
||||
@@ -135,6 +135,36 @@ function honeypot_rules_event_info() {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Implements hook_library().
|
||||
*/
|
||||
function honeypot_library() {
|
||||
$info = system_get_info('module', 'honeypot');
|
||||
$version = $info['version'];
|
||||
|
||||
// Library for Honeypot JS.
|
||||
$libraries['timestamp.js'] = array(
|
||||
'title' => 'Javascript to support timelimit on cached pages.',
|
||||
'version' => $version,
|
||||
'js' => array(
|
||||
array(
|
||||
'type' => 'setting',
|
||||
'data' => array(
|
||||
'honeypot' => array(
|
||||
'jsToken' => honeypot_get_signed_timestamp('js_token:' . mt_rand(0, 2147483647)),
|
||||
),
|
||||
),
|
||||
),
|
||||
drupal_get_path('module', 'honeypot') . '/js/honeypot.js' => array(
|
||||
'group' => JS_LIBRARY,
|
||||
'weight' => 3,
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $libraries;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an array of all the protected forms on the site, by form_id.
|
||||
*
|
||||
@@ -233,8 +263,16 @@ function honeypot_add_form_protection(&$form, &$form_state, $options = array())
|
||||
);
|
||||
|
||||
// Disable page caching to make sure timestamp isn't cached.
|
||||
if (user_is_anonymous()) {
|
||||
drupal_page_is_cacheable(FALSE);
|
||||
if (user_is_anonymous() && drupal_page_is_cacheable()) {
|
||||
// Use javascript implementation if this page should be cached.
|
||||
if (variable_get('honeypot_use_js_for_cached_pages', FALSE)) {
|
||||
$form['honeypot_time']['#default_value'] = 'no_js_available';
|
||||
$form['honeypot_time']['#attached']['library'][] = array('honeypot', 'timestamp.js');
|
||||
$form['#attributes']['class'][] = 'honeypot-timestamp-js';
|
||||
}
|
||||
else {
|
||||
drupal_page_is_cacheable(FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -261,7 +299,7 @@ function _honeypot_honeypot_validate($element, &$form_state) {
|
||||
/**
|
||||
* Validate honeypot's time restriction field.
|
||||
*/
|
||||
function _honeypot_time_restriction_validate($element, &$form_state) {
|
||||
function _honeypot_time_restriction_validate(&$element, &$form_state) {
|
||||
if (!empty($form_state['programmed'])) {
|
||||
// Don't do anything if the form was submitted programmatically.
|
||||
return;
|
||||
@@ -272,8 +310,43 @@ function _honeypot_time_restriction_validate($element, &$form_state) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Get the time value.
|
||||
$honeypot_time = honeypot_get_time_from_signed_timestamp($form_state['values']['honeypot_time']);
|
||||
if ($form_state['values']['honeypot_time'] == 'no_js_available') {
|
||||
// Set an error, but do not penalize the user as it might be a legitimate
|
||||
// attempt.
|
||||
form_set_error('', t('You seem to have javascript disabled. Please confirm your form submission.'));
|
||||
|
||||
if (variable_get('honeypot_log', 0)) {
|
||||
$variables = array(
|
||||
'%form' => $form_state['values']['form_id'],
|
||||
);
|
||||
watchdog('honeypot', 'User tried to submit form %form without javascript enabled.', $variables);
|
||||
}
|
||||
|
||||
// Update the value in $form_state and $element.
|
||||
$form_state['values']['honeypot_time'] = honeypot_get_signed_timestamp(REQUEST_TIME);
|
||||
$element['#value'] = $form_state['values']['honeypot_time'];
|
||||
return;
|
||||
}
|
||||
|
||||
$honeypot_time = FALSE;
|
||||
|
||||
// Update the honeypot_time for JS requests and get the $honeypot_time value.
|
||||
if (strpos($form_state['values']['honeypot_time'], 'js_token:') === 0) {
|
||||
$interval = _honeypot_get_interval_from_signed_js_value($form_state['values']['honeypot_time']);
|
||||
if ($interval) {
|
||||
// Set correct value for timestamp validation.
|
||||
$honeypot_time = REQUEST_TIME - $interval;
|
||||
|
||||
// Update form_state and element values so they're correct.
|
||||
$form_state['values']['honeypot_time'] = honeypot_get_signed_timestamp($honeypot_time);
|
||||
$element['#value'] = $form_state['values']['honeypot_time'];
|
||||
}
|
||||
}
|
||||
// Otherwise just get the $honeypot_time value.
|
||||
else {
|
||||
// Get the time value.
|
||||
$honeypot_time = honeypot_get_time_from_signed_timestamp($form_state['values']['honeypot_time']);
|
||||
}
|
||||
|
||||
// Get the honeypot_time_limit.
|
||||
$time_limit = honeypot_get_time_limit($form_state['values']);
|
||||
@@ -284,11 +357,43 @@ function _honeypot_time_restriction_validate($element, &$form_state) {
|
||||
_honeypot_log($form_state['values']['form_id'], 'honeypot_time');
|
||||
// Get the time limit again, since it increases after first failure.
|
||||
$time_limit = honeypot_get_time_limit($form_state['values']);
|
||||
// Update the honeypot_time value in the form state and element.
|
||||
$form_state['values']['honeypot_time'] = honeypot_get_signed_timestamp(REQUEST_TIME);
|
||||
$element['#value'] = $form_state['values']['honeypot_time'];
|
||||
form_set_error('', t('There was a problem with your form submission. Please wait @limit seconds and try again.', array('@limit' => $time_limit)));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an interval if the given javascript submitted value is valid.
|
||||
*
|
||||
* @param string $honeypot_time
|
||||
* The signed interval as submitted via javascript.
|
||||
*
|
||||
* @return int|FALSE
|
||||
* The interval in seconds if the token is valid, FALSE otherwise.
|
||||
*/
|
||||
function _honeypot_get_interval_from_signed_js_value($honeypot_time) {
|
||||
$t = explode('|', $honeypot_time);
|
||||
|
||||
if (count($t) != 3) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$js_token = $t[0] . '|' . $t[1];
|
||||
$token_check = honeypot_get_time_from_signed_timestamp($js_token);
|
||||
if (!$token_check) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
$interval = (int) $t[2];
|
||||
if ($interval == 0) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
return $interval;
|
||||
}
|
||||
|
||||
/**
|
||||
* Log blocked form submissions.
|
||||
*
|
||||
@@ -398,7 +503,7 @@ function honeypot_log_failure($form_id, $type) {
|
||||
* The path to the honeypot.css file.
|
||||
*/
|
||||
function honeypot_get_css_file_path() {
|
||||
return variable_get('file_public_path', conf_path() . '/files') . '/honeypot/honeypot.css';
|
||||
return honeypot_file_default_scheme() . '://honeypot/honeypot.css';
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -408,7 +513,7 @@ function honeypot_get_css_file_path() {
|
||||
* The honeypot element class name (e.g. 'url').
|
||||
*/
|
||||
function honeypot_create_css($element_name) {
|
||||
$path = 'public://honeypot';
|
||||
$path = honeypot_file_default_scheme() . '://honeypot';
|
||||
|
||||
if (!file_prepare_directory($path, FILE_CREATE_DIRECTORY)) {
|
||||
drupal_set_message(t('Unable to create Honeypot CSS directory, %path. Check the permissions on your files directory.', array('%path' => file_uri_target($path))), 'error');
|
||||
@@ -487,3 +592,15 @@ function honeypot_get_time_from_signed_timestamp($signed_timestamp) {
|
||||
|
||||
return $honeypot_time;
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the default file stream for honeypot.
|
||||
*
|
||||
* @return
|
||||
* 'public', 'private' or any other file scheme defined as the default.
|
||||
*
|
||||
* @see file_default_scheme()
|
||||
*/
|
||||
function honeypot_file_default_scheme() {
|
||||
return variable_get('honeypot_file_default_scheme', file_default_scheme());
|
||||
}
|
||||
|
@@ -366,6 +366,60 @@ class HoneypotCssTestCase extends DrupalWebTestCase {
|
||||
// Revert the honeypot element name back to the original.
|
||||
variable_set('honeypot_element_name', $original_element_name);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test CSS works when default file scheme is not public://
|
||||
*/
|
||||
public function testHoneypotCssNonpublicFileSystem() {
|
||||
variable_set('file_default_scheme', 'private');
|
||||
|
||||
$honeypot_css = honeypot_get_css_file_path();
|
||||
|
||||
// Delete the Honeypot CSS file (if it exists).
|
||||
file_unmanaged_delete($honeypot_css);
|
||||
|
||||
// Make sure the Honeypot CSS file doesn't exist.
|
||||
$this->assertFalse(file_exists($honeypot_css));
|
||||
|
||||
// Run cron.
|
||||
honeypot_cron();
|
||||
|
||||
// Make sure the Honeypot CSS file exists.
|
||||
$this->assertTrue(file_exists($honeypot_css));
|
||||
}
|
||||
|
||||
/**
|
||||
* Test CSS file availability.
|
||||
*/
|
||||
public function testHoneypotCssAvailability() {
|
||||
// Public CSS file can be consumed.
|
||||
variable_set('file_default_scheme', 'public');
|
||||
if ($wrapper = file_stream_wrapper_get_instance_by_uri(honeypot_get_css_file_path())) {
|
||||
$url = $wrapper->getExternalUrl();
|
||||
}
|
||||
$this->drupalGet($url);
|
||||
$this->assertResponse(200);
|
||||
|
||||
|
||||
// Private CSS file can not be consumed.
|
||||
variable_set('file_default_scheme', 'private');
|
||||
honeypot_cron();
|
||||
if ($wrapper = file_stream_wrapper_get_instance_by_uri(honeypot_get_css_file_path())) {
|
||||
$url = $wrapper->getExternalUrl();
|
||||
}
|
||||
$this->drupalGet($url);
|
||||
$this->assertNoResponse(200);
|
||||
|
||||
// Site default is private, but override honeypot's to public to consume.
|
||||
variable_set('honeypot_file_default_scheme', 'public');
|
||||
honeypot_cron();
|
||||
if ($wrapper = file_stream_wrapper_get_instance_by_uri(honeypot_get_css_file_path())) {
|
||||
$url = $wrapper->getExternalUrl();
|
||||
}
|
||||
$this->drupalGet($url);
|
||||
$this->assertResponse(200);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -423,4 +477,5 @@ class HoneypotTriggerTestCase extends DrupalWebTestCase {
|
||||
$this->drupalGet('node');
|
||||
$this->assertText(t('has been banned'), 'User banned successfully.');
|
||||
}
|
||||
|
||||
}
|
||||
|
37
sites/all/modules/contrib/form/honeypot/js/honeypot.js
Normal file
37
sites/all/modules/contrib/form/honeypot/js/honeypot.js
Normal file
@@ -0,0 +1,37 @@
|
||||
(function ($) {
|
||||
|
||||
Drupal.honeypot = {};
|
||||
Drupal.honeypot.timestampJS = new Date();
|
||||
|
||||
Drupal.behaviors.honeypotJS = {
|
||||
attach: function (context, settings) {
|
||||
$('form.honeypot-timestamp-js').once('honeypot-timestamp').bind('submit', function() {
|
||||
var $honeypotTime = $(this).find('input[name="honeypot_time"]');
|
||||
$honeypotTime.attr('value', Drupal.behaviors.honeypotJS.getIntervalTimestamp());
|
||||
});
|
||||
},
|
||||
getIntervalTimestamp: function() {
|
||||
var now = new Date();
|
||||
var interval = Math.floor((now - Drupal.honeypot.timestampJS) / 1000);
|
||||
return Drupal.settings.honeypot.jsToken + '|' + interval;
|
||||
}
|
||||
};
|
||||
|
||||
if (Drupal.ajax && Drupal.ajax.prototype && Drupal.ajax.prototype.beforeSubmit) {
|
||||
Drupal.ajax.prototype.honeypotOriginalBeforeSubmit = Drupal.ajax.prototype.beforeSubmit;
|
||||
Drupal.ajax.prototype.beforeSubmit = function (form_values, element, options) {
|
||||
if (this.form && $(this.form).hasClass('honeypot-timestamp-js')) {
|
||||
for (key in form_values) {
|
||||
// Inject the right interval timestamp.
|
||||
if (form_values[key].name == 'honeypot_time' && form_values[key].value == 'no_js_available') {
|
||||
form_values[key].value = Drupal.behaviors.honeypotJS.getIntervalTimestamp();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Call the original function in case someone else has overridden it.
|
||||
return Drupal.ajax.prototype.honeypotOriginalBeforeSubmit(form_values, element, options);
|
||||
}
|
||||
}
|
||||
|
||||
}(jQuery));
|
@@ -4,9 +4,8 @@ core = 7.x
|
||||
package = Testing
|
||||
hidden = true
|
||||
|
||||
; Information added by Drupal.org packaging script on 2016-03-11
|
||||
version = "7.x-1.22"
|
||||
; Information added by Drupal.org packaging script on 2018-08-09
|
||||
version = "7.x-1.25"
|
||||
core = "7.x"
|
||||
project = "honeypot"
|
||||
datestamp = "1457672041"
|
||||
|
||||
datestamp = "1533849190"
|
||||
|
Reference in New Issue
Block a user