MediaWiki fundraising/REL1_35
createAndPromote.php
Go to the documentation of this file.
1<?php
26require_once __DIR__ . '/Maintenance.php';
27
29
36 private static $permitRoles = [ 'sysop', 'bureaucrat', 'interface-admin', 'bot' ];
37
38 public function __construct() {
39 parent::__construct();
40 $this->addDescription( 'Create a new user account and/or grant it additional rights' );
41 $this->addOption(
42 'force',
43 'If acccount exists already, just grant it rights or change password.'
44 );
45 foreach ( self::$permitRoles as $role ) {
46 $this->addOption( $role, "Add the account to the {$role} group" );
47 }
48
49 $this->addOption(
50 'custom-groups',
51 'Comma-separated list of groups to add the user to',
52 false,
53 true
54 );
55
56 $this->addArg( "username", "Username of new user" );
57 $this->addArg( "password", "Password to set", false );
58 }
59
60 public function execute() {
61 $username = $this->getArg( 0 );
62 $password = $this->getArg( 1 );
63 $force = $this->hasOption( 'force' );
64 $inGroups = [];
65
66 $user = User::newFromName( $username );
67 if ( !is_object( $user ) ) {
68 $this->fatalError( "invalid username." );
69 }
70
71 $exists = ( $user->idForName() !== 0 );
72
73 if ( $exists && !$force ) {
74 $this->fatalError( "Account exists. Perhaps you want the --force option?" );
75 } elseif ( !$exists && !$password ) {
76 $this->error( "Argument <password> required!" );
77 $this->maybeHelp( true );
78 } elseif ( $exists ) {
79 $inGroups = $user->getGroups();
80 }
81
82 $groups = array_filter( self::$permitRoles, [ $this, 'hasOption' ] );
83 if ( $this->hasOption( 'custom-groups' ) ) {
84 $allGroups = array_flip( User::getAllGroups() );
85 $customGroupsText = $this->getOption( 'custom-groups' );
86 if ( $customGroupsText !== '' ) {
87 $customGroups = explode( ',', $customGroupsText );
88 foreach ( $customGroups as $customGroup ) {
89 if ( isset( $allGroups[$customGroup] ) ) {
90 $groups[] = trim( $customGroup );
91 } else {
92 $this->output( "$customGroup is not a valid group, ignoring!\n" );
93 }
94 }
95 }
96 }
97
98 $promotions = array_diff(
99 $groups,
100 $inGroups
101 );
102
103 if ( $exists && !$password && count( $promotions ) === 0 ) {
104 $this->output( "Account exists and nothing to do.\n" );
105
106 return;
107 } elseif ( count( $promotions ) !== 0 ) {
108 $dbDomain = WikiMap::getCurrentWikiDbDomain()->getId();
109 $promoText = "User:{$username} into " . implode( ', ', $promotions ) . "...\n";
110 if ( $exists ) {
111 $this->output( "$dbDomain: Promoting $promoText" );
112 } else {
113 $this->output( "$dbDomain: Creating and promoting $promoText" );
114 }
115 }
116
117 if ( !$exists ) {
118 // Create the user via AuthManager as there may be various side
119 // effects that are performed by the configured AuthManager chain.
120 $status = MediaWikiServices::getInstance()->getAuthManager()->autoCreateUser(
121 $user,
122 MediaWiki\Auth\AuthManager::AUTOCREATE_SOURCE_MAINT,
123 false
124 );
125 if ( !$status->isGood() ) {
126 $this->fatalError( $status->getMessage( false, false, 'en' )->text() );
127 }
128 }
129
130 if ( $password ) {
131 # Try to set the password
132 try {
133 $status = $user->changeAuthenticationData( [
134 'username' => $user->getName(),
135 'password' => $password,
136 'retype' => $password,
137 ] );
138 if ( !$status->isGood() ) {
139 throw new PasswordError( $status->getMessage( false, false, 'en' )->text() );
140 }
141 if ( $exists ) {
142 $this->output( "Password set.\n" );
143 $user->saveSettings();
144 }
145 } catch ( PasswordError $pwe ) {
146 $this->fatalError( $pwe->getText() );
147 }
148 }
149
150 # Promote user
151 array_map( [ $user, 'addGroup' ], $promotions );
152
153 if ( !$exists ) {
154 # Increment site_stats.ss_users
155 $ssu = SiteStatsUpdate::factory( [ 'users' => 1 ] );
156 $ssu->doUpdate();
157 }
158
159 $this->output( "done.\n" );
160 }
161}
162
163$maintClass = CreateAndPromote::class;
164require_once RUN_MAINTENANCE_IF_MAIN;
const RUN_MAINTENANCE_IF_MAIN
Maintenance script to create an account and grant it rights.
execute()
Do the actual work.
__construct()
Default constructor.
getText()
Get the text to display when reporting the error on the command line.
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
error( $err, $die=0)
Throw an error to the user.
addArg( $arg, $description, $required=true)
Add some args that are needed.
output( $out, $channel=null)
Throw some output to the user.
hasOption( $name)
Checks to see if a particular option was set.
getArg( $argId=0, $default=null)
Get an argument.
addDescription( $text)
Set the description text.
maybeHelp( $force=false)
Maybe show the help.
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.
getOption( $name, $default=null)
Get an option, or return the default.
fatalError( $msg, $exitCode=1)
Output a message and terminate the current script.
MediaWikiServices is the service locator for the application scope of MediaWiki.
Show an error when any operation involving passwords fails to run.
A helper class for throttling authentication attempts.