X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=lib%2Fnickname.php;h=e21517497a18cd0587530bc14519fb9ebf310ff5;hb=586fb5a5175d7a10f5f78dd026434e48202e5451;hp=2792d32fd50494900a01e4cbf09a55617d1fab5c;hpb=db7ef52d1352fa3fa49ddf85dcd2bb124c00d303;p=quix0rs-gnu-social.git diff --git a/lib/nickname.php b/lib/nickname.php index 2792d32fd5..e21517497a 100644 --- a/lib/nickname.php +++ b/lib/nickname.php @@ -27,8 +27,7 @@ class Nickname * Nickname::normalize() to get the canonical form, or Nickname::isValid() * if you just need to check if it's properly formatted. * - * This, DISPLAY_FMT, and CANONICAL_FMT replace the old NICKNAME_FMT, - * but be aware that these should not be enclosed in []s. + * This, DISPLAY_FMT, and CANONICAL_FMT should not be enclosed in []s. * * @fixme would prefer to define in reference to the other constants */ @@ -36,6 +35,7 @@ class Nickname /** * Regex fragment for acceptable user-formatted variant of a nickname. + * * This includes some chars such as underscore which will be removed * from the normalized canonical form, but still must fit within * field length limits. @@ -44,11 +44,21 @@ class Nickname * Nickname::normalize() to get the canonical form, or Nickname::isValid() * if you just need to check if it's properly formatted. * - * This and CANONICAL_FMT replace the old NICKNAME_FMT, but be aware - * that these should not be enclosed in []s. + * This, INPUT_FMT and CANONICAL_FMT should not be enclosed in []s. */ const DISPLAY_FMT = '[0-9a-zA-Z_]{1,64}'; + /** + * Simplified regex fragment for acceptable full WebFinger ID of a user + * + * We could probably use an email regex here, but mainly we are interested + * in matching it in our URLs, like https://social.example/user@example.com + */ + const WEBFINGER_FMT = '(?:\w+[\w\-\_\.]*)?\w+\@'.URL_REGEX_DOMAIN_NAME; + + // old one without support for -_. in nickname part: + // const WEBFINGER_FMT = '[0-9a-zA-Z_]{1,64}\@[0-9a-zA-Z_-.]{3,255}'; + /** * Regex fragment for checking a canonical nickname. * @@ -60,8 +70,7 @@ class Nickname * there are multiple possible denormalized forms for each valid * canonical-form name. * - * This and DISPLAY_FMT replace the old NICKNAME_FMT, but be aware - * that these should not be enclosed in []s. + * This, INPUT_FMT and DISPLAY_FMT should not be enclosed in []s. */ const CANONICAL_FMT = '[0-9a-z]{1,64}'; @@ -70,6 +79,16 @@ class Nickname */ const MAX_LEN = 64; + /** + * Regex with non-capturing group that matches whitespace and some + * characters which are allowed right before an @ or ! when mentioning + * other users. Like: 'This goes out to:@mmn (@chimo too) (!awwyiss).' + * + * FIXME: Make this so you can have multiple whitespace but not multiple + * parenthesis or something. '(((@n_n@)))' might as well be a smiley. + */ + const BEFORE_MENTIONS = '(?:^|[\s\.\,\:\;\[\(]+)'; + /** * Nice simple check of whether the given string is a valid input nickname, * which can be normalized into an internally canonical form. @@ -110,15 +129,17 @@ class Nickname */ public static function normalize($str, $checkuse=false) { + if (mb_strlen($str) > self::MAX_LEN) { + // Display forms must also fit! + throw new NicknameTooLongException(); + } + // We should also have UTF-8 normalization (Ã¥ to a etc.) $str = trim($str); $str = str_replace('_', '', $str); $str = mb_strtolower($str); - if (mb_strlen($str) > self::MAX_LEN) { - // Display forms must also fit! - throw new NicknameTooLongException(); - } elseif (mb_strlen($str) < 1) { + if (mb_strlen($str) < 1) { throw new NicknameEmptyException(); } elseif (!self::isCanonical($str)) { throw new NicknameInvalidException(); @@ -126,9 +147,10 @@ class Nickname throw new NicknameBlacklistedException(); } elseif (self::isSystemPath($str)) { throw new NicknamePathCollisionException(); - } elseif ($checkuse && $user = self::isTaken($str)) { - if ($user instanceof User) { - throw new NicknameTakenException($user); + } elseif ($checkuse) { + $profile = self::isTaken($str); + if ($profile instanceof Profile) { + throw new NicknameTakenException($profile); } } @@ -155,6 +177,8 @@ class Nickname public static function isBlacklisted($str) { $blacklist = common_config('nickname', 'blacklist'); + if(!$blacklist) + return false; return in_array($str, $blacklist); } @@ -173,30 +197,50 @@ class Nickname // All directory and file names in site root should be blacklisted $d = dir(INSTALLDIR); while (false !== ($entry = $d->read())) { - $paths[] = $entry; + $paths[$entry] = true; } $d->close(); // All top level names in the router should be blacklisted $router = Router::get(); - foreach (array_keys($router->m->getPaths()) as $path) { - if (preg_match('/^\/(.*?)[\/\?]/',$path,$matches)) { - $paths[] = $matches[1]; + foreach ($router->m->getPaths() as $path) { + if (preg_match('/^([^\/\?]+)[\/\?]/',$path,$matches) && isset($matches[1])) { + $paths[$matches[1]] = true; } } - return in_array($str, $paths); + + // FIXME: this assumes the 'path' is in the first-level directory, though common it's not certain + foreach (['avatar', 'attachments'] as $cat) { + $paths[basename(common_config($cat, 'path'))] = true; + } + + return in_array($str, array_keys($paths)); } /** * Is the nickname already in use locally? Checks the User table. * * @param string $str - * @return User|null Returns null if no such user, otherwise a User object + * @return Profile|null Returns Profile if nickname found, otherwise null */ public static function isTaken($str) { - $user = User::getKV('nickname', $str); - return $user; // null if no such User entry + $found = User::getKV('nickname', $str); + if ($found instanceof User) { + return $found->getProfile(); + } + + $found = Local_group::getKV('nickname', $str); + if ($found instanceof Local_group) { + return $found->getProfile(); + } + + $found = Group_alias::getKV('alias', $str); + if ($found instanceof Group_alias) { + return $found->getProfile(); + } + + return null; } } @@ -281,11 +325,11 @@ class NicknamePathCollisionException extends NicknameException class NicknameTakenException extends NicknameException { - public $user = null; // the User which occupies the nickname + public $profile = null; // the Profile which occupies the nickname - public function __construct(User $user, $msg=null, $code=400) + public function __construct(Profile $profile, $msg=null, $code=400) { - $this->byuser = $user; + $this->profile = $profile; if ($msg === null) { $msg = $this->defaultMessage();