增加1.39支持

master
落雨楓 2 years ago
parent 479c07678b
commit cb158d7398

@ -1,14 +1,14 @@
{ {
"name": "Isekai OpenID Connect", "name": "Isekai OpenID Connect",
"namemsg": "isekai-oidc-name", "namemsg": "isekai-oidc-name",
"author": "hyperzlib", "author": "Hyperzlib",
"version": "1.1.0", "version": "1.1.2",
"url": "https://www.isekai.cn", "url": "https://www.isekai.cn",
"descriptionmsg": "isekai-oidc-desc", "descriptionmsg": "isekai-oidc-desc",
"license-name": "MIT", "license-name": "MIT",
"type": "other", "type": "other",
"requires": { "requires": {
"MediaWiki": ">= 1.35.0"
}, },
"MessagesDirs": { "MessagesDirs": {
"IsekaiOIDC": [ "IsekaiOIDC": [
@ -28,7 +28,7 @@
"BeforePageDisplay": "Isekai\\OIDC\\IsekaiOIDCAuthHooks::onBeforePageDisplay", "BeforePageDisplay": "Isekai\\OIDC\\IsekaiOIDCAuthHooks::onBeforePageDisplay",
"UserLogoutComplete": "Isekai\\OIDC\\IsekaiOIDCAuthHooks::onLogout", "UserLogoutComplete": "Isekai\\OIDC\\IsekaiOIDCAuthHooks::onLogout",
"GetPreferences": "Isekai\\OIDC\\IsekaiOIDCAuthHooks::onGetPreferences", "GetPreferences": "Isekai\\OIDC\\IsekaiOIDCAuthHooks::onGetPreferences",
"PersonalUrls": "Isekai\\OIDC\\IsekaiOIDCAuthHooks::onPersonalUrls", "SkinTemplateNavigation::Universal": "Isekai\\OIDC\\IsekaiOIDCAuthHooks::onSkinTemplateUniversalNavigation",
"ResourceLoaderGetConfigVars": "Isekai\\OIDC\\IsekaiOIDCAuthHooks::onResourceLoaderGetConfigVars" "ResourceLoaderGetConfigVars": "Isekai\\OIDC\\IsekaiOIDCAuthHooks::onResourceLoaderGetConfigVars"
}, },
"ExtensionMessagesFiles": { "ExtensionMessagesFiles": {

@ -3,9 +3,8 @@
namespace Isekai\OIDC; namespace Isekai\OIDC;
use ApiBase; use ApiBase;
use MediaWiki\MediaWikiServices;
use Wikimedia\ParamValidator\ParamValidator; use Wikimedia\ParamValidator\ParamValidator;
use Isekai\OIDC\IsekaiOIDCAuth;
use User;
class ApiOidcWebhook extends ApiBase { class ApiOidcWebhook extends ApiBase {
public function __construct( $main, $method ) { public function __construct( $main, $method ) {
@ -38,17 +37,19 @@ class ApiOidcWebhook extends ApiBase {
private function keycloakCallback() { private function keycloakCallback() {
if (!$this->getRequest()->wasPosted()) { if (!$this->getRequest()->wasPosted()) {
return $this->addError('isekaioidc-api-post-body-invalid'); $this->addError('isekaioidc-api-post-body-invalid');
return;
} }
$postBody = $this->getRequest()->getRawPostString(); $postBody = $this->getRequest()->getRawPostString();
$postData = json_decode($postBody); $postData = json_decode($postBody);
if (!$this->getRequest()->wasPosted() || !$postData) { if (!$this->getRequest()->wasPosted() || !$postData) {
return $this->addError('isekaioidc-api-post-body-invalid'); $this->addError('isekaioidc-api-post-body-invalid');
return;
} }
global $wgIsekaiOIDC; global $wgIsekaiOIDC;
$realm = $wgIsekaiOIDC['realm']; $realm = $wgIsekaiOIDC['realm'];
$apiMode = isset($wgIsekaiOIDC['apiMode']) ? $wgIsekaiOIDC['apiMode'] : 'oauth'; $apiMode = $wgIsekaiOIDC['apiMode'] ?? 'oauth';
$eventType = $postData->type; $eventType = $postData->type;
$subject = $postData->userId; $subject = $postData->userId;
@ -75,7 +76,7 @@ class ApiOidcWebhook extends ApiBase {
'phone' => $userInfo->phone_number, 'phone' => $userInfo->phone_number,
]; ];
$user = User::newFromId($userId); $user = MediaWikiServices::getInstance()->getUserFactory()->newFromId($userId);
IsekaiOIDCAuth::updateUserInfo($user, $newProfile); IsekaiOIDCAuth::updateUserInfo($user, $newProfile);
} }
$this->getResult()->addValue(null, 'webhook', 1); $this->getResult()->addValue(null, 'webhook', 1);
@ -85,11 +86,11 @@ class ApiOidcWebhook extends ApiBase {
return [ return [
'provider' => [ 'provider' => [
ParamValidator::PARAM_DEFAULT => null, ParamValidator::PARAM_DEFAULT => null,
ApiBase::PARAM_TYPE => 'text', ParamValidator::PARAM_TYPE => 'text',
], ],
'key' => [ 'key' => [
ParamValidator::PARAM_DEFAULT => null, ParamValidator::PARAM_DEFAULT => null,
ApiBase::PARAM_TYPE => 'text', ParamValidator::PARAM_TYPE => 'text',
] ]
]; ];
} }

@ -15,7 +15,6 @@ use Title;
use SpecialPage; use SpecialPage;
use Sanitizer; use Sanitizer;
use RequestContext; use RequestContext;
use WebRequest;
class IsekaiOIDCAuth extends AbstractPrimaryAuthenticationProvider { class IsekaiOIDCAuth extends AbstractPrimaryAuthenticationProvider {
@ -88,12 +87,7 @@ class IsekaiOIDCAuth extends AbstractPrimaryAuthenticationProvider {
$GLOBALS['wgIsekaiOIDCRemember'] = true; $GLOBALS['wgIsekaiOIDCRemember'] = true;
} }
if ( method_exists( MediaWikiServices::class, 'getAuthManager' ) ) { $authManager = MediaWikiServices::getInstance()->getAuthManager();
// MediaWiki 1.35+
$authManager = MediaWikiServices::getInstance()->getAuthManager();
} else {
$authManager = AuthManager::singleton();
}
$request = RequestContext::getMain()->getRequest(); $request = RequestContext::getMain()->getRequest();
$session = $request->getSession(); $session = $request->getSession();
$session->clear('AuthManager::AutoCreateBlacklist'); // 防止缓存检测 $session->clear('AuthManager::AutoCreateBlacklist'); // 防止缓存检测
@ -308,22 +302,17 @@ class IsekaiOIDCAuth extends AbstractPrimaryAuthenticationProvider {
*/ */
public static function updateUserInfo($user, $data = null) { public static function updateUserInfo($user, $data = null) {
if (is_string($user)) { if (is_string($user)) {
$user = User::newFromName($user); $user = MediaWikiServices::getInstance()->getUserFactory()->newFromName($user);
} }
if ($data) { if ($data) {
$accessToken = isset($data['accessToken']) ? $data['accessToken'] : null; $accessToken = $data['accessToken'] ?? null;
$refreshToken = isset($data['refreshToken']) ? $data['refreshToken'] : null; $refreshToken = $data['refreshToken'] ?? null;
$newEmail = isset($data['email']) ? $data['email'] : null; $newEmail = $data['email'] ?? null;
$newRealName = isset($data['realname']) ? $data['realname'] : null; $newRealName = $data['realname'] ?? null;
$newPhone = isset($data['phone']) ? $data['phone'] : null; $newPhone = $data['phone'] ?? null;
} else { } else {
if ( method_exists( MediaWikiServices::class, 'getAuthManager' ) ) { $authManager = MediaWikiServices::getInstance()->getAuthManager();
// MediaWiki 1.35+
$authManager = MediaWikiServices::getInstance()->getAuthManager();
} else {
$authManager = AuthManager::singleton();
}
$accessToken = $authManager->getAuthenticationSessionData(self::ACCESS_TOKEN_SESSION_KEY); $accessToken = $authManager->getAuthenticationSessionData(self::ACCESS_TOKEN_SESSION_KEY);
$refreshToken = $authManager->getAuthenticationSessionData(self::REFRESH_TOKEN_SESSION_KEY); $refreshToken = $authManager->getAuthenticationSessionData(self::REFRESH_TOKEN_SESSION_KEY);
@ -340,7 +329,8 @@ class IsekaiOIDCAuth extends AbstractPrimaryAuthenticationProvider {
wfDebugLog( self::LOG_TAG, wfDebugLog( self::LOG_TAG,
'update access token for: ' . $user->getId() . '.' . 'update access token for: ' . $user->getId() . '.' .
PHP_EOL ); PHP_EOL );
$dbw = wfGetDB( DB_MASTER );
$dbw = MediaWikiServices::getInstance()->getDBLoadBalancer()->getMaintenanceConnectionRef( DB_PRIMARY );
$dbw->upsert( $dbw->upsert(
self::OIDC_TABLE, self::OIDC_TABLE,
[ [
@ -382,19 +372,15 @@ class IsekaiOIDCAuth extends AbstractPrimaryAuthenticationProvider {
* @param int $id user id * @param int $id user id
*/ */
public function saveExtraAttributes( $id ) { public function saveExtraAttributes( $id ) {
if ( method_exists( MediaWikiServices::class, 'getAuthManager' ) ) { $authManager = MediaWikiServices::getInstance()->getAuthManager();
// MediaWiki 1.35+
$authManager = MediaWikiServices::getInstance()->getAuthManager();
} else {
$authManager = AuthManager::singleton();
}
if ( $this->subject === null ) { if ( $this->subject === null ) {
$this->subject = $authManager->getAuthenticationSessionData( $this->subject = $authManager->getAuthenticationSessionData(
self::OIDC_SUBJECT_SESSION_KEY ); self::OIDC_SUBJECT_SESSION_KEY );
$authManager->removeAuthenticationSessionData( $authManager->removeAuthenticationSessionData(
self::OIDC_SUBJECT_SESSION_KEY ); self::OIDC_SUBJECT_SESSION_KEY );
} }
$dbw = wfGetDB( DB_MASTER ); $dbw = MediaWikiServices::getInstance()->getDBLoadBalancer()->getMaintenanceConnectionRef( DB_PRIMARY );
$dbw->upsert( $dbw->upsert(
self::OIDC_TABLE, self::OIDC_TABLE,
[ [
@ -412,7 +398,7 @@ class IsekaiOIDCAuth extends AbstractPrimaryAuthenticationProvider {
} }
public static function findUser( $subject ) { public static function findUser( $subject ) {
$dbr = wfGetDB( DB_REPLICA ); $dbr = MediaWikiServices::getInstance()->getDBLoadBalancer()->getMaintenanceConnectionRef( DB_REPLICA );
$row = $dbr->selectRow( $row = $dbr->selectRow(
[ [
'user', 'user',
@ -441,7 +427,7 @@ class IsekaiOIDCAuth extends AbstractPrimaryAuthenticationProvider {
} }
public static function findOidcDataByUserId( $userId ) { public static function findOidcDataByUserId( $userId ) {
$dbr = wfGetDB( DB_REPLICA ); $dbr = MediaWikiServices::getInstance()->getDBLoadBalancer()->getMaintenanceConnectionRef( DB_REPLICA );
$row = $dbr->selectRow( $row = $dbr->selectRow(
[ [
self::OIDC_TABLE self::OIDC_TABLE
@ -503,7 +489,7 @@ class IsekaiOIDCAuth extends AbstractPrimaryAuthenticationProvider {
return null; return null;
} }
$username = $nt->getText(); $username = $nt->getText();
$dbr = wfGetDB( DB_REPLICA ); $dbr = MediaWikiServices::getInstance()->getDBLoadBalancer()->getMaintenanceConnectionRef( DB_REPLICA );
$row = $dbr->selectRow( $row = $dbr->selectRow(
[ [
'user', 'user',
@ -531,7 +517,7 @@ class IsekaiOIDCAuth extends AbstractPrimaryAuthenticationProvider {
private static function getMigratedIdByEmail( $email ) { private static function getMigratedIdByEmail( $email ) {
wfDebugLog( self::LOG_TAG, 'Matching user to email ' . $email . '.' . wfDebugLog( self::LOG_TAG, 'Matching user to email ' . $email . '.' .
PHP_EOL ); PHP_EOL );
$dbr = wfGetDB( DB_REPLICA ); $dbr = MediaWikiServices::getInstance()->getDBLoadBalancer()->getMaintenanceConnectionRef( DB_REPLICA );
$row = $dbr->selectRow( $row = $dbr->selectRow(
[ [
'user', 'user',
@ -565,19 +551,25 @@ class IsekaiOIDCAuth extends AbstractPrimaryAuthenticationProvider {
$preferred_username = 'User'; $preferred_username = 'User';
} }
if ( User::idFromName( $preferred_username ) === null ) { if ( MediaWikiServices::getInstance()
->getUserIdentityLookup()
->getUserIdentityByName( $preferred_username ) ) {
return $preferred_username; return $preferred_username;
} }
$count = 1; $count = 1;
while ( User::idFromName( $preferred_username . $count ) !== null ) { while ( MediaWikiServices::getInstance()
$count++; ->getUserIdentityLookup()
->getUserIdentityByName( $preferred_username . $count ) ) {
$count ++;
} }
return $preferred_username . $count; return $preferred_username . $count;
} }
protected static function punycodeEnc($str){ protected static function punycodeEnc( $str ){
$punycode = new PunyCode(); $punycode = new PunyCode();
return $punycode->encode($str); return $punycode->encode( $str );
} }
} }

@ -1,13 +1,10 @@
<?php <?php
namespace Isekai\OIDC; namespace Isekai\OIDC;
use Exception;
use Html; use Html;
use MediaWiki\MediaWikiServices; use MediaWiki\MediaWikiServices;
use User;
use OutputPage; use OutputPage;
use RequestContext; use RequestContext;
use MediaWiki\Session\SessionManager;
use Title; use Title;
class IsekaiOIDCAuthHooks { class IsekaiOIDCAuthHooks {
@ -33,7 +30,7 @@ class IsekaiOIDCAuthHooks {
/** /**
* Implements LoadExtensionSchemaUpdates hook. * Implements LoadExtensionSchemaUpdates hook.
* *
* @param DatabaseUpdater $updater * @param \DatabaseUpdater $updater
*/ */
public static function loadExtensionSchemaUpdates( $updater ) { public static function loadExtensionSchemaUpdates( $updater ) {
$dir = dirname(__DIR__) . '/sql/'; $dir = dirname(__DIR__) . '/sql/';
@ -55,10 +52,10 @@ class IsekaiOIDCAuthHooks {
$needLogout = $request->getCookie(self::SYNLOGOUT_SESSIONKEY); $needLogout = $request->getCookie(self::SYNLOGOUT_SESSIONKEY);
$isLogoutPage = $title != null && $title->isSpecial('Userlogout'); $isLogoutPage = $title != null && $title->isSpecial('Userlogout');
if ($isLogoutPage || $needLogout) { // 需要重定向到用户退出页面 if ($isLogoutPage || $needLogout) { // 需要重定向到用户退出页面
$old_name = $request->getCookie('UserName'); $oldName = $request->getCookie('UserName');
wfDebugLog('IsekaiOIDC', 'oldUser: ' . $old_name); wfDebugLog('IsekaiOIDC', 'oldUser: ' . $oldName);
$oldUser = User::newFromName($old_name); $oldUser = MediaWikiServices::getInstance()->getUserFactory()->newFromName($oldName);
if ( $oldUser === false ) { if ( $oldUser === false ) {
return; return;
} }
@ -132,7 +129,7 @@ class IsekaiOIDCAuthHooks {
'default' => Html::openElement('a', [ 'default' => Html::openElement('a', [
'href' => $profileUrl, 'href' => $profileUrl,
]) . ]) .
'<img src="' . $avatarLink . '" width="64" height="64"></img>' . '<img src="' . $avatarLink . '" alt="avatar" width="64" height="64">' .
Html::closeElement('a'), Html::closeElement('a'),
'section' => 'personal/info', 'section' => 'personal/info',
); );
@ -141,25 +138,26 @@ class IsekaiOIDCAuthHooks {
return true; return true;
} }
/** /**
* @param array &$personal_urls * @param \SkinTemplate $skinTemplate
* @param Title $title * @param $links
* @param \SkinTemplate $skin * @return void
*/ */
public static function onPersonalUrls(&$personal_urls, $title, $skin) { public static function onSkinTemplateUniversalNavigation(\SkinTemplate $skinTemplate, &$links) {
if (isset($personal_urls['createaccount'])) { if (isset($links['user-menu']['createaccount'])) {
unset($personal_urls['createaccount']); unset($links['user-menu']['createaccount']);
} }
if (isset($personal_urls['login'])) { if (isset($links['user-menu']['login'])) {
$personal_urls['login']['text'] = wfMessage('nav-login-createaccount')->text(); $links['user-menu']['login']['text'] = wfMessage('nav-login-createaccount')->text();
} }
} }
/** /**
* @param array &$personal_urls * @param $vars
* @param string $skin * @param string $skin
* @param \Config $config * @param \Config $config
*/ * @return bool
*/
public static function onResourceLoaderGetConfigVars(&$vars, $skin, $config) { public static function onResourceLoaderGetConfigVars(&$vars, $skin, $config) {
global $wgIsekaiOIDC; global $wgIsekaiOIDC;
if (isset($wgIsekaiOIDC['avatarUrl'])) { if (isset($wgIsekaiOIDC['avatarUrl'])) {

@ -41,7 +41,7 @@ class SpecialIsekaiOIDCCallback extends LoginSignupSpecialPage {
public function setHeaders() { public function setHeaders() {
// override the page title if we are doing a forced reauthentication // override the page title if we are doing a forced reauthentication
parent::setHeaders(); parent::setHeaders();
if ( $this->securityLevel && $this->getUser()->isLoggedIn() ) { if ( $this->securityLevel && $this->getUser()->isRegistered() ) {
$this->getOutput()->setPageTitle( $this->msg( 'login-security' ) ); $this->getOutput()->setPageTitle( $this->msg( 'login-security' ) );
} }
} }
@ -50,17 +50,22 @@ class SpecialIsekaiOIDCCallback extends LoginSignupSpecialPage {
return false; return false;
} }
/** /**
* Run any hooks registered for logins, then HTTP redirect to * Run any hooks registered for logins, then HTTP redirect to
* $this->mReturnTo (or Main Page if that's undefined). Formerly we had a * $this->mReturnTo (or Main Page if that's undefined). Formerly we had a
* nice message here, but that's really not as useful as just being sent to * nice message here, but that's really not as useful as just being sent to
* wherever you logged in from. It should be clear that the action was * wherever you logged in from. It should be clear that the action was
* successful, given the lack of error messages plus the appearance of your * successful, given the lack of error messages plus the appearance of your
* name in the upper right. * name in the upper right.
* @param bool $direct True if the action was successful just now; false if that happened * @param bool $direct True if the action was successful just now; false if that happened
* pre-redirection (so this handler was called already) * pre-redirection (so this handler was called already)
* @param StatusValue|null $extraMessages * @param \StatusValue|null $extraMessages
*/ * @throws \ErrorPageError
* @throws \FatalError
* @throws \MWException
* @throws \PermissionsError
* @throws \ReadOnlyError
*/
protected function successfulAction( $direct = false, $extraMessages = null ) { protected function successfulAction( $direct = false, $extraMessages = null ) {
global $wgSecureLogin, $wgIsekaiOIDCRemember; global $wgSecureLogin, $wgIsekaiOIDCRemember;
@ -110,7 +115,7 @@ class SpecialIsekaiOIDCCallback extends LoginSignupSpecialPage {
} }
protected function clearToken() { protected function clearToken() {
return $this->getRequest()->getSession()->resetToken( 'AuthManagerSpecialPage:IsekaiOIDCCallback' ); $this->getRequest()->getSession()->resetToken( 'AuthManagerSpecialPage:IsekaiOIDCCallback' );
} }
protected function getTokenName() { protected function getTokenName() {

Loading…
Cancel
Save