Commit c2e3e308 authored by Aaron Wells's avatar Aaron Wells Committed by Gerrit Code Review

Adding reCAPTCHA support to user self-registration page

Bug 1252098

Change-Id: I9f2386fcb69510a23f66efc3bce32697fb8c8616
parent a68681d8
......@@ -417,6 +417,28 @@ $siteoptionform = array(
'help' => true,
'disabled' => in_array('disableexternalresources', $OVERRIDDEN),
),
'recaptchaonregisterform' => array(
'type' => 'checkbox',
'title' => get_string('recaptchaonregisterform', 'admin'),
'description' => get_string('recaptchaonregisterformdesc', 'admin'),
'defaultvalue' => get_config('recaptchaonregisterform', 'admin'),
'help' => true,
'disabled' => in_array('recaptchaonregisterform', $OVERRIDDEN)
),
'recaptchapublickey' => array(
'type' => 'text',
'title' => get_string('recaptchapublickey', 'admin'),
'description' => get_string('recaptchapublickeydesc', 'admin'),
'defaultvalue' => get_config('recaptchapublickey'),
'disabled' => in_array('recaptchapublickey', $OVERRIDDEN)
),
'recaptchaprivatekey' => array(
'type' => 'text',
'title' => get_string('recaptchaprivatekey', 'admin'),
'description' => get_string('recaptchaprivatekeydesc', 'admin'),
'defaultvalue' => get_config('recaptchaprivatekey'),
'disabled' => in_array('recaptchaprivatekey', $OVERRIDDEN)
),
),
),
# TODO: this should become "Network Settings" at some point
......@@ -701,7 +723,8 @@ function siteoptions_submit(Pieform $form, $values) {
'registration_sendweeklyupdates', 'institutionexpirynotification', 'institutionautosuspend',
'showselfsearchsideblock', 'searchusernames', 'searchplugin', 'showtagssideblock',
'tagssideblockmaxtags', 'country', 'viewmicroheaders', 'userscanchooseviewthemes',
'remoteavatars', 'userscanhiderealnames', 'antispam', 'spamhaus', 'surbl', 'anonymouscomments', 'loggedinprofileviewaccess', 'disableexternalresources',
'remoteavatars', 'userscanhiderealnames', 'antispam', 'spamhaus', 'surbl', 'anonymouscomments',
'recaptchaonregisterform', 'recaptchapublickey', 'recaptchaprivatekey', 'loggedinprofileviewaccess', 'disableexternalresources',
'proxyaddress', 'proxyauthmodel', 'proxyauthcredentials', 'smtphosts', 'smtpport', 'smtpuser', 'smtppass', 'smtpsecure',
'noreplyaddress', 'defaultnotificationmethod', 'homepageinfo', 'showonlineuserssideblock', 'onlineuserssideblockmaxusers',
'registerterms', 'licensemetadata', 'licenseallowcustom', 'allowmobileuploads', 'creategroups', 'createpublicgroups', 'allowgroupcategories', 'wysiwyg',
......@@ -810,6 +833,21 @@ function siteoptions_submit(Pieform $form, $values) {
}
}
if (get_config('recaptchaonregisterform')
&& !(
get_config('recaptchapublickey')
&& get_config('recaptchaprivatekey')
)
) {
$form->reply(
PIEFORM_ERR,
array(
'message' => get_string('recaptchakeysmissing', 'admin'),
'goto' => '/admin/site/options.php',
)
);
}
$message = get_string('siteoptionsset', 'admin');
if ($oldtheme != $values['theme']) {
global $USER;
......
......@@ -22,6 +22,8 @@ $string['passwordformdescription'] = 'Your password must be at least six charact
For good security, consider using a passphrase. A passphrase is a sentence rather than a single word. Consider using a favourite quote or listing two (or more!) of your favourite things separated by spaces.';
$string['passwordinvalidform'] = 'Your password must be at least six characters long. Passwords are case sensitive and must be different from your username.<br/>
For good security, consider using a passphrase. A passphrase is a sentence rather than a single word. Consider using a favourite quote or listing two (or more!) of your favourite things separated by spaces.';
$string['recaptcharegistertitle'] = 'reCAPTCHA challenge';
$string['recaptcharegisterdesc'] = 'Please enter the words you see in the box, in order and separated by a space. Doing so helps prevent automated programs from abusing this service.';
$string['registeredemailsubject'] = 'You have registered at %s';
$string['registeredemailmessagetext'] = 'Hi %s,
......
......@@ -66,6 +66,10 @@ class AuthInternal extends Auth {
return false;
}
public static function can_use_registration_captcha() {
return true;
}
/**
* For internal authentication, passwords can contain a range of letters,
* numbers and symbols. There is a minimum limit of six characters allowed
......
......@@ -224,27 +224,36 @@ abstract class Auth {
}
/**
* Returns whether the authentication instance can automatically create a
* Returns whether the authentication instance can automatically create a
* user record.
*
* Auto creating users means that the authentication plugin can say that
* Auto creating users means that the authentication plugin can say that
* users who don't exist yet in Mahara's usr table are allowed, and Mahara
* should create a user account for them. Example: the first time a user logs
* in, when authenticating against an ldap store or similar).
*
* However, if a plugin says a user can be authenticated, then it must
* implement the get_user_info() method which will be called to find out
* information about the user so a record in the usr table _can_ be created
* However, if a plugin says a user can be authenticated, then it must
* implement the get_user_info() method which will be called to find out
* information about the user so a record in the usr table _can_ be created
* for the new user.
*
* Authentication methods must implement this method. Some may choose to
* implement it by returning an instance config value that the admin user
* Authentication methods must implement this method. Some may choose to
* implement it by returning an instance config value that the admin user
* can set.
*
* @return bool
*/
public abstract function can_auto_create_users();
/**
* If this plugin allows new user's to self-register, this function will be
* called to check whether it is okay to display a captcha method on the new
* user self-registration form.
*/
public static function can_use_registration_captcha() {
return true;
}
/**
* Given a username, returns a hash of information about a user from the
* external data source.
......@@ -2067,6 +2076,12 @@ function auth_generate_registration_form($formname, $authname='internal', $goto)
);
}
if (call_static_method('Auth'.ucfirst($authname), 'can_use_registration_captcha')) {
$elements['captcha'] = array(
'type' => 'captcha',
);
}
$elements['submit'] = array(
'type' => 'submit',
'value' => get_string('register'),
......
......@@ -341,6 +341,14 @@ $string['licenseallowcustom'] = 'Allow custom licenses';
$string['licenseallowcustomdescription'] = "For license metadata, allow users to enter any URL as the license. If not checked, users will be limited to the licenses configured by the site administrator.";
$string['allowmobileuploads'] = 'Allow mobile uploads';
$string['allowmobileuploadsdescription'] = 'If checked, users will have the option of setting an authentication token. Content uploaded with this token will be saved as artefacts.';
$string['recaptchakeysmissing'] = 'reCAPTCHA is turned on, but it will not function until you also provide a private and public key.';
$string['recaptchanotpassed'] = 'The reCAPTCHA wasn\'t entered correctly. Please try it again.';
$string['recaptchaonregisterform'] = 'reCAPTCHA on user registration form';
$string['recaptchaonregisterformdesc'] = 'If checked, users self-registering a new account will have to prove themselves human by passing a <a href="http://recaptcha.org/">reCAPTCHA</a> test.';
$string['recaptchaprivatekey'] = 'reCAPTCHA private key';
$string['recaptchaprivatekeydesc'] = 'The private key for your site\'s reCAPTCHA account.';
$string['recaptchapublickey'] = 'reCAPTCHA public key';
$string['recaptchapublickeydesc'] = 'The public key for your site\'s reCAPTCHA account.';
$string['remoteavatars'] = 'Display remote avatars';
$string['remoteavatarsdescription'] = 'If checked, the <a href="http://www.gravatar.com">Gravatar</a> service will be used for users\' default profile pictures.';
$string['searchplugin'] = 'Search plugin';
......
<!-- @license http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later -->
<!-- @copyright For copyright information on Mahara, please see the README file distributed with this software. -->
<h3>reCAPTCHA on register form</h3>
<p>If checked, users self-registering a new account will have to prove themselves human by passing a reCAPTCHA test.
This should prevent spam accounts from being created by an automated script.</p>
<p>In order for this feature to work, you will also need to provide a reCAPTCHA public and private key. You can obtain these from the reCAPTCHA
website, <a href="http://recaptcha.org">http://recaptcha.org</a>.</p>
<?php
/**
* @package mahara
* @subpackage form-element
* @author Catalyst IT Ltd
* @license http://www.gnu.org/copyleft/gpl.html GNU GPL version 3 or later
* @copyright For copyright information on Mahara, please see the README file distributed with this software.
*
*/
/**
* Defines a form element that adds a CAPTCHA to a form. To use, simply add an element of
* type "captcha" to your form, in the point where you want the CAPTCHA field to display:
*
* $elements['captcha'] = array(
* 'type' => 'captcha',
* );
*
* You can optionally also fill in the title and description. If not supplied, default
* values will be used.
*
* The CAPTCHA element will only be displayed if a CAPTCHA method is configured and enabled
* in the sitewide settings. If it is displayed, it will validate the user's input
* automagically.
*
* @param Pieform $form
* @param array $element
*/
function pieform_element_captcha(Pieform $form, &$element) {
// TODO: Make this a pluggable system for other CAPTCHA providers?
return recaptcha_get_html(get_config('recaptchapublickey'));
}
/**
* The CAPTCHA element returns no value. Its only purpose is validation.
*
* @param Pieform $form
* @param array $element
*/
function pieform_element_captcha_get_value(Pieform $form, $element) {
return null;
}
/**
* Hide the element if captcha is not enabled and configured.
*
* If we are showing the element, add a "rule" to it in order to trigger validation.
*
* @param array $element
* @return mixed Boolean FALSE if the element shouldn't be displayed; the modified element if it should be displayed
*/
function pieform_element_captcha_set_attributes($element) {
if (
get_config('recaptchaonregisterform')
&& get_config('recaptchapublickey')
&& get_config('recaptchaprivatekey')
) {
require_once(get_config('libroot').'recaptcha/recaptchalib.php');
if (array_key_exists('rules', $element)) {
$element['rules'] = array();
}
$element['rules']['validate'] = array();
if (empty($element['description'])) {
$element['description'] = get_string('recaptcharegisterdesc', 'auth.internal');
}
if (empty($element['title'])) {
$element['title'] = get_string('recaptcharegistertitle', 'auth.internal');
}
}
else {
// Don't display this element if captcha not configured
return false;
}
return $element;
}
/**
* Validate the CAPTCHA.
*
* @param Pieform $form
* @param string $value
* @param array $element
* @param array $data
* @return mixed An error string if validation failed; boolean FALSE if validation passed
*/
function pieform_element_captcha_rule_validate(Pieform $form, $value, $element, $data) {
$resp = recaptcha_check_answer(
get_config('recaptchaprivatekey'),
$_SERVER['REMOTE_ADDR'],
$_POST['recaptcha_challenge_field'],
$_POST['recaptcha_response_field']
);
if (!$resp->is_valid) {
return get_string('recaptchanotpassed', 'admin');
}
return false;
}
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment