Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
0.00% |
0 / 54 |
|
0.00% |
0 / 4 |
CRAP | |
0.00% |
0 / 1 |
MigrateInitialAccountsTask | |
0.00% |
0 / 54 |
|
0.00% |
0 / 4 |
42 | |
0.00% |
0 / 1 |
getName | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getDescription | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getDependencies | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
execute | |
0.00% |
0 / 51 |
|
0.00% |
0 / 1 |
12 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\CentralAuth; |
4 | |
5 | use MediaWiki\Status\Status; |
6 | use MWCryptRand; |
7 | |
8 | class MigrateInitialAccountsTask extends \MediaWiki\Installer\Task\Task { |
9 | |
10 | /** |
11 | * @return string |
12 | */ |
13 | public function getName() { |
14 | return 'centralauth-migrate-accounts'; |
15 | } |
16 | |
17 | /** |
18 | * @return string |
19 | */ |
20 | public function getDescription() { |
21 | return '[CentralAuth] Globalizing initial user'; |
22 | } |
23 | |
24 | /** |
25 | * @return string[] |
26 | */ |
27 | public function getDependencies() { |
28 | return [ 'created-user-names', 'extension-tables', 'services' ]; |
29 | } |
30 | |
31 | public function execute(): Status { |
32 | $services = $this->getServices(); |
33 | $dbw = $services->getConnectionProvider()->getPrimaryDatabase( 'virtual-centralauth' ); |
34 | |
35 | $names = $this->getContext()->getProvision( 'created-user-names' ); |
36 | if ( !$names ) { |
37 | return Status::newGood(); |
38 | } |
39 | |
40 | // Assume that there are very few users, so we don't need batching. |
41 | $users = $dbw->newSelectQueryBuilder() |
42 | ->from( 'user' ) |
43 | ->select( [ |
44 | 'user_id', |
45 | 'user_email', |
46 | 'user_name', |
47 | 'user_email_authenticated', |
48 | 'user_password', |
49 | 'user_registration', |
50 | ] ) |
51 | ->where( [ 'user_name' => $names ] ) |
52 | ->caller( __METHOD__ ) |
53 | ->fetchResultSet(); |
54 | |
55 | // We're in the installer, so none of the CentralAuth code except for this script is loaded, |
56 | // therefore we can't rely on any of our services or default values of config options. |
57 | // Migrate the users manually using custom database queries. |
58 | |
59 | foreach ( $users as $user ) { |
60 | $dbw->doAtomicSection( __METHOD__, static function ( $dbw, $fname ) use ( $user ) { |
61 | global $wgDBname; |
62 | |
63 | // Unlike migratePass0/1, we don't need to store anything into globalnames and localnames, |
64 | // these tables are only used for incomplete migrations and we're doing a complete one. |
65 | |
66 | // See CentralAuthUser::storeGlobalData() |
67 | $dbw->newInsertQueryBuilder() |
68 | ->insertInto( 'globaluser' ) |
69 | ->row( [ |
70 | 'gu_name' => $user->user_name, |
71 | 'gu_home_db' => $wgDBname, |
72 | 'gu_email' => $user->user_email, |
73 | 'gu_email_authenticated' => $user->user_email_authenticated, |
74 | 'gu_password' => $user->user_password, |
75 | 'gu_locked' => 0, |
76 | 'gu_hidden_level' => 0, |
77 | 'gu_registration' => $user->user_registration, |
78 | 'gu_auth_token' => MWCryptRand::generateHex( 32 ), |
79 | ] ) |
80 | ->caller( $fname ) |
81 | ->execute(); |
82 | $gu_id = $dbw->insertId(); |
83 | |
84 | // See CentralAuthUser::attach() |
85 | $dbw->newInsertQueryBuilder() |
86 | ->insertInto( 'localuser' ) |
87 | ->row( [ |
88 | 'lu_wiki' => $wgDBname, |
89 | 'lu_name' => $user->user_name, |
90 | 'lu_attached_timestamp' => $user->user_registration, |
91 | 'lu_attached_method' => 'new', |
92 | 'lu_local_id' => $user->user_id, |
93 | 'lu_global_id' => $gu_id, |
94 | ] ) |
95 | ->caller( $fname ) |
96 | ->execute(); |
97 | |
98 | // We don't handle AntiSpoof integration here, because it's complicated, and the |
99 | // AntiSpoof extension doesn't handle the initial accounts either. |
100 | } ); |
101 | } |
102 | |
103 | return Status::newGood(); |
104 | } |
105 | } |