createAndPromote: use AuthManager::autoCreateUser
authorBryan Davis <bd808@wikimedia.org>
Sun, 30 Dec 2018 02:41:27 +0000 (19:41 -0700)
committerGergő Tisza <gtisza@wikimedia.org>
Tue, 8 Jan 2019 20:45:12 +0000 (20:45 +0000)
Use AuthManager::autoCreateUser when creating a new user via
createAndPromote.php so that configured AuthManager providers have
a chance to perform validations and extra actions beyond local account
creation.

Bug: T212689
Change-Id: I4972507bbaf65bb542934c281c37bd8a5c7a26b7

includes/auth/AuthManager.php
maintenance/createAndPromote.php

index 0c9f615..9686555 100644 (file)
@@ -54,7 +54,8 @@ use Wikimedia\ObjectFactory;
  * Code that is related to some SessionProvider or PrimaryAuthenticationProvider can
  * create a (non-reserved) user by calling AuthManager::autoCreateUser(); it is then the provider's
  * responsibility to ensure that the user can authenticate somehow (see especially
- * PrimaryAuthenticationProvider::autoCreatedAccount()).
+ * PrimaryAuthenticationProvider::autoCreatedAccount()). The same functionality can also be used
+ * from Maintenance scripts such as createAndPromote.php.
  * If you are writing code that is not associated with such a provider and needs to create accounts
  * programmatically for real users, you should rethink your architecture. There is no good way to
  * do that as such code has no knowledge of what authentication methods are enabled on the wiki and
@@ -113,6 +114,9 @@ class AuthManager implements LoggerAwareInterface {
        /** Auto-creation is due to SessionManager */
        const AUTOCREATE_SOURCE_SESSION = \MediaWiki\Session\SessionManager::class;
 
+       /** Auto-creation is due to a Maintenance script */
+       const AUTOCREATE_SOURCE_MAINT = '::Maintenance::';
+
        /** @var AuthManager|null */
        private static $instance = null;
 
@@ -1542,13 +1546,16 @@ class AuthManager implements LoggerAwareInterface {
         * explicitly (e.g. from a maintenance script) is also fine.
         *
         * @param User $user User to auto-create
-        * @param string $source What caused the auto-creation? This must be the ID
-        *  of a PrimaryAuthenticationProvider or the constant self::AUTOCREATE_SOURCE_SESSION.
+        * @param string $source What caused the auto-creation? This must be one of:
+        *  - the ID of a PrimaryAuthenticationProvider,
+        *  - the constant self::AUTOCREATE_SOURCE_SESSION, or
+        *  - the constant AUTOCREATE_SOURCE_MAINT.
         * @param bool $login Whether to also log the user in
         * @return Status Good if user was created, Ok if user already existed, otherwise Fatal
         */
        public function autoCreateUser( User $user, $source, $login = true ) {
                if ( $source !== self::AUTOCREATE_SOURCE_SESSION &&
+                       $source !== self::AUTOCREATE_SOURCE_MAINT &&
                        !$this->getAuthenticationProvider( $source ) instanceof PrimaryAuthenticationProvider
                ) {
                        throw new \InvalidArgumentException( "Unknown auto-creation source: $source" );
index 24ab3d2..93614e0 100644 (file)
@@ -112,9 +112,16 @@ class CreateAndPromote extends Maintenance {
                }
 
                if ( !$exists ) {
-                       # Insert the account into the database
-                       $user->addToDatabase();
-                       $user->saveSettings();
+                       // Create the user via AuthManager as there may be various side
+                       // effects that are perfomed by the configured AuthManager chain.
+                       $status = MediaWiki\Auth\AuthManager::singleton()->autoCreateUser(
+                               $user,
+                               MediaWiki\Auth\AuthManager::AUTOCREATE_SOURCE_MAINT,
+                               false
+                       );
+                       if ( !$status->isGood() ) {
+                               $this->fatalError( $status->getWikiText( null, null, 'en' ) );
+                       }
                }
 
                if ( $password ) {