MediaWiki  1.34.0
UpdateTables.php
Go to the documentation of this file.
1 <?php
2 
4 
8 use Wikimedia;
9 use FormatJson;
10 use ConfigException;
11 
12 class UpdateTables {
16  protected $updater;
17 
21  protected $base;
22 
27  public static function callback( $updater ) {
28  $dir = dirname( dirname( dirname( __DIR__ ) ) );
29  $handler = new static( $updater, $dir );
30  return $handler->execute();
31  }
32 
37  protected function __construct( $updater, $base ) {
38  $this->updater = $updater;
39  $this->base = $base;
40  }
41 
42  protected function execute() {
43  switch ( $this->updater->getDB()->getType() ) {
44  case 'mysql':
45  case 'sqlite':
46  $this->updater->addExtensionTable( 'oathauth_users', "{$this->base}/sql/mysql/tables.sql" );
47  $this->updater->addExtensionUpdate( [ [ $this, 'schemaUpdateOldUsersFromInstaller' ] ] );
48  $this->updater->dropExtensionField(
49  'oathauth_users',
50  'secret_reset',
51  "{$this->base}/sql/mysql/patch-remove_reset.sql"
52  );
53  $this->updater->addExtensionField(
54  'oathauth_users',
55  'module',
56  "{$this->base}/sql/mysql/patch-add_generic_fields.sql"
57  );
58 
59  $this->updater->addExtensionUpdate(
60  [ [ __CLASS__, 'schemaUpdateSubstituteForGenericFields' ] ]
61  );
62  $this->updater->dropExtensionField(
63  'oathauth_users',
64  'secret',
65  "{$this->base}/sql/mysql/patch-remove_module_specific_fields.sql"
66  );
67 
68  $this->updater->addExtensionUpdate(
69  [ [ __CLASS__, 'schemaUpdateTOTPToMultipleKeys' ] ]
70  );
71 
72  break;
73 
74  case 'oracle':
75  $this->updater->addExtensionTable( 'oathauth_users', "{$this->base}/sql/oracle/tables.sql" );
76  break;
77 
78  case 'postgres':
79  $this->updater->addExtensionTable( 'oathauth_users', "{$this->base}/sql/postgres/tables.sql" );
80  break;
81  }
82 
83  return true;
84  }
85 
94  global $wgOATHAuthDatabase;
95  $lb = MediaWikiServices::getInstance()->getDBLoadBalancerFactory()
96  ->getMainLB( $wgOATHAuthDatabase );
97  $dbw = $lb->getConnectionRef( DB_MASTER, [], $wgOATHAuthDatabase );
98  return self::schemaUpdateOldUsers( $dbw );
99  }
100 
108  global $wgOATHAuthDatabase;
109  $lb = MediaWikiServices::getInstance()->getDBLoadBalancerFactory()
110  ->getMainLB( $wgOATHAuthDatabase );
111  $dbw = $lb->getConnectionRef( DB_MASTER, [], $wgOATHAuthDatabase );
112  return self::convertToGenericFields( $dbw );
113  }
114 
122  global $wgOATHAuthDatabase;
123  $lb = MediaWikiServices::getInstance()->getDBLoadBalancerFactory()
124  ->getMainLB( $wgOATHAuthDatabase );
125  $dbw = $lb->getConnectionRef( DB_MASTER, [], $wgOATHAuthDatabase );
126  return self::switchTOTPToMultipleKeys( $dbw );
127  }
128 
135  public static function convertToGenericFields( IDatabase $db ) {
136  if ( !$db->fieldExists( 'oathauth_users', 'secret' ) ) {
137  return true;
138  }
139 
140  $services = MediaWikiServices::getInstance();
141  $batchSize = $services->getMainConfig()->get( 'UpdateRowsPerQuery' );
142  $lbFactory = $services->getDBLoadBalancerFactory();
143  while ( true ) {
144  $lbFactory->waitForReplication();
145 
146  $res = $db->select(
147  'oathauth_users',
148  [ 'id', 'secret', 'scratch_tokens' ],
149  [
150  'module' => '',
151  'data IS NULL',
152  'secret IS NOT NULL'
153  ],
154  __METHOD__,
155  [ 'LIMIT' => $batchSize ]
156  );
157 
158  if ( $res->numRows() === 0 ) {
159  return true;
160  }
161 
162  foreach ( $res as $row ) {
163  $db->update(
164  'oathauth_users',
165  [
166  'module' => 'totp',
167  'data' => FormatJson::encode( [
168  'keys' => [ [
169  'secret' => $row->secret,
170  'scratch_tokens' => $row->scratch_tokens
171  ] ]
172  ] )
173  ],
174  [ 'id' => $row->id ],
175  __METHOD__
176  );
177  }
178  }
179 
180  return true;
181  }
182 
190  public static function switchTOTPToMultipleKeys( IDatabase $db ) {
191  if ( !$db->fieldExists( 'oathauth_users', 'data' ) ) {
192  return true;
193  }
194 
195  $res = $db->select(
196  'oathauth_users',
197  [ 'id', 'data' ],
198  [
199  'module' => 'totp'
200  ],
201  __METHOD__
202  );
203 
204  foreach ( $res as $row ) {
205  $data = FormatJson::decode( $row->data, true );
206  if ( isset( $data['keys'] ) ) {
207  continue;
208  }
209  $db->update(
210  'oathauth_users',
211  [
212  'data' => FormatJson::encode( [
213  'keys' => [ $data ]
214  ] )
215  ],
216  [ 'id' => $row->id ],
217  __METHOD__
218  );
219  }
220 
221  return true;
222  }
223 
230  public static function schemaUpdateOldUsers( IDatabase $db ) {
231  if ( !$db->fieldExists( 'oathauth_users', 'secret_reset' ) ) {
232  return true;
233  }
234 
235  $res = $db->select(
236  'oathauth_users',
237  [ 'id', 'scratch_tokens' ],
238  [ 'is_validated != 0' ],
239  __METHOD__
240  );
241 
242  foreach ( $res as $row ) {
243  Wikimedia\suppressWarnings();
244  $scratchTokens = unserialize( base64_decode( $row->scratch_tokens ) );
245  Wikimedia\restoreWarnings();
246  if ( $scratchTokens ) {
247  $db->update(
248  'oathauth_users',
249  [ 'scratch_tokens' => implode( ',', $scratchTokens ) ],
250  [ 'id' => $row->id ],
251  __METHOD__
252  );
253  }
254  }
255 
256  // Remove rows from the table where user never completed the setup process
257  $db->delete( 'oathauth_users', [ 'is_validated' => 0 ], __METHOD__ );
258 
259  return true;
260  }
261 }
MediaWiki\Extension\OATHAuth\Hook\LoadExtensionSchemaUpdates\UpdateTables\schemaUpdateOldUsersFromInstaller
schemaUpdateOldUsersFromInstaller(DatabaseUpdater $updater)
Helper function for converting old users to the new schema.
Definition: UpdateTables.php:93
DatabaseUpdater
Class for handling database updates.
Definition: DatabaseUpdater.php:36
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:117
MediaWiki\Extension\OATHAuth\Hook\LoadExtensionSchemaUpdates\UpdateTables\schemaUpdateTOTPToMultipleKeys
static schemaUpdateTOTPToMultipleKeys(DatabaseUpdater $updater)
Helper function for converting single TOTP keys to multi-key system.
Definition: UpdateTables.php:121
MediaWiki\Extension\OATHAuth\Hook\LoadExtensionSchemaUpdates\UpdateTables\schemaUpdateOldUsers
static schemaUpdateOldUsers(IDatabase $db)
Helper function for converting old users to the new schema.
Definition: UpdateTables.php:230
MediaWiki\Extension\OATHAuth\Hook\LoadExtensionSchemaUpdates\UpdateTables\execute
execute()
Definition: UpdateTables.php:42
$res
$res
Definition: testCompression.php:52
Wikimedia\Rdbms\IDatabase
Basic database interface for live and lazy-loaded relation database handles.
Definition: IDatabase.php:38
MediaWiki\MediaWikiServices\getInstance
static getInstance()
Returns the global default instance of the top level service locator.
Definition: MediaWikiServices.php:138
FormatJson\decode
static decode( $value, $assoc=false)
Decodes a JSON string.
Definition: FormatJson.php:174
FormatJson\encode
static encode( $value, $pretty=false, $escaping=0)
Returns the JSON representation of a value.
Definition: FormatJson.php:115
MediaWiki\Extension\OATHAuth\Hook\LoadExtensionSchemaUpdates\UpdateTables\schemaUpdateSubstituteForGenericFields
static schemaUpdateSubstituteForGenericFields(DatabaseUpdater $updater)
Helper function for converting old, TOTP specific, column values to new structure.
Definition: UpdateTables.php:107
FormatJson
JSON formatter wrapper class.
Definition: FormatJson.php:26
MediaWiki\Extension\OATHAuth\Hook\LoadExtensionSchemaUpdates\UpdateTables\__construct
__construct( $updater, $base)
Definition: UpdateTables.php:37
ConfigException
Exceptions for config failures.
Definition: ConfigException.php:28
MediaWiki\Extension\OATHAuth\Hook\LoadExtensionSchemaUpdates\UpdateTables
Definition: UpdateTables.php:12
DB_MASTER
const DB_MASTER
Definition: defines.php:26
MediaWiki\Extension\OATHAuth\Hook\LoadExtensionSchemaUpdates\UpdateTables\$updater
DatabaseUpdater $updater
Definition: UpdateTables.php:16
MediaWiki\Extension\OATHAuth\Hook\LoadExtensionSchemaUpdates\UpdateTables\switchTOTPToMultipleKeys
static switchTOTPToMultipleKeys(IDatabase $db)
Switch from using single keys to multi-key support.
Definition: UpdateTables.php:190
Wikimedia\Rdbms\IDatabase\update
update( $table, $values, $conds, $fname=__METHOD__, $options=[])
UPDATE wrapper.
MediaWiki\Extension\OATHAuth\Hook\LoadExtensionSchemaUpdates\UpdateTables\callback
static callback( $updater)
Definition: UpdateTables.php:27
unserialize
unserialize( $serialized)
Definition: ApiMessageTrait.php:146
MediaWiki\Extension\OATHAuth\Hook\LoadExtensionSchemaUpdates
Definition: UpdateTables.php:3
Wikimedia\Rdbms\IDatabase\fieldExists
fieldExists( $table, $field, $fname=__METHOD__)
Determines whether a field exists in a table.
Wikimedia
This program is free software; you can redistribute it and/or modify it under the terms of the GNU Ge...
Wikimedia\Rdbms\IDatabase\select
select( $table, $vars, $conds='', $fname=__METHOD__, $options=[], $join_conds=[])
Execute a SELECT query constructed using the various parameters provided.
MediaWiki\Extension\OATHAuth\Hook\LoadExtensionSchemaUpdates\UpdateTables\convertToGenericFields
static convertToGenericFields(IDatabase $db)
Converts old, TOTP specific, column values to new structure.
Definition: UpdateTables.php:135
MediaWiki\Extension\OATHAuth\Hook\LoadExtensionSchemaUpdates\UpdateTables\$base
string $base
Definition: UpdateTables.php:21
Wikimedia\Rdbms\IDatabase\delete
delete( $table, $conds, $fname=__METHOD__)
DELETE query wrapper.