Exemple #1
0
/**
 * Given a username, returns one of several codes to indicate whether it is valid to be a NEW username or not.
 *
 * Codes:
 * - OK: A user with this username may be created.
 * - INVALID: This is not a valid username.  This may mean that it is too long or has characters that aren't permitted, etc.
 * - EXISTS: A user with this name, so you cannot create one with this name.
 *
 * TODO: Is this a duplicate of user::isCreatableName()? It is important to note that wgWikiaMaxNameChars may be less than wgMaxNameChars which
 * is intentional because there are some long usernames that were created when only wgMaxNameChars limited to 255 characters and we still want
 * those usernames to be valid (so that they can still login), but we just don't want NEW accounts to be created above the length of wgWikiaMaxNameChars.
 *
 * @param string $uName The user name to check
 *
 * @return bool|string Return errors as an i18n key or true if the name is valid
 */
function wfValidateUserName($uName)
{
    if (!User::isNotMaxNameChars($uName)) {
        return 'userlogin-bad-username-length';
    }
    $userTitle = Title::newFromText($uName);
    if (is_null($userTitle)) {
        return 'userlogin-bad-username-character';
    }
    $uName = $userTitle->getText();
    if (!User::isCreatableName($uName)) {
        return 'userlogin-bad-username-character';
    }
    $dbr = wfGetDB(DB_SLAVE);
    $uName = $dbr->strencode($uName);
    if ($uName == '') {
        return 'userlogin-bad-username-character';
    }
    if (class_exists('SpoofUser')) {
        $spoof = new SpoofUser($uName);
        if ($spoof->isLegal()) {
            $conflicts = $spoof->getConflicts();
            if (!empty($conflicts)) {
                return 'userlogin-bad-username-taken';
            }
        }
    }
    if (in_array($uName, F::app()->wg->ReservedUsernames)) {
        // if we returned 'invalid', that would be confusing once a user
        // checked and found that the name already met the naming requirements.
        return 'userlogin-bad-username-taken';
    }
    // This username is valid
    return true;
}
 public function execute()
 {
     $params = $this->extractRequestParams();
     $res = $this->getResult();
     $res->addValue(null, $this->getModuleName(), array('username' => $params['username']));
     $spoof = new SpoofUser($params['username']);
     if ($spoof->isLegal()) {
         $normalized = $spoof->getNormalized();
         $res->addValue(null, $this->getModuleName(), array('normalised' => $normalized));
         $unfilteredConflicts = $spoof->getConflicts();
         if (empty($unfilteredConflicts)) {
             $res->addValue(null, $this->getModuleName(), array('result' => 'pass'));
         } else {
             $hasSuppressed = false;
             $conflicts = array();
             foreach ($unfilteredConflicts as $conflict) {
                 if (!User::newFromName($conflict)->isHidden()) {
                     $conflicts[] = $conflict;
                 } else {
                     $hasSuppressed = true;
                 }
             }
             if ($hasSuppressed) {
                 $res->addValue(null, $this->getModuleName(), array('suppressed' => 'true'));
             }
             $res->addValue(null, $this->getModuleName(), array('result' => 'conflict'));
             $res->setIndexedTagName($conflicts, 'u');
             $res->addValue(array($this->getModuleName()), 'users', $conflicts);
         }
     } else {
         $error = $spoof->getError();
         $res->addValue('antispoof', 'result', 'error');
         $res->addValue('antispoof', 'error', $error);
     }
 }
