BryanDavis has uploaded a new change for review. https://gerrit.wikimedia.org/r/297936
Change subject: Cleanup localuser records when wiki is missing data ...................................................................... Cleanup localuser records when wiki is missing data Under some (undefined) circumstances the localuser table can record that a user has been attached to a wiki but the wiki's own db is missing a record for the user. There is a maintenance script to find an cleanup these dangling records, but that's not of much help for a user who is affected by the dangling record as they will not be able to authenticate to the effected wiki until the next time someone runs the script. Add logic to catch this problem in the most likely places and proactively clean up the dangling attachment record. The cleanup is done by running a job which cleans up the record in a safe manner and clears caches as appropriate. Bug: T119736 Change-Id: I3d219cfff0dc835faa72d5fe72a80e57235dcb04 --- M extension.json A includes/CentralAuthUnattachUserJob.php M includes/CentralAuthUser.php A includes/LocalUserNotFoundException.php 4 files changed, 124 insertions(+), 8 deletions(-) git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/CentralAuth refs/changes/36/297936/1 diff --git a/extension.json b/extension.json index 769b703..2b149e9 100644 --- a/extension.json +++ b/extension.json @@ -70,7 +70,8 @@ "LocalRenameUserJob": "LocalRenameUserJob", "LocalUserMergeJob": "LocalUserMergeJob", "LocalPageMoveJob": "LocalPageMoveJob", - "CentralAuthCreateLocalAccountJob": "CentralAuthCreateLocalAccountJob" + "CentralAuthCreateLocalAccountJob": "CentralAuthCreateLocalAccountJob", + "CentralAuthUnattachUserJob": "CentralAuthUnattachUserJob" }, "LogTypes": [ "globalauth", @@ -194,7 +195,9 @@ "CentralAuthHooks": "includes/CentralAuthHooks.php", "CentralAuthPreAuthManagerHooks": "includes/CentralAuthPreAuthManagerHooks.php", "CentralAuthSuppressUserJob": "includes/SuppressUserJob.php", + "CentralAuthUnattachUserJob": "includes/CentralAuthUnattachUserJob.php", "CentralAuthCreateLocalAccountJob": "includes/CreateLocalAccountJob.php", + "LocalUserNotFoundException": "includes/LocalUserNotFoundException.php", "WikiSet": "includes/WikiSet.php", "SpecialCentralAutoLogin": "includes/specials/SpecialCentralAutoLogin.php", "CentralAuthUserArray": "includes/CentralAuthUserArray.php", diff --git a/includes/CentralAuthUnattachUserJob.php b/includes/CentralAuthUnattachUserJob.php new file mode 100644 index 0000000..760e27b --- /dev/null +++ b/includes/CentralAuthUnattachUserJob.php @@ -0,0 +1,53 @@ +<?php +/** + * @section LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + */ + +/** + * A job to unattach a user. + * + * @copyright © 2016 Wikimedia Foundation and contributors. + */ +class CentralAuthUnattachUserJob extends Job { + + /** + * Constructor + * + * @param Title $title Associated title + * @param array $params Job parameters + */ + public function __construct( $title, $params ) { + parent::__construct( 'CentralAuthUnattachUserJob', $title, $params ); + } + + /** + * Execute the job + * + * @return bool + */ + public function run() { + $username = $this->params['username']; + $wiki = $this->params['wiki']; + $user = CentralAuthUser::getMasterInstanceByName( $username ); + if ( $user->exists() ) { + $user->adminUnattach( array( $wiki ) ); + } + return true; + } +} diff --git a/includes/CentralAuthUser.php b/includes/CentralAuthUser.php index 083400c..5d7eea2 100644 --- a/includes/CentralAuthUser.php +++ b/includes/CentralAuthUser.php @@ -1391,6 +1391,23 @@ } /** + * Queue a job to unattach this user from a named wiki. + * + * @param string $wikiId + */ + protected function queueAdminUnattachJob( $wikiId ) { + $job = Job::factory( + 'CentralAuthUnattachUserJob', + Title::makeTitleSafe( NS_USER, $this->getName() ), + array( + 'username' => $this->getName(), + 'wiki' => $wikiId, + ) + ); + JobQueueGroup::singleton()->push( $job ); + } + + /** * Delete a global account and log what happened * * @param $reason string Reason for the deletion @@ -2238,8 +2255,17 @@ $wikis = $this->queryAttachedBasic(); foreach ( $wikis as $wikiId => $_ ) { - $localUser = $this->localUserData( $wikiId ); - $wikis[$wikiId] = array_merge( $wikis[$wikiId], $localUser ); + try { + $localUser = $this->localUserData( $wikiId ); + $wikis[$wikiId] = array_merge( $wikis[$wikiId], $localUser ); + } catch (LocalUserNotFoundException $e) { + // T119736: localuser table told us that the user was attached + // from $wikiId but there is no data in the master or slaves + // that corroborates that. + unset( $wikis[$wikiId] ); + // Queue a job to delete the bogus attachment record. + $this->queueAdminUnattachJob( $wikiId ); + } } $this->mAttachedInfo = $wikis; @@ -2300,8 +2326,16 @@ $items = array(); foreach ( $wikiIDs as $wikiID ) { - $data = $this->localUserData( $wikiID ); - $items[$wikiID] = $data; + try { + $data = $this->localUserData( $wikiID ); + $items[$wikiID] = $data; + } catch ( LocalUserNotFoundException $e ) { + // T119736: localuser table told us that the user was attached + // from $wikiId but there is no data in the master or slaves + // that corroborates that. + // Queue a job to delete the bogus attachment record. + $this->queueAdminUnattachJob( $wikiID ); + } } return $items; @@ -2313,7 +2347,7 @@ * Returns most data in the user and ipblocks tables, user groups, and editcount. * * @param $wikiID String - * @throws Exception if local user not found + * @throws LocalUserNotFoundException if local user not found * @return array */ protected function localUserData( $wikiID ) { @@ -2337,7 +2371,7 @@ } if ( !$row ) { $lb->reuseConnection( $db ); - throw new Exception( "Could not find local user data for {$this->mName}@{$wikiID}" ); + throw new LocalUserNotFoundException( "Could not find local user data for {$this->mName}@{$wikiID}" ); } /** @var $row object */ @@ -2860,4 +2894,4 @@ private function clearLocalUserCache( $wikiId, $userId ) { User::purge( $wikiId, $userId ); } -} \ No newline at end of file +} diff --git a/includes/LocalUserNotFoundException.php b/includes/LocalUserNotFoundException.php new file mode 100644 index 0000000..5f804f3 --- /dev/null +++ b/includes/LocalUserNotFoundException.php @@ -0,0 +1,26 @@ +<?php +/** + * @section LICENSE + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License along + * with this program; if not, write to the Free Software Foundation, Inc., + * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. + * http://www.gnu.org/copyleft/gpl.html + * + * @file + */ + +/** + * @copyright © 2016 Wikimedia Foundation and contributors + */ +class LocalUserNotFoundException extends Exception { +} -- To view, visit https://gerrit.wikimedia.org/r/297936 To unsubscribe, visit https://gerrit.wikimedia.org/r/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I3d219cfff0dc835faa72d5fe72a80e57235dcb04 Gerrit-PatchSet: 1 Gerrit-Project: mediawiki/extensions/CentralAuth Gerrit-Branch: master Gerrit-Owner: BryanDavis <bda...@wikimedia.org> _______________________________________________ MediaWiki-commits mailing list MediaWiki-commits@lists.wikimedia.org https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits