aboutsummaryrefslogtreecommitdiff
path: root/mod
diff options
context:
space:
mode:
authorbrettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544>2010-09-30 19:56:49 +0000
committerbrettp <brettp@36083f99-b078-4883-b0ff-0f9b5a30f544>2010-09-30 19:56:49 +0000
commitfad92747bec989fd6728eb7349c9ede4674764ff (patch)
tree6f1c6ca613dff0af2a769c6b13aa97d00cb432a9 /mod
parent9af90ffc9a20033ca9fdd9182122c01600a0867b (diff)
downloadelgg-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.php52
-rw-r--r--mod/uservalidationbyemail/lib/functions.php107
-rw-r--r--mod/uservalidationbyemail/start.php216
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