/** * @return array */ function changeableGroups() { if ($this->mGlobalUser->exists() && $this->mGlobalUser->isAttached() && $this->mGlobalUser->hasGlobalPermission('globalgroupmembership')) { $allGroups = CentralAuthUser::availableGlobalGroups(); # specify addself and removeself as empty arrays -- bug 16098 return array('add' => $allGroups, 'remove' => $allGroups, 'add-self' => array(), 'remove-self' => array()); } return array('add' => array(), 'remove' => array(), 'add-self' => array(), 'remove-self' => array()); }
public function execute() { $userName = '******'; // <- targer username $user = new CentralAuthUser( $userName ); if ( !$user->exists() ) { echo "Cannot unsuppress non-existent user {$userName}!\n"; exit( 0 ); } $userName = $user->getName(); // sanity $wikis = $user->listAttached(); // wikis with attached accounts foreach ( $wikis as $wiki ) { $lb = wfGetLB( $wiki ); $dbw = $lb->getConnection( DB_MASTER, array(), $wiki ); # Get local ID like $user->localUserData( $wiki ) does $localUserId = $dbw->selectField( 'user', 'user_id', array( 'user_name' => $userName ), __METHOD__ ); $delUserBit = Revision::DELETED_USER; $hiddenCount = $dbw->selectField( 'revision', 'COUNT(*)', array( 'rev_user' => $localUserId, "rev_deleted & $delUserBit != 0" ), __METHOD__ ); echo "$hiddenCount edits have the username hidden on \"$wiki\"\n"; # Unsuppress username on edits if ( $hiddenCount > 0 ) { echo "Unsuppressed edits of attached account (local id $localUserId) on \"$wiki\"..."; IPBlockForm::unsuppressUserName( $userName, $localUserId, $dbw ); echo "done!\n\n"; } $lb->reuseConnection( $dbw ); // not really needed # Don't lag too bad wfWaitForSlaves( 5 ); } }
/** * @param array $row * @return string */ private function listWikiItem(array $row) { if ($row === null) { // https://bugzilla.wikimedia.org/show_bug.cgi?id=28767 // It seems sometimes local accounts aren't correctly created // Revisiting the wiki solves the issue return ''; } $html = Xml::openElement('tr'); if ($this->mCanUnmerge && $this->mGlobalUser->exists()) { if (!empty($row['attachedMethod'])) { $html .= Xml::openElement('td') . $this->adminCheck($row['wiki']) . Xml::closeElement('td'); } else { // Account is unattached, don't show checkbox to detach $html .= Xml::element('td'); } } $html .= Xml::openElement('td') . $this->foreignUserLink($row['wiki']) . Xml::closeElement('td'); $attachedTimestamp = isset($row['attachedTimestamp']) ? $row['attachedTimestamp'] : ''; $html .= $this->getAttachedTimestampField($attachedTimestamp) . Xml::openElement('td', array('style' => "text-align: center;")); if (empty($row['attachedMethod'])) { $html .= $this->msg('centralauth-admin-unattached')->parse(); } else { $html .= $this->formatMergeMethod($row['attachedMethod']); } $html .= Xml::closeElement('td') . Xml::openElement('td') . $this->formatBlockStatus($row) . Xml::closeElement('td') . Xml::openElement('td', array('style' => "text-align: right;")) . $this->formatEditcount($row) . Xml::closeElement('td') . Xml::openElement('td') . $this->formatGroups($row) . Xml::closeElement('td') . Xml::closeElement('tr'); return $html; }
function execute($subpage) { global $wgContLang; $this->setHeaders(); $this->mCanUnmerge = $this->getUser()->isAllowed('centralauth-unmerge'); $this->mCanLock = $this->getUser()->isAllowed('centralauth-lock'); $this->mCanOversight = $this->getUser()->isAllowed('centralauth-oversight'); $this->mCanEdit = $this->mCanUnmerge || $this->mCanLock || $this->mCanOversight; $this->getOutput()->addModules('ext.centralauth'); $this->getOutput()->addModuleStyles('ext.centralauth.noflash'); $this->addMergeMethodDescriptions(); $this->mUserName = trim(str_replace('_', ' ', $this->getRequest()->getText('target', $subpage))); $this->mUserName = $wgContLang->ucfirst($this->mUserName); $this->mPosted = $this->getRequest()->wasPosted(); $this->mMethod = $this->getRequest()->getVal('wpMethod'); $this->mWikis = (array) $this->getRequest()->getArray('wpWikis'); // Possible demo states // success, all accounts merged // successful login, some accounts merged, others left // successful login, others left // not account owner, others left // is owner / is not owner // did / did not merge some accounts // do / don't have more accounts to merge if ($this->mUserName === '') { # First time through $this->getOutput()->addWikiMsg('centralauth-admin-intro'); $this->showUsernameForm(); return; } $this->mGlobalUser = $globalUser = new CentralAuthUser($this->mUserName); if (!$globalUser->exists() || $globalUser->isOversighted() && !$this->mCanOversight) { $this->showError('centralauth-admin-nonexistent', $this->mUserName); $this->showUsernameForm(); return; } $continue = true; if ($this->mCanEdit && $this->mPosted) { $continue = $this->doSubmit(); } $this->mAttachedLocalAccounts = $this->mGlobalUser->queryAttached(); $this->mUnattachedLocalAccounts = $this->mGlobalUser->queryUnattached(); $this->showUsernameForm(); if ($continue) { $this->showInfo(); if ($this->mCanLock) { $this->showStatusForm(); } if ($this->mCanUnmerge) { $this->showActionForm('delete'); } if ($this->mCanEdit) { $this->showLogExtract(); } $this->showWikiLists(); } }
public function execute() { $dbw = CentralAuthUser::getCentralDB(); $databaseUpdates = new UsersToRenameDatabaseUpdates($dbw); // CentralAuthUser::chooseHomeWiki is expensive and called // multiple times, so lets cache it. $cache = new MapCacheLRU($this->mBatchSize); do { $rows = $this->doQuery(); $insertRows = array(); foreach ($rows as $row) { $this->lName = $row->name; $this->lWiki = $row->wiki; if ($cache->has($row->name)) { $attachableWikis = $cache->get($row->name); } else { $ca = new CentralAuthUser($row->name); $attachableWikis = array(); $unattached = $ca->queryUnattached(); if ($ca->exists()) { $home = $ca->getHomeWiki(); $attachableWikis[] = $home; foreach ($unattached as $wiki => $info) { if ($ca->getEmailAuthenticationTimestamp() && $info['email'] === $ca->getEmail() && !is_null($info['emailAuthenticated'])) { $attachableWikis[] = $wiki; } } } else { $home = $ca->chooseHomeWiki($unattached); $attachableWikis[] = $home; if ($unattached[$home]['email'] && isset($unattached[$home]['emailAuthenticated'])) { foreach ($unattached as $wiki => $info) { if ($wiki !== $home && $unattached[$home]['email'] === $info['email'] && isset($info['emailAuthenticated'])) { $attachableWikis[] = $wiki; } } } } $cache->set($row->name, $attachableWikis); } if (!in_array($row->wiki, $attachableWikis)) { // Unattached account which is not attachable, // so they're getting renamed :( $this->output("{$row->name}@{$row->wiki} is going to be renamed.\n"); $insertRows[] = (array) $row; } } $databaseUpdates->batchInsert($insertRows); $count = $dbw->affectedRows(); $this->output("Inserted {$count} users who we will rename\n"); $this->output("Waiting for slaves...\n"); CentralAuthUser::waitForSlaves(); } while ($count !== 0); }
/** * Get the CentralAuthUser from a line of text * * @param $username string * @return CentralAuthUser|string User object, or a string containing the error */ private function getGlobalUser($username) { $username = trim($username); if ($username === '') { return false; } $username = $this->getLanguage()->ucfirst($username); $globalUser = new CentralAuthUser($username); if (!$globalUser->exists() || !$this->mCanOversight && ($globalUser->isOversighted() || $globalUser->isHidden())) { return $this->msg('centralauth-admin-nonexistent', $username)->parse(); } return $globalUser; }
function process($username) { $central = new CentralAuthUser($username); if (!$central->exists()) { $this->output("ERROR: [{$username}] Central account does not exist. So how'd we find it?\n"); return; } try { $unattached = $central->queryUnattached(); } catch (Exception $e) { // This might happen due to localnames inconsistencies (bug 67350) $this->output("ERROR: [{$username}] Fetching unattached accounts failed.\n"); return; } foreach ($unattached as $wiki => $local) { if ($local['email'] === '' && $local['password'] === '') { $this->output("SKIP: [{$username}] Account on {$wiki} has no password or email\n"); return; } } if ($this->fix) { $reason = wfMessage('centralauth-delete-empty-account')->inContentLanguage()->text(); $status = $central->adminDelete($reason); if (!$status->isGood()) { $msg = $status->errors[0]['message']; if ($msg instanceof Message) { $msg = $msg->getKey(); } $this->output("ERROR: [{$username}] Delete failed ({$msg})\n"); return; } $this->output("DELETE: [{$username}] Deleted\n"); } else { $this->output("DELETE: [{$username}] Would delete\n"); } if (count($unattached) !== 0 && $this->migrate) { if ($this->fix) { $central = CentralAuthUser::newUnattached($username, true); if ($central->storeAndMigrate(array(), !$this->suppressRC, $this->safe)) { $unattachedAfter = count($central->queryUnattached()); $this->output("MIGRATE: [{$username}] Success; {$unattachedAfter} left unattached\n"); } else { $this->output("MIGRATE: [{$username}] Fail\n"); } } else { $this->output("MIGRATE: [{$username}] Would attempt\n"); } } }
/** * Execute the job * * @return bool */ public function run() { $username = $this->params['username']; $by = $this->params['by']; $wikis = $this->params['wikis']; $suppress = $this->params['suppress']; $reason = $this->params['reason']; $user = new CentralAuthUser($username); if (!$user->exists()) { wfDebugLog('suppressjob', "Requested to suppress non-existent user {$username} by {$by}."); } foreach ($wikis as $wiki) { $user->doLocalSuppression($suppress, $wiki, $by, $reason); wfDebugLog('suppressjob', ($suppress ? 'S' : 'Uns') . "uppressed {$username} at {$wiki} by {$by} via job queue."); } return true; }
/** * Switches a user's preferences off * @param $user User object to set preferences for * @param $global bool Whether to apply this change on all wikis in $wgPrefSwitchWikis */ public static function switchOff($user, $global = false) { self::switchOffUser($user); if ($global) { $globalUser = new CentralAuthUser($user->getName()); if (!$globalUser->exists()) { return; } $accounts = $globalUser->queryAttached(); foreach ($accounts as $account) { $remoteUser = UserRightsProxy::newFromName($account['wiki'], $globalUser->getName(), true); if ($remoteUser) { self::switchOffUser($remoteUser); } } } }
public function execute() { $globalUser = new CentralAuthUser($this->getParameter('user')); if (!$this->getUser()->isAllowed('centralauth-lock')) { $this->dieUsageMsg(array('badaccess-groups')); } elseif (!$globalUser->exists()) { $this->dieUsageMsg(array('nosuchuser', $globalUser->getName())); } elseif ($globalUser->isOversighted() && !$this->getUser()->isAllowed('centralauth-oversight')) { $this->dieUsageMsg(array('nosuchuser', $globalUser->getName())); } elseif (!$this->getRequest()->getCheck('locked') && $this->getParameter('hidden') === null) { $this->dieUsage("At least one of the parameters locked, hidden is required", "missingparam"); } $setLocked = $this->getParameter('locked'); if (!$setLocked) { // Don't lock or unlock $setLocked = null; } else { $setLocked = $setLocked === 'lock'; } $setHidden = $this->getParameter('hidden'); $reason = $this->getParameter('reason'); $stateCheck = $this->getParameter('statecheck'); if ($stateCheck && $stateCheck !== $globalUser->getStateHash(true)) { $this->dieUsage('Edit conflict detected, Aborting.', 'editconflict'); } $status = $globalUser->adminLockHide($setLocked, $setHidden, $reason, $this->getContext()); // Logging etc if ($status->isGood()) { $this->getResult()->addValue(null, $this->getModuleName(), array('user' => $globalUser->getName(), 'locked' => $globalUser->isLocked(), 'hidden' => $globalUser->getHiddenLevel(), 'reason' => $reason)); } else { if (is_callable(array($this, 'getErrorFormatter'))) { $error = $this->getErrorFormatter()->arrayFromStatus($status); } else { $error = $this->getResult()->convertStatusToArray($status); } $this->getResult()->addValue('error', null, $error); $this->getResult()->addValue(null, $this->getModuleName(), array('user' => $globalUser->getName(), 'locked' => $globalUser->isLocked(), 'hidden' => $globalUser->getHiddenLevel())); } }
/** * @param $name * @return string|bool */ public function validateUsername($name) { if ($name === null || $name === '') { // blank cloner field, bypass. return true; } $name = User::getCanonicalName($name, 'usable'); if (!$name) { return $this->msg('centralauth-usermerge-invalid', $name)->escaped(); } if ($name === $this->getUser()->getName()) { return $this->msg('centralauth-usermerge-noself')->escaped(); } $caUser = new CentralAuthUser($name); if (!$caUser->exists()) { return $this->msg('centralauth-usermerge-invalid', $name)->escaped(); } if ($caUser->renameInProgress()) { return $this->msg('centralauth-usermerge-already', $name)->escaped(); } return true; }
public function execute() { if (!$this->getUser()->isAllowed('centralauth-unmerge')) { $this->dieUsageMsg(array('badaccess-groups')); } $params = $this->extractRequestParams(); $globalUser = new CentralAuthUser($params['user']); if (!$globalUser->exists()) { $this->dieUsageMsg(array('nosuchuser', $globalUser->getName())); } elseif ($globalUser->isOversighted() && !$this->getUser()->isAllowed('centralauth-oversight')) { $this->dieUsageMsg(array('nosuchuser', $globalUser->getName())); } $status = $globalUser->adminDelete($params['reason']); if ($status->isGood()) { $this->getResult()->addValue(null, $this->getModuleName(), array('user' => $globalUser->getName(), 'reason' => $params['reason'])); } else { if (is_callable(array($this, 'getErrorFormatter'))) { $error = $this->getErrorFormatter()->arrayFromStatus($status); } else { $error = $this->getResult()->convertStatusToArray($status); } $this->getResult()->addValue('error', null, $error); } }
protected function rename($row, DatabaseBase $dbw) { $wiki = $row->utr_wiki; $name = $row->utr_name; $newNamePrefix = User::getCanonicalName($name . '~' . str_replace('_', '-', $wiki), 'usable'); if (!$newNamePrefix) { $this->log("ERROR: New name '{$name}~{$wiki}' is not valid"); return; } $this->log("Beginning rename of {$newNamePrefix}"); $newCAUser = new CentralAuthUser($newNamePrefix); $count = 0; // Edge case: Someone created User:Foo~wiki manually. // So just start appending numbers to the end of the name // until we get one that isn't used. while ($newCAUser->exists()) { $count++; $newCAUser = new CentralAuthUser($newNamePrefix . (string) $count); } if ($newNamePrefix !== $newCAUser->getName()) { $this->log("WARNING: New name is now {$newCAUser->getName()}"); } $this->log("Renaming {$name} to {$newCAUser->getName()}."); $statuses = new GlobalRenameUserStatus($name); $success = $statuses->setStatuses(array(array('ru_wiki' => $wiki, 'ru_oldname' => $name, 'ru_newname' => $newCAUser->getName(), 'ru_status' => 'queued'))); if (!$success) { $this->log("WARNING: Race condition, renameuser_status already set for {$newCAUser->getName()}. Skipping."); return; } $this->log("Set renameuser_status for {$newCAUser->getName()}."); $job = new LocalRenameUserJob(Title::newFromText('Global rename job'), array('from' => $name, 'to' => $newCAUser->getName(), 'renamer' => 'Maintenance script', 'movepages' => true, 'suppressredirects' => true, 'promotetoglobal' => true, 'reason' => $this->getOption('reason'))); JobQueueGroup::singleton($row->utr_wiki)->push($job); $this->log("Submitted job for {$newCAUser->getName()}."); $updates = new UsersToRenameDatabaseUpdates($dbw); $updates->markRenamed($row->utr_name, $row->utr_wiki); }
function doAttachMerge() { global $wgCentralAuthDryRun; $globalUser = new CentralAuthUser($this->getUser()->getName()); if (!$globalUser->exists()) { throw new MWException("User doesn't exist -- race condition?"); } if ($globalUser->isAttached()) { throw new MWException("Already attached -- race condition?"); } if ($wgCentralAuthDryRun) { $this->dryRunError(); return; } $password = $this->getRequest()->getText('wpPassword'); if ($globalUser->authenticate($password) == 'ok') { $globalUser->attach(wfWikiID(), 'password'); $this->getOutput()->addWikiMsg('centralauth-attach-success'); $this->showCleanupForm(); } else { $this->getOutput()->addHTML('<div class="errorbox">' . wfMsg('wrongpassword') . '</div>' . $this->attachActionForm()); } }
/** * @covers CentralAuthUser::attach */ public function testAttach() { $caUser = new CentralAuthUser('GlobalUser'); $caUser->attach('anotherwiki', 'admin', false); $this->assertSame(true, $caUser->exists()); $this->assertSame(true, in_array('anotherwiki', $caUser->listAttached())); }
public function execute() { $params = $this->extractRequestParams(); $prop = array_flip((array) $params['prop']); if (is_null($params['user'])) { $params['user'] = $this->getUser()->getName(); } $user = new CentralAuthUser($params['user']); // Add basic info $result = $this->getResult(); $data = array(); $userExists = $user->exists(); if ($userExists) { $data['home'] = $user->getHomeWiki(); $data['id'] = $user->getId(); $data['registration'] = wfTimestamp(TS_ISO_8601, $user->getRegistration()); if ($user->isLocked()) { $data['locked'] = ''; } if ($user->isHidden()) { $data['hidden'] = ''; } } else { $data['missing'] = ''; } $result->addValue('query', $this->getModuleName(), $data); // Add requested info if ($userExists && isset($prop['groups'])) { $groups = $user->getGlobalGroups(); $result->setIndexedTagName($groups, 'g'); $result->addValue(array('query', $this->getModuleName()), 'groups', $groups); } if ($userExists && isset($prop['rights'])) { $rights = $user->getGlobalRights(); $result->setIndexedTagName($rights, 'r'); $result->addValue(array('query', $this->getModuleName()), 'rights', $rights); } if ($userExists && isset($prop['merged'])) { $accounts = $user->queryAttached(); foreach ($accounts as $account) { $dbname = $account['wiki']; $a = array('wiki' => $dbname, 'url' => $this->getUrl($dbname), 'timestamp' => wfTimestamp(TS_ISO_8601, $account['attachedTimestamp']), 'method' => $account['attachedMethod'], 'editcount' => $account['editCount']); if ($account['blocked']) { $a['blocked'] = array('expiry' => $this->getLanguage()->formatExpiry($account['block-expiry'], TS_ISO_8601), 'reason' => $account['block-reason']); } $result->addValue(array('query', $this->getModuleName(), 'merged'), null, $a); } $result->setIndexedTagName_internal(array('query', $this->getModuleName(), 'merged'), 'account'); } if (isset($prop['unattached'])) { $accounts = $user->queryUnattached(); foreach ($accounts as $account) { $a = array('wiki' => $account['wiki'], 'editcount' => $account['editCount']); if ($account['blocked']) { $a['blocked'] = array('expiry' => $this->getLanguage()->formatExpiry($account['block-expiry'], TS_ISO_8601), 'reason' => $account['block-reason']); } $result->addValue(array('query', $this->getModuleName(), 'unattached'), null, $a); } $result->setIndexedTagName_internal(array('query', $this->getModuleName(), 'unattached'), 'account'); } }
public function execute() { $params = $this->extractRequestParams(); $prop = array_flip((array) $params['prop']); if (is_null($params['user'])) { $params['user'] = $this->getUser()->getName(); } $user = new CentralAuthUser($params['user']); // Add basic info $result = $this->getResult(); $data = array(); $userExists = $user->exists(); if ($userExists && ($user->getHiddenLevel() === CentralAuthUser::HIDDEN_NONE || $this->getUser()->isAllowed('centralauth-oversight'))) { // The global user exists and it's not hidden or the current user is allowed to see it $data['home'] = $user->getHomeWiki(); $data['id'] = $user->getId(); $data['registration'] = wfTimestamp(TS_ISO_8601, $user->getRegistration()); $data['name'] = $user->getName(); if ($user->isLocked()) { $data['locked'] = ''; } if ($user->isHidden()) { $data['hidden'] = ''; } } else { // The user doesn't exist or we pretend it doesn't if it's hidden $data['missing'] = ''; } $result->addValue('query', $this->getModuleName(), $data); // Add requested info if ($userExists && isset($prop['groups'])) { $groups = $user->getGlobalGroups(); $result->setIndexedTagName($groups, 'g'); $result->addValue(array('query', $this->getModuleName()), 'groups', $groups); } if ($userExists && isset($prop['rights'])) { $rights = $user->getGlobalRights(); $result->setIndexedTagName($rights, 'r'); $result->addValue(array('query', $this->getModuleName()), 'rights', $rights); } $attachedAccounts = null; if ($userExists && (isset($prop['merged']) || isset($prop['editcount']))) { $attachedAccounts = $user->queryAttached(); } if ($userExists && isset($prop['merged'])) { foreach ($attachedAccounts as $account) { $dbname = $account['wiki']; $wiki = WikiMap::getWiki($dbname); $a = array('wiki' => $dbname, 'url' => $wiki->getCanonicalServer(), 'timestamp' => wfTimestamp(TS_ISO_8601, $account['attachedTimestamp']), 'method' => $account['attachedMethod'], 'editcount' => $account['editCount']); if ($account['blocked']) { $a['blocked'] = array('expiry' => $this->getLanguage()->formatExpiry($account['block-expiry'], TS_ISO_8601), 'reason' => $account['block-reason']); } $result->addValue(array('query', $this->getModuleName(), 'merged'), null, $a); } if (defined('ApiResult::META_CONTENT')) { $result->addIndexedTagName(array('query', $this->getModuleName(), 'merged'), 'account'); } else { $result->setIndexedTagName_internal(array('query', $this->getModuleName(), 'merged'), 'account'); } } if ($userExists && isset($prop['editcount'])) { $editcount = 0; foreach ($attachedAccounts as $account) { $editcount += $account['editCount']; } $result->addValue('query', $this->getModuleName(), array('editcount' => $editcount)); } if (isset($prop['unattached'])) { $accounts = $user->queryUnattached(); foreach ($accounts as $account) { $a = array('wiki' => $account['wiki'], 'editcount' => $account['editCount']); if ($account['blocked']) { $a['blocked'] = array('expiry' => $this->getLanguage()->formatExpiry($account['block-expiry'], TS_ISO_8601), 'reason' => $account['block-reason']); } $result->addValue(array('query', $this->getModuleName(), 'unattached'), null, $a); } if (defined('ApiResult::META_CONTENT')) { $result->addIndexedTagName(array('query', $this->getModuleName(), 'unattached'), 'account'); } else { $result->setIndexedTagName_internal(array('query', $this->getModuleName(), 'unattached'), 'account'); } } }
/** * @param $uid * @param $oldName * @param $newName * @return bool */ static function onRenameUserPreRename($uid, $oldName, $newName) { $oldCentral = new CentralAuthUser($oldName); if ($oldCentral->exists() && $oldCentral->isAttached()) { $oldCentral->adminUnattach(array(wfWikiID())); } return true; }
function migrate($username, $homewiki = null) { $this->total++; $this->output("CentralAuth account migration for: " . $username . "\n"); $central = new CentralAuthUser($username); try { $unattached = $central->queryUnattached(); } catch (Exception $e) { // This might happen due to localnames inconsistencies (bug 67350) $this->output("ERROR: Fetching unattached accounts for {$username} failed."); return; } /** * Migration with an existing global account */ if ($central->exists()) { $this->output("INFO: A global account already exists for: {$username}\n"); if ($this->getOption('attachmissing', false) && !is_null($central->getEmailAuthenticationTimestamp())) { foreach ($unattached as $wiki => $local) { if ($central->getEmail() === $local['email'] && !is_null($local['emailAuthenticated'])) { $this->output("ATTACHING: {$username}@{$wiki}\n"); $central->attach($wiki, 'mail', !$this->suppressRC); } } } if ($this->getOption('attachbroken', false)) { // This option is for bug 61876 / bug 39996 where the account has // an empty password and email set, and became unattached. // Since there is no way an account can have an empty password manually // it has to be due to a CentralAuth bug. So just attach it then. // But just to be on the safe side, check that it also has 0 edits. foreach ($unattached as $wiki => $local) { if ($local['email'] === '' && $local['password'] === '' && $local['editCount'] === '0') { $this->output("ATTACHING: {$username}@{$wiki}\n"); // Ironically, the attachment is made due to lack of a password. $central->attach($wiki, 'password', !$this->suppressRC); } } } } else { if (count($unattached) == 0) { $this->output("ERROR: No local accounts found for: {$username}\n"); return; } if ($this->safe && count($unattached) !== 1) { $this->output("ERROR: More than 1 local user account found for username: {$username}\n"); foreach ($unattached as $local) { $this->output("\t" . $central->getName() . "@" . $local['wiki'] . "\n"); } return; } if ($homewiki !== null) { if (!array_key_exists($homewiki, $unattached)) { $this->output("ERROR: Unattached user not found for {$username}@{$homewiki}\n"); return; } $this->output("INFO: Setting homewiki for '{$username}' to {$homewiki}\n"); $central->mHomeWiki = $homewiki; } // Check that all unattached (i.e. ALL) accounts have a confirmed email // address and that the addresses are all the same. We are using this // to match accounts to the same user, since we can't use the password. $emailMatch = true; $email = null; foreach ($unattached as $local) { if (is_null($email)) { $email = $local['email']; } if ($local['email'] === $email && !is_null($local['emailAuthenticated'])) { continue; } $emailMatch = false; break; } // All of the emails are the same and confirmed? Merge all the accounts. // They aren't? Skip, or merge the winner if --auto was specified. if ($emailMatch) { $this->output("Email addresses match and are confirmed for: {$username}\n"); $central->storeAndMigrate(array(), !$this->suppressRC); } else { if (isset($central->mHomeWiki) || $this->autoMigrate) { $central->storeAndMigrate(array(), !$this->suppressRC); } else { $this->output("ERROR: Auto migration is disabled and email addresses do not match for: {$username}\n"); } } } $unattachedAfter = $central->queryUnattached(); if (count($unattachedAfter) == 0) { $this->migrated++; return; } elseif (count($unattachedAfter) > 0 && count($unattachedAfter) < count($unattached)) { $this->partial++; $this->output("INFO: Incomplete migration for '{$username}'\n"); } if ($this->resetToken) { $this->output("INFO: Resetting CentralAuth auth token for '{$username}'\n"); $central->resetAuthToken(); } }
/** * @param $name * @return CentralAuthGroupMembershipProxy|null */ public static function newFromName($name) { $name = User::getCanonicalName($name); $globalUser = new CentralAuthUser($name); return $globalUser->exists() ? new CentralAuthGroupMembershipProxy($globalUser) : null; }
/** * Check to see if a given username is available for use via CentralAuth. * * Note that this is not a definiative check. It does not include checking * for AntiSpoof, TitleBlacklist or other AbortNewAccount hook blocks. * Unfortunately the only cannonical way to validate that an account is * available is to make the account and check that it wasn't blocked by * something. * * @param string $name * @return Status Canonicalized name */ public static function isNameAvailable($name) { $safe = User::getCanonicalName($name, 'creatable'); $status = Status::newGood($safe); if ($safe === false || $safe === '') { $status->fatal('globalrenamerequest-newname-err-invalid'); return $status; } if (self::nameHasPendingRequest($safe)) { $status->fatal('globalrenamerequest-newname-err-taken'); return $status; } // New user creation checks against local wiki only using an API // request, but we need to check against te central user table instead $centralUser = new CentralAuthUser($safe); if ($centralUser->exists() || $centralUser->listUnattached()) { $status->fatal('globalrenamerequest-newname-err-taken'); return $status; } // Check to see if there is an active rename to the desired name. $progress = $centralUser->renameInProgress(); if ($progress && $safe == $progress[1]) { $status->fatal('globalrenamerequest-newname-err-taken'); return $status; } return $status; }
/** * Check if a user should authenticate locally if the global authentication fails. * If either this or strict() returns true, local authentication is not used. * * @param $username String: username. * @return bool */ public function strictUserAuth($username) { // Authenticate locally if the global account doesn't exist, // or the local account isn't attached // If strict is on, local authentication won't work at all $central = new CentralAuthUser($username); return $central->exists() && $central->isAttached(); }
/** * When renaming an account, ensure that the presence records are updated. * @param $userId int * @param $oldName string * @param $newName string * @return bool */ static function onRenameUserComplete($userId, $oldName, $newName) { $oldCentral = new CentralAuthUser($oldName); $newCentral = new CentralAuthUser($newName); if ($newCentral->exists() && $oldCentral->renameInProgressOn(wfWikiID())) { // This is a global rename, just update the row. $oldCentral->updateLocalName(wfWikiID(), $newName); } else { $oldCentral->removeLocalName(wfWikiID()); $newCentral->addLocalName(wfWikiID()); } return true; }
function doAttachMerge() { global $wgCentralAuthDryRun; $globalUser = new CentralAuthUser($this->getUser()->getName()); if (!$globalUser->exists()) { throw new Exception("User doesn't exist -- race condition?"); } if ($globalUser->isAttached()) { // Already attached - race condition $this->showCleanupForm(); return; } if ($wgCentralAuthDryRun) { $this->dryRunError(); return; } $password = $this->getRequest()->getText('wpPassword'); if ($globalUser->authenticate($password) == 'ok') { $globalUser->attach(wfWikiID(), 'password'); $this->getOutput()->addWikiMsg('centralauth-attach-success'); $this->showCleanupForm(); } else { $this->getOutput()->addHTML(Html::rawElement('div', array("class" => "errorbox"), $this->msg('wrongpassword')->escaped()) . $this->attachActionForm()); } }