From 386065fd65764a03fe9c28f0cf6b06b45ef6048c Mon Sep 17 00:00:00 2001 From: Lex Lim Date: Mon, 15 May 2023 08:02:14 +0000 Subject: [PATCH] =?UTF-8?q?=E6=9B=B4=E6=94=B9=E5=A4=B4=E5=83=8F=E8=8E=B7?= =?UTF-8?q?=E5=8F=96=E6=96=B9=E5=BC=8F=EF=BC=8C=E4=BF=AE=E5=A4=8D=E6=96=B0?= =?UTF-8?q?=E7=94=A8=E6=88=B7=E7=9A=84=E7=94=A8=E6=88=B7=E5=90=8D=E7=94=9F?= =?UTF-8?q?=E6=88=90=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- extension.json | 2 +- includes/ApiOIDCAvatar.php | 9 +++-- includes/IsekaiOIDCAuth.php | 37 +++++++++++++++---- includes/IsekaiOIDCAuthHooks.php | 62 ++++++++++++++++++++++---------- 4 files changed, 80 insertions(+), 30 deletions(-) diff --git a/extension.json b/extension.json index 698ecbb..f25cfb9 100644 --- a/extension.json +++ b/extension.json @@ -30,7 +30,7 @@ "GetPreferences": "Isekai\\OIDC\\IsekaiOIDCAuthHooks::onGetPreferences", "SkinTemplateNavigation::Universal": "Isekai\\OIDC\\IsekaiOIDCAuthHooks::onSkinTemplateUniversalNavigation", "ResourceLoaderGetConfigVars": "Isekai\\OIDC\\IsekaiOIDCAuthHooks::onResourceLoaderGetConfigVars", - "Isekai::GetUserAvatar": "Isekai\\OIDC\\IsekaiOIDCAuthHooks::onGetUserAvatar" + "Isekai::GetUsersAvatar": "Isekai\\OIDC\\IsekaiOIDCAuthHooks::onGetUsersAvatar" }, "ExtensionMessagesFiles": { "IsekaiOIDCAlias": "IsekaiOIDC.alias.php" diff --git a/includes/ApiOIDCAvatar.php b/includes/ApiOIDCAvatar.php index 06aa3eb..7d84ea4 100644 --- a/includes/ApiOIDCAvatar.php +++ b/includes/ApiOIDCAvatar.php @@ -38,12 +38,15 @@ class ApiOIDCAvatar extends ApiQueryBase { $size = $this->getParameter('size'); - $avatarUrl = ''; + $avatars = []; $hookContainer = $services->getHookContainer(); - $hookContainer->run('Isekai::GetUserAvatar', [&$avatarUrl, $size, $user]); + $hookContainer->run('Isekai::GetUsersAvatar', [&$avatars, [$user], $size]); - if (empty($avatarUrl)) { + $avatarUrl = ''; + if (isset($avatars[$user->getId()])) { + $avatarUrl = $avatars[$user->getId()]; + } else { if (isset($wgIsekaiOIDC['defaultAvatarUrl'])) { $avatarUrl = $wgIsekaiOIDC['defaultAvatarUrl']; } else { diff --git a/includes/IsekaiOIDCAuth.php b/includes/IsekaiOIDCAuth.php index 17a3ad5..4f5ae47 100644 --- a/includes/IsekaiOIDCAuth.php +++ b/includes/IsekaiOIDCAuth.php @@ -454,6 +454,28 @@ class IsekaiOIDCAuth extends AbstractPrimaryAuthenticationProvider { } } + public static function findOidcSubjectsByUserIds( array $userIds ) { + $dbr = MediaWikiServices::getInstance()->getDBLoadBalancer()->getMaintenanceConnectionRef( DB_REPLICA ); + $rows = $dbr->select( + [ + self::OIDC_TABLE + ], + [ + 'oidc_user', + 'oidc_subject' + ], + [ + 'oidc_user' => $userIds + ], + __METHOD__ + ); + $subjects = []; + foreach ( $rows as $row ) { + $subjects[$row->oidc_user] = $row->oidc_subject; + } + return $subjects; + } + private static function getPreferredUsername( $config, $oidc, $realname, $email ) { if ( isset( $config['preferred_username'] ) ) { wfDebugLog( self::LOG_TAG, 'Using ' . $config['preferred_username'] . @@ -555,18 +577,19 @@ class IsekaiOIDCAuth extends AbstractPrimaryAuthenticationProvider { $preferred_username = 'User'; } - if ( MediaWikiServices::getInstance() - ->getUserIdentityLookup() - ->getUserIdentityByName( $preferred_username ) ) { + $userIdentityLookup = MediaWikiServices::getInstance()->getUserIdentityLookup(); + $userIdentity = $userIdentityLookup->getUserIdentityByName( $preferred_username ); + if ( !$userIdentity || !$userIdentity->isRegistered() ) { return $preferred_username; } $count = 1; - while ( MediaWikiServices::getInstance() - ->getUserIdentityLookup() - ->getUserIdentityByName( $preferred_username . $count ) ) { - + while ( true ) { + $userIdentity = $userIdentityLookup->getUserIdentityByName( $preferred_username . $count ); + if ( !$userIdentity || !$userIdentity->isRegistered() ) { + break; + } $count ++; } return $preferred_username . $count; diff --git a/includes/IsekaiOIDCAuthHooks.php b/includes/IsekaiOIDCAuthHooks.php index d556f84..c80c2e9 100644 --- a/includes/IsekaiOIDCAuthHooks.php +++ b/includes/IsekaiOIDCAuthHooks.php @@ -171,33 +171,57 @@ class IsekaiOIDCAuthHooks { return true; } - public static function onGetUserAvatar(&$avatarUrl, $size, $user) { + /** + * Get avatar url for users + * @param array &$avatars + * @param \User[] $users + * @param int $size + */ + public static function onGetUsersAvatar(&$avatars, array $users, $size = 128) { + if (!is_array($avatars)) { + $avatars = []; + } + $services = MediaWikiServices::getInstance(); $config = $services->getMainConfig(); $wgIsekaiOIDC = $config->get('IsekaiOIDC'); if (isset($wgIsekaiOIDC['avatarUrl'])) { - list($subject, $accessToken, $refreshToken) = IsekaiOIDCAuth::findOidcDataByUserId($user->getId()); - $avatarFinded = false; - if ($subject) { - $avatarUrl = str_replace(['{openid}', '{username}'], [urlencode($subject), urlencode($user->getName())], $wgIsekaiOIDC['avatarUrl']); - $avatarFinded = true; - } else { - if (isset($wgIsekaiOIDC['defaultAvatarUrl'])) { - $avatarUrl = $wgIsekaiOIDC['defaultAvatarUrl']; - $avatarFinded = true; + $userIds = array_map(function($user) { + return $user->getId(); + }, $users); + + $subjects = IsekaiOIDCAuth::findOidcSubjectsByUserIds($userIds); + + foreach ($users as $user) { + $subject = null; + if (isset($subjects[$user->getId()])) { + $subject = $subjects[$user->getId()]; } - } - if ($avatarFinded) { - if ($size <= 64) { - $avatarUrl = "$avatarUrl?size=md"; - } else if ($size <= 128) { - $avatarUrl = "$avatarUrl?size=lg"; - } else if ($size <= 256) { - $avatarUrl = "$avatarUrl?size=xl"; + $avatarFinded = false; + if ($subject) { + $avatarUrl = str_replace(['{openid}', '{username}'], [urlencode($subject), urlencode($user->getName())], $wgIsekaiOIDC['avatarUrl']); + $avatarFinded = true; } else { - $avatarUrl = "$avatarUrl?size=xxl"; + if (isset($wgIsekaiOIDC['defaultAvatarUrl'])) { + $avatarUrl = $wgIsekaiOIDC['defaultAvatarUrl']; + $avatarFinded = true; + } + } + + if ($avatarFinded) { + if ($size <= 64) { + $avatarUrl = "$avatarUrl?size=md"; + } else if ($size <= 128) { + $avatarUrl = "$avatarUrl?size=lg"; + } else if ($size <= 256) { + $avatarUrl = "$avatarUrl?size=xl"; + } else { + $avatarUrl = "$avatarUrl?size=xxl"; + } + + $avatars[$user->getId()] = $avatarUrl; } } }