|
|
|
<?php
|
|
|
|
namespace Isekai\OIDC;
|
|
|
|
|
|
|
|
use MediaWiki\Auth\AuthManager;
|
|
|
|
use MediaWiki\Logger\LoggerFactory;
|
|
|
|
use LoginSignupSpecialPage;
|
|
|
|
use LoginHelper;
|
|
|
|
|
|
|
|
class SpecialIsekaiOIDCCallback extends LoginSignupSpecialPage {
|
|
|
|
protected static $allowedActions = [
|
|
|
|
AuthManager::ACTION_LOGIN,
|
|
|
|
AuthManager::ACTION_LOGIN_CONTINUE
|
|
|
|
];
|
|
|
|
|
|
|
|
protected static $messages = [
|
|
|
|
'authform-newtoken' => 'nocookiesforlogin',
|
|
|
|
'authform-notoken' => 'sessionfailure',
|
|
|
|
'authform-wrongtoken' => 'sessionfailure',
|
|
|
|
];
|
|
|
|
|
|
|
|
public function __construct() {
|
|
|
|
parent::__construct( 'IsekaiOIDCCallback' );
|
|
|
|
}
|
|
|
|
|
|
|
|
public function doesWrites() {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getLoginSecurityLevel() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getDefaultAction( $subPage ) {
|
|
|
|
return AuthManager::ACTION_LOGIN;
|
|
|
|
}
|
|
|
|
|
|
|
|
public function getDescription() {
|
|
|
|
return $this->msg( 'login' )->text();
|
|
|
|
}
|
|
|
|
|
|
|
|
public function setHeaders() {
|
|
|
|
// override the page title if we are doing a forced reauthentication
|
|
|
|
parent::setHeaders();
|
|
|
|
if ( $this->securityLevel && $this->getUser()->isRegistered() ) {
|
|
|
|
$this->getOutput()->setPageTitle( $this->msg( 'login-security' ) );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function isSignup() {
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Run any hooks registered for logins, then HTTP redirect to
|
|
|
|
* $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
|
|
|
|
* 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
|
|
|
|
* name in the upper right.
|
|
|
|
* @param bool $direct True if the action was successful just now; false if that happened
|
|
|
|
* pre-redirection (so this handler was called already)
|
|
|
|
* @param \StatusValue|null $extraMessages
|
|
|
|
* @throws \ErrorPageError
|
|
|
|
* @throws \FatalError
|
|
|
|
* @throws \MWException
|
|
|
|
* @throws \PermissionsError
|
|
|
|
* @throws \ReadOnlyError
|
|
|
|
*/
|
|
|
|
protected function successfulAction( $direct = false, $extraMessages = null ) {
|
|
|
|
global $wgSecureLogin, $wgIsekaiOIDCRemember;
|
|
|
|
|
|
|
|
$user = $this->targetUser ?: $this->getUser();
|
|
|
|
$session = $this->getRequest()->getSession();
|
|
|
|
|
|
|
|
if ( $wgIsekaiOIDCRemember ) {
|
|
|
|
$session->setRememberUser(true);
|
|
|
|
}
|
|
|
|
|
|
|
|
if ( $direct ) {
|
|
|
|
$user->touch();
|
|
|
|
|
|
|
|
$this->clearToken();
|
|
|
|
|
|
|
|
if ( $user->requiresHTTPS() ) {
|
|
|
|
$this->mStickHTTPS = true;
|
|
|
|
}
|
|
|
|
$session->setForceHTTPS( $wgSecureLogin && $this->mStickHTTPS );
|
|
|
|
|
|
|
|
// If the user does not have a session cookie at this point, they probably need to
|
|
|
|
// do something to their browser.
|
|
|
|
if ( !$this->hasSessionCookie() ) {
|
|
|
|
$this->mainLoginForm( [ /*?*/ ], $session->getProvider()->whyNoSession() );
|
|
|
|
// TODO something more specific? This used to use nocookieslogin
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
# Run any hooks; display injected HTML if any, else redirect
|
|
|
|
$injected_html = '';
|
|
|
|
$this->getHookRunner()->onUserLoginComplete(
|
|
|
|
$user, $injected_html, $direct );
|
|
|
|
|
|
|
|
if ( $injected_html !== '' || $extraMessages ) {
|
|
|
|
$this->showSuccessPage( 'success', $this->msg( 'loginsuccesstitle' ),
|
|
|
|
'loginsuccess', $injected_html, $extraMessages );
|
|
|
|
} else {
|
|
|
|
$helper = new LoginHelper( $this->getContext() );
|
|
|
|
$helper->showReturnToPage( 'successredirect', $this->mReturnTo, $this->mReturnToQuery,
|
|
|
|
$this->mStickHTTPS );
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getToken() {
|
|
|
|
return $this->getRequest()->getSession()->getToken( 'AuthManagerSpecialPage:IsekaiOIDCCallback' );
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function clearToken() {
|
|
|
|
$this->getRequest()->getSession()->resetToken( 'AuthManagerSpecialPage:IsekaiOIDCCallback' );
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getTokenName() {
|
|
|
|
return 'wpLoginToken';
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function getGroupName() {
|
|
|
|
return 'login';
|
|
|
|
}
|
|
|
|
|
|
|
|
protected function logAuthResult( $success, $status = null ) {
|
|
|
|
LoggerFactory::getInstance( 'authevents' )->info( 'Login attempt', [
|
|
|
|
'event' => 'login',
|
|
|
|
'successful' => $success,
|
|
|
|
'status' => $status,
|
|
|
|
] );
|
|
|
|
}
|
|
|
|
}
|