You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
171 lines
5.2 KiB
PHTML
171 lines
5.2 KiB
PHTML
3 years ago
|
<?php
|
||
|
namespace Isekai\OIDC;
|
||
|
|
||
|
use Exception;
|
||
|
use Html;
|
||
|
use MediaWiki\MediaWikiServices;
|
||
|
use User;
|
||
|
use OutputPage;
|
||
|
use RequestContext;
|
||
|
use MediaWiki\Session\SessionManager;
|
||
|
use Title;
|
||
|
|
||
|
class IsekaiOIDCAuthHooks {
|
||
|
const SYNLOGIN_SESSIONKEY = 'IsekaiOIDCSyncLogin';
|
||
|
const SYNLOGOUT_SESSIONKEY = 'IsekaiOIDCSyncLogout';
|
||
|
|
||
|
public static function onRegistration() {
|
||
|
$passwordProviders = [
|
||
|
'MediaWiki\Auth\LocalPasswordPrimaryAuthenticationProvider',
|
||
|
'MediaWiki\Auth\TemporaryPasswordPrimaryAuthenticationProvider'
|
||
|
];
|
||
|
$providers = $GLOBALS['wgAuthManagerAutoConfig'];
|
||
|
if ( isset( $providers['primaryauth'] ) ) {
|
||
|
$primaries = $providers['primaryauth'];
|
||
|
foreach ( $primaries as $key => $provider ) {
|
||
|
if ( in_array( $provider['class'], $passwordProviders ) ) {
|
||
|
unset( $GLOBALS['wgAuthManagerAutoConfig']['primaryauth'][$key] );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Implements LoadExtensionSchemaUpdates hook.
|
||
|
*
|
||
|
* @param DatabaseUpdater $updater
|
||
|
*/
|
||
|
public static function loadExtensionSchemaUpdates( $updater ) {
|
||
|
$dir = dirname(__DIR__) . '/sql/';
|
||
|
$type = $updater->getDB()->getType();
|
||
|
$updater->addExtensionTable( 'isekai_oidc',
|
||
|
$dir . $type . '/AddTable.sql' );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Implements PageBeforeDisplay hook.
|
||
|
* @param OutputPage $out
|
||
|
*/
|
||
|
public static function onBeforePageDisplay($out) {
|
||
|
global $wgIsekaiOIDC;
|
||
|
|
||
|
if (isset($wgIsekaiOIDC['syncLogout']) && $wgIsekaiOIDC['syncLogout']) {
|
||
|
$title = $out->getTitle();
|
||
|
$request = RequestContext::getMain()->getRequest();
|
||
|
$needLogout = $request->getCookie(self::SYNLOGOUT_SESSIONKEY);
|
||
|
$isLogoutPage = $title != null && $title->isSpecial('Userlogout');
|
||
|
if ($isLogoutPage || $needLogout) { // 需要重定向到用户退出页面
|
||
|
$old_name = $request->getCookie('UserName');
|
||
|
wfDebugLog('IsekaiOIDC', 'oldUser: ' . $old_name);
|
||
|
|
||
|
$oldUser = User::newFromName($old_name);
|
||
|
if ( $oldUser === false ) {
|
||
|
return;
|
||
|
}
|
||
|
list($subject, $accessToken, $refreshToken) = IsekaiOIDCAuth::findOidcDataByUserId($oldUser->getId());
|
||
|
if ($subject != null) {
|
||
|
$redirectUri = '';
|
||
|
if ($isLogoutPage) {
|
||
|
$returnto = $request->getVal('returnto');
|
||
|
$returntoquery = $request->getVal('returntoquery');
|
||
|
if ($returnto) {
|
||
|
$returnto = Title::newFromText($returnto);
|
||
|
} else {
|
||
|
$returnto = Title::newMainPage();
|
||
|
}
|
||
|
if (!$returnto) {
|
||
|
$returnto = Title::newMainPage();
|
||
|
}
|
||
|
$redirectUri = Title::newMainPage()->getFullURL($returntoquery);
|
||
|
} else if ($title != null) {
|
||
|
$redirectUri = $title->getFullURL();
|
||
|
} else {
|
||
|
$redirectUri = Title::newMainPage()->getFullURL();
|
||
|
}
|
||
|
|
||
|
$url = $wgIsekaiOIDC['endpoint'] . 'protocol/openid-connect/logout?' .
|
||
|
http_build_query([ 'redirect_uri' => $redirectUri ]);
|
||
|
wfDebugLog('IsekaiOIDC', 'logout url: ' . $url);
|
||
|
$response = $request->response();
|
||
|
$response->clearCookie(self::SYNLOGOUT_SESSIONKEY);
|
||
|
$response->header('Location: ' . $url);
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
public static function onLogout($user, &$injected_html) {
|
||
|
$request = RequestContext::getMain()->getRequest();
|
||
|
$request->response()->setCookie(self::SYNLOGOUT_SESSIONKEY, 1);
|
||
|
}
|
||
|
|
||
|
public static function onGetPreferences(\User $user, &$preferences) {
|
||
|
global $wgIsekaiOIDC;
|
||
|
$profileUrl = $wgIsekaiOIDC['endpoint'] . 'account/';
|
||
|
$referrer = $wgIsekaiOIDC['clientID'];
|
||
|
$referrerUri = Title::newFromText('Special:Preferences')->getCanonicalURL();
|
||
|
$profileUrl .= '?' . http_build_query([
|
||
|
'referrer' => $referrer,
|
||
|
'referrer_uri' => $referrerUri
|
||
|
]);
|
||
|
|
||
|
$preferences['global-profile'] = array(
|
||
|
'type' => 'info',
|
||
|
'raw' => true,
|
||
|
'label-message' => 'prefs-global-profile',
|
||
|
'help-message' => 'prefs-help-golbal-profile',
|
||
|
'default' => strval(new \OOUI\ButtonWidget([
|
||
|
'id' => 'global-profile-link',
|
||
|
'href' => $profileUrl,
|
||
|
'label' => wfMessage('btn-idp-profile-settings')->text(),
|
||
|
])),
|
||
|
'section' => 'personal/info',
|
||
|
);
|
||
|
|
||
|
if (isset($wgIsekaiOIDC['avatarUrl'])) {
|
||
|
list($subject, $accessToken, $refreshToken) = IsekaiOIDCAuth::findOidcDataByUserId($user->getId());
|
||
|
$avatarLink = str_replace(['{openid}', '{username}'], [urlencode($subject), urlencode($user->getName())], $wgIsekaiOIDC['avatarUrl']);
|
||
|
$preferences['editavatar'] = array(
|
||
|
'type' => 'info',
|
||
|
'raw' => true,
|
||
|
'label-message' => 'prefs-editavatar',
|
||
|
'default' => Html::openElement('a', [
|
||
|
'href' => $profileUrl,
|
||
|
]) .
|
||
|
'<img src="' . $avatarLink . '" width="64" height="64"></img>' .
|
||
|
Html::closeElement('a'),
|
||
|
'section' => 'personal/info',
|
||
|
);
|
||
|
}
|
||
|
|
||
|
return true;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param array &$personal_urls
|
||
|
* @param Title $title
|
||
|
* @param \SkinTemplate $skin
|
||
|
*/
|
||
|
public static function onPersonalUrls(&$personal_urls, $title, $skin) {
|
||
|
if (isset($personal_urls['createaccount'])) {
|
||
|
unset($personal_urls['createaccount']);
|
||
|
}
|
||
|
if (isset($personal_urls['login'])) {
|
||
|
$personal_urls['login']['text'] = wfMessage('nav-login-createaccount')->text();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param array &$personal_urls
|
||
|
* @param string $skin
|
||
|
* @param \Config $config
|
||
|
*/
|
||
|
public static function onResourceLoaderGetConfigVars(&$vars, $skin, $config) {
|
||
|
global $wgIsekaiOIDC;
|
||
|
if (isset($wgIsekaiOIDC['avatarUrl'])) {
|
||
|
$vars['wgAvatarTemplate'] = $wgIsekaiOIDC['avatarUrl'];
|
||
|
}
|
||
|
return true;
|
||
|
}
|
||
|
}
|