MediaWiki REL1_39
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 account 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 $services = MediaWikiServices::getInstance();
66
67 $user = $services->getUserFactory()->newFromName( $username );
68 if ( !is_object( $user ) ) {
69 $this->fatalError( "invalid username." );
70 }
71
72 $exists = ( $user->idForName() !== 0 );
73
74 if ( $exists && !$force ) {
75 $this->fatalError( "Account exists. Perhaps you want the --force option?" );
76 } elseif ( !$exists && !$password ) {
77 $this->error( "Argument <password> required!" );
78 $this->maybeHelp( true );
79 } elseif ( $exists ) {
80 $inGroups = $services->getUserGroupManager()->getUserGroups( $user );
81 }
82
83 $groups = array_filter( self::$permitRoles, [ $this, 'hasOption' ] );
84 if ( $this->hasOption( 'custom-groups' ) ) {
85 $allGroups = array_fill_keys( $services->getUserGroupManager()->listAllGroups(), true );
86 $customGroupsText = $this->getOption( 'custom-groups' );
87 if ( $customGroupsText !== '' ) {
88 $customGroups = explode( ',', $customGroupsText );
89 foreach ( $customGroups as $customGroup ) {
90 if ( isset( $allGroups[$customGroup] ) ) {
91 $groups[] = trim( $customGroup );
92 } else {
93 $this->output( "$customGroup is not a valid group, ignoring!\n" );
94 }
95 }
96 }
97 }
98
99 $promotions = array_diff(
100 $groups,
101 $inGroups
102 );
103
104 if ( $exists && !$password && count( $promotions ) === 0 ) {
105 $this->output( "Account exists and nothing to do.\n" );
106
107 return;
108 } elseif ( count( $promotions ) !== 0 ) {
109 $dbDomain = WikiMap::getCurrentWikiDbDomain()->getId();
110 $promoText = "User:{$username} into " . implode( ', ', $promotions ) . "...\n";
111 if ( $exists ) {
112 $this->output( "$dbDomain: Promoting $promoText" );
113 } else {
114 $this->output( "$dbDomain: Creating and promoting $promoText" );
115 }
116 }
117
118 if ( !$exists ) {
119 // Create the user via AuthManager as there may be various side
120 // effects that are performed by the configured AuthManager chain.
121 $status = MediaWikiServices::getInstance()->getAuthManager()->autoCreateUser(
122 $user,
123 MediaWiki\Auth\AuthManager::AUTOCREATE_SOURCE_MAINT,
124 false
125 );
126 if ( !$status->isGood() ) {
127 $this->fatalError( $status->getMessage( false, false, 'en' )->text() );
128 }
129 }
130
131 if ( $password ) {
132 # Try to set the password
133 try {
134 $status = $user->changeAuthenticationData( [
135 'username' => $user->getName(),
136 'password' => $password,
137 'retype' => $password,
138 ] );
139 if ( !$status->isGood() ) {
140 throw new PasswordError( $status->getMessage( false, false, 'en' )->text() );
141 }
142 if ( $exists ) {
143 $this->output( "Password set.\n" );
144 $user->saveSettings();
145 }
146 } catch ( PasswordError $pwe ) {
147 $this->fatalError( $pwe->getText() );
148 }
149 }
150
151 $userGroupManager = $services->getUserGroupManager();
152 # Promote user
153 $userGroupManager->addUserToMultipleGroups( $user, $promotions );
154
155 if ( !$exists ) {
156 # Increment site_stats.ss_users
157 $ssu = SiteStatsUpdate::factory( [ 'users' => 1 ] );
158 $ssu->doUpdate();
159 }
160
161 $this->output( "done.\n" );
162 }
163}
164
165$maintClass = CreateAndPromote::class;
166require_once RUN_MAINTENANCE_IF_MAIN;
Maintenance script to create an account and grant it rights.
execute()
Do the actual work.
__construct()
Default constructor.
getText()
Format plain text message for the current exception object.
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.
Service locator for MediaWiki core services.
Show an error when any operation involving passwords fails to run.
A helper class for throttling authentication attempts.