X-Git-Url: https://git.cyclocoop.org/?a=blobdiff_plain;f=includes%2Fspecials%2FSpecialUserlogin.php;h=71efefa79543ca2a37860399ccdc4db162e951b7;hb=44840d15929d8ecfc1d7c31d6f7e86d873ac15a2;hp=17c8ec912291fbd7478d1b158c1abec945a75213;hpb=b7ea8a066475efa097414d54dcb0e3e955548c94;p=lhc%2Fweb%2Fwiklou.git diff --git a/includes/specials/SpecialUserlogin.php b/includes/specials/SpecialUserlogin.php index 17c8ec9122..71efefa795 100644 --- a/includes/specials/SpecialUserlogin.php +++ b/includes/specials/SpecialUserlogin.php @@ -50,12 +50,20 @@ class LoginForm extends SpecialPage { var $mType, $mReason, $mRealName; var $mAbortLoginErrorMsg = 'login-abort-generic'; private $mLoaded = false; + private $mSecureLoginUrl; /** * @ var WebRequest */ private $mOverrideRequest = null; + /** + * Effective request; set at the beginning of load + * + * @var WebRequest $mRequest + */ + private $mRequest = null; + /** * @param WebRequest $request */ @@ -81,6 +89,7 @@ class LoginForm extends SpecialPage { } else { $request = $this->mOverrideRequest; } + $this->mRequest = $request; $this->mType = $request->getText( 'type' ); $this->mUsername = $request->getText( 'wpName' ); @@ -103,18 +112,18 @@ class LoginForm extends SpecialPage { $this->mReturnTo = $request->getVal( 'returnto', '' ); $this->mReturnToQuery = $request->getVal( 'returntoquery', '' ); - if( $wgEnableEmail ) { + if ( $wgEnableEmail ) { $this->mEmail = $request->getText( 'wpEmail' ); } else { $this->mEmail = ''; } - if( !in_array( 'realname', $wgHiddenPrefs ) ) { + if ( !in_array( 'realname', $wgHiddenPrefs ) ) { $this->mRealName = $request->getText( 'wpRealName' ); } else { $this->mRealName = ''; } - if( !$wgAuth->validDomain( $this->mDomain ) ) { + if ( !$wgAuth->validDomain( $this->mDomain ) ) { $this->mDomain = $wgAuth->getDomain(); } $wgAuth->setDomain( $this->mDomain ); @@ -123,7 +132,7 @@ class LoginForm extends SpecialPage { # 2. Do not return to PasswordReset after a successful password change # but goto Wiki start page (Main_Page) instead ( bug 33997 ) $returnToTitle = Title::newFromText( $this->mReturnTo ); - if( is_object( $returnToTitle ) && ( + if ( is_object( $returnToTitle ) && ( $returnToTitle->isSpecial( 'Userlogout' ) || $returnToTitle->isSpecial( 'PasswordReset' ) ) ) { $this->mReturnTo = ''; @@ -132,22 +141,34 @@ class LoginForm extends SpecialPage { } function getDescription() { - return $this->msg( $this->getUser()->isAllowed( 'createaccount' ) ? - 'userlogin' : 'userloginnocreate' )->text(); + if ( $this->mType === 'signup' ) { + return $this->msg( 'createaccount' )->text(); + } else { + return $this->msg( 'login' )->text(); + } } - public function execute( $par ) { + /* + * @param $subPage string|null + */ + public function execute( $subPage ) { if ( session_id() == '' ) { wfSetupSession(); } $this->load(); + + // Check for [[Special:Userlogin/signup]. This affects form display and + // page title. + if ( $subPage == 'signup' ) { + $this->mType = 'signup'; + } $this->setHeaders(); + // If logging in and not on HTTPS, either redirect to it or offer a link. global $wgSecureLogin; if ( $this->mType !== 'signup' && - $wgSecureLogin && WebRequest::detectProtocol() !== 'https' ) { $title = $this->getFullTitle(); @@ -157,19 +178,24 @@ class LoginForm extends SpecialPage { 'wpStickHTTPS' => $this->mStickHTTPS ); $url = $title->getFullURL( $query, false, PROTO_HTTPS ); - $this->getOutput()->redirect( $url ); - return; - } - - if ( $par == 'signup' ) { # Check for [[Special:Userlogin/signup]] - $this->mType = 'signup'; + if ( $wgSecureLogin ) { + $this->getOutput()->redirect( $url ); + return; + } else { + // A wiki without HTTPS login support should set $wgServer to + // http://somehost, in which case the secure URL generated + // above won't actually start with https:// + if ( substr( $url, 0, 8 ) === 'https://' ) { + $this->mSecureLoginUrl = $url; + } + } } if ( !is_null( $this->mCookieCheck ) ) { $this->onCookieRedirectCheck( $this->mCookieCheck ); return; - } elseif( $this->mPosted ) { - if( $this->mCreateaccount ) { + } elseif ( $this->mPosted ) { + if ( $this->mCreateaccount ) { $this->addNewAccount(); return; } elseif ( $this->mCreateaccountMail ) { @@ -193,7 +219,7 @@ class LoginForm extends SpecialPage { } $status = $this->addNewaccountInternal(); - if( !$status->isGood() ) { + if ( !$status->isGood() ) { $error = $this->getOutput()->parse( $status->getWikiText() ); $this->mainLoginForm( $error ); return; @@ -212,7 +238,7 @@ class LoginForm extends SpecialPage { $out = $this->getOutput(); $out->setPageTitle( $this->msg( 'accmailtitle' ) ); - if( !$result->isGood() ) { + if ( !$result->isGood() ) { $this->mainLoginForm( $this->msg( 'mailerror', $result->getWikiText() )->text() ); } else { $out->addWikiMsg( 'accmailtext', $u->getName(), $u->getEmail() ); @@ -229,7 +255,7 @@ class LoginForm extends SpecialPage { # Create the account and abort if there's a problem doing so $status = $this->addNewAccountInternal(); - if( !$status->isGood() ) { + if ( !$status->isGood() ) { $error = $this->getOutput()->parse( $status->getWikiText() ); $this->mainLoginForm( $error ); return false; @@ -241,7 +267,7 @@ class LoginForm extends SpecialPage { if ( $this->getUser()->isAnon() ) { # If we showed up language selection links, and one was in use, be # smart (and sensible) and save that language as the user's preference - if( $wgLoginLanguageSelector && $this->mLanguage ) { + if ( $wgLoginLanguageSelector && $this->mLanguage ) { $u->setOption( 'language', $this->mLanguage ); } else { @@ -258,9 +284,9 @@ class LoginForm extends SpecialPage { $out = $this->getOutput(); # Send out an email authentication message if needed - if( $wgEmailAuthentication && Sanitizer::validateEmail( $u->getEmail() ) ) { + if ( $wgEmailAuthentication && Sanitizer::validateEmail( $u->getEmail() ) ) { $status = $u->sendConfirmationMail(); - if( $status->isGood() ) { + if ( $status->isGood() ) { $out->addWikiMsg( 'confirmemail_oncreate' ); } else { $out->addWikiText( $status->getWikiText( 'confirmemail_sendfailed' ) ); @@ -273,7 +299,7 @@ class LoginForm extends SpecialPage { # If not logged in, assume the new account as the current one and set # session cookies then show a "welcome" message or a "need cookies" # message as needed - if( $this->getUser()->isAnon() ) { + if ( $this->getUser()->isAnon() ) { $u->setCookies(); $wgUser = $u; // This should set it for OutputPage and the Skin @@ -282,7 +308,7 @@ class LoginForm extends SpecialPage { $this->getContext()->setUser( $u ); wfRunHooks( 'AddNewAccount', array( $u, false ) ); $u->addNewUserLogEntry( 'create' ); - if( $this->hasSessionCookie() ) { + if ( $this->hasSessionCookie() ) { $this->successfulCreation(); } else { $this->cookieRedirectCheck( 'new' ); @@ -309,7 +335,7 @@ class LoginForm extends SpecialPage { $wgMinimalPasswordLength, $wgEmailConfirmToEdit; // If the user passes an invalid domain, something is fishy - if( !$wgAuth->validDomain( $this->mDomain ) ) { + if ( !$wgAuth->validDomain( $this->mDomain ) ) { return Status::newFatal( 'wrongpassword' ); } @@ -318,8 +344,8 @@ class LoginForm extends SpecialPage { // cation server before they create an account (otherwise, they can // create a local account and login as any domain user). We only need // to check this for domains that aren't local. - if( 'local' != $this->mDomain && $this->mDomain != '' ) { - if( + if ( 'local' != $this->mDomain && $this->mDomain != '' ) { + if ( !$wgAuth->canCreateAccounts() && ( !$wgAuth->userExists( $this->mUsername ) || @@ -417,7 +443,7 @@ class LoginForm extends SpecialPage { $u->setRealName( $this->mRealName ); $abortError = ''; - if( !wfRunHooks( 'AbortNewAccount', array( $u, &$abortError ) ) ) { + if ( !wfRunHooks( 'AbortNewAccount', array( $u, &$abortError ) ) ) { // Hook point to add extra creation throttles and blocks wfDebug( "LoginForm::addNewAccountInternal: a hook blocked creation\n" ); return Status::newFatal( new RawMessage( $abortError ) ); @@ -440,7 +466,7 @@ class LoginForm extends SpecialPage { } } - if( !$wgAuth->addUser( $u, $this->mPassword, $this->mEmail, $this->mRealName ) ) { + if ( !$wgAuth->addUser( $u, $this->mPassword, $this->mEmail, $this->mRealName ) ) { return Status::newFatal( 'externaldberror' ); } @@ -538,7 +564,7 @@ class LoginForm extends SpecialPage { } $u = User::newFromName( $this->mUsername ); - if( !( $u instanceof User ) || !User::isUsableName( $u->getName() ) ) { + if ( !( $u instanceof User ) || !User::isUsableName( $u->getName() ) ) { return self::ILLEGAL; } @@ -556,13 +582,13 @@ class LoginForm extends SpecialPage { // Give general extensions, such as a captcha, a chance to abort logins $abort = self::ABORTED; - if( !wfRunHooks( 'AbortLogin', array( $u, $this->mPassword, &$abort, &$this->mAbortLoginErrorMsg ) ) ) { + if ( !wfRunHooks( 'AbortLogin', array( $u, $this->mPassword, &$abort, &$this->mAbortLoginErrorMsg ) ) ) { return $abort; } global $wgBlockDisablesLogin; if ( !$u->checkPassword( $this->mPassword ) ) { - if( $u->checkTemporaryPassword( $this->mPassword ) ) { + if ( $u->checkTemporaryPassword( $this->mPassword ) ) { // The e-mailed temporary password should not be used for actu- // al logins; that's a very sloppy habit, and insecure if an // attacker has a few seconds to click "search" on someone's o- @@ -579,7 +605,7 @@ class LoginForm extends SpecialPage { // As a side-effect, we can authenticate the user's e-mail ad- // dress if it's not already done, since the temporary password // was sent via e-mail. - if( !$u->isEmailConfirmed() ) { + if ( !$u->isEmailConfirmed() ) { $u->confirmEmail(); $u->saveSettings(); } @@ -688,7 +714,7 @@ class LoginForm extends SpecialPage { } $abortError = ''; - if( !wfRunHooks( 'AbortAutoAccount', array( $user, &$abortError ) ) ) { + if ( !wfRunHooks( 'AbortAutoAccount', array( $user, &$abortError ) ) ) { // Hook point to add extra creation throttles and blocks wfDebug( "LoginForm::attemptAutoCreate: a hook blocked creation: $abortError\n" ); $this->mAbortLoginErrorMsg = $abortError; @@ -714,14 +740,14 @@ class LoginForm extends SpecialPage { case self::SUCCESS: # We've verified now, update the real record $user = $this->getUser(); - if( (bool)$this->mRemember != $user->getBoolOption( 'rememberpassword' ) ) { + if ( (bool)$this->mRemember != $user->getBoolOption( 'rememberpassword' ) ) { $user->setOption( 'rememberpassword', $this->mRemember ? 1 : 0 ); $user->saveSettings(); } else { $user->invalidateCache(); } - if( $wgSecureLogin && !$this->mStickHTTPS ) { + if ( $wgSecureLogin && !$this->mStickHTTPS ) { $user->setCookies( null, false ); } else { $user->setCookies(); @@ -733,7 +759,7 @@ class LoginForm extends SpecialPage { $key = wfMemcKey( 'password-throttle', $request->getIP(), md5( $this->mUsername ) ); $wgMemc->delete( $key ); - if( $this->hasSessionCookie() || $this->mSkipCookieCheck ) { + if ( $this->hasSessionCookie() || $this->mSkipCookieCheck ) { /* Replace the language object to provide user interface in * correct language immediately on this first page load. */ @@ -763,7 +789,7 @@ class LoginForm extends SpecialPage { $this->mainLoginForm( $this->msg( 'wrongpassword' )->text() ); break; case self::NOT_EXISTS: - if( $this->getUser()->isAllowed( 'createaccount' ) ) { + if ( $this->getUser()->isAllowed( 'createaccount' ) ) { $this->mainLoginForm( $this->msg( 'nosuchuser', wfEscapeWikiText( $this->mUsername ) )->parse() ); } else { @@ -781,7 +807,7 @@ class LoginForm extends SpecialPage { $this->resetLoginForm( $this->msg( 'resetpass_announce' )->text() ); break; case self::CREATE_BLOCKED: - $this->userBlockedMessage( $this->getUser()->mBlock ); + $this->userBlockedMessage( $this->getUser()->isBlockedFromCreateAccount() ); break; case self::THROTTLED: $this->mainLoginForm( $this->msg( 'login-throttled' )->text() ); @@ -822,7 +848,7 @@ class LoginForm extends SpecialPage { return Status::newFatal( 'noemail', $u->getName() ); } $ip = $this->getRequest()->getIP(); - if( !$ip ) { + if ( !$ip ) { return Status::newFatal( 'badipaddress' ); } @@ -856,7 +882,7 @@ class LoginForm extends SpecialPage { $injected_html = ''; wfRunHooks( 'UserLoginComplete', array( &$currentUser, &$injected_html ) ); - if( $injected_html !== '' ) { + if ( $injected_html !== '' ) { $this->displaySuccessfulAction( $this->msg( 'loginsuccesstitle' ), 'loginsuccess', $injected_html ); } else { @@ -935,6 +961,29 @@ class LoginForm extends SpecialPage { ); } + /** + * Add a "return to" link or redirect to it. + * Extensions can use this to reuse the "return to" logic after + * inject steps (such as redirection) into the login process. + * + * @param $type string, one of the following: + * - error: display a return to link ignoring $wgRedirectOnLogin + * - success: display a return to link using $wgRedirectOnLogin if needed + * - successredirect: send an HTTP redirect using $wgRedirectOnLogin if needed + * @param string $returnTo + * @param array|string $returnToQuery + * @param bool $stickHTTPs Keep redirect link on HTTPs + * @since 1.22 + */ + public function showReturnToPage( + $type, $returnTo = '', $returnToQuery = '', $stickHTTPs = false + ) { + $this->mReturnTo = $returnTo; + $this->mReturnToQuery = $returnToQuery; + $this->mStickHTTPS = $stickHTTPs; + $this->executeReturnTo( $type ); + } + /** * Add a "return to" link or redirect to it. * @@ -962,7 +1011,7 @@ class LoginForm extends SpecialPage { if ( $wgSecureLogin && !$this->mStickHTTPS ) { $options = array( 'http' ); $proto = PROTO_HTTP; - } elseif( $wgSecureLogin ) { + } elseif ( $wgSecureLogin ) { $options = array( 'https' ); $proto = PROTO_HTTPS; } else { @@ -989,6 +1038,7 @@ class LoginForm extends SpecialPage { $titleObj = $this->getTitle(); $user = $this->getUser(); + $out = $this->getOutput(); if ( $this->mType == 'signup' ) { // Block signup here if in readonly. Keeps user from @@ -1016,15 +1066,33 @@ class LoginForm extends SpecialPage { if ( $this->mType == 'signup' ) { $template = new UsercreateTemplate(); + + $out->addModuleStyles( array( + 'mediawiki.ui', + 'mediawiki.special.createaccount' + ) ); + // XXX hack pending RL or JS parse() support for complex content messages + // https://bugzilla.wikimedia.org/show_bug.cgi?id=25349 + $out->addJsConfigVars( 'wgCreateacctImgcaptchaHelp', + $this->msg( 'createacct-imgcaptcha-help' )->parse() ); + $out->addModules( array( + 'mediawiki.special.createaccount.js' + ) ); + // Must match number of benefits defined in messages + $template->set( 'benefitCount', 3 ); + $q = 'action=submitlogin&type=signup'; $linkq = 'type=login'; - $linkmsg = 'gotaccount'; - $this->getOutput()->addModules( 'mediawiki.special.userlogin.signup' ); } else { $template = new UserloginTemplate(); + + $out->addModuleStyles( array( + 'mediawiki.ui', + 'mediawiki.special.userlogin' + ) ); + $q = 'action=submitlogin&type=login'; $linkq = 'type=signup'; - $linkmsg = 'nologin'; } if ( $this->mReturnTo !== '' ) { @@ -1037,16 +1105,14 @@ class LoginForm extends SpecialPage { $linkq .= $returnto; } - # Don't show a "create account" link if the user can't - if( $this->showCreateOrLoginLink( $user ) ) { + # Don't show a "create account" link if the user can't. + if ( $this->showCreateOrLoginLink( $user ) ) { # Pass any language selection on to the mode switch link - if( $wgLoginLanguageSelector && $this->mLanguage ) { + if ( $wgLoginLanguageSelector && $this->mLanguage ) { $linkq .= '&uselang=' . $this->mLanguage; } - $link = Html::element( 'a', array( 'href' => $titleObj->getLocalURL( $linkq ) ), - $this->msg( $linkmsg . 'link' )->text() ); # Calling either 'gotaccountlink' or 'nologinlink' - - $template->set( 'link', $this->msg( $linkmsg )->rawParams( $link )->parse() ); + // Supply URL, login template creates the button. + $template->set( 'createOrLoginHref', $titleObj->getLocalURL( $linkq ) ); } else { $template->set( 'link', '' ); } @@ -1061,6 +1127,7 @@ class LoginForm extends SpecialPage { : is_array( $wgPasswordResetRoutes ) && in_array( true, array_values( $wgPasswordResetRoutes ) ); $template->set( 'header', '' ); + $template->set( 'skin', $this->getSkin() ); $template->set( 'name', $this->mUsername ); $template->set( 'password', $this->mPassword ); $template->set( 'retype', $this->mRetype ); @@ -1099,15 +1166,16 @@ class LoginForm extends SpecialPage { } # Prepare language selection links as needed - if( $wgLoginLanguageSelector ) { + if ( $wgLoginLanguageSelector ) { $template->set( 'languages', $this->makeLanguageSelector() ); - if( $this->mLanguage ) { + if ( $this->mLanguage ) { $template->set( 'uselang', $this->mLanguage ); } } + $template->set( 'secureLoginUrl', $this->mSecureLoginUrl ); // Use loginend-https for HTTPS requests if it's not blank, loginend otherwise - // Ditto for signupend + // Ditto for signupend. New forms use neither. $usingHTTPS = WebRequest::detectProtocol() == 'https'; $loginendHTTPS = $this->msg( 'loginend-https' ); $signupendHTTPS = $this->msg( 'signupend-https' ); @@ -1130,7 +1198,6 @@ class LoginForm extends SpecialPage { wfRunHooks( 'UserLoginForm', array( &$template ) ); } - $out = $this->getOutput(); $out->disallowUserJs(); // just in case... $out->addTemplate( $template ); } @@ -1143,9 +1210,9 @@ class LoginForm extends SpecialPage { * @return Boolean */ function showCreateOrLoginLink( &$user ) { - if( $this->mType == 'signup' ) { + if ( $this->mType == 'signup' ) { return true; - } elseif( $user->isAllowed( 'createaccount' ) ) { + } elseif ( $user->isAllowed( 'createaccount' ) ) { return true; } else { return false; @@ -1224,7 +1291,7 @@ class LoginForm extends SpecialPage { */ private function renewSessionId() { global $wgSecureLogin, $wgCookieSecure; - if( $wgSecureLogin && !$this->mStickHTTPS ) { + if ( $wgSecureLogin && !$this->mStickHTTPS ) { $wgCookieSecure = false; } @@ -1283,10 +1350,10 @@ class LoginForm extends SpecialPage { */ function makeLanguageSelector() { $msg = $this->msg( 'loginlanguagelinks' )->inContentLanguage(); - if( !$msg->isBlank() ) { + if ( !$msg->isBlank() ) { $langs = explode( "\n", $msg->text() ); $links = array(); - foreach( $langs as $lang ) { + foreach ( $langs as $lang ) { $lang = trim( $lang, '* ' ); $parts = explode( '|', $lang ); if ( count( $parts ) >= 2 ) { @@ -1309,15 +1376,15 @@ class LoginForm extends SpecialPage { * @return string */ function makeLanguageSelectorLink( $text, $lang ) { - if( $this->getLanguage()->getCode() == $lang ) { + if ( $this->getLanguage()->getCode() == $lang ) { // no link for currently used language return htmlspecialchars( $text ); } $query = array( 'uselang' => $lang ); - if( $this->mType == 'signup' ) { + if ( $this->mType == 'signup' ) { $query['type'] = 'signup'; } - if( $this->mReturnTo !== '' ) { + if ( $this->mReturnTo !== '' ) { $query['returnto'] = $this->mReturnTo; $query['returntoquery'] = $this->mReturnToQuery; }