jenkins-bot has submitted this change and it was merged.

Change subject: Implement OAuth user checks
......................................................................


Implement OAuth user checks

Implement the OAuth cross-wiki identity hooks, so we can ensure the
user who authorizes an OAuth Client on one wiki is the same user who
is using it on potentially a different wiki.

OAuth change Ic274ff3d65ecfa9d602fb92b8998276ce722f5b1 also adds the
hook OAuthGetUserNamesFromCentralIds.

Change-Id: I71632de70d7364c52816749b26c9dfcb3cfd67cc
---
M CentralAuth.php
M CentralAuthHooks.php
2 files changed, 114 insertions(+), 0 deletions(-)

Approvals:
  Aaron Schulz: Looks good to me, approved
  jenkins-bot: Verified



diff --git a/CentralAuth.php b/CentralAuth.php
index 6049e63..dd3a377 100644
--- a/CentralAuth.php
+++ b/CentralAuth.php
@@ -299,6 +299,11 @@
 // For SecurePoll
 $wgHooks['SecurePoll_GetUserParams'][] = 
'CentralAuthHooks::onSecurePoll_GetUserParams';
 
+// For OAuth
+$wgHooks['OAuthGetLocalUserFromCentralId'][] = 
'CentralAuthHooks::onOAuthGetLocalUserFromCentralId';
+$wgHooks['OAuthGetCentralIdFromLocalUser'][] = 
'CentralAuthHooks::onOAuthGetCentralIdFromLocalUser';
+$wgHooks['OAuthGetUserNamesFromCentralIds'][] = 
'CentralAuthHooks::onOAuthGetUserNamesFromCentralIds';
+
 $wgAvailableRights[] = 'centralauth-merge';
 $wgAvailableRights[] = 'centralauth-unmerge';
 $wgAvailableRights[] = 'centralauth-lock';
diff --git a/CentralAuthHooks.php b/CentralAuthHooks.php
index 02079dc..f6a555e 100644
--- a/CentralAuthHooks.php
+++ b/CentralAuthHooks.php
@@ -1321,4 +1321,113 @@
                wfRunHooks( 'CentralAuthIsUIReloadRecommended', array( $user, 
&$recommendReload ) );
                return $recommendReload;
        }
