Skip to content

Commit

Permalink
Enable time limits on registration
Browse files Browse the repository at this point in the history
  • Loading branch information
ctgraham committed May 31, 2018
1 parent 2c0baf4 commit a4b5a73
Show file tree
Hide file tree
Showing 5 changed files with 84 additions and 13 deletions.
57 changes: 54 additions & 3 deletions FormHoneypotPlugin.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ class FormHoneypotPlugin extends GenericPlugin {

/**
* @var $availableElements array()
* This array this the possible input elements
* This array lists the possible input elements
*/
public $availableElements = array(
'userUrl' => 'user.url',
Expand All @@ -30,7 +30,23 @@ class FormHoneypotPlugin extends GenericPlugin {
'signature' => 'user.signature',
'biography' => 'user.biography',
);


/**
* @var $settingNames array()
* This array represents the fields on the settings form
*/
public $settingNames = array(
'element' => 'string',
'minimumTime' => 'int',
'maximumTime' => 'int',
);

/**
* @var $formTimerSetting string
* This is the name of the setting used to track a users time during registration
*/
public $formTimerSetting = 'registrationTimer';

/**
* Called as a plugin is registered to the registry
* @param $category String Name of category plugin was registered to
Expand All @@ -45,6 +61,8 @@ function register($category, $path) {
HookRegistry::register('Templates::Common::Footer::PageFooter', array($this, 'insertHtml'));
// Attach to the registration form validation
HookRegistry::register('registrationform::validate', array($this, 'validateHoneypot'));
// Attach to the registration form display
HookRegistry::register('registrationform::display', array($this, 'initializeTimer'));
}
return $success;
}
Expand Down Expand Up @@ -145,6 +163,8 @@ function validateHoneypot($hookName, $params) {
$journal =& Request::getJournal();
if (isset($journal)) {
$element = $this->getSetting($journal->getId(), 'element');
$minTime = $this->getSetting($journal->getId(), 'minimumTime');
$maxTime = $this->getSetting($journal->getId(), 'maximumTime');
}
$form = $params[0];
// If we have an element selected as a honeypot, check it
Expand All @@ -163,6 +183,37 @@ function validateHoneypot($hookName, $params) {
);
}
}
if ($form && $form->isValid() && ($minTime > 0 || $maxTime > 0)) {
// Get the initial access to this form within this session
$sessionManager =& SessionManager::getManager();
$session =& $sessionManager->getUserSession();
$started = $session->getSessionVar($this->getName()."::".$this->formTimerSetting);
if (!$started || ($minTime > 0 && time() - $started < $minTime) || ($maxTime > 0 && time() - $started > $maxTime)) {
$form->addError(
'username',
__('plugins.generic.formHoneypot.invalidSessionTime')
);
} else {
$started = $session->unsetSessionVar($this->getName()."::".$this->formTimerSetting);
}
}
return false;
}

/**
* Start monitoring for timing for form completion
* @param $hookName string Name of hook calling function
* @return boolean
*/
function initializeTimer($hookName) {
// remember when this form was initialized for the user
// we'll store it as a user setting on form execution
$sessionManager =& SessionManager::getManager();
$session =& $sessionManager->getUserSession();
$started = $session->getSessionVar($this->getName()."::".$this->formTimerSetting);
if (!$started) {
$session->setSessionVar($this->getName()."::".$this->formTimerSetting, time());
}
return false;
}

Expand Down Expand Up @@ -193,7 +244,7 @@ function manage($verb, $args, &$message, &$messageParams) {
$this->import('FormHoneypotSettingsForm');
$form = new FormHoneypotSettingsForm($this, $journal->getId());
// This assigns select options
$templateMgr->assign('elementOptions', $this->availableElements);
$templateMgr->assign('elementOptions', array_merge(array('' => ''), $this->availableElements));
if (Request::getUserVar('save')) {
$form->readInputData();
if ($form->validate()) {
Expand Down
13 changes: 9 additions & 4 deletions FormHoneypotSettingsForm.inc.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ function FormHoneypotSettingsForm(&$plugin, $journalId) {

parent::Form($plugin->getTemplatePath() . 'settingsForm.tpl');

$this->addCheck(new FormValidator($this, 'element', 'required', 'plugins.generic.formHoneypot.manager.settings.elementRequired'));
$this->addCheck(new FormValidatorCustom($this, 'minimumTime', 'optional', 'plugins.generic.formHoneypot.manager.settings.minimumTimeNumber', create_function('$s', 'return ($s === "0" || $s > 0);')));
$this->addCheck(new FormValidatorCustom($this, 'maximimTime', 'optional', 'plugins.generic.formHoneypot.manager.settings.maximumTimeNumber', create_function('$s', 'return ($s === "0" || $s > 0);')));
$this->addCheck(new FormValidatorPost($this));
}

Expand All @@ -44,14 +45,16 @@ function FormHoneypotSettingsForm(&$plugin, $journalId) {
function initData() {
$journalId = $this->journalId;
$plugin =& $this->plugin;
$this->_data['element'] = $plugin->getSetting($journalId, 'element');
foreach (array_keys($this->plugin->settingNames) as $k) {
$this->_data[$k] = $plugin->getSetting($journalId, $k);
}
}

/**
* Assign form data to user-submitted data.
*/
function readInputData() {
$this->readUserVars(array('element'));
$this->readUserVars(array_keys($this->plugin->settingNames));
}

/**
Expand All @@ -60,7 +63,9 @@ function readInputData() {
function execute() {
$plugin =& $this->plugin;
$journalId = $this->journalId;
$plugin->updateSetting($journalId, 'element', $this->getData('element'), 'string');
foreach ($this->plugin->settingNames as $k => $v) {
$plugin->updateSetting($journalId, $k, $this->getData($k), $v);
}
}

}
Expand Down
9 changes: 6 additions & 3 deletions locale/en_US/locale.xml
Original file line number Diff line number Diff line change
Expand Up @@ -14,13 +14,16 @@

<!-- Form Honeypot -->
<message key="plugins.generic.formHoneypot.displayName">Form Honeypot Plugin</message>
<message key="plugins.generic.formHoneypot.description"><![CDATA[This plugin will convert one of the fields on the user registration form into a honeypot. This field will be hidden from users and an error will be presented if a bot fills out the field.]]></message>
<message key="plugins.generic.formHoneypot.description"><![CDATA[This plugin will convert one of the fields on the user registration form into a honeypot. This field will be hidden from users and an error will be presented if a bot fills out the field. You may also select a minimum and maximum time to allow for form completion. For example, if a bot completes the form in under 2 seconds or tries to use the same form 30 minutes (1800 seconds) later, the registration can be blocked.]]></message>
<message key="plugins.generic.formHoneypot.leaveBlank">Leave this blank</message>
<message key="plugins.generic.formHoneypot.doNotUseThisField">This field must be left blank: {$element}</message>

<message key="plugins.generic.formHoneypot.invalidSessionTime">Your registration has been blocked.</message>
<!-- Form Honeypot Settings Management -->
<message key="plugins.generic.formHoneypot.manager.formHoneypotSettings">Form Honeypot Settings</message>
<message key="plugins.generic.formHoneypot.manager.settings.description"><![CDATA[Select the field on the registration form which you would like to convert into a bot honeypot. This field will be hidden from normal users via javascript, but bots are likely to still see and to try to use the field. Using this field will result in a registration error. The field will still be available to users from the user profile form after registration.]]></message>
<message key="plugins.generic.formHoneypot.manager.settings.element">Form Element</message>
<message key="plugins.generic.formHoneypot.manager.settings.elementRequired">The form element selection is required.</message>
<message key="plugins.generic.formHoneypot.manager.settings.minimumTime">Minimum time (in seconds)</message>
<message key="plugins.generic.formHoneypot.manager.settings.minimumTimeNumber">Minimum time must be a positive numeric value.</message>
<message key="plugins.generic.formHoneypot.manager.settings.maximumTime">Maximum time (in seconds)</message>
<message key="plugins.generic.formHoneypot.manager.settings.maximumTimeNumber">Maximum time must be a positive numeric value.</message>
</locale>
14 changes: 13 additions & 1 deletion settingsForm.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,25 @@
{include file="common/formErrors.tpl"}
<table width="100%" class="data">
<tr valign="top">
<td width="20%" class="label">{fieldLabel name="formHoneypotElement" required="true" key="plugins.generic.formHoneypot.manager.settings.element"}</td>
<td width="20%" class="label">{fieldLabel name="formHoneypotElement" key="plugins.generic.formHoneypot.manager.settings.element"}</td>
<td width="80%" class="value">
<select class="selectMenu" name="element" id="element">
{html_options_translate options=$elementOptions selected=$element}
</select>
</td>
</tr>
<tr valign="top">
<td width="20%" class="label">{fieldLabel name="minimimTime" key="plugins.generic.formHoneypot.manager.settings.minimumTime"}</td>
<td width="80%" class="value">
<input type="text" name="minimumTime" id="minimumTime" value="{$minimumTime|escape}" size="15" maxlength="15" class="textField" />
</td>
</tr>
<tr valign="top">
<td width="20%" class="label">{fieldLabel name="maximumTime" key="plugins.generic.formHoneypot.manager.settings.maximumTime"}</td>
<td width="80%" class="value">
<input type="text" name="maximumTime" id="formHoneypotMaximumTime" value="{$maximumTime|escape}" size="15" maxlength="15" class="textField" />
</td>
</tr>
</table>

<br/>
Expand Down
4 changes: 2 additions & 2 deletions version.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,8 @@
<version>
<application>formHoneypot</application>
<type>plugins.generic</type>
<release>1.0.0.0</release>
<date>2018-05-22</date>
<release>1.1.0.0</release>
<date>2018-05-31</date>
<lazy-load>1</lazy-load>
<class>FormHoneypotPlugin</class>
</version>

0 comments on commit a4b5a73

Please sign in to comment.