@recaptime-dev's working patches + fork for Phorge, a community fork of Phabricator. (Upstream dev and stable branches are at upstream/main and upstream/stable respectively.) hq.recaptime.dev/wiki/Phorge
phorge phabricator
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Allow usernames to include ".", "-" and "_"

Summary:
See T1303, which presents a reasonable case for inclusion of these characters in valid usernames.

Also, unify username validity handling.

Test Plan: Created a new user with a valid name. Tried to create a new user with an invalid name. Ran unit tests.

Reviewers: btrahan, vrana

Reviewed By: btrahan

CC: aran

Maniphest Tasks: T1303

Differential Revision: https://secure.phabricator.com/D2651

+47 -15
+2 -2
scripts/user/account_admin.php
··· 29 29 } 30 30 31 31 if (!PhabricatorUser::validateUsername($username)) { 32 - echo "The username '{$username}' is invalid. Usernames must consist of only ". 33 - "numbers and letters.\n"; 32 + $valid = PhabricatorUser::describeValidUsername(); 33 + echo "The username '{$username}' is invalid. {$valid}\n"; 34 34 exit(1); 35 35 } 36 36
+1 -1
src/applications/auth/controller/oauthregistration/PhabricatorOAuthDefaultRegistrationController.php
··· 65 65 $errors[] = 'Username is required.'; 66 66 } else if (!PhabricatorUser::validateUsername($username)) { 67 67 $e_username = 'Invalid'; 68 - $errors[] = 'Username must consist of only numbers and letters.'; 68 + $errors[] = PhabricatorUser::describeValidUsername(); 69 69 } else { 70 70 $e_username = null; 71 71 }
+5
src/applications/people/PhabricatorUserEditor.php
··· 62 62 throw new Exception("Email has already been created!"); 63 63 } 64 64 65 + if (!PhabricatorUser::validateUsername($user->getUsername())) { 66 + $valid = PhabricatorUser::describeValidUsername(); 67 + throw new Exception("Username is invalid! {$valid}"); 68 + } 69 + 65 70 // Always set a new user's email address to primary. 66 71 $email->setIsPrimary(1); 67 72
+1 -1
src/applications/people/controller/PhabricatorPeopleEditController.php
··· 153 153 $errors[] = "Username is required."; 154 154 $e_username = 'Required'; 155 155 } else if (!PhabricatorUser::validateUsername($user->getUsername())) { 156 - $errors[] = "Username must consist of only numbers and letters."; 156 + $errors[] = PhabricatorUser::describeValidUsername(); 157 157 $e_username = 'Invalid'; 158 158 } else { 159 159 $e_username = null;
+6 -1
src/applications/people/storage/PhabricatorUser.php
··· 549 549 ->saveAndSend(); 550 550 } 551 551 552 + public static function describeValidUsername() { 553 + return 'Usernames must contain only numbers, letters, period, underscore '. 554 + 'and hyphen, and can not end with a period.'; 555 + } 556 + 552 557 public static function validateUsername($username) { 553 - return (bool)preg_match('/^[a-zA-Z0-9]+$/', $username); 558 + return (bool)preg_match('/^[a-zA-Z0-9._-]*[a-zA-Z0-9_-]$/', $username); 554 559 } 555 560 556 561 public static function getDefaultProfileImageURI() {
+25 -4
src/applications/people/storage/__tests__/PhabricatorUserTestCase.php
··· 23 23 'alincoln' => true, 24 24 'alincoln69' => true, 25 25 'hd3' => true, 26 - '7' => true, // Silly, but permitted. 27 - '0' => true, 28 26 'Alincoln' => true, 27 + 'a.lincoln' => true, 29 28 30 29 'alincoln!' => false, 30 + '' => false, 31 + 32 + // These are silly, but permitted. 33 + '7' => true, 34 + '0' => true, 35 + '____' => true, 36 + '-' => true, 37 + 38 + // These are not permitted because they make capturing @mentions 39 + // ambiguous. 40 + 'joe.' => false, 41 + 42 + // We can never allow these because they invalidate usernames as tokens 43 + // in commit messages ("Reviewers: alincoln, usgrant"), or as parameters 44 + // in URIs ("/p/alincoln/", "?user=alincoln"), or make them unsafe in 45 + // HTML. Theoretically we escape all the HTML/URI stuff, but these 46 + // restrictions make attacks more difficult and are generally reasonable, 47 + // since usernames like "<^, ,^>" don't seem very important to support. 48 + '<script>' => false, 49 + 'a lincoln' => false, 31 50 ' alincoln' => false, 32 - '____' => false, 33 - '' => false, 51 + 'alincoln ' => false, 52 + 'a,lincoln' => false, 53 + 'a&lincoln' => false, 54 + 'a/lincoln' => false, 34 55 ); 35 56 36 57 foreach ($map as $name => $expect) {
+7 -6
src/infrastructure/markup/remarkup/markuprule/PhabricatorRemarkupRuleMention.php
··· 28 28 const KEY_MENTIONED = 'phabricator.mentioned-user-phids'; 29 29 30 30 31 - // NOTE: Negative lookahead for period prevents us from picking up email 32 - // addresses, while allowing constructs like "@tomo, lol". The negative 33 - // lookbehind for a word character prevents us from matching "mail@lists" 34 - // while allowing "@tomo/@mroch". The negative lookahead prevents us from 35 - // matching "@joe.com" while allowing us to match "hey, @joe.". 36 - const REGEX = '/(?<!\w)@([a-zA-Z0-9]+)\b(?![.]\w)/'; 31 + // NOTE: The negative lookbehind prevents matches like "mail@lists", while 32 + // allowing constructs like "@tomo/@mroch". Since we now allow periods in 33 + // usernames, we can't resonably distinguish that "@company.com" isn't a 34 + // username, so we'll incorrectly pick it up, but there's little to be done 35 + // about that. We forbid terminal periods so that we can correctly capture 36 + // "@joe" instead of "@joe." in "Hey, @joe.". 37 + const REGEX = '/(?<!\w)@([a-zA-Z0-9._-]*[a-zA-Z0-9_-])/'; 37 38 38 39 public function apply($text) { 39 40 return preg_replace_callback(