+
+       /**
+        * Get the username from CentralAuth for a list of CentralAuth user 
id's. Sets the name
+        * to false if the userid doesn't exist, or the username is hidden.
+        * @param string $wgMWOAuthCentralWiki
+        * @param array &$namesById array of userIds=>names to associate
+        * @param bool|User $audience show hidden names based on this user, or 
false for public
+        * @param string $wgMWOAuthSharedUserSource the authoritative extension
+        */
+       public static function onOAuthGetUserNamesFromCentralIds( 
$wgMWOAuthCentralWiki, &$namesById, $audience, $wgMWOAuthSharedUserSource ) {
+               if ( $wgMWOAuthSharedUserSource !== 'CentralAuth' ) {
+                       // We aren't supposed to handle this
+                       return true;
+               }
+               $dbr = CentralAuthUser::getCentralSlaveDB();
+               foreach ( $namesById as $userid => $name ) {
+                       $name = $dbr->selectField(
+                               'globaluser',
+                               'gu_name',
+                               array( 'gu_id' => $userid ),
+                               __METHOD__
+                       );
+                       $namesById[$userid] = $name;
+                       $centralUser = new CentralAuthUser( $name );
+                       if ( $centralUser->getHiddenLevel() !== 
CentralAuthUser::HIDDEN_NONE
+                               && !( $audience instanceof User
+                               && $audience->isAllowed( 
'centralauth-oversight' ) )
+                       ) {
+                               $namesById[$userid] = '';
+                       }
+               }
+               return true;
+       }
+
+       /**
+        * Check that the local user object is part of a global account, and 
the account is
+        * attached on this wiki, and the central OAuth wiki, so we know that 
the same username
+        * on both wikis references the same user. Set the user object to false 
if they are not.
+        * @param int $userId the central OAuth wiki user_id for this username
+        * @param string $wgMWOAuthCentralWiki
+        * @param User &$user the loca user object
+        * @param string $wgMWOAuthSharedUserSource the authoritative extension
+        */
+       public static function onOAuthGetLocalUserFromCentralId( $userId, 
$wgMWOAuthCentralWiki, &$user, $wgMWOAuthSharedUserSource ) {
+               if ( $wgMWOAuthSharedUserSource !== 'CentralAuth' ) {
+                       // We aren't supposed to handle this
+                       return true;
+               }
+               $dbr = CentralAuthUser::getCentralSlaveDB();
+               $user_name = $dbr->selectField(
+                       'globaluser',
+                       'gu_name',
+                       array( 'gu_id' => $userId ),
+                       __METHOD__
+               );
+
+               if ( $user_name === false ) {
+                       wfDebugLog( 'CentralAuth', __METHOD__ . ": invalid 
userId ($userId) passed to CentralAuth by OAuth" );
+                       $user = false;
+                       return false;
+               }
+
+               $centralUser = new CentralAuthUser( $user_name );
+
+               if ( $centralUser->isLocked()
+                       || !$centralUser->isAttached()
+                       || !$centralUser->attachedOn( $wgMWOAuthCentralWiki )
+               ) {
+                       wfDebugLog( 'CentralAuth', __METHOD__ . ": user 
'{$user_name}' cannot use OAuth on " . wfWikiID() );
+                       $user = false;
+                       return false;
+               }
+
+               $user = User::newFromName( $user_name );
+               // One last sanity check
+               if ( $user->getId() == 0 ) {
+                       throw new MWException( "Attached user couldn't be 
loaded from name" );
+               }
+               return true;
+       }
+
+       /**
+        * Set the user_id to false if the user is not a global user, or if the 
user is not
+        * attached on both the local wiki, and the central OAuth wiki, where 
user grants
+        * are tracked. This prevents OAuth from assuming the identity of a 
user on the local
+        * wiki is the same as the user on the central wiki, even if they have 
the same username.
+        * @param User $user the local user object
+        * @param string $wgMWOAuthCentralWiki
+        * @param int &$id the user_id of the matching name on the central wiki
+        * @param string $wgMWOAuthSharedUserSource the authoritative extension
+        */
+       public static function onOAuthGetCentralIdFromLocalUser( $user, 
$wgMWOAuthCentralWiki, &$id, $wgMWOAuthSharedUserSource ) {
+               if ( $wgMWOAuthSharedUserSource !== 'CentralAuth' ) {
+                       // We aren't supposed to handle this
+                       return true;
+               }
+               $centralUser = CentralAuthUser::getInstance( $user );
+               if ( $centralUser->getId() == 0
+                       || !$centralUser->isAttached()
+                       || !$centralUser->attachedOn( $wgMWOAuthCentralWiki )
+               ) {
+                       wfDebugLog( 'CentralAuth', __METHOD__ . ": user 
'{$user->getName()}' cannot use OAuth on " . wfWikiID() );
+                       $id = false;
+                       return false;
+               }
+
+               $id = $centralUser->getId();
+               return true;
+       }
 }

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

Gerrit-MessageType: merged
Gerrit-Change-Id: I71632de70d7364c52816749b26c9dfcb3cfd67cc
Gerrit-PatchSet: 8
Gerrit-Project: mediawiki/extensions/CentralAuth
Gerrit-Branch: master
Gerrit-Owner: CSteipp <[email protected]>
Gerrit-Reviewer: Aaron Schulz <[email protected]>
Gerrit-Reviewer: Anomie <[email protected]>
Gerrit-Reviewer: CSteipp <[email protected]>
Gerrit-Reviewer: jenkins-bot

_______________________________________________
MediaWiki-commits mailing list
[email protected]
https://lists.wikimedia.org/mailman/listinfo/mediawiki-commits

Reply via email to