/**
  * @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;
 }
Esempio n. 9
0
 /**
  * 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');
         }
     }
 }
Esempio n. 18
0
 /**
  * @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());
     }
 }