Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
98.75% |
79 / 80 |
|
91.67% |
11 / 12 |
CRAP | |
0.00% |
0 / 1 |
SpecialGlobalBlockStatus | |
98.75% |
79 / 80 |
|
91.67% |
11 / 12 |
21 | |
0.00% |
0 / 1 |
__construct | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
execute | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
1 | |||
setParameter | |
100.00% |
21 / 21 |
|
100.00% |
1 / 1 |
6 | |||
alterForm | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
1 | |||
getFormFields | |
100.00% |
20 / 20 |
|
100.00% |
1 / 1 |
2 | |||
onSubmit | |
100.00% |
10 / 10 |
|
100.00% |
1 / 1 |
3 | |||
showSuccess | |
100.00% |
7 / 7 |
|
100.00% |
1 / 1 |
1 | |||
doesWrites | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getGroupName | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getDisplayFormat | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getDescription | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
checkExecutePermissions | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 |
1 | <?php |
2 | |
3 | namespace MediaWiki\Extension\GlobalBlocking\Special; |
4 | |
5 | use ErrorPageError; |
6 | use Exception; |
7 | use HTMLForm; |
8 | use MediaWiki\Block\BlockUtils; |
9 | use MediaWiki\Extension\GlobalBlocking\Services\GlobalBlockingLinkBuilder; |
10 | use MediaWiki\Extension\GlobalBlocking\Services\GlobalBlockLocalStatusLookup; |
11 | use MediaWiki\Extension\GlobalBlocking\Services\GlobalBlockLocalStatusManager; |
12 | use MediaWiki\Extension\GlobalBlocking\Services\GlobalBlockLookup; |
13 | use MediaWiki\SpecialPage\FormSpecialPage; |
14 | use MediaWiki\SpecialPage\SpecialPage; |
15 | use MediaWiki\User\User; |
16 | use MediaWiki\User\UserIdentity; |
17 | use MediaWiki\User\UserNameUtils; |
18 | use Wikimedia\IPUtils; |
19 | |
20 | class SpecialGlobalBlockStatus extends FormSpecialPage { |
21 | private ?string $mTarget; |
22 | private ?bool $mCurrentStatus; |
23 | private ?bool $mWhitelistStatus; |
24 | |
25 | private BlockUtils $blockUtils; |
26 | private UserNameUtils $userNameUtils; |
27 | private GlobalBlockLookup $globalBlockLookup; |
28 | private GlobalBlockLocalStatusManager $globalBlockLocalStatusManager; |
29 | private GlobalBlockLocalStatusLookup $globalBlockLocalStatusLookup; |
30 | private GlobalBlockingLinkBuilder $globalBlockingLinkBuilder; |
31 | |
32 | /** |
33 | * @param BlockUtils $blockUtils |
34 | * @param UserNameUtils $userNameUtils |
35 | * @param GlobalBlockLookup $globalBlockLookup |
36 | * @param GlobalBlockLocalStatusManager $globalBlockLocalStatusManager |
37 | * @param GlobalBlockLocalStatusLookup $globalBlockLocalStatusLookup |
38 | * @param GlobalBlockingLinkBuilder $globalBlockingLinkBuilder |
39 | */ |
40 | public function __construct( |
41 | BlockUtils $blockUtils, |
42 | UserNameUtils $userNameUtils, |
43 | GlobalBlockLookup $globalBlockLookup, |
44 | GlobalBlockLocalStatusManager $globalBlockLocalStatusManager, |
45 | GlobalBlockLocalStatusLookup $globalBlockLocalStatusLookup, |
46 | GlobalBlockingLinkBuilder $globalBlockingLinkBuilder |
47 | ) { |
48 | parent::__construct( 'GlobalBlockStatus', 'globalblock-whitelist' ); |
49 | $this->blockUtils = $blockUtils; |
50 | $this->userNameUtils = $userNameUtils; |
51 | $this->globalBlockLookup = $globalBlockLookup; |
52 | $this->globalBlockLocalStatusManager = $globalBlockLocalStatusManager; |
53 | $this->globalBlockLocalStatusLookup = $globalBlockLocalStatusLookup; |
54 | $this->globalBlockingLinkBuilder = $globalBlockingLinkBuilder; |
55 | } |
56 | |
57 | /** @inheritDoc */ |
58 | public function execute( $par ) { |
59 | $this->addHelpLink( 'Extension:GlobalBlocking' ); |
60 | $out = $this->getOutput(); |
61 | $out->disableClientCache(); |
62 | $out->setSubtitle( $this->globalBlockingLinkBuilder->buildSubtitleLinks( $this ) ); |
63 | |
64 | parent::execute( $par ); |
65 | } |
66 | |
67 | /** |
68 | * @param string|null $par Parameter from the URL, may be null or a string (probably an IP) |
69 | * that was inserted |
70 | * @return void |
71 | * @throws Exception |
72 | */ |
73 | protected function setParameter( $par ) { |
74 | $request = $this->getRequest(); |
75 | |
76 | // Parse the target from the request or URL. |
77 | $target = trim( $request->getText( 'address', $par ?? '' ) ); |
78 | if ( !$target ) { |
79 | // If no target was provided, show the form with an empty target and the disable checkbox checked (as this |
80 | // is the most common action). |
81 | $this->mTarget = $target; |
82 | $this->mCurrentStatus = true; |
83 | $this->mWhitelistStatus = false; |
84 | return; |
85 | } |
86 | |
87 | // If the target is an IP address, sanitize it before assigning it as the target. |
88 | if ( IPUtils::isValidRange( $target ) ) { |
89 | $this->mTarget = IPUtils::sanitizeRange( $target ); |
90 | } elseif ( IPUtils::isIPAddress( $target ) ) { |
91 | $this->mTarget = IPUtils::sanitizeIP( $target ); |
92 | } else { |
93 | $normalisedTarget = $this->userNameUtils->getCanonical( $target ); |
94 | if ( $normalisedTarget ) { |
95 | $this->mTarget = $normalisedTarget; |
96 | } else { |
97 | // Allow invalid targets to be set, so that the user can be shown an error message. |
98 | $this->mTarget = $target; |
99 | } |
100 | } |
101 | |
102 | // Set the relevant user for the skin and assign it before the form is rendered to HTML. |
103 | [ $targetForSkin ] = $this->blockUtils->parseBlockTarget( $target ); |
104 | if ( $targetForSkin instanceof UserIdentity ) { |
105 | $this->getSkin()->setRelevantUser( $targetForSkin ); |
106 | } |
107 | |
108 | $this->mCurrentStatus = (bool)$this->globalBlockLocalStatusLookup |
109 | ->getLocalWhitelistInfo( $this->globalBlockLookup->getGlobalBlockId( $this->mTarget ) ); |
110 | $this->mWhitelistStatus = $request->getCheck( 'wpWhitelistStatus' ); |
111 | } |
112 | |
113 | protected function alterForm( HTMLForm $form ) { |
114 | $form->setPreHtml( $this->msg( 'globalblocking-whitelist-intro' )->parse() ); |
115 | $form->setWrapperLegendMsg( 'globalblocking-whitelist-legend' ); |
116 | $form->setSubmitTextMsg( 'globalblocking-whitelist-submit' ); |
117 | } |
118 | |
119 | protected function getFormFields() { |
120 | $accountBlocksEnabled = $this->getConfig()->get( 'GlobalBlockingAllowGlobalAccountBlocks' ); |
121 | return [ |
122 | 'address' => [ |
123 | 'name' => 'address', |
124 | 'type' => 'text', |
125 | 'id' => 'mw-globalblocking-ipaddress mw-globalblocking-target', |
126 | 'label-message' => $accountBlocksEnabled ? 'globalblocking-target' : 'globalblocking-ipaddress', |
127 | 'default' => $this->mTarget, |
128 | 'required' => true, |
129 | ], |
130 | 'Reason' => [ |
131 | 'type' => 'text', |
132 | 'label-message' => 'globalblocking-whitelist-reason' |
133 | ], |
134 | 'WhitelistStatus' => [ |
135 | 'type' => 'check', |
136 | 'label-message' => 'globalblocking-whitelist-statuslabel', |
137 | 'default' => $this->mCurrentStatus |
138 | ] |
139 | ]; |
140 | } |
141 | |
142 | public function onSubmit( array $data ) { |
143 | if ( $this->mWhitelistStatus ) { |
144 | // Locally disable the block |
145 | $status = $this->globalBlockLocalStatusManager |
146 | ->locallyDisableBlock( $this->mTarget, $data['Reason'], $this->getUser() ); |
147 | $successMsg = 'globalblocking-whitelist-whitelisted'; |
148 | } else { |
149 | // Locally re-enable the block |
150 | $status = $this->globalBlockLocalStatusManager |
151 | ->locallyEnableBlock( $this->mTarget, $data['Reason'], $this->getUser() ); |
152 | $successMsg = 'globalblocking-whitelist-dewhitelisted'; |
153 | } |
154 | |
155 | if ( !$status->isGood() ) { |
156 | return $status; |
157 | } |
158 | |
159 | return $this->showSuccess( $this->mTarget, $status->getValue()['id'], $successMsg ); |
160 | } |
161 | |
162 | /** |
163 | * Show a message indicating that the change in the local status of the global block was successful. |
164 | * |
165 | * @param string $target The target of the global block that had its local status modified |
166 | * @param int $id The ID of the global block that had its local status modified (same as the ID in gbw_id). |
167 | * @param string $successMsg The message key used as the success message. |
168 | * @return true |
169 | */ |
170 | protected function showSuccess( string $target, int $id, string $successMsg ): bool { |
171 | $out = $this->getOutput(); |
172 | $out->addWikiMsg( $successMsg, $target, $id ); |
173 | $out->addHTML( $this->getLinkRenderer()->makeKnownLink( |
174 | SpecialPage::getTitleFor( 'GlobalBlockList' ), |
175 | $this->msg( 'globalblocking-return' )->text() |
176 | ) ); |
177 | return true; |
178 | } |
179 | |
180 | public function doesWrites() { |
181 | return true; |
182 | } |
183 | |
184 | protected function getGroupName() { |
185 | return 'users'; |
186 | } |
187 | |
188 | protected function getDisplayFormat() { |
189 | return 'ooui'; |
190 | } |
191 | |
192 | public function getDescription() { |
193 | return $this->msg( 'globalblocking-whitelist' ); |
194 | } |
195 | |
196 | protected function checkExecutePermissions( User $user ) { |
197 | parent::checkExecutePermissions( $user ); |
198 | // If wgApplyGlobalBlocks is false, the user should not be able to access this special page. |
199 | if ( !$this->getConfig()->get( 'ApplyGlobalBlocks' ) ) { |
200 | throw new ErrorPageError( $this->getDescription(), 'globalblocking-whitelist-notapplied' ); |
201 | } |
202 | } |
203 | } |