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

<?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;
}
}