Gergő Tisza has uploaded a new change for review.

  https://gerrit.wikimedia.org/r/204059

Change subject: Autocreate some local accounts when global account is created
......................................................................

Autocreate some local accounts when global account is created

Add $wgCentralAuthAutoCreateWikis site config option;
run a job on global account creation to create an attached
local account on all listed wikis.

Bug: T74469
Bug: T94885
Change-Id: I3937b9e6d0df1ef608d64388167a3b37a3ea5de3
---
M CentralAuth.php
M includes/CentralAuthPlugin.php
A includes/CreateLocalAccountJob.php
3 files changed, 117 insertions(+), 0 deletions(-)


  git pull ssh://gerrit.wikimedia.org:29418/mediawiki/extensions/CentralAuth 
refs/changes/59/204059/1

diff --git a/CentralAuth.php b/CentralAuth.php
index a5e9b1e..13089cf 100644
--- a/CentralAuth.php
+++ b/CentralAuth.php
@@ -134,6 +134,16 @@
 $wgCentralAuthAutoLoginWikis = array();
 
 /**
+ * List of wiki IDs on which an attached local account should be created 
automatically when the
+ * global account is created.
+ *
+ * The wiki ID is typically the database name, except when table prefixes are
+ * used, in which case it is the database name, a hyphen separator, and then
+ * the table prefix.
+ */
+$wgCentralAuthAutoCreateWikis = array();
+
+/**
  * Local filesystem path to the icon returned by Special:CentralAutoLogin
  * Should be a 20x20px PNG.
  */
@@ -275,6 +285,7 @@
 $wgAutoloadClasses['CentralAuthPlugin'] = 
"$caBase/includes/CentralAuthPlugin.php";
 $wgAutoloadClasses['CentralAuthHooks'] = 
"$caBase/includes/CentralAuthHooks.php";
 $wgAutoloadClasses['CentralAuthSuppressUserJob'] = 
"$caBase/includes/SuppressUserJob.php";
+$wgAutoloadClasses['CentralAuthCreateLocalAccountJob'] = 
"$caBase/includes/CreateLocalAccountJob.php";
 $wgAutoloadClasses['WikiSet'] = "$caBase/includes/WikiSet.php";
 $wgAutoloadClasses['SpecialCentralAutoLogin'] = 
"$caBase/includes/specials/SpecialCentralAutoLogin.php";
 $wgAutoloadClasses['CentralAuthUserArray'] = 
"$caBase/includes/CentralAuthUserArray.php";
@@ -335,6 +346,7 @@
 $wgJobClasses['LocalRenameUserJob'] = 'LocalRenameUserJob';
 $wgJobClasses['LocalUserMergeJob'] = 'LocalUserMergeJob';
 $wgJobClasses['LocalPageMoveJob'] = 'LocalPageMoveJob';
+$wgJobClasses['CentralAuthCreateLocalAccountJob'] = 
'CentralAuthCreateLocalAccountJob';
 
 $wgHooks['SetupAfterCache'][] = 'CentralAuthHooks::onSetupAfterCache';
 $wgHooks['AuthPluginSetup'][] = 'CentralAuthHooks::onAuthPluginSetup';
diff --git a/includes/CentralAuthPlugin.php b/includes/CentralAuthPlugin.php
index fb903a9..5a893bd 100644
--- a/includes/CentralAuthPlugin.php
+++ b/includes/CentralAuthPlugin.php
@@ -270,6 +270,7 @@
                                // @fixme is this even vaguely reliable? pah
                                $central->register( $password, $email );
                                $central->attach( wfWikiID(), 'new' );
+                               $this->autoCreateAccounts( $central );
                        }
                        // Note: If $wgCentralAuthPreventUnattached is enabled,
                        // accounts where a global does not exist, but there are
@@ -326,4 +327,27 @@
        public function getUserInstance( User &$user ) {
                return CentralAuthUser::getInstance( $user );
        }
+
+       /**
+        * Sets up jobs to create and attach a local account for the given user 
on every wiki listed in
+        * $wgCentralAuthAutoCreateWikis.
+        * @param CentralAuthUser $centralUser
+        */
+       private function autoCreateAccounts( CentralAuthUser $centralUser ) {
+               global $wgCentralAuthAutoCreateWikis;
+
+               $name = $centralUser->getName();
+               $thisWiki = wfWikiID();
+               foreach ( $wgCentralAuthAutoCreateWikis as $wiki ) {
+                       if ( $wiki === $thisWiki ) {
+                               continue;
+                       }
+                       $job = Job::factory(
+                               'CentralAuthCreateLocalAccountJob',
+                               Title::makeTitleSafe( NS_USER, $name ),
+                               array( 'name' => $name, 'from' => $thisWiki )
+                       );
+                       JobQueueGroup::singleton( $wiki )->push( $job );
+               }
+       }
 }
