MediaWiki  master
createAndPromote.php
Go to the documentation of this file.
1 <?php
26 require_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;
162 require_once RUN_MAINTENANCE_IF_MAIN;
getArg( $argId=0, $default=null)
Get an argument.
const RUN_MAINTENANCE_IF_MAIN
Definition: Maintenance.php:39
maybeHelp( $force=false)
Maybe show the help.
error( $err, $die=0)
Throw an error to the user.
getOption( $name, $default=null)
Get an option, or return the default.
Maintenance script to create an account and grant it rights.
Abstract maintenance class for quickly writing and churning out maintenance scripts with minimal effo...
Definition: Maintenance.php:86
hasOption( $name)
Checks to see if a particular option exists.
A helper class for throttling authentication attempts.
static getAllGroups()
Return the set of defined explicit groups.
Definition: User.php:4805
static factory(array $deltas)
static singleton()
Get the global AuthManager.
addDescription( $text)
Set the description text.
addArg( $arg, $description, $required=true)
Add some args that are needed.
output( $out, $channel=null)
Throw some output to the user.
static getCurrentWikiDbDomain()
Definition: WikiMap.php:293
getText()
Get the text to display when reporting the error on the command line.
Show an error when any operation involving passwords fails to run.
addOption( $name, $description, $required=false, $withArg=false, $shortName=false, $multiOccurrence=false)
Add a parameter to the script.
fatalError( $msg, $exitCode=1)
Output a message and terminate the current script.
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition: User.php:515