3 * This program is free software; you can redistribute it and/or modify
4 * it under the terms of the GNU General Public License as published by
5 * the Free Software Foundation; either version 2 of the License, or
6 * (at your option) any later version.
8 * This program is distributed in the hope that it will be useful,
9 * but WITHOUT ANY WARRANTY; without even the implied warranty of
10 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11 * GNU General Public License for more details.
13 * You should have received a copy of the GNU General Public License along
14 * with this program; if not, write to the Free Software Foundation, Inc.,
15 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
16 * http://www.gnu.org/copyleft/gpl.html
21 namespace MediaWiki\Specials
;
24 use MediaWiki\Auth\AuthManager
;
25 use MediaWiki\Logger\LoggerFactory
;
26 use MediaWiki\MainConfigNames
;
27 use MediaWiki\SpecialPage\LoginSignupSpecialPage
;
28 use MediaWiki\SpecialPage\SpecialPage
;
29 use MediaWiki\User\UserIdentity
;
30 use MediaWiki\User\UserIdentityUtils
;
34 * Implements Special:UserLogin
36 * @ingroup SpecialPage
39 class SpecialUserLogin
extends LoginSignupSpecialPage
{
41 protected static $allowedActions = [
42 AuthManager
::ACTION_LOGIN
,
43 AuthManager
::ACTION_LOGIN_CONTINUE
47 protected static $messages = [
48 'authform-newtoken' => 'nocookiesforlogin',
49 'authform-notoken' => 'sessionfailure',
50 'authform-wrongtoken' => 'sessionfailure',
53 private UserIdentityUtils
$identityUtils;
56 * @param AuthManager $authManager
58 public function __construct( AuthManager
$authManager, UserIdentityUtils
$identityUtils ) {
59 parent
::__construct( 'Userlogin' );
60 $this->setAuthManager( $authManager );
61 $this->identityUtils
= $identityUtils;
64 public function doesWrites() {
68 public function isListed() {
69 return $this->getAuthManager()->canAuthenticateNow();
72 protected function getLoginSecurityLevel() {
76 protected function getDefaultAction( $subPage ) {
77 return AuthManager
::ACTION_LOGIN
;
80 public function getDescription() {
81 return $this->msg( 'login' );
84 public function setHeaders() {
85 // override the page title if we are doing a forced reauthentication
87 if ( $this->securityLevel
&& $this->getUser()->isRegistered() ) {
88 $this->getOutput()->setPageTitleMsg( $this->msg( 'login-security' ) );
92 protected function isSignup() {
96 protected function beforeExecute( $subPage ) {
97 if ( $subPage === 'signup' ||
$this->getRequest()->getText( 'type' ) === 'signup' ) {
98 // B/C for old account creation URLs
99 $title = SpecialPage
::getTitleFor( 'CreateAccount' );
100 $query = array_diff_key( $this->getRequest()->getQueryValues(),
101 array_fill_keys( [ 'type', 'title' ], true ) );
102 $url = $title->getFullURL( $query, false, PROTO_CURRENT
);
103 $this->getOutput()->redirect( $url );
106 return parent
::beforeExecute( $subPage );
110 * Run any hooks registered for logins, then HTTP redirect to
111 * $this->mReturnTo (or Main Page if that's undefined). Formerly we had a
112 * nice message here, but that's really not as useful as just being sent to
113 * wherever you logged in from. It should be clear that the action was
114 * successful, given the lack of error messages plus the appearance of your
115 * name in the upper right.
116 * @param bool $direct True if the action was successful just now; false if that happened
117 * pre-redirection (so this handler was called already)
118 * @param StatusValue|null $extraMessages
120 protected function successfulAction( $direct = false, $extraMessages = null ) {
121 $secureLogin = $this->getConfig()->get( MainConfigNames
::SecureLogin
);
123 $user = $this->targetUser ?
: $this->getUser();
124 $session = $this->getRequest()->getSession();
132 if ( $user->requiresHTTPS() ) {
133 $this->mStickHTTPS
= true;
135 $session->setForceHTTPS( $secureLogin && $this->mStickHTTPS
);
137 // If the user does not have a session cookie at this point, they probably need to
138 // do something to their browser.
139 if ( !$this->hasSessionCookie() ) {
140 $this->mainLoginForm( [ /*?*/ ], $session->getProvider()->whyNoSession() );
141 // TODO something more specific? This used to use nocookieslogin
145 # Run any hooks; display injected HTML if any, else redirect
146 $this->getHookRunner()->onUserLoginComplete(
147 $user, $injected_html, $direct );
150 if ( $injected_html !== '' ||
$extraMessages ) {
151 $this->showSuccessPage( 'success', $this->msg( 'loginsuccesstitle' ),
152 'loginsuccess', $injected_html, $extraMessages );
154 $helper = new LoginHelper( $this->getContext() );
155 $helper->showReturnToPage( 'successredirect', $this->mReturnTo
, $this->mReturnToQuery
,
156 $this->mStickHTTPS
, $this->mReturnToAnchor
);
160 protected function getToken() {
161 return $this->getRequest()->getSession()->getToken( '', 'login' );
164 protected function clearToken() {
165 $this->getRequest()->getSession()->resetToken( 'login' );
168 protected function getTokenName() {
169 return 'wpLoginToken';
172 protected function getGroupName() {
176 protected function logAuthResult( $success, UserIdentity
$performer, $status = null ) {
177 LoggerFactory
::getInstance( 'authevents' )->info( 'Login attempt', [
179 'successful' => $success,
180 'accountType' => $this->identityUtils
->getShortUserTypeInternal( $performer ),
181 'status' => strval( $status ),
187 * Retain the old class name for backwards compatibility.
188 * @deprecated since 1.41
190 class_alias( SpecialUserLogin
::class, 'SpecialUserLogin' );