Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 50
0.00% covered (danger)
0.00%
0 / 15
CRAP
0.00% covered (danger)
0.00%
0 / 1
SpecialUserLogin
0.00% covered (danger)
0.00%
0 / 49
0.00% covered (danger)
0.00%
0 / 15
702
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 2
0.00% covered (danger)
0.00%
0 / 1
2
 doesWrites
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 isListed
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getLoginSecurityLevel
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDefaultAction
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getDescription
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 setHeaders
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
12
 isSignup
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 beforeExecute
0.00% covered (danger)
0.00%
0 / 8
0.00% covered (danger)
0.00%
0 / 1
12
 successfulAction
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
72
 getToken
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 clearToken
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getTokenName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 getGroupName
0.00% covered (danger)
0.00%
0 / 1
0.00% covered (danger)
0.00%
0 / 1
2
 logAuthResult
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
2
1<?php
2/**
3 * Implements Special:UserLogin
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or
8 * (at your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
18 * http://www.gnu.org/copyleft/gpl.html
19 *
20 * @file
21 * @ingroup SpecialPage
22 */
23
24namespace MediaWiki\Specials;
25
26use LoginHelper;
27use MediaWiki\Auth\AuthManager;
28use MediaWiki\Logger\LoggerFactory;
29use MediaWiki\MainConfigNames;
30use MediaWiki\SpecialPage\LoginSignupSpecialPage;
31use MediaWiki\SpecialPage\SpecialPage;
32use StatusValue;
33
34/**
35 * Implements Special:UserLogin
36 *
37 * @ingroup SpecialPage
38 */
39class SpecialUserLogin extends LoginSignupSpecialPage {
40    protected static $allowedActions = [
41        AuthManager::ACTION_LOGIN,
42        AuthManager::ACTION_LOGIN_CONTINUE
43    ];
44
45    protected static $messages = [
46        'authform-newtoken' => 'nocookiesforlogin',
47        'authform-notoken' => 'sessionfailure',
48        'authform-wrongtoken' => 'sessionfailure',
49    ];
50
51    /**
52     * @param AuthManager $authManager
53     */
54    public function __construct( AuthManager $authManager ) {
55        parent::__construct( 'Userlogin' );
56        $this->setAuthManager( $authManager );
57    }
58
59    public function doesWrites() {
60        return true;
61    }
62
63    public function isListed() {
64        return $this->getAuthManager()->canAuthenticateNow();
65    }
66
67    protected function getLoginSecurityLevel() {
68        return false;
69    }
70
71    protected function getDefaultAction( $subPage ) {
72        return AuthManager::ACTION_LOGIN;
73    }
74
75    public function getDescription() {
76        return $this->msg( 'login' );
77    }
78
79    public function setHeaders() {
80        // override the page title if we are doing a forced reauthentication
81        parent::setHeaders();
82        if ( $this->securityLevel && $this->getUser()->isRegistered() ) {
83            $this->getOutput()->setPageTitleMsg( $this->msg( 'login-security' ) );
84        }
85    }
86
87    protected function isSignup() {
88        return false;
89    }
90
91    protected function beforeExecute( $subPage ) {
92        if ( $subPage === 'signup' || $this->getRequest()->getText( 'type' ) === 'signup' ) {
93            // B/C for old account creation URLs
94            $title = SpecialPage::getTitleFor( 'CreateAccount' );
95            $query = array_diff_key( $this->getRequest()->getValues(),
96                array_fill_keys( [ 'type', 'title' ], true ) );
97            $url = $title->getFullURL( $query, false, PROTO_CURRENT );
98            $this->getOutput()->redirect( $url );
99            return false;
100        }
101        return parent::beforeExecute( $subPage );
102    }
103
104    /**
105     * Run any hooks registered for logins, then HTTP redirect to
106     * $this->mReturnTo (or Main Page if that's undefined).  Formerly we had a
107     * nice message here, but that's really not as useful as just being sent to
108     * wherever you logged in from.  It should be clear that the action was
109     * successful, given the lack of error messages plus the appearance of your
110     * name in the upper right.
111     * @param bool $direct True if the action was successful just now; false if that happened
112     *    pre-redirection (so this handler was called already)
113     * @param StatusValue|null $extraMessages
114     */
115    protected function successfulAction( $direct = false, $extraMessages = null ) {
116        $secureLogin = $this->getConfig()->get( MainConfigNames::SecureLogin );
117
118        $user = $this->targetUser ?: $this->getUser();
119        $session = $this->getRequest()->getSession();
120
121        $injected_html = '';
122        if ( $direct ) {
123            $user->touch();
124
125            $this->clearToken();
126
127            if ( $user->requiresHTTPS() ) {
128                $this->mStickHTTPS = true;
129            }
130            $session->setForceHTTPS( $secureLogin && $this->mStickHTTPS );
131
132            // If the user does not have a session cookie at this point, they probably need to
133            // do something to their browser.
134            if ( !$this->hasSessionCookie() ) {
135                $this->mainLoginForm( [ /*?*/ ], $session->getProvider()->whyNoSession() );
136                // TODO something more specific? This used to use nocookieslogin
137                return;
138            }
139
140            # Run any hooks; display injected HTML if any, else redirect
141            $this->getHookRunner()->onUserLoginComplete(
142                $user, $injected_html, $direct );
143        }
144
145        if ( $injected_html !== '' || $extraMessages ) {
146            $this->showSuccessPage( 'success', $this->msg( 'loginsuccesstitle' ),
147                'loginsuccess', $injected_html, $extraMessages );
148        } else {
149            $helper = new LoginHelper( $this->getContext() );
150            $helper->showReturnToPage( 'successredirect', $this->mReturnTo, $this->mReturnToQuery,
151                $this->mStickHTTPS );
152        }
153    }
154
155    protected function getToken() {
156        return $this->getRequest()->getSession()->getToken( '', 'login' );
157    }
158
159    protected function clearToken() {
160        $this->getRequest()->getSession()->resetToken( 'login' );
161    }
162
163    protected function getTokenName() {
164        return 'wpLoginToken';
165    }
166
167    protected function getGroupName() {
168        return 'login';
169    }
170
171    protected function logAuthResult( $success, $status = null ) {
172        LoggerFactory::getInstance( 'authevents' )->info( 'Login attempt', [
173            'event' => 'login',
174            'successful' => $success,
175            'status' => strval( $status ),
176        ] );
177    }
178}
179
180/**
181 * Retain the old class name for backwards compatibility.
182 * @deprecated since 1.41
183 */
184class_alias( SpecialUserLogin::class, 'SpecialUserLogin' );