MediaWiki REL1_34
createAndPromote.php
Go to the documentation of this file.
1<?php
26require_once __DIR__ . '/Maintenance.php';
27
34 private static $permitRoles = [ 'sysop', 'bureaucrat', 'interface-admin', 'bot' ];
35
36 public function __construct() {
37 parent::__construct();
38 $this->addDescription( 'Create a new user account and/or grant it additional rights' );
39 $this->addOption(
40 'force',
41 'If acccount exists already, just grant it rights or change password.'
42 );
43 foreach ( self::$permitRoles as $role ) {
44 $this->addOption( $role, "Add the account to the {$role} group" );
45 }
46
47 $this->addOption(
48 'custom-groups',
49 'Comma-separated list of groups to add the user to',
50 false,
51 true
52 );
53
54 $this->addArg( "username", "Username of new user" );
55 $this->addArg( "password", "Password to set (not required if --force is used)", false );
56 }
57
58 public function execute() {
59 $username = $this->getArg( 0 );
60 $password = $this->getArg( 1 );
61 $force = $this->hasOption( 'force' );
62 $inGroups = [];
63
64 $user = User::newFromName( $username );
65 if ( !is_object( $user ) ) {
66 $this->fatalError( "invalid username." );
67 }
68
69 $exists = ( $user->idForName() !== 0 );
70
71 if ( $exists && !$force ) {
72 $this->fatalError( "Account exists. Perhaps you want the --force option?" );
73 } elseif ( !$exists && !$password ) {
74 $this->error( "Argument <password> required!" );
75 $this->maybeHelp( true );
76 } elseif ( $exists ) {
77 $inGroups = $user->getGroups();
78 }
79
80 $groups = array_filter( self::$permitRoles, [ $this, 'hasOption' ] );
81 if ( $this->hasOption( 'custom-groups' ) ) {
82 $allGroups = array_flip( User::getAllGroups() );
83 $customGroupsText = $this->getOption( 'custom-groups' );
84 if ( $customGroupsText !== '' ) {
85 $customGroups = explode( ',', $customGroupsText );
86 foreach ( $customGroups as $customGroup ) {
87 if ( isset( $allGroups[$customGroup] ) ) {
88 $groups[] = trim( $customGroup );
89 } else {
90 $this->output( "$customGroup is not a valid group, ignoring!\n" );
91 }
92 }
93 }
94 }
95
96 $promotions = array_diff(
97 $groups,
98 $inGroups
99 );
100
101 if ( $exists && !$password && count( $promotions ) === 0 ) {
102 $this->output( "Account exists and nothing to do.\n" );
103
104 return;
105 } elseif ( count( $promotions ) !== 0 ) {
106 $dbDomain = WikiMap::getCurrentWikiDbDomain()->getId();
107 $promoText = "User:{$username} into " . implode( ', ', $promotions ) . "...\n";
108 if ( $exists ) {
109 $this->output( "$dbDomain: Promoting $promoText" );
110 } else {
111 $this->output( "$dbDomain: Creating and promoting $promoText" );
112 }
113 }
114
115 if ( !$exists ) {
116 // Create the user via AuthManager as there may be various side
117 // effects that are performed by the configured AuthManager chain.
118 $status = MediaWiki\Auth\AuthManager::singleton()->autoCreateUser(
119 $user,
120 MediaWiki\Auth\AuthManager::AUTOCREATE_SOURCE_MAINT,
121 false
122 );
123 if ( !$status->isGood() ) {
124 $this->fatalError( $status->getMessage( false, false, 'en' )->text() );
125 }
126 }
127
128 if ( $password ) {
129 # Try to set the password
130 try {
131 $status = $user->changeAuthenticationData( [
132 'username' => $user->getName(),
133 'password' => $password,
134 'retype' => $password,
135 ] );
136 if ( !$status->isGood() ) {
137 throw new PasswordError( $status->getMessage( false, false, 'en' )->text() );
138 }
139 if ( $exists ) {
140 $this->output( "Password set.\n" );
141 $user->saveSettings();
142 }
143 } catch ( PasswordError $pwe ) {
144 $this->fatalError( $pwe->getText() );
145 }
146 }
147
148 # Promote user
149 array_map( [ $user, 'addGroup' ], $promotions );
150
151 if ( !$exists ) {
152 # Increment site_stats.ss_users
153 $ssu = SiteStatsUpdate::factory( [ 'users' => 1 ] );
154 $ssu->doUpdate();
155 }
156
157 $this->output( "done.\n" );
158 }
159}
160
161$maintClass = CreateAndPromote::class;
162require_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 exists.
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.
Show an error when any operation involving passwords fails to run.
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition User.php:518
static getAllGroups()
Return the set of defined explicit groups.
Definition User.php:4914
A helper class for throttling authentication attempts.