diff options
author | marcus <marcus@36083f99-b078-4883-b0ff-0f9b5a30f544> | 2008-08-25 14:45:49 +0000 |
---|---|---|
committer | marcus <marcus@36083f99-b078-4883-b0ff-0f9b5a30f544> | 2008-08-25 14:45:49 +0000 |
commit | 7b62937942d4506c2d2a23c4a7211adbeccd83d1 (patch) | |
tree | 13f185f0a38f1d2cf5469eaa3863ff9b4677b361 | |
parent | 1793406d859437dee279a6a8f9870565834c3e7c (diff) | |
download | elgg-7b62937942d4506c2d2a23c4a7211adbeccd83d1.tar.gz elgg-7b62937942d4506c2d2a23c4a7211adbeccd83d1.tar.bz2 |
Closes #254: If mb_string is installed then internationalised usernames are supported in file system.
Because of this I have raised mbstring from recommended to a (non-fatal) core requirement.
Because of the lack of a unicode ctype_alnum function the validation occurs at username input. Because of this I have improved the user registration code:
This code now validates for special chars etc in the username. I have also introduced the following new plugin hooks (which are run after primary validation) which provide plugins with the ability to add other requirements (extra security etc).
'registeruser:validate:password'
'registeruser:validate:username'
'registeruser:validate:email'
Marcus Povey 25/8/08
git-svn-id: https://code.elgg.org/elgg/trunk@2040 36083f99-b078-4883-b0ff-0f9b5a30f544
-rw-r--r-- | engine/lib/filestore.php | 44 | ||||
-rw-r--r-- | engine/lib/users.php | 81 | ||||
-rw-r--r-- | languages/en.php | 6 |
3 files changed, 123 insertions, 8 deletions
diff --git a/engine/lib/filestore.php b/engine/lib/filestore.php index e959d6c9e..daed925f5 100644 --- a/engine/lib/filestore.php +++ b/engine/lib/filestore.php @@ -260,6 +260,39 @@ } /** + * Multibyte string tokeniser. + * + * Splits a string into an array. Will fail safely if mbstring is not installed (although this may still + * not handle . + * + * @param string $string String + * @param string $charset The charset, defaults to UTF8 + * @return array + */ + private function mb_str_split($string, $charset = 'UTF8') + { + if (is_callable('mb_substr')) + { + $length = mb_strlen($string); + $array = array(); + + while ($length) + { + $array[] = mb_substr($string, 0, 1, $charset); + $string = mb_substr($string, 1, $length, $charset); + + $length = mb_strlen($string); + } + + return $array; + } + else + return str_split($string); + + return false; + } + + /** * Construct the filename matrix. * * @param string $filename @@ -268,16 +301,19 @@ { $matrix = ""; - $len = strlen($filename); + $name = $filename; + $filename = $this->mb_str_split($filename); + if (!$filename) return false; + + $len = count($filename); if ($len>$this->matrix_depth) $len = $this->matrix_depth; for ($n = 0; $n < $len; $n++) {
- if (ctype_alnum($filename[$n])) - $matrix .= $filename[$n] . "/";
+ $matrix .= $filename[$n] . "/";
} - return $matrix.$filename."/"; + return $matrix.$name."/"; } public function getParameters() diff --git a/engine/lib/users.php b/engine/lib/users.php index edc444585..e29a920ff 100644 --- a/engine/lib/users.php +++ b/engine/lib/users.php @@ -1026,6 +1026,78 @@ { return md5($password . $user->salt); } + + /** + * Simple function which ensures that a username contains only valid characters. + * + * This should only permit chars that are valid on the file system as well. + * + * @param string $username + * @throws RegistrationException on invalid + */ + function validate_username($username) + { + // Basic, check length + if (strlen($username)<4) throw new RegistrationException(elgg_echo('registration:usernametooshort')); + + // Blacklist for bad characters (partially nicked from mediawiki) + + $blacklist = '/[' . + '\x{0080}-\x{009f}' . # iso-8859-1 control chars + '\x{00a0}' . # non-breaking space + '\x{2000}-\x{200f}' . # various whitespace + '\x{2028}-\x{202f}' . # breaks and control chars + '\x{3000}' . # ideographic space + '\x{e000}-\x{f8ff}' . # private use + ']/u'; + + if ( + preg_match($blacklist, $username) || + + // Belts and braces TODO: Tidy into main unicode + (strpos($username, '.')!==false) || + (strpos($username, '/')!==false) || + (strpos($username, '\\')!==false) || + (strpos($username, '"')!==false) || + (strpos($username, '\'')!==false) || + (strpos($username, '*')!==false) || + (strpos($username, '&')!==false) + ) + throw new RegistrationException(elgg_echo('registration:invalidchars')); + + $result = true; + return $result = trigger_plugin_hook('registeruser:validate:username', 'all', array('username' => $username), $result); + } + + /** + * Simple validation of a password. + * + * @param string $password + * @throws RegistrationException on invalid + */ + function validate_password($password) + { + if (strlen($password)<6) throw new RegistrationException(elgg_echo('registration:passwordtooshort')); + + $result = true; + return $result = trigger_plugin_hook('registeruser:validate:password', 'all', array('password' => $password), $result); + } + + /** + * Simple validation of a email. + * + * @param string $address + * @throws RegistrationException on invalid + * @return bool + */ + function validate_email_address($address) + { + if (!is_email_address($address)) throw new RegistrationException(elgg_echo('registration:notemail')); + + // Got here, so lets try a hook (defaulting to ok) + $result = true; + return $result = trigger_plugin_hook('registeruser:validate:email', 'all', array('email' => $address), $result); + } /**
* Registers a user, returning false if the username already exists
@@ -1059,11 +1131,14 @@ $access_status = access_get_show_hidden_status(); access_show_hidden_entities(true); - if (!is_email_address($email)) throw new RegistrationException(elgg_echo('registration:notemail')); + // Validate email address + if (!validate_email_address($email)) throw new RegistrationException(elgg_echo('registration:emailnotvalid')); - if (strlen($username)<4) throw new RegistrationException(elgg_echo('registration:usernametooshort')); + // Validate password + if (!validate_password($password)) throw new RegistrationException(elgg_echo('registration:passwordnotvalid')); - if (strlen($password)<6) throw new RegistrationException(elgg_echo('registration:passwordtooshort')); + // Validate the username + if (!validate_username($username)) throw new RegistrationException(elgg_echo('registration:usernamenotvalid')); // Check to see if $username exists already
if ($user = get_user_by_username($username)) {
diff --git a/languages/en.php b/languages/en.php index 6e72793c0..cdfb22c29 100644 --- a/languages/en.php +++ b/languages/en.php @@ -386,7 +386,11 @@ To remove a widget drag it back to the <b>Widget gallery</b>.", 'registration:userexists' => 'That username already exists',
'registration:usernametooshort' => 'Your username must be a minimum of 4 characters long.',
'registration:passwordtooshort' => 'The password must be a minimum of 6 characters long.',
- 'registration:dupeemail' => 'This email address has already been registered.',
+ 'registration:dupeemail' => 'This email address has already been registered.', + 'registration:invalidchars' => 'Sorry, your email address contains invalid characters.', + 'registration:emailnotvalid' => 'Sorry, the email address you entered is invalid on this system', + 'registration:passwordnotvalid' => 'Sorry, the password you entered is invalid on this system', + 'registration:usernamenotvalid' => 'Sorry, the username you entered is invalid on this system',
'adduser' => "Add User",
'adduser:ok' => "You have successfully added a new user.",
|