Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
100.00% |
10 / 10 |
|
100.00% |
2 / 2 |
CRAP | |
100.00% |
1 / 1 |
SchemaChangesHandler | |
100.00% |
10 / 10 |
|
100.00% |
2 / 2 |
12 | |
100.00% |
1 / 1 |
__construct | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
newFromGlobalState | n/a |
0 / 0 |
n/a |
0 / 0 |
1 | |||||
onLoadExtensionSchemaUpdates | n/a |
0 / 0 |
n/a |
0 / 0 |
7 | |||||
createAbuseFilterUser | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
3 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\AbuseFilter\Hooks\Handlers; |
4 | |
5 | use DatabaseUpdater; |
6 | use MediaWiki\Extension\AbuseFilter\Maintenance\MigrateActorsAF; |
7 | use MediaWiki\Extension\AbuseFilter\Maintenance\UpdateVarDumps; |
8 | use MediaWiki\Installer\Hook\LoadExtensionSchemaUpdatesHook; |
9 | use MediaWiki\MediaWikiServices; |
10 | use MediaWiki\User\User; |
11 | use MediaWiki\User\UserGroupManager; |
12 | use MessageLocalizer; |
13 | use RequestContext; |
14 | |
15 | class SchemaChangesHandler implements LoadExtensionSchemaUpdatesHook { |
16 | /** @var MessageLocalizer */ |
17 | private $messageLocalizer; |
18 | /** @var UserGroupManager */ |
19 | private $userGroupManager; |
20 | |
21 | /** |
22 | * @param MessageLocalizer $messageLocalizer |
23 | * @param UserGroupManager $userGroupManager |
24 | */ |
25 | public function __construct( MessageLocalizer $messageLocalizer, UserGroupManager $userGroupManager ) { |
26 | $this->messageLocalizer = $messageLocalizer; |
27 | $this->userGroupManager = $userGroupManager; |
28 | } |
29 | |
30 | /** |
31 | * @note The hook doesn't allow injecting services! |
32 | * @codeCoverageIgnore |
33 | * @return self |
34 | */ |
35 | public static function newFromGlobalState(): self { |
36 | return new self( |
37 | // @todo Use a proper MessageLocalizer once available (T247127) |
38 | RequestContext::getMain(), |
39 | MediaWikiServices::getInstance()->getUserGroupManager() |
40 | ); |
41 | } |
42 | |
43 | /** |
44 | * @codeCoverageIgnore This is tested by installing or updating MediaWiki |
45 | * @param DatabaseUpdater $updater |
46 | */ |
47 | public function onLoadExtensionSchemaUpdates( $updater ) { |
48 | global $wgAbuseFilterActorTableSchemaMigrationStage; |
49 | |
50 | $dbType = $updater->getDB()->getType(); |
51 | $dir = __DIR__ . "/../../../db_patches"; |
52 | |
53 | $updater->addExtensionTable( |
54 | 'abuse_filter', |
55 | "$dir/$dbType/tables-generated.sql" |
56 | ); |
57 | |
58 | if ( $dbType === 'mysql' || $dbType === 'sqlite' ) { |
59 | if ( $dbType === 'mysql' ) { |
60 | // 1.37 |
61 | $updater->renameExtensionIndex( |
62 | 'abuse_filter_log', |
63 | 'ip_timestamp', |
64 | 'afl_ip_timestamp', |
65 | "$dir/mysql/patch-rename-indexes.sql", |
66 | true |
67 | ); |
68 | |
69 | // 1.38 |
70 | // This one has its own files because apparently, sometimes this particular index can already |
71 | // have the correct name (T291725) |
72 | $updater->renameExtensionIndex( |
73 | 'abuse_filter_log', |
74 | 'wiki_timestamp', |
75 | 'afl_wiki_timestamp', |
76 | "$dir/mysql/patch-rename-wiki-timestamp-index.sql", |
77 | true |
78 | ); |
79 | |
80 | // 1.38 |
81 | // This one is also separate to avoid interferences with the afl_filter field removal below. |
82 | $updater->renameExtensionIndex( |
83 | 'abuse_filter_log', |
84 | 'filter_timestamp', |
85 | 'afl_filter_timestamp', |
86 | "$dir/mysql/patch-rename-filter_timestamp-index.sql", |
87 | true |
88 | ); |
89 | } |
90 | // 1.38 |
91 | $updater->dropExtensionField( |
92 | 'abuse_filter_log', |
93 | 'afl_filter', |
94 | "$dir/$dbType/patch-remove-afl_filter.sql" |
95 | ); |
96 | } elseif ( $dbType === 'postgres' ) { |
97 | $updater->addExtensionUpdate( [ |
98 | 'dropPgIndex', 'abuse_filter_log', 'abuse_filter_log_timestamp' |
99 | ] ); |
100 | $updater->addExtensionUpdate( [ |
101 | 'dropPgField', 'abuse_filter_log', 'afl_filter' |
102 | ] ); |
103 | $updater->addExtensionUpdate( [ |
104 | 'dropDefault', 'abuse_filter_log', 'afl_filter_id' |
105 | ] ); |
106 | $updater->addExtensionUpdate( [ |
107 | 'dropDefault', 'abuse_filter_log', 'afl_global' |
108 | ] ); |
109 | $updater->addExtensionUpdate( [ |
110 | 'renameIndex', 'abuse_filter', 'abuse_filter_user', 'af_user' |
111 | ] ); |
112 | $updater->addExtensionUpdate( [ |
113 | 'renameIndex', 'abuse_filter', 'abuse_filter_group_enabled_id', 'af_group_enabled' |
114 | ] ); |
115 | $updater->addExtensionUpdate( [ |
116 | 'renameIndex', 'abuse_filter_action', 'abuse_filter_action_consequence', 'afa_consequence' |
117 | ] ); |
118 | $updater->addExtensionUpdate( [ |
119 | 'renameIndex', 'abuse_filter_log', 'abuse_filter_log_filter_timestamp_full', 'afl_filter_timestamp_full' |
120 | ] ); |
121 | $updater->addExtensionUpdate( [ |
122 | 'renameIndex', 'abuse_filter_log', 'abuse_filter_log_user_timestamp', 'afl_user_timestamp' |
123 | ] ); |
124 | $updater->addExtensionUpdate( [ |
125 | 'renameIndex', 'abuse_filter_log', 'abuse_filter_log_timestamp', 'afl_timestamp' |
126 | ] ); |
127 | $updater->addExtensionUpdate( [ |
128 | 'renameIndex', 'abuse_filter_log', 'abuse_filter_log_page_timestamp', 'afl_page_timestamp' |
129 | ] ); |
130 | $updater->addExtensionUpdate( [ |
131 | 'renameIndex', 'abuse_filter_log', 'abuse_filter_log_ip_timestamp', 'afl_ip_timestamp' |
132 | ] ); |
133 | $updater->addExtensionUpdate( [ |
134 | 'renameIndex', 'abuse_filter_log', 'abuse_filter_log_rev_id', 'afl_rev_id' |
135 | ] ); |
136 | $updater->addExtensionUpdate( [ |
137 | 'renameIndex', 'abuse_filter_log', 'abuse_filter_log_wiki_timestamp', 'afl_wiki_timestamp' |
138 | ] ); |
139 | $updater->addExtensionUpdate( [ |
140 | 'renameIndex', 'abuse_filter_history', 'abuse_filter_history_filter', 'afh_filter' |
141 | ] ); |
142 | $updater->addExtensionUpdate( [ |
143 | 'renameIndex', 'abuse_filter_history', 'abuse_filter_history_user', 'afh_user' |
144 | ] ); |
145 | $updater->addExtensionUpdate( [ |
146 | 'renameIndex', 'abuse_filter_history', 'abuse_filter_history_user_text', 'afh_user_text' |
147 | ] ); |
148 | $updater->addExtensionUpdate( [ |
149 | 'renameIndex', 'abuse_filter_history', 'abuse_filter_history_timestamp', 'afh_timestamp' |
150 | ] ); |
151 | $updater->addExtensionUpdate( [ |
152 | 'changeNullableField', ' abuse_filter_history', 'afh_public_comments', 'NULL', true |
153 | ] ); |
154 | $updater->addExtensionUpdate( [ |
155 | 'changeNullableField', ' abuse_filter_history', 'afh_actions', 'NULL', true |
156 | ] ); |
157 | } |
158 | |
159 | // 1.41 |
160 | $updater->addExtensionUpdate( [ |
161 | 'addField', 'abuse_filter', 'af_actor', |
162 | "$dir/$dbType/patch-add-af_actor.sql", true |
163 | ] ); |
164 | |
165 | // 1.41 |
166 | $updater->addExtensionUpdate( [ |
167 | 'addField', 'abuse_filter_history', 'afh_actor', |
168 | "$dir/$dbType/patch-add-afh_actor.sql", true |
169 | ] ); |
170 | |
171 | $updater->addExtensionUpdate( [ [ $this, 'createAbuseFilterUser' ] ] ); |
172 | // 1.35 |
173 | $updater->addPostDatabaseUpdateMaintenance( UpdateVarDumps::class ); |
174 | |
175 | // Don't launch the script on update.php if the migration stage is not high enough. |
176 | // This would throw an exception. |
177 | // Also check if the global is set. |
178 | // If globals aren't loaded, it's install.php, and not update.php. This is intentional, |
179 | // see for instance, T193855 or T198331. |
180 | if ( isset( $wgAbuseFilterActorTableSchemaMigrationStage ) && |
181 | ( $wgAbuseFilterActorTableSchemaMigrationStage & SCHEMA_COMPAT_WRITE_NEW ) |
182 | ) { |
183 | // 1.41 |
184 | $updater->addPostDatabaseUpdateMaintenance( MigrateActorsAF::class ); |
185 | } |
186 | } |
187 | |
188 | /** |
189 | * Updater callback to create the AbuseFilter user after the user tables have been updated. |
190 | * @param DatabaseUpdater $updater |
191 | * @return bool |
192 | */ |
193 | public function createAbuseFilterUser( DatabaseUpdater $updater ): bool { |
194 | $username = $this->messageLocalizer->msg( 'abusefilter-blocker' )->inContentLanguage()->text(); |
195 | $user = User::newFromName( $username ); |
196 | |
197 | if ( $user && !$updater->updateRowExists( 'create abusefilter-blocker-user' ) ) { |
198 | $user = User::newSystemUser( $username, [ 'steal' => true ] ); |
199 | $updater->insertUpdateRow( 'create abusefilter-blocker-user' ); |
200 | // Promote user so it doesn't look too crazy. |
201 | $this->userGroupManager->addUserToGroup( $user, 'sysop' ); |
202 | return true; |
203 | } |
204 | return false; |
205 | } |
206 | } |