updated mailgun, mailsystem, honeypot, googleanalitycs, features, content_taxonomy

This commit is contained in:
2019-05-13 17:55:28 +02:00
parent 2ffad14939
commit e08a2639c6
54 changed files with 1911 additions and 423 deletions

View File

@@ -0,0 +1,58 @@
# Honeypot
[![Build Status](https://travis-ci.org/geerlingguy/drupal-honeypot.svg?branch=7.x-1.x)](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).

View File

@@ -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).

View 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"

View File

@@ -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(

View File

@@ -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"

View File

@@ -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');
}
/**

View File

@@ -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());
}

View File

@@ -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.');
}
}

View 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));

View File

@@ -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"