diff options
author | brettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544> | 2010-09-30 19:56:49 +0000 |
---|---|---|
committer | brettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544> | 2010-09-30 19:56:49 +0000 |
commit | fad92747bec989fd6728eb7349c9ede4674764ff (patch) | |
tree | 6f1c6ca613dff0af2a769c6b13aa97d00cb432a9 /mod | |
parent | 9af90ffc9a20033ca9fdd9182122c01600a0867b (diff) | |
download | elgg-fad92747bec989fd6728eb7349c9ede4674764ff.tar.gz elgg-fad92747bec989fd6728eb7349c9ede4674764ff.tar.bz2 |
Fixes #617, #2271 User validation removed from core to UserValidationByEmail plugin. Without a validation plugin, users can login immediately.
Fixes #2243 Removed "You have validated your email" email. Users are logged in immediately after registration or validating email.
Refs #2409 Added register, user plugin hook that is called only on self registration. Can be used to halt registration.
git-svn-id: http://code.elgg.org/elgg/trunk@6983 36083f99-b078-4883-b0ff-0f9b5a30f544
Diffstat (limited to 'mod')
-rw-r--r-- | mod/uservalidationbyemail/languages/en.php | 52 | ||||
-rw-r--r-- | mod/uservalidationbyemail/lib/functions.php | 107 | ||||
-rw-r--r-- | mod/uservalidationbyemail/start.php | 216 |
3 files changed, 279 insertions, 96 deletions
diff --git a/mod/uservalidationbyemail/languages/en.php b/mod/uservalidationbyemail/languages/en.php index 44eb5e45b..6b3a6f708 100644 --- a/mod/uservalidationbyemail/languages/en.php +++ b/mod/uservalidationbyemail/languages/en.php @@ -1,33 +1,31 @@ <?php - /** - * Email user validation plugin language pack. - * - * @package ElggUserValidationByEmail - * @author Curverider Ltd - * @link http://elgg.com/ - */ - - $english = array( - - 'email:validate:subject' => "%s please confirm your email address!", - 'email:validate:body' => "Hi %s, +/** + * Email user validation plugin language pack. + * + * @package Elgg.Core.Plugin + * @subpackage ElggUserValidationByEmail + */ + +$english = array( + 'email:validate:subject' => "%s please confirm your email address for %s!", + 'email:validate:body' => "%s, + +Before you can start you using %s, you must confirm your email address. Please confirm your email address by clicking on the link below: %s + +If you can't click on the link, copy and paste it to your browser manually. + +%s +%s ", - 'email:validate:success:subject' => "Email validated %s!", - 'email:validate:success:body' => "Hi %s, - -Congratulations, you have successfully validated your email address.", - - - 'email:confirm:success' => "You have confirmed your email address!", - 'email:confirm:fail' => "Your email address could not be verified...", - - 'uservalidationbyemail:registerok' => "To activate your account, please confirm your email address by clicking on the link we just sent you." - - ); - - add_translation("en",$english); -?>
\ No newline at end of file + 'email:confirm:success' => "You have confirmed your email address!", + 'email:confirm:fail' => "Your email address could not be verified...", + + 'uservalidationbyemail:registerok' => "To activate your account, please confirm your email address by clicking on the link we just sent you." + +); + +add_translation("en", $english);
\ No newline at end of file diff --git a/mod/uservalidationbyemail/lib/functions.php b/mod/uservalidationbyemail/lib/functions.php new file mode 100644 index 000000000..ed66b40d4 --- /dev/null +++ b/mod/uservalidationbyemail/lib/functions.php @@ -0,0 +1,107 @@ +<?php +/** + * Helper functions + * + * @package Elgg.Core.Plugin + * @subpackage UserValidationByEmail + */ + +/** + * Generate an email activation code. + * + * @param int $user_guid The guid of the user + * @param string $email_address Email address + * @return string + */ +function uservalidationbyemail_generate_code($user_guid, $email_address) { + global $CONFIG; + + // Note I bind to site URL, this is important on multisite! + return md5($user_guid . $email_address . $CONFIG->site->url . get_site_secret()); +} + +/** + * Request user validation email. + * Send email out to the address and request a confirmation. + * + * @param int $user_guid The user + * @return mixed + */ +function uservalidationbyemail_request_validation($user_guid) { + global $CONFIG; + + $user_guid = (int)$user_guid; + $user = get_entity($user_guid); + + if (($user) && ($user instanceof ElggUser)) { + // Work out validate link + $code = uservalidationbyemail_generate_code($user_guid, $user->email); + $link = "{$CONFIG->site->url}pg/uservalidationbyemail/confirm?u=$user_guid&c=$code"; + $site = $CONFIG->site; + + // Send validation email + $subject = sprintf(elgg_echo('email:validate:subject'), $user->name, $site->name); + $body = sprintf(elgg_echo('email:validate:body'), $user->name, $site->name, $link, $site->name, $site->url); + $result = notify_user($user->guid, $CONFIG->site->guid, $subject, $body, NULL, 'email'); + + if ($result) { + system_message(elgg_echo('uservalidationbyemail:registerok')); + } + + return $result; + } + + return FALSE; +} + +/** + * Validate a user + * + * @param unknown_type $user_guid + * @param unknown_type $code + * @return unknown + */ +function uservalidationbyemail_validate_email($user_guid, $code) { + $user = get_entity($user_guid); + + if ($code == uservalidationbyemail_generate_code($user_guid, $user->email)) { + return uservalidationbyemail_set_user_validation_status($user_guid, true, 'email'); + } + + return false; +} + +/** + * Set the validation status for a user. + * + * @param bool $status Validated (true) or false + * @param string $method Optional method to say how a user was validated + * @return bool + */ +function uservalidationbyemail_set_user_validation_status($user_guid, $status, $method = '') { + if (!$status) { + $method = ''; + } + + if ($status) { + if ( + (create_metadata($user_guid, 'validated', $status,'', 0, ACCESS_PUBLIC)) && + (create_metadata($user_guid, 'validated_method', $method,'', 0, ACCESS_PUBLIC)) + ) { + return TRUE; + } + } else { + $validated = get_metadata_byname($user_guid, 'validated'); + $validated_method = get_metadata_byname($user_guid, 'validated_method'); + + if ( + ($validated) && + ($validated_method) && + (delete_metadata($validated->id)) && + (delete_metadata($validated_method->id)) + ) + return TRUE; + } + + return FALSE; +}
\ No newline at end of file diff --git a/mod/uservalidationbyemail/start.php b/mod/uservalidationbyemail/start.php index 3ce7542c2..677fea231 100644 --- a/mod/uservalidationbyemail/start.php +++ b/mod/uservalidationbyemail/start.php @@ -1,36 +1,120 @@ <?php /** * Email user validation plugin. - * Non-admin or admin created accounts are invalid until their email address is confirmed. + * Non-admin accounts are invalid until their email address is confirmed. * - * @package ElggUserValidationByEmail - * @author Curverider Ltd - * @link http://elgg.com/ + * @package Elgg.Core.Plugin + * @subpackage UserValidationByEmail */ function uservalidationbyemail_init() { global $CONFIG; + require_once dirname(__FILE__) . '/lib/functions.php'; + // Register page handler to validate users - // This isn't an action because security is handled by the validation codes. + // This doesn't need to be an action because security is handled by the validation codes. register_page_handler('uservalidationbyemail', 'uservalidationbyemail_page_handler'); - // Register hook listening to new users. - register_elgg_event_handler('validate', 'user', 'uservalidationbyemail_email_validation'); - + // mark users as unvalidated when they register + register_plugin_hook('register', 'user', 'uservalidationbyemail_disable_new_user'); + + // prevent users from logging in if they aren't validated + register_plugin_hook('action', 'login', 'uservalidationbyemail_check_login_attempt'); + + // when requesting a new password + register_plugin_hook('action', 'user/requestnewpassword', 'uservalidationbyemail_check_request_password'); + + // prevent the engine from logging in users via login() + register_elgg_event_handler('login', 'user', 'uservalidationbyemail_check_manual_login'); + + // make admin users always validated + register_elgg_event_handler('make_admin', 'user', 'uservalidationbyemail_validate_new_admin_user'); + // register Walled Garden public pages register_plugin_hook('public_pages', 'walled_garden', 'uservalidationbyemail_public_pages'); } /** - * Get security token, forward to action. + * Disables a user upon registration. + * + * @param unknown_type $hook + * @param unknown_type $type + * @param unknown_type $value + * @param unknown_type $params + */ +function uservalidationbyemail_disable_new_user($hook, $type, $value, $params) { + $user = elgg_get_array_value('user', $params); + + // no clue what's going on, so don't react. + if (!$user instanceof ElggUser) { + return NULL; + } + + // disable user to prevent showing up on the site + // Don't do a recursive disable. Any entities owned by the user at this point + // are products of plugins that hook into create user and might need + // access to the entities. + // @todo That ^ sounds like a specific case...would be nice to track it down... + $user->disable('uservalidationbyemail_new_user', FALSE); + + // set user as unvalidated and send out validation email + uservalidationbyemail_set_user_validation_status($user->guid, FALSE); + uservalidationbyemail_request_validation($user->guid); + + return TRUE; +} + +/** + * Checks if a login failed because the user hasn't validated his account. + * + * @param unknown_type $hook + * @param unknown_type $type + * @param unknown_type $value + * @param unknown_type $params + */ +function uservalidationbyemail_check_login_attempt($hook, $type, $value, $params) { + // everything is only stored in the input at this point + $username = get_input('username'); + $password = get_input("password"); + + if (empty($username) || empty($password)) { + // return true to let the original login action deal with it. + return TRUE; + } + + // see if we need to resolve an email address to a username + if (strpos($username, '@') !== FALSE && ($users = get_user_by_email($username))) { + $username = $users[0]->username; + } + + // See the users exists and isn't validated + $access_status = access_get_show_hidden_status(); + access_show_hidden_entities(TRUE); + + $user = get_user_by_username($username); + + // only resend validation if the password is correct + if ($user && authenticate($username, $password) && !$user->validated) { + // show an error and resend validation email + uservalidationbyemail_request_validation($user->guid); + // halt action + $value = FALSE; + } + + access_show_hidden_entities($access_status); + + return $value; +} + +/** + * Checks sent passed validation code and user guids and validates the user. * - * @param unknown_type $page - * @return unknown_type + * @param array $page */ function uservalidationbyemail_page_handler($page) { global $CONFIG; - + if (isset($page[0]) && $page[0] == 'confirm') { $code = sanitise_string(get_input('c', FALSE)); $user_guid = get_input('u', FALSE); @@ -47,9 +131,7 @@ function uservalidationbyemail_page_handler($page) { $user = get_entity($user_guid); $user->enable(); - - notify_user($user_guid, $CONFIG->site->guid, sprintf(elgg_echo('email:validate:success:subject'), $user->username), sprintf(elgg_echo('email:validate:success:body'), $user->name), NULL, 'email'); - + login($user); } else { register_error(elgg_echo('email:confirm:fail')); } @@ -66,84 +148,80 @@ function uservalidationbyemail_page_handler($page) { } /** - * Request email validation. + * Make sure any admin users are automatically validated + * + * @param unknown_type $event + * @param unknown_type $type + * @param unknown_type $object */ -function uservalidationbyemail_email_validation($event, $object_type, $object) { - if (($object) && ($object instanceof ElggUser)) { - uservalidationbyemail_request_validation($object->guid); +function uservalidationbyemail_validate_new_admin_user($event, $type, $user) { + if ($user instanceof ElggUser && !$user->validated) { + uservalidationbyemail_set_user_validation_status($user->guid, TRUE, 'admin_user'); } - return true; + return TRUE; } /** - * Generate an email activation code. - * - * @param int $user_guid The guid of the user - * @param string $email_address Email address - * @return string + * Registers public pages to allow in the case Private Network has been enabled. */ -function uservalidationbyemail_generate_code($user_guid, $email_address) { - global $CONFIG; - - // Note I bind to site URL, this is important on multisite! - return md5($user_guid . $email_address . $CONFIG->site->url . get_site_secret()); +function uservalidationbyemail_public_pages($hook, $type, $return_value, $params) { + $return_value[] = 'pg/uservalidationbyemail/confirm'; + return $return_value; } /** - * Request user validation email. - * Send email out to the address and request a confirmation. + * Prevent a manual code login with login(). * - * @param int $user_guid The user - * @return mixed + * @param unknown_type $event + * @param unknown_type $type + * @param unknown_type $user */ -function uservalidationbyemail_request_validation($user_guid) { - global $CONFIG; - - $user_guid = (int)$user_guid; - $user = get_entity($user_guid); +function uservalidationbyemail_check_manual_login($event, $type, $user) { + $access_status = access_get_show_hidden_status(); + access_show_hidden_entities(TRUE); - if (($user) && ($user instanceof ElggUser)) { - // Work out validate link - $code = uservalidationbyemail_generate_code($user_guid, $user->email); - $link = "{$CONFIG->site->url}pg/uservalidationbyemail/confirm?u=$user_guid&c=$code"; + // @todo register_error()? + $return = ($user instanceof ElggUser && !$user->validated) ? FALSE : NULL; - // Send validation email - $result = notify_user($user->guid, $CONFIG->site->guid, sprintf(elgg_echo('email:validate:subject'), $user->username), sprintf(elgg_echo('email:validate:body'), $user->name, $link), NULL, 'email'); - if ($result) { - system_message(elgg_echo('uservalidationbyemail:registerok')); - } + access_show_hidden_entities($access_status); - return $result; - } - - return FALSE; + return $return; } /** - * Validate a user + * Deny requests to change password if the account isn't validated. * - * @param unknown_type $user_guid - * @param unknown_type $code - * @return unknown + * @todo This is needed because changing the password requires the entity to be enabled. + * + * @param unknown_type $hook + * @param unknown_type $type + * @param unknown_type $value + * @param unknown_type $params */ -function uservalidationbyemail_validate_email($user_guid, $code) { - $user = get_entity($user_guid); +function uservalidationbyemail_check_request_password($hook, $type, $value, $params) { + $username = get_input('username'); - if ($code == uservalidationbyemail_generate_code($user_guid, $user->email)) { - return set_user_validation_status($user_guid, true, 'email'); + // see if we need to resolve an email address to a username + if (strpos($username, '@') !== FALSE && ($users = get_user_by_email($username))) { + $username = $users[0]->username; } - return false; -} + // See the users exists and isn't validated + $access_status = access_get_show_hidden_status(); + access_show_hidden_entities(TRUE); -/** - * Registers public pages to allow in the case Private Network has been enabled. - */ -function uservalidationbyemail_public_pages($hook, $type, $return_value, $params) { - $return_value[] = 'pg/uservalidationbyemail/confirm'; - return $return_value; + $user = get_user_by_username($username); + + // resend validation instead of resetting password + if ($user && !$user->validated) { + uservalidationbyemail_request_validation($user->guid); + $value = FALSE; + } + + access_show_hidden_entities($access_status); + + return $value; } -// Initialise register_elgg_event_handler('init', 'system', 'uservalidationbyemail_init');
\ No newline at end of file |