diff --git a/includes/CreateLocalAccountJob.php 
b/includes/CreateLocalAccountJob.php
new file mode 100644
index 0000000..6ca07e5
--- /dev/null
+++ b/includes/CreateLocalAccountJob.php
@@ -0,0 +1,81 @@
+<?php
+
+/**
+ * Creates a local account and connects it to the global account.
+ * Used to ensure that all users have an attached local account on certain 
wikis which have some
+ * special "central" role (such as $wgMWOAuthCentralWiki for the OAuth 
extension).
+ * @see $wgCentralAuthAutoCreateWikis
+ */
+class CentralAuthCreateLocalAccountJob extends Job {
+       /**
+        * @param Title $title Not used
+        * @param array $params name => user name, from => wiki where the job 
is created
+        */
+       public function __construct( $title, $params ) {
+               parent::__construct( 'CentralAuthCreateLocalAccountJob', 
$title, $params );
+       }
+
+       /**
+        * Try to create and attach the user.
+        * Largely follows CentralAuthHooks::attemptAddUser() which cannot be 
directly reused because
+        * it assumes a web context.
+        * @throws Exception
+        * @return bool Success
+        */
+       public function run() {
+               global $wgAuth;
+
+               $username = $this->params['name'];
+               $from = $this->params['from'];
+               $wiki = wfWikiID();
+
+               $user = User::newFromName( $username );
+               $centralUser = CentralAuthUser::getInstance( $user );
+
+               if ( !$wgAuth->autoCreate() ) {
+                       // denied by configuration
+                       return true;
+               } elseif ( $user->getId() !== 0 ) {
+                       wfDebugLog( 'CentralAuth', __CLASS__ . ": tried to 
create local account for $username "
+                               . "on $wiki from $from but one already 
exists\n" );
+                       return true;
+               } elseif ( !$centralUser->exists() ) {
+                       wfDebugLog( 'CentralAuth', __CLASS__ . ": tried to 
create local account for $username "
+                               . "on $wiki from $from but no global account 
exists\n" );
+                       return true;
+               } elseif ( $centralUser->attachedOn( $wiki ) ) {
+                       wfDebugLog( 'CentralAuth', __CLASS__ . ": tried to 
create local account for $username "
+                               . "on $wiki from $from but an attached local 
account already exists\n" );
+                       return true;
+               }
+
+               $user->loadDefaults( $username );
+
+               $abortMessage = '';
+               if ( !Hooks::run( 'AbortAutoAccount', array( $user, 
&$abortMessage ) ) ) {
+                       wfDebugLog( 'CentralAuth', __CLASS__ . ": tried to 
create local account for $username "
+                               . "on $wiki from $from but denied by other 
extension: $abortMessage\n" );
+                       return true;
+               } elseif ( $user->getName() !== $username ) {
+                       throw new Exception( "AbortAutoAccount hook tried to 
change the user name" );
+               }
+
+               $status = $user->addToDatabase();
+               if ( !$status->isOK() ) {
+                       wfDebugLog( 'CentralAuth', __CLASS__ . ": tried to 
create local account for $username "
+                               . "on $wiki from $from but 
User::addToDatabase() failed with status: "
+                               . $status->getWikiText() . "\n" );
+                       return false;
+               }
+
+               $wgAuth->initUser( $user, true );
+
+               Hooks::run( 'AuthPluginAutoCreate', array( $user ) );
+
+               # Update user count
+               $statsUpdate = new SiteStatsUpdate( 0, 0, 0, 0, 1 );
+               $statsUpdate->doUpdate();
+
+               return true;
+       }
+}

-- 
To view, visit https://gerrit.wikimedia.org/r/204059
To unsubscribe, visit https://gerrit.wikimedia.org/r/settings

Gerrit-MessageType: newchange
Gerrit-Change-Id: I3937b9e6d0df1ef608d64388167a3b37a3ea5de3
Gerrit-PatchSet: 1
Gerrit-Project: mediawiki/extensions/CentralAuth
Gerrit-Branch: master
Gerrit-Owner: Gergő Tisza <gti...@wikimedia.org>

_______________________________________________
MediaWiki-commits mailing list
MediaWiki-commits@lists.wikimedia.org
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to