From b76be11a85418b32235eaec3fd42e3a0d9af83dc Mon Sep 17 00:00:00 2001 From: Brion Vibber Date: Sun, 5 Jun 2005 11:19:52 +0000 Subject: [PATCH] * (bug 2223) Add unique index on user_name field to prevent duplicate accounts --- RELEASE-NOTES | 1 + maintenance/archives/patch-user_nameindex.sql | 13 ++++++++ maintenance/tables.sql | 2 +- maintenance/updaters.inc | 18 +++++++++++ maintenance/userDupes.inc | 30 ++++++++++++++++++- maintenance/userDupes.php | 3 +- 6 files changed, 64 insertions(+), 3 deletions(-) create mode 100644 maintenance/archives/patch-user_nameindex.sql diff --git a/RELEASE-NOTES b/RELEASE-NOTES index d1fc875d71..a0a230f9b5 100644 --- a/RELEASE-NOTES +++ b/RELEASE-NOTES @@ -266,6 +266,7 @@ Various bugfixes, small features, and a few experimental things: * (bug 2319) Fix parse hook tag matching * (bug 2329) Fix title formatting in several special pages +* (bug 2223) Add unique index on user_name field to prevent duplicate accounts === Caveats === diff --git a/maintenance/archives/patch-user_nameindex.sql b/maintenance/archives/patch-user_nameindex.sql new file mode 100644 index 0000000000..9bf0aab1bb --- /dev/null +++ b/maintenance/archives/patch-user_nameindex.sql @@ -0,0 +1,13 @@ +-- +-- Change the index on user_name to a unique index to prevent +-- duplicate registrations from creeping in. +-- +-- Run maintenance/userDupes.php or through the updater first +-- to clean up any prior duplicate accounts. +-- +-- Added 2005-06-05 +-- + + ALTER TABLE /*$wgDBprefix*/user + DROP INDEX user_name, +ADD UNIQUE INDEX user_name(user_name); diff --git a/maintenance/tables.sql b/maintenance/tables.sql index 2bf8de4939..37db68bec0 100644 --- a/maintenance/tables.sql +++ b/maintenance/tables.sql @@ -104,7 +104,7 @@ CREATE TABLE /*$wgDBprefix*/user ( user_email_token_expires CHAR(14) BINARY, PRIMARY KEY user_id (user_id), - INDEX user_name (user_name(10)), + UNIQUE INDEX user_name (user_name), INDEX (user_email_token) ) TYPE=InnoDB; diff --git a/maintenance/updaters.inc b/maintenance/updaters.inc index e2255c740f..735a724f9d 100644 --- a/maintenance/updaters.inc +++ b/maintenance/updaters.inc @@ -8,6 +8,7 @@ require_once 'convertLinks.inc'; require_once 'InitialiseMessages.inc'; +require_once 'userDupes.inc'; $wgRenamedTables = array( # from to patch file @@ -556,6 +557,21 @@ function do_old_links_update() { } } +function do_user_unique_update() { + global $wgDatabase; + $duper = new UserDupes( $wgDatabase ); + if( $duper->hasUniqueIndex() ) { + echo "Already have unique user_name index.\n"; + } else { + if( !$duper->clearDupes() ) { + echo "WARNING: This next step will probably fail due to unfixed duplicates...\n"; + } + echo "Adding unique index on user_name... "; + dbsource( 'maintenance/archives/patch-user_nameindex.sql', $wgDatabase ); + echo "ok\n"; + } +} + function do_all_updates() { global $wgNewTables, $wgNewFields, $wgRenamedTables; @@ -598,6 +614,8 @@ function do_all_updates() { do_drop_img_type(); flush(); + do_user_unique_update(); flush(); + initialiseMessages(); flush(); } diff --git a/maintenance/userDupes.inc b/maintenance/userDupes.inc index 0e315aa902..e0b2498889 100644 --- a/maintenance/userDupes.inc +++ b/maintenance/userDupes.inc @@ -25,6 +25,30 @@ class UserDupes { var $unresolvable; var $trimmed; + function UserDupes( &$database ) { + $this->db =& $database; + } + + /** + * Check if this database's user table has already had a unique + * user_name index applied. + * @return bool + */ + function hasUniqueIndex() { + $fname = 'UserDupes::hasUniqueIndex'; + #if( $wgDatabase->indexExists( 'image', 'PRIMARY' ) ) { + $info = $this->db->indexInfo( 'user', 'user_name', $fname ); + if( !$info ) { + echo "WARNING: doesn't seem to have user_name index at all!\n"; + return false; + } + + # Confusingly, 'Non_unique' is 0 for *unique* indexes, + # and 1 for *non-unique* indexes. Pass the crack, MySQL, + # it's obviously some good stuff! + return ( $info->Non_unique == 0 ); + } + /** * Checks the database for duplicate user account records * and remove them in preparation for application of a unique @@ -56,7 +80,11 @@ class UserDupes { function checkDupes( $doDelete=false ) { global $wgDBname; - $this->db =& wfGetDB( DB_MASTER ); + if( $this->hasUniqueIndex() ) { + echo "$wgDBname already has a unique index on its user table.\n"; + return true; + } + $this->lock(); echo "Checking for duplicate accounts...\n"; diff --git a/maintenance/userDupes.php b/maintenance/userDupes.php index 45041a519b..8dca2b581a 100644 --- a/maintenance/userDupes.php +++ b/maintenance/userDupes.php @@ -26,7 +26,8 @@ require_once( 'maintenance/userDupes.inc' ); $wgTitle = Title::newFromText( 'Dupe user entry cleanup script' ); $fix = isset( $options['fix'] ); -$duper = new UserDupes(); +$dbw =& wfGetDB( DB_MASTER ); +$duper = new UserDupes( $dbw ); $retval = $duper->checkDupes( $fix ); if( $retval ) { -- 2.20.1