Exemple #3
0
 /**
  * @dataProvider providePositives
  * See http://www.phpunit.de/manual/3.4/en/appendixes.annotations.html#appendixes.annotations.dataProvider
  */
 public function testCheckSpoofing($userName, $spooferName)
 {
     $Alice = new SpoofUser($userName);
     $Eve = new SpoofUser($spooferName);
     if ($Eve->isLegal()) {
         $this->assertEquals($Alice->getNormalized(), $Eve->getNormalized(), "Check that '{$spooferName}' can't spoof account '{$userName}'");
     }
 }
 /**
  * Can be used to cancel user account creation
  *
  * @param $user User
  * @param $message string
  * @return bool true to continue, false to abort user creation
  */
 public static function asAbortNewAccountHook($user, &$message)
 {
     global $wgAntiSpoofAccounts, $wgUser, $wgRequest;
     if (!$wgAntiSpoofAccounts) {
         $mode = 'LOGGING ';
         $active = false;
     } elseif ($wgRequest->getCheck('wpIgnoreAntiSpoof') && $wgUser->isAllowed('override-antispoof')) {
         $mode = 'OVERRIDE ';
         $active = false;
     } else {
         $mode = '';
         $active = true;
     }
     $name = $user->getName();
     $spoof = new SpoofUser($name);
     if ($spoof->isLegal()) {
         $normalized = $spoof->getNormalized();
         $conflicts = $spoof->getConflicts();
         if (empty($conflicts)) {
             wfDebugLog('antispoof', "{$mode}PASS new account '{$name}' [{$normalized}]");
         } else {
             wfDebugLog('antispoof', "{$mode}CONFLICT new account '{$name}' [{$normalized}] spoofs " . implode(',', $conflicts));
             if ($active) {
                 $numConflicts = count($conflicts);
                 $message = wfMessage('antispoof-conflict-top', $name)->numParams($numConflicts)->parse();
                 $message .= '<ul>';
                 foreach ($conflicts as $simUser) {
                     $message .= '<li>' . wfMessage('antispoof-conflict-item', $simUser)->escaped() . '</li>';
                 }
                 $message .= '</ul>' . wfMessage('antispoof-conflict-bottom')->parse();
                 return false;
             }
         }
     } else {
         $error = $spoof->getError();
         wfDebugLog('antispoof', "{$mode}ILLEGAL new account '{$name}' {$error}");
         if ($active) {
             $message = wfMessage('antispoof-name-illegal', $name, $error)->text();
             return false;
         }
     }
     return true;
 }
 /**
  * AntiSpoof: verify whether the name is legal for a new account.
  *
  * @see extensions/AntiSpoof
  */
 public function checkAntiSpoof()
 {
     $this->response->setFormat('json');
     $this->response->setCacheValidity(\WikiaResponse::CACHE_DISABLED);
     if ($this->getVal('secret') != $this->wg->TheSchwartzSecretToken) {
         $this->response->setVal('allow', false);
         $this->response->setVal('message', 'invalid secret');
         return;
     }
     $username = $this->getVal('username');
     // Allow the given user name if the AntiSpoof extension is disabled.
     if (empty($this->wg->EnableAntiSpoofExt)) {
         $this->response->setVal('allow', true);
         return;
     }
     $spoofUser = new \SpoofUser($username);
     // Allow the given user name if it is legal and does not conflict with other names.
     $this->response->setVal('allow', $spoofUser->isLegal() && !$spoofUser->getConflicts());
     return;
 }
Exemple #6
0
/**
 * Hook for user creation form submissions.
 * @param User $u
 * @param string $message
 * @return bool true to continue, false to abort user creation
 */
function asAbortNewAccountHook($user, &$message)
{
    global $wgAntiSpoofAccounts, $wgUser, $wgRequest;
    wfLoadExtensionMessages('AntiSpoof');
    if (!$wgAntiSpoofAccounts) {
        $mode = 'LOGGING ';
        $active = false;
    } elseif ($wgRequest->getCheck('wpIgnoreAntiSpoof') && $wgUser->isAllowed('override-antispoof')) {
        $mode = 'OVERRIDE ';
        $active = false;
    } else {
        $mode = '';
        $active = true;
    }
    $name = $user->getName();
    $spoof = new SpoofUser($name);
    if ($spoof->isLegal()) {
        $normalized = $spoof->getNormalized();
        $conflict = $spoof->getConflict();
        if ($conflict === false) {
            wfDebugLog('antispoof', "{$mode}PASS new account '{$name}' [{$normalized}]");
        } else {
            wfDebugLog('antispoof', "{$mode}CONFLICT new account '{$name}' [{$normalized}] spoofs '{$conflict}'");
            if ($active) {
                $message = wfMsg('antispoof-name-conflict', $name, $conflict);
                return false;
            }
        }
    } else {
        $error = $spoof->getError();
        wfDebugLog('antispoof', "{$mode}ILLEGAL new account '{$name}' {$error}");
        if ($active) {
            $message = wfMsg('antispoof-name-illegal', $name, $error);
            return false;
        }
    }
    return true;
}
 /**
  * Checks if the request provided to the constructor is valid.
  *
  * @return bool True if all prerequisites are met
  */
 protected function setup()
 {
     wfProfileIn(__METHOD__);
     global $wgContLang, $wgCapitalLinks;
     //Sanitize input data
     $oldnamePar = trim(str_replace('_', ' ', $this->mRequestData->oldUsername));
     $oldTitle = Title::makeTitle(NS_USER, $oldnamePar);
     // Force uppercase of newusername, otherwise wikis with wgCapitalLinks=false can create lc usernames
     $newTitle = Title::makeTitleSafe(NS_USER, $wgContLang->ucfirst($this->mRequestData->newUsername));
     $oun = is_object($oldTitle) ? $oldTitle->getText() : '';
     $nun = is_object($newTitle) ? $newTitle->getText() : '';
     $this->addInternalLog("title: old={$oun} new={$nun}");
     //AntiSpoof test
     if (class_exists('SpoofUser')) {
         $oNewSpoofUser = new SpoofUser($nun);
         if (!$oNewSpoofUser->isLegal()) {
             $this->addWarning(wfMessage('userrenametool-error-antispoof-conflict', $nun));
         }
     } else {
         $this->addError(wfMessage('userrenametool-error-antispoof-notinstalled'));
     }
     //Phalanx test
     $warning = RenameUserHelper::testBlock($oun);
     if (!empty($warning)) {
         $this->addWarning($warning);
     }
     $warning = RenameUserHelper::testBlock($nun);
     if (!empty($warning)) {
         $this->addWarning($warning);
     }
     //Invalid old user name entered
     if (!$oun) {
         $this->addError(wfMessage('userrenametool-errorinvalid', $this->mRequestData->oldUsername)->inContentLanguage()->text());
         wfProfileOut(__METHOD__);
         return false;
     }
     //Invalid new user name entered
     if (!$nun) {
         $this->addError(wfMessage('userrenametool-errorinvalidnew', $this->mRequestData->newUsername)->inContentLanguage()->text());
         wfProfileOut(__METHOD__);
         return false;
     }
     //Old username is the same as new username
     if ($oldTitle->getText() === $newTitle->getText()) {
         $this->addError(wfMessage('userrenametool-error-same-user')->inContentLanguage()->text());
         wfProfileOut(__METHOD__);
         return false;
     }
     //validate new username and disable validation for old username
     $olduser = User::newFromName($oldTitle->getText(), false);
     $newuser = User::newFromName($newTitle->getText(), 'creatable');
     // It won't be an object if for instance "|" is supplied as a value
     if (!is_object($olduser)) {
         $this->addError(wfMessage('userrenametool-errorinvalid', $this->mRequestData->oldUsername)->inContentLanguage()->text());
         wfProfileOut(__METHOD__);
         return false;
     }
     if (!is_object($newuser) || !User::isCreatableName($newuser->getName())) {
         $this->addError(wfMessage('userrenametool-errorinvalid', $this->mRequestData->newUsername)->inContentLanguage()->text());
         wfProfileOut(__METHOD__);
         return false;
     }
     $this->addInternalLog("user: old={$olduser->getName()}:{$olduser->getId()} new={$newuser->getName()}:{$newuser->getId()}");
     // Check for the existence of lowercase oldusername in database.
     // Until r19631 it was possible to rename a user to a name with first character as lowercase
     if ($oldTitle->getText() !== $wgContLang->ucfirst($oldTitle->getText())) {
         // oldusername was entered as lowercase -> check for existence in table 'user'
         $dbr = WikiFactory::db(DB_SLAVE);
         $uid = $dbr->selectField('`user`', 'user_id', array('user_name' => $oldTitle->getText()), __METHOD__);
         $this->addLog('Running query: ' . $dbr->lastQuery() . " resulted in " . $dbr->affectedRows() . " row(s) being affected.");
         if ($uid === false) {
             if (!$wgCapitalLinks) {
                 $uid = 0;
                 // We are on a lowercase wiki but lowercase username does not exists
             } else {
                 // We are on a standard uppercase wiki, use normal
                 $uid = $olduser->idForName();
                 $oldTitle = Title::makeTitleSafe(NS_USER, $olduser->getName());
             }
         }
     } else {
         // oldusername was entered as upperase -> standard procedure
         $uid = $olduser->idForName();
     }
     $this->addInternalLog("id: uid={$uid} old={$olduser->getName()}:{$olduser->getId()} new={$newuser->getName()}:{$newuser->getId()}");
     //If old user name does not exist:
     if ($uid == 0) {
         $this->addError(wfMessage('userrenametool-errordoesnotexist', $this->mRequestData->oldUsername)->inContentLanguage()->text());
         wfProfileOut(__METHOD__);
         return false;
     } elseif ($olduser->isLocked()) {
         $this->addError(wfMessage('userrenametool-errorlocked', $this->mRequestData->oldUsername)->inContentLanguage()->text());
         wfProfileOut(__METHOD__);
         return false;
     } elseif ($olduser->isAllowed('bot')) {
         $this->addError(wfMessage('userrenametool-errorbot', $this->mRequestData->oldUsername)->inContentLanguage()->text());
         wfProfileOut(__METHOD__);
         return false;
     }
     $fakeuid = 0;
     //If new user name does exist (we have a special case - repeating rename process)
     if ($newuser->idForName() != 0) {
         $repeating = false;
         $processing = false;
         //invalidate properties cache and reload to get updated data
         //needed here, if the cache is wrong bad things happen
         $this->addInternalLog("pre-invalidate: titletext={$oldTitle->getText()} old={$olduser->getName()}");
         $olduser->invalidateCache();
         $olduser = User::newFromName($oldTitle->getText(), false);
         $renameData = $olduser->getGlobalAttribute('renameData', '');
         $this->addInternalLog("post-invalidate: titletext={$oldTitle->getText()} old={$olduser->getName()}:{$olduser->getId()}");
         $this->addLog("Scanning user option renameData for process data: {$renameData}");
         if (stripos($renameData, self::RENAME_TAG) !== false) {
             $tokens = explode(';', $renameData, 3);
             if (!empty($tokens[0])) {
                 $nameTokens = explode('=', $tokens[0], 2);
                 $repeating = count($nameTokens) == 2 && $nameTokens[0] === self::RENAME_TAG && $nameTokens[1] === $newuser->getName();
             }
             if (!empty($tokens[1])) {
                 $statusTokens = explode('=', $tokens[1], 2);
                 $processing = count($statusTokens) == 2 && $statusTokens[0] === self::PROCESS_TAG && (int) $statusTokens[1] === 1;
             }
             if (!empty($tokens[2])) {
                 $blockTokens = explode('=', $tokens[2], 2);
                 if (count($blockTokens) == 2 && $blockTokens[0] === self::PHALANX_BLOCK_TAG && is_numeric($blockTokens[1])) {
                     $this->mPhalanxBlockId = (int) $blockTokens[1];
                 }
             }
         }
         /**
         			 * Not needed, process must be resumable even in case of fatal errors, if 2 processes are run nothing bad happens
         			//if the process is already running throw an error
         			if($processing){
         				$this->addError( wfMessage( 'userrenametool-errorprocessing', $olduser->getName(), $newuser->getName())->inContentLanguage()->text() );
         				wfProfileOut(__METHOD__);
         				return false;
         			}*/
         if ($repeating) {
             $this->addWarning(wfMessage('userrenametool-warn-repeat', $this->mRequestData->oldUsername, $this->mRequestData->newUsername)->inContentLanguage()->text());
             //Swap the uids because the real user ID is the new user ID in this special case
             $fakeuid = $uid;
             $uid = $newuser->idForName();
         } else {
             //In the case other than repeating the process drop an error
             $this->addError(wfMessage('userrenametool-errorexists', $newuser->getName())->inContentLanguage()->text());
             wfProfileOut(__METHOD__);
             return false;
         }
     }
     //Execute Warning hook (arguments the same as in the original Renameuser extension)
     if (!$this->mActionConfirmed) {
         wfRunHooks('UserRename::Warning', array($this->mRequestData->oldUsername, $this->mRequestData->newUsername, &$this->mWarnings));
     }
     $this->mOldUsername = $olduser->getName();
     $this->mNewUsername = $newuser->getName();
     $this->mUserId = (int) $uid;
     $this->mFakeUserId = $fakeuid;
     $this->addInternalLog("setup: uid={$this->mUserId} fakeuid={$this->mFakeUserId} old={$this->mOldUsername} new={$this->mNewUsername}");
     //If there are only warnings and user confirmed that, do not show them again
     //on success page ;-)
     if ($this->mActionConfirmed) {
         $this->mWarnings = array();
     } elseif (count($this->mWarnings)) {
         //in case action is not confirmed and there are warnings display them and wait for confirmation before running the process
         wfProfileOut(__METHOD__);
         return false;
     }
     wfProfileOut(__METHOD__);
     return empty($this->mErrors);
 }