aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authormarcus <marcus@36083f99-b078-4883-b0ff-0f9b5a30f544>2008-08-25 14:45:49 +0000
committermarcus <marcus@36083f99-b078-4883-b0ff-0f9b5a30f544>2008-08-25 14:45:49 +0000
commit7b62937942d4506c2d2a23c4a7211adbeccd83d1 (patch)
tree13f185f0a38f1d2cf5469eaa3863ff9b4677b361
parent1793406d859437dee279a6a8f9870565834c3e7c (diff)
downloadelgg-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.php44
-rw-r--r--engine/lib/users.php81
-rw-r--r--languages/en.php6
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.",