Merge "Special:Newpages feed now shows first revision instead of latest revision"
[lhc/web/wiklou.git] / includes / specials / SpecialUserLogin.php
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
24 use MediaWiki\Auth\AuthManager;
25 use MediaWiki\Logger\LoggerFactory;
26
27 /**
28 * Implements Special:UserLogin
29 *
30 * @ingroup SpecialPage
31 */
32 class SpecialUserLogin extends LoginSignupSpecialPage {
33 protected static $allowedActions = [
34 AuthManager::ACTION_LOGIN,
35 AuthManager::ACTION_LOGIN_CONTINUE
36 ];
37
38 protected static $messages = [
39 'authform-newtoken' => 'nocookiesforlogin',
40 'authform-notoken' => 'sessionfailure',
41 'authform-wrongtoken' => 'sessionfailure',
42 ];
43
44 public function __construct() {
45 parent::__construct( 'Userlogin' );
46 }
47
48 public function doesWrites() {
49 return true;
50 }
51
52 protected function getLoginSecurityLevel() {
53 return false;
54 }
55
56 protected function getDefaultAction( $subPage ) {
57 return AuthManager::ACTION_LOGIN;
58 }
59
60 public function getDescription() {
61 return $this->msg( 'login' )->text();
62 }
63
64 public function setHeaders() {
65 // override the page title if we are doing a forced reauthentication
66 parent::setHeaders();
67 if ( $this->securityLevel && $this->getUser()->isLoggedIn() ) {
68 $this->getOutput()->setPageTitle( $this->msg( 'login-security' ) );
69 }
70 }
71
72 protected function isSignup() {
73 return false;
74 }
75
76 protected function beforeExecute( $subPage ) {
77 if ( $subPage === 'signup' || $this->getRequest()->getText( 'type' ) === 'signup' ) {
78 // B/C for old account creation URLs
79 $title = SpecialPage::getTitleFor( 'CreateAccount' );
80 $query = array_diff_key( $this->getRequest()->getValues(),
81 array_fill_keys( [ 'type', 'title' ], true ) );
82 $url = $title->getFullURL( $query, false, PROTO_CURRENT );
83 $this->getOutput()->redirect( $url );
84 return false;
85 }
86 return parent::beforeExecute( $subPage );
87 }
88
89 /**
90 * Run any hooks registered for logins, then HTTP redirect to
91 * $this->mReturnTo (or Main Page if that's undefined). Formerly we had a
92 * nice message here, but that's really not as useful as just being sent to
93 * wherever you logged in from. It should be clear that the action was
94 * successful, given the lack of error messages plus the appearance of your
95 * name in the upper right.
96 * @param bool $direct True if the action was successful just now; false if that happened
97 * pre-redirection (so this handler was called already)
98 * @param StatusValue|null $extraMessages
99 */
100 protected function successfulAction( $direct = false, $extraMessages = null ) {
101 global $wgSecureLogin;
102
103 $user = $this->targetUser ?: $this->getUser();
104 $session = $this->getRequest()->getSession();
105
106 if ( $direct ) {
107 $user->touch();
108
109 $this->clearToken();
110
111 if ( $user->requiresHTTPS() ) {
112 $this->mStickHTTPS = true;
113 }
114 $session->setForceHTTPS( $wgSecureLogin && $this->mStickHTTPS );
115
116 // If the user does not have a session cookie at this point, they probably need to
117 // do something to their browser.
118 if ( !$this->hasSessionCookie() ) {
119 $this->mainLoginForm( [ /*?*/ ], $session->getProvider()->whyNoSession() );
120 // TODO something more specific? This used to use nocookieslogin
121 return;
122 }
123 }
124
125 # Run any hooks; display injected HTML if any, else redirect
126 $injected_html = '';
127 Hooks::run( 'UserLoginComplete', [ &$user, &$injected_html, $direct ] );
128
129 if ( $injected_html !== '' || $extraMessages ) {
130 $this->showSuccessPage( 'success', $this->msg( 'loginsuccesstitle' ),
131 'loginsuccess', $injected_html, $extraMessages );
132 } else {
133 $helper = new LoginHelper( $this->getContext() );
134 $helper->showReturnToPage( 'successredirect', $this->mReturnTo, $this->mReturnToQuery,
135 $this->mStickHTTPS );
136 }
137 }
138
139 protected function getToken() {
140 return $this->getRequest()->getSession()->getToken( '', 'login' );
141 }
142
143 protected function clearToken() {
144 return $this->getRequest()->getSession()->resetToken( 'login' );
145 }
146
147 protected function getTokenName() {
148 return 'wpLoginToken';
149 }
150
151 protected function getGroupName() {
152 return 'login';
153 }
154
155 protected function logAuthResult( $success, $status = null ) {
156 LoggerFactory::getInstance( 'authevents' )->info( 'Login attempt', [
157 'event' => 'login',
158 'successful' => $success,
159 'status' => $status,
160 ] );
161 }
162 }