Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
98.26% covered (success)
98.26%
113 / 115
50.00% covered (danger)
50.00%
1 / 2
CRAP
0.00% covered (danger)
0.00%
0 / 1
BlockUsers
98.26% covered (success)
98.26%
113 / 115
50.00% covered (danger)
50.00%
1 / 2
11
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
70 / 70
100.00% covered (success)
100.00%
1 / 1
1
 execute
95.56% covered (success)
95.56%
43 / 45
0.00% covered (danger)
0.00%
0 / 1
10
1<?php
2
3/**
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License along
15 * with this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
17 * http://www.gnu.org/copyleft/gpl.html
18 *
19 * @file
20 * @ingroup Maintenance
21 */
22
23// @codeCoverageIgnoreStart
24require_once __DIR__ . '/Maintenance.php';
25// @codeCoverageIgnoreEnd
26
27use MediaWiki\Maintenance\Maintenance;
28use MediaWiki\User\User;
29
30class BlockUsers extends Maintenance {
31
32    public function __construct() {
33        parent::__construct();
34
35        $this->addDescription(
36            "Blocks a list of usernames. Can use STDIN or the file argument.\n\n" .
37            'Note, this is probably most useful when dealing with spammers, with a ' .
38            "list you've generated with an SQL query or similar.\n\n" .
39            'By default, all users are hard blocked, auto blocked from any current and subsequent ' .
40            'IP addresses, email disabled, unable to write to their user page and unable to ' .
41            'create further accounts with no expiry to this block. You can change the expiry ' .
42            'with --expiry parameter.'
43        );
44
45        $this->addArg(
46            'file',
47            'File with list of users to block',
48            false
49        );
50
51        $this->addOption(
52            'performer',
53            'User to make the blocks',
54            false,
55            true
56        );
57
58        $this->addOption(
59            'reason',
60            'Reason for the blocks',
61            false,
62            true
63        );
64
65        $this->addOption(
66            'reblock',
67            'Reblock users who are already blocked',
68            false,
69            false
70        );
71
72        $this->addOption(
73            'expiry',
74            'Expiry of your block',
75            false,
76            true
77        );
78
79        $this->addOption(
80            'unblock',
81            'Should this unblock?',
82            false,
83            false
84        );
85
86        $this->addOption(
87            'allow-createaccount',
88            'Allow account creation for blocked IPs',
89            false
90        );
91
92        $this->addOption(
93            'allow-email',
94            'Allow blocked accounts to send emails',
95            false
96        );
97
98        $this->addOption(
99            'allow-talkedit',
100            'Allow blocked accounts to edit their own talk page',
101            false
102        );
103
104        $this->addOption(
105            'disable-hardblock',
106            'Don\'t block logged in accounts from a blocked IP address (will still block temporary accounts)',
107            false
108        );
109
110        $this->addOption(
111            'disable-autoblock',
112            'Don\'t autoblock IP addresses used by the accounts',
113            false
114        );
115    }
116
117    public function execute() {
118        $performerName = $this->getOption( 'performer', false );
119        $reason = $this->getOption( 'reason', '' );
120        $unblocking = $this->getOption( 'unblock', false );
121        $reblock = $this->hasOption( 'reblock' );
122        $expiry = $this->getOption( 'expiry', 'indefinite' );
123
124        if ( $performerName ) {
125            $performer = $this->getServiceContainer()->getUserFactory()->newFromName( $performerName );
126        } else {
127            $performer = User::newSystemUser( User::MAINTENANCE_SCRIPT_USER, [ 'steal' => true ] );
128        }
129
130        if ( $performer === null ) {
131            $this->fatalError( "Unable to parse performer's username" );
132        }
133
134        if ( $this->hasArg( 0 ) ) {
135            $file = fopen( $this->getArg( 0 ), 'r' );
136        } else {
137            $file = $this->getStdin();
138        }
139
140        # Setup
141        if ( !$file ) {
142            $this->fatalError( "Unable to read file, exiting" );
143        }
144
145        # Handle each entry
146        $blockUserFactory = $this->getServiceContainer()->getBlockUserFactory();
147        $unblockUserFactory = $this->getServiceContainer()->getUnblockUserFactory();
148        $action = $unblocking ? "Unblocking" : "Blocking";
149        for ( $linenum = 1; !feof( $file ); $linenum++ ) {
150            $line = trim( fgets( $file ) );
151            if ( $line == '' ) {
152                continue;
153            }
154
155            if ( $unblocking ) {
156                $res = $unblockUserFactory->newUnblockUser(
157                    $line,
158                    $performer,
159                    $reason
160                )->unblockUnsafe();
161            } else {
162                $res = $blockUserFactory->newBlockUser(
163                    $line,
164                    $performer,
165                    $expiry,
166                    $reason,
167                    [
168                        'isCreateAccountBlocked' => !$this->hasOption( 'allow-createaccount' ),
169                        'isEmailBlocked' => !$this->hasOption( 'allow-email' ),
170                        'isUserTalkEditBlocked' => !$this->hasOption( 'allow-talkedit' ),
171                        'isHardBlock' => !$this->hasOption( 'disable-hardblock' ),
172                        'isAutoblocking' => !$this->hasOption( 'disable-autoblock' ),
173                    ]
174                )->placeBlockUnsafe( $reblock );
175            }
176
177            if ( $res->isOK() ) {
178                $this->output( "{$action} '{$line}' succeeded.\n" );
179            } else {
180                $errorsText = $res->getMessage()->text();
181                $this->output( "{$action} '{$line}' failed ({$errorsText}).\n" );
182            }
183        }
184    }
185}
186
187// @codeCoverageIgnoreStart
188$maintClass = BlockUsers::class;
189require_once RUN_MAINTENANCE_IF_MAIN;
190// @codeCoverageIgnoreEnd