MediaWiki  master
LoginSignupSpecialPage.php
Go to the documentation of this file.
1 <?php
31 use Wikimedia\ScopedCallback;
32 
39  protected $mReturnTo;
40  protected $mPosted;
41  protected $mAction;
42  protected $mLanguage;
43  protected $mReturnToQuery;
44  protected $mToken;
45  protected $mStickHTTPS;
46  protected $mFromHTTP;
47  protected $mEntryError = '';
48  protected $mEntryErrorType = 'error';
49 
50  protected $mLoaded = false;
51  protected $mLoadedRequest = false;
52  protected $mSecureLoginUrl;
53  private $reasonValidatorResult = null;
54 
56  protected $securityLevel;
57 
63  protected $targetUser;
64 
66  protected $authForm;
67 
68  abstract protected function isSignup();
69 
76  abstract protected function successfulAction( $direct = false, $extraMessages = null );
77 
83  abstract protected function logAuthResult( $success, $status = null );
84 
85  public function __construct( $name, $restriction = '' ) {
87  parent::__construct( $name, $restriction );
88 
89  // Override UseMediaWikiEverywhere to true, to force login and create form to use mw ui
91  }
92 
93  protected function setRequest( array $data, $wasPosted = null ) {
94  parent::setRequest( $data, $wasPosted );
95  $this->mLoadedRequest = false;
96  }
97 
101  private function loadRequestParameters() {
102  if ( $this->mLoadedRequest ) {
103  return;
104  }
105  $this->mLoadedRequest = true;
106  $request = $this->getRequest();
107 
108  $this->mPosted = $request->wasPosted();
109  $this->mAction = $request->getVal( 'action' );
110  $this->mFromHTTP = $request->getBool( 'fromhttp', false )
111  || $request->getBool( 'wpFromhttp', false );
112  $this->mStickHTTPS = $this->getConfig()->get( 'ForceHTTPS' )
113  || ( !$this->mFromHTTP && $request->getProtocol() === 'https' )
114  || $request->getBool( 'wpForceHttps', false );
115  $this->mLanguage = $request->getText( 'uselang' );
116  $this->mReturnTo = $request->getVal( 'returnto', '' );
117  $this->mReturnToQuery = $request->getVal( 'returntoquery', '' );
118  }
119 
125  protected function load( $subPage ) {
126  global $wgSecureLogin;
127 
128  $this->loadRequestParameters();
129  if ( $this->mLoaded ) {
130  return;
131  }
132  $this->mLoaded = true;
133  $request = $this->getRequest();
134 
135  $securityLevel = $this->getRequest()->getText( 'force' );
136  if (
137  $securityLevel &&
138  MediaWikiServices::getInstance()->getAuthManager()->securitySensitiveOperationStatus(
139  $securityLevel ) === AuthManager::SEC_REAUTH
140  ) {
141  $this->securityLevel = $securityLevel;
142  }
143 
144  $this->loadAuth( $subPage );
145 
146  $this->mToken = $request->getVal( $this->getTokenName() );
147 
148  // Show an error or warning passed on from a previous page
149  $entryError = $this->msg( $request->getVal( 'error', '' ) );
150  $entryWarning = $this->msg( $request->getVal( 'warning', '' ) );
151  // bc: provide login link as a parameter for messages where the translation
152  // was not updated
153  $loginreqlink = $this->getLinkRenderer()->makeKnownLink(
154  $this->getPageTitle(),
155  $this->msg( 'loginreqlink' )->text(),
156  [],
157  [
158  'returnto' => $this->mReturnTo,
159  'returntoquery' => $this->mReturnToQuery,
160  'uselang' => $this->mLanguage ?: null,
161  'fromhttp' => $wgSecureLogin && $this->mFromHTTP ? '1' : null,
162  ]
163  );
164 
165  // Only show valid error or warning messages.
166  if ( $entryError->exists()
167  && in_array( $entryError->getKey(), LoginHelper::getValidErrorMessages(), true )
168  ) {
169  $this->mEntryErrorType = 'error';
170  $this->mEntryError = $entryError->rawParams( $loginreqlink )->parse();
171 
172  } elseif ( $entryWarning->exists()
173  && in_array( $entryWarning->getKey(), LoginHelper::getValidErrorMessages(), true )
174  ) {
175  $this->mEntryErrorType = 'warning';
176  $this->mEntryError = $entryWarning->rawParams( $loginreqlink )->parse();
177  }
178 
179  # 1. When switching accounts, it sucks to get automatically logged out
180  # 2. Do not return to PasswordReset after a successful password change
181  # but goto Wiki start page (Main_Page) instead ( T35997 )
182  $returnToTitle = Title::newFromText( $this->mReturnTo );
183  if ( is_object( $returnToTitle )
184  && ( $returnToTitle->isSpecial( 'Userlogout' )
185  || $returnToTitle->isSpecial( 'PasswordReset' ) )
186  ) {
187  $this->mReturnTo = '';
188  $this->mReturnToQuery = '';
189  }
190  }
191 
192  protected function getPreservedParams( $withToken = false ) {
193  global $wgSecureLogin;
194 
195  $params = parent::getPreservedParams( $withToken );
196  $params += [
197  'returnto' => $this->mReturnTo ?: null,
198  'returntoquery' => $this->mReturnToQuery ?: null,
199  ];
200  if ( $wgSecureLogin && !$this->isSignup() ) {
201  $params['fromhttp'] = $this->mFromHTTP ? '1' : null;
202  }
203  return $params;
204  }
205 
206  protected function beforeExecute( $subPage ) {
207  // finish initializing the class before processing the request - T135924
208  $this->loadRequestParameters();
209  return parent::beforeExecute( $subPage );
210  }
211 
216  public function execute( $subPage ) {
217  if ( $this->mPosted ) {
218  $time = microtime( true );
219  $profilingScope = new ScopedCallback( function () use ( $time ) {
220  $time = microtime( true ) - $time;
221  $statsd = MediaWikiServices::getInstance()->getStatsdDataFactory();
222  $statsd->timing( "timing.login.ui.{$this->authAction}", $time * 1000 );
223  } );
224  }
225 
226  $authManager = MediaWikiServices::getInstance()->getAuthManager();
227  $session = SessionManager::getGlobalSession();
228 
229  // Session data is used for various things in the authentication process, so we must make
230  // sure a session cookie or some equivalent mechanism is set.
231  $session->persist();
232  // Explicitly disable cache to ensure cookie blocks may be set (T152462).
233  // (Technically redundant with sessions persisting from this page.)
234  $this->getOutput()->enableClientCache( false );
235 
236  $this->load( $subPage );
237  $this->setHeaders();
238  $this->checkPermissions();
239 
240  // Make sure the system configuration allows log in / sign up
241  if ( !$this->isSignup() && !$authManager->canAuthenticateNow() ) {
242  if ( !$session->canSetUser() ) {
243  throw new ErrorPageError( 'cannotloginnow-title', 'cannotloginnow-text', [
244  $session->getProvider()->describe( RequestContext::getMain()->getLanguage() )
245  ] );
246  }
247  throw new ErrorPageError( 'cannotlogin-title', 'cannotlogin-text' );
248  } elseif ( $this->isSignup() && !$authManager->canCreateAccounts() ) {
249  throw new ErrorPageError( 'cannotcreateaccount-title', 'cannotcreateaccount-text' );
250  }
251 
252  /*
253  * In the case where the user is already logged in, and was redirected to
254  * the login form from a page that requires login, do not show the login
255  * page. The use case scenario for this is when a user opens a large number
256  * of tabs, is redirected to the login page on all of them, and then logs
257  * in on one, expecting all the others to work properly.
258  *
259  * However, do show the form if it was visited intentionally (no 'returnto'
260  * is present). People who often switch between several accounts have grown
261  * accustomed to this behavior.
262  *
263  * Also make an exception when force=<level> is set in the URL, which means the user must
264  * reauthenticate for security reasons.
265  */
266  if ( !$this->isSignup() && !$this->mPosted && !$this->securityLevel &&
267  ( $this->mReturnTo !== '' || $this->mReturnToQuery !== '' ) &&
268  $this->getUser()->isRegistered()
269  ) {
270  $this->successfulAction();
271  return;
272  }
273 
274  // If logging in and not on HTTPS, either redirect to it or offer a link.
275  global $wgSecureLogin;
276  if ( $this->getRequest()->getProtocol() !== 'https' ) {
277  $title = $this->getFullTitle();
278  $query = $this->getPreservedParams( false ) + [
279  'title' => null,
280  ( $this->mEntryErrorType === 'error' ? 'error'
281  : 'warning' ) => $this->mEntryError,
282  ] + $this->getRequest()->getQueryValues();
283  $url = $title->getFullURL( $query, false, PROTO_HTTPS );
284  if ( $wgSecureLogin && !$this->mFromHTTP ) {
285  // Avoid infinite redirect
286  $url = wfAppendQuery( $url, 'fromhttp=1' );
287  $this->getOutput()->redirect( $url );
288  // Since we only do this redir to change proto, always vary
289  $this->getOutput()->addVaryHeader( 'X-Forwarded-Proto' );
290 
291  return;
292  } else {
293  // A wiki without HTTPS login support should set $wgServer to
294  // http://somehost, in which case the secure URL generated
295  // above won't actually start with https://
296  if ( substr( $url, 0, 8 ) === 'https://' ) {
297  $this->mSecureLoginUrl = $url;
298  }
299  }
300  }
301 
302  if ( !$this->isActionAllowed( $this->authAction ) ) {
303  // FIXME how do we explain this to the user? can we handle session loss better?
304  // messages used: authpage-cannot-login, authpage-cannot-login-continue,
305  // authpage-cannot-create, authpage-cannot-create-continue
306  $this->mainLoginForm( [], 'authpage-cannot-' . $this->authAction );
307  return;
308  }
309 
310  if ( $this->canBypassForm( $button_name ) ) {
311  $this->setRequest( [], true );
312  $this->getRequest()->setVal( $this->getTokenName(), $this->getToken() );
313  if ( $button_name ) {
314  $this->getRequest()->setVal( $button_name, true );
315  }
316  }
317 
318  $status = $this->trySubmit();
319 
320  if ( !$status || !$status->isGood() ) {
321  $this->mainLoginForm( $this->authRequests, $status ? $status->getMessage() : '', 'error' );
322  return;
323  }
324 
326  $response = $status->getValue();
327 
328  $returnToUrl = $this->getPageTitle( 'return' )
329  ->getFullURL( $this->getPreservedParams( true ), false, PROTO_HTTPS );
330  switch ( $response->status ) {
331  case AuthenticationResponse::PASS:
332  $this->logAuthResult( true );
333  $this->proxyAccountCreation = $this->isSignup() && !$this->getUser()->isAnon();
334  $this->targetUser = User::newFromName( $response->username );
335 
336  if (
337  !$this->proxyAccountCreation
338  && $response->loginRequest
340  ) {
341  // successful registration; log the user in instantly
342  $response2 = $authManager->beginAuthentication( [ $response->loginRequest ],
343  $returnToUrl );
344  if ( $response2->status !== AuthenticationResponse::PASS ) {
345  LoggerFactory::getInstance( 'login' )
346  ->error( 'Could not log in after account creation' );
347  $this->successfulAction( true, Status::newFatal( 'createacct-loginerror' ) );
348  break;
349  }
350  }
351 
352  if ( !$this->proxyAccountCreation ) {
353  // Ensure that the context user is the same as the session user.
355  }
356 
357  $this->successfulAction( true );
358  break;
359  case AuthenticationResponse::FAIL:
360  // fall through
361  case AuthenticationResponse::RESTART:
362  unset( $this->authForm );
363  if ( $response->status === AuthenticationResponse::FAIL ) {
364  $action = $this->getDefaultAction( $subPage );
365  $messageType = 'error';
366  } else {
367  $action = $this->getContinueAction( $this->authAction );
368  $messageType = 'warning';
369  }
370  $this->logAuthResult( false, $response->message ? $response->message->getKey() : '-' );
371  $this->loadAuth( $subPage, $action, true );
372  $this->mainLoginForm( $this->authRequests, $response->message, $messageType );
373  break;
374  case AuthenticationResponse::REDIRECT:
375  unset( $this->authForm );
376  $this->getOutput()->redirect( $response->redirectTarget );
377  break;
378  case AuthenticationResponse::UI:
379  unset( $this->authForm );
380  $this->authAction = $this->isSignup() ? AuthManager::ACTION_CREATE_CONTINUE
381  : AuthManager::ACTION_LOGIN_CONTINUE;
382  $this->authRequests = $response->neededRequests;
383  $this->mainLoginForm( $response->neededRequests, $response->message, $response->messageType );
384  break;
385  default:
386  throw new LogicException( 'invalid AuthenticationResponse' );
387  }
388  }
389 
403  private function canBypassForm( &$button_name ) {
404  $button_name = null;
405  if ( $this->isContinued() ) {
406  return false;
407  }
408  $fields = AuthenticationRequest::mergeFieldInfo( $this->authRequests );
409  foreach ( $fields as $fieldname => $field ) {
410  if ( !isset( $field['type'] ) ) {
411  return false;
412  }
413  if ( !empty( $field['skippable'] ) ) {
414  continue;
415  }
416  if ( $field['type'] === 'button' ) {
417  if ( $button_name !== null ) {
418  $button_name = null;
419  return false;
420  } else {
421  $button_name = $fieldname;
422  }
423  } elseif ( $field['type'] !== 'null' ) {
424  return false;
425  }
426  }
427  return true;
428  }
429 
439  protected function showSuccessPage(
440  $type, $title, $msgname, $injected_html, $extraMessages
441  ) {
442  $out = $this->getOutput();
443  $out->setPageTitle( $title );
444  if ( $msgname ) {
445  $out->addWikiMsg( $msgname, wfEscapeWikiText( $this->getUser()->getName() ) );
446  }
447  if ( $extraMessages ) {
448  $extraMessages = Status::wrap( $extraMessages );
449  $out->addWikiTextAsInterface(
450  $extraMessages->getWikiText( false, false, $this->getLanguage() )
451  );
452  }
453 
454  $out->addHTML( $injected_html );
455 
456  $helper = new LoginHelper( $this->getContext() );
457  $helper->showReturnToPage( $type, $this->mReturnTo, $this->mReturnToQuery, $this->mStickHTTPS );
458  }
459 
475  public function showReturnToPage(
476  $type, $returnTo = '', $returnToQuery = '', $stickHTTPS = false
477  ) {
478  $helper = new LoginHelper( $this->getContext() );
479  $helper->showReturnToPage( $type, $returnTo, $returnToQuery, $stickHTTPS );
480  }
481 
486  protected function setSessionUserForCurrentRequest() {
487  global $wgUser, $wgLang;
488 
489  $context = RequestContext::getMain();
490  $localContext = $this->getContext();
491  if ( $context !== $localContext ) {
492  // remove AuthManagerSpecialPage context hack
493  $this->setContext( $context );
494  }
495 
496  $user = $context->getRequest()->getSession()->getUser();
497 
498  $wgUser = $user;
499  $context->setUser( $user );
500 
501  $wgLang = $context->getLanguage();
502  }
503 
518  protected function mainLoginForm( array $requests, $msg = '', $msgtype = 'error' ) {
519  $user = $this->getUser();
520  $out = $this->getOutput();
521 
522  // FIXME how to handle empty $requests - restart, or no form, just an error message?
523  // no form would be better for no session type errors, restart is better when can* fails.
524  if ( !$requests ) {
525  $this->authAction = $this->getDefaultAction( $this->subPage );
526  $this->authForm = null;
527  $requests = MediaWikiServices::getInstance()->getAuthManager()
528  ->getAuthenticationRequests( $this->authAction, $user );
529  }
530 
531  // Generic styles and scripts for both login and signup form
532  $out->addModuleStyles( [
533  'mediawiki.ui',
534  'mediawiki.ui.button',
535  'mediawiki.ui.checkbox',
536  'mediawiki.ui.input',
537  'mediawiki.special.userlogin.common.styles'
538  ] );
539  if ( $this->isSignup() ) {
540  // XXX hack pending RL or JS parse() support for complex content messages T27349
541  $out->addJsConfigVars( 'wgCreateacctImgcaptchaHelp',
542  $this->msg( 'createacct-imgcaptcha-help' )->parse() );
543 
544  // Additional styles and scripts for signup form
545  $out->addModules( 'mediawiki.special.createaccount' );
546  $out->addModuleStyles( [
547  'mediawiki.special.userlogin.signup.styles'
548  ] );
549  } else {
550  // Additional styles for login form
551  $out->addModuleStyles( [
552  'mediawiki.special.userlogin.login.styles'
553  ] );
554  }
555  $out->disallowUserJs(); // just in case...
556 
557  $form = $this->getAuthForm( $requests, $this->authAction, $msg, $msgtype );
558  $form->prepareForm();
559 
560  $submitStatus = Status::newGood();
561  if ( $msg && $msgtype === 'warning' ) {
562  $submitStatus->warning( $msg );
563  } elseif ( $msg && $msgtype === 'error' ) {
564  $submitStatus->fatal( $msg );
565  }
566 
567  // warning header for non-standard workflows (e.g. security reauthentication)
568  if (
569  !$this->isSignup() &&
570  $this->getUser()->isRegistered() &&
571  $this->authAction !== AuthManager::ACTION_LOGIN_CONTINUE
572  ) {
573  $reauthMessage = $this->securityLevel ? 'userlogin-reauth' : 'userlogin-loggedin';
574  $submitStatus->warning( $reauthMessage, $this->getUser()->getName() );
575  }
576 
577  $formHtml = $form->getHTML( $submitStatus );
578 
579  $out->addHTML( $this->getPageHtml( $formHtml ) );
580  }
581 
588  protected function getPageHtml( $formHtml ) {
590 
591  $loginPrompt = $this->isSignup() ? '' : Html::rawElement( 'div',
592  [ 'id' => 'userloginprompt' ], $this->msg( 'loginprompt' )->parseAsBlock() );
593  $languageLinks = $wgLoginLanguageSelector ? $this->makeLanguageSelector() : '';
594  $signupStartMsg = $this->msg( 'signupstart' );
595  $signupStart = ( $this->isSignup() && !$signupStartMsg->isDisabled() )
596  ? Html::rawElement( 'div', [ 'id' => 'signupstart' ], $signupStartMsg->parseAsBlock() ) : '';
597  if ( $languageLinks ) {
598  $languageLinks = Html::rawElement( 'div', [ 'id' => 'languagelinks' ],
599  Html::rawElement( 'p', [], $languageLinks )
600  );
601  }
602 
603  $benefitsContainer = '';
604  if ( $this->isSignup() && $this->showExtraInformation() ) {
605  // messages used:
606  // createacct-benefit-icon1 createacct-benefit-head1 createacct-benefit-body1
607  // createacct-benefit-icon2 createacct-benefit-head2 createacct-benefit-body2
608  // createacct-benefit-icon3 createacct-benefit-head3 createacct-benefit-body3
609  $benefitCount = 3;
610  $benefitList = '';
611  for ( $benefitIdx = 1; $benefitIdx <= $benefitCount; $benefitIdx++ ) {
612  $headUnescaped = $this->msg( "createacct-benefit-head$benefitIdx" )->text();
613  $iconClass = $this->msg( "createacct-benefit-icon$benefitIdx" )->text();
614  $benefitList .= Html::rawElement( 'div', [ 'class' => "mw-number-text $iconClass" ],
615  Html::rawElement( 'h3', [],
616  $this->msg( "createacct-benefit-head$benefitIdx" )->escaped()
617  )
618  . Html::rawElement( 'p', [],
619  $this->msg( "createacct-benefit-body$benefitIdx" )->params( $headUnescaped )->escaped()
620  )
621  );
622  }
623  $benefitsContainer = Html::rawElement( 'div', [ 'class' => 'mw-createacct-benefits-container' ],
624  Html::rawElement( 'h2', [], $this->msg( 'createacct-benefit-heading' )->escaped() )
625  . Html::rawElement( 'div', [ 'class' => 'mw-createacct-benefits-list' ],
626  $benefitList
627  )
628  );
629  }
630 
631  $html = Html::rawElement( 'div', [ 'class' => 'mw-ui-container' ],
632  $loginPrompt
633  . $languageLinks
634  . $signupStart
635  . Html::rawElement( 'div', [ 'id' => 'userloginForm' ],
636  $formHtml
637  )
638  . $benefitsContainer
639  );
640 
641  return $html;
642  }
643 
652  protected function getAuthForm( array $requests, $action, $msg = '', $msgType = 'error' ) {
653  // FIXME merge this with parent
654 
655  if ( isset( $this->authForm ) ) {
656  return $this->authForm;
657  }
658 
659  $usingHTTPS = $this->getRequest()->getProtocol() === 'https';
660 
661  // get basic form description from the auth logic
662  $fieldInfo = AuthenticationRequest::mergeFieldInfo( $requests );
663  // this will call onAuthChangeFormFields()
664  $formDescriptor = $this->fieldInfoToFormDescriptor( $requests, $fieldInfo, $this->authAction );
665  $this->postProcessFormDescriptor( $formDescriptor, $requests );
666 
667  $context = $this->getContext();
668  if ( $context->getRequest() !== $this->getRequest() ) {
669  // We have overridden the request, need to make sure the form uses that too.
670  $context = new DerivativeContext( $this->getContext() );
671  $context->setRequest( $this->getRequest() );
672  }
673  $form = HTMLForm::factory( 'vform', $formDescriptor, $context );
674 
675  $form->addHiddenField( 'authAction', $this->authAction );
676  if ( $this->mLanguage ) {
677  $form->addHiddenField( 'uselang', $this->mLanguage );
678  }
679  $form->addHiddenField( 'force', $this->securityLevel );
680  $form->addHiddenField( $this->getTokenName(), $this->getToken()->toString() );
681  $config = $this->getConfig();
682  if ( $config->get( 'SecureLogin' ) && !$config->get( 'ForceHTTPS' ) ) {
683  // If using HTTPS coming from HTTP, then the 'fromhttp' parameter must be preserved
684  if ( !$this->isSignup() ) {
685  $form->addHiddenField( 'wpForceHttps', (int)$this->mStickHTTPS );
686  $form->addHiddenField( 'wpFromhttp', $usingHTTPS );
687  }
688  }
689 
690  // set properties of the form itself
691  $form->setAction( $this->getPageTitle()->getLocalURL( $this->getReturnToQueryStringFragment() ) );
692  $form->setName( 'userlogin' . ( $this->isSignup() ? '2' : '' ) );
693  if ( $this->isSignup() ) {
694  $form->setId( 'userlogin2' );
695  }
696 
697  $form->suppressDefaultSubmit();
698 
699  $this->authForm = $form;
700 
701  return $form;
702  }
703 
705  public function onAuthChangeFormFields(
706  array $requests, array $fieldInfo, array &$formDescriptor, $action
707  ) {
708  $formDescriptor = self::mergeDefaultFormDescriptor( $fieldInfo, $formDescriptor,
709  $this->getFieldDefinitions() );
710  }
711 
718  protected function showExtraInformation() {
719  return $this->authAction !== $this->getContinueAction( $this->authAction )
721  }
722 
727  protected function getFieldDefinitions() {
728  global $wgEmailConfirmToEdit;
729 
730  $isRegistered = $this->getUser()->isRegistered();
731  $continuePart = $this->isContinued() ? 'continue-' : '';
732  $anotherPart = $isRegistered ? 'another-' : '';
733  // @phan-suppress-next-line PhanUndeclaredMethod
734  $expiration = $this->getRequest()->getSession()->getProvider()->getRememberUserDuration();
735  $expirationDays = ceil( $expiration / ( 3600 * 24 ) );
736  $secureLoginLink = '';
737  if ( $this->mSecureLoginUrl ) {
738  $secureLoginLink = Html::element( 'a', [
739  'href' => $this->mSecureLoginUrl,
740  'class' => 'mw-ui-flush-right mw-secure',
741  ], $this->msg( 'userlogin-signwithsecure' )->text() );
742  }
743  $usernameHelpLink = '';
744  if ( !$this->msg( 'createacct-helpusername' )->isDisabled() ) {
745  $usernameHelpLink = Html::rawElement( 'span', [
746  'class' => 'mw-ui-flush-right',
747  ], $this->msg( 'createacct-helpusername' )->parse() );
748  }
749 
750  if ( $this->isSignup() ) {
751  $fieldDefinitions = [
752  'statusarea' => [
753  // Used by the mediawiki.special.createaccount module for error display.
754  // FIXME: Merge this with HTMLForm's normal status (error) area
755  'type' => 'info',
756  'raw' => true,
757  'default' => Html::element( 'div', [ 'id' => 'mw-createacct-status-area' ] ),
758  'weight' => -105,
759  ],
760  'username' => [
761  'label-raw' => $this->msg( 'userlogin-yourname' )->escaped() . $usernameHelpLink,
762  'id' => 'wpName2',
763  'placeholder-message' => $isRegistered ? 'createacct-another-username-ph'
764  : 'userlogin-yourname-ph',
765  ],
766  'mailpassword' => [
767  // create account without providing password, a temporary one will be mailed
768  'type' => 'check',
769  'label-message' => 'createaccountmail',
770  'name' => 'wpCreateaccountMail',
771  'id' => 'wpCreateaccountMail',
772  ],
773  'password' => [
774  'id' => 'wpPassword2',
775  'autocomplete' => 'new-password',
776  'placeholder-message' => 'createacct-yourpassword-ph',
777  'help-message' => 'createacct-useuniquepass',
778  'hide-if' => [ '===', 'wpCreateaccountMail', '1' ],
779  ],
780  'domain' => [],
781  'retype' => [
782  'type' => 'password',
783  'label-message' => 'createacct-yourpasswordagain',
784  'id' => 'wpRetype',
785  'cssclass' => 'loginPassword',
786  'size' => 20,
787  'autocomplete' => 'new-password',
788  'validation-callback' => function ( $value, $alldata ) {
789  if ( empty( $alldata['mailpassword'] ) && !empty( $alldata['password'] ) ) {
790  if ( !$value ) {
791  return $this->msg( 'htmlform-required' );
792  } elseif ( $value !== $alldata['password'] ) {
793  return $this->msg( 'badretype' );
794  }
795  }
796  return true;
797  },
798  'hide-if' => [ '===', 'wpCreateaccountMail', '1' ],
799  'placeholder-message' => 'createacct-yourpasswordagain-ph',
800  ],
801  'email' => [
802  'type' => 'email',
803  'label-message' => $wgEmailConfirmToEdit ? 'createacct-emailrequired'
804  : 'createacct-emailoptional',
805  'id' => 'wpEmail',
806  'cssclass' => 'loginText',
807  'size' => '20',
808  'autocomplete' => 'email',
809  // FIXME will break non-standard providers
810  'required' => $wgEmailConfirmToEdit,
811  'validation-callback' => function ( $value, $alldata ) {
812  global $wgEmailConfirmToEdit;
813 
814  // AuthManager will check most of these, but that will make the auth
815  // session fail and this won't, so nicer to do it this way
816  if ( !$value && $wgEmailConfirmToEdit ) {
817  // no point in allowing registration without email when email is
818  // required to edit
819  return $this->msg( 'noemailtitle' );
820  } elseif ( !$value && !empty( $alldata['mailpassword'] ) ) {
821  // cannot send password via email when there is no email address
822  return $this->msg( 'noemailcreate' );
823  } elseif ( $value && !Sanitizer::validateEmail( $value ) ) {
824  return $this->msg( 'invalidemailaddress' );
825  }
826  return true;
827  },
828  'placeholder-message' => 'createacct-' . $anotherPart . 'email-ph',
829  ],
830  'realname' => [
831  'type' => 'text',
832  'help-message' => $isRegistered ? 'createacct-another-realname-tip'
833  : 'prefs-help-realname',
834  'label-message' => 'createacct-realname',
835  'cssclass' => 'loginText',
836  'size' => 20,
837  'id' => 'wpRealName',
838  'autocomplete' => 'name',
839  ],
840  'reason' => [
841  // comment for the user creation log
842  'type' => 'text',
843  'label-message' => 'createacct-reason',
844  'cssclass' => 'loginText',
845  'id' => 'wpReason',
846  'size' => '20',
847  'validation-callback' => function ( $value, $alldata ) {
848  // if the user sets an email address as the user creation reason, confirm that
849  // that was their intent
850  if ( $value && Sanitizer::validateEmail( $value ) ) {
851  if ( $this->reasonValidatorResult !== null ) {
853  }
854  $this->reasonValidatorResult = true;
855  $authManager = MediaWikiServices::getInstance()->getAuthManager();
856  if ( !$authManager->getAuthenticationSessionData( 'reason-retry', false ) ) {
857  $authManager->setAuthenticationSessionData( 'reason-retry', true );
858  $this->reasonValidatorResult = $this->msg( 'createacct-reason-confirm' );
859  }
861  }
862  return true;
863  },
864  'placeholder-message' => 'createacct-reason-ph',
865  ],
866  'createaccount' => [
867  // submit button
868  'type' => 'submit',
869  'default' => $this->msg( 'createacct-' . $anotherPart . $continuePart .
870  'submit' )->text(),
871  'name' => 'wpCreateaccount',
872  'id' => 'wpCreateaccount',
873  'weight' => 100,
874  ],
875  ];
876  } else {
877  // When the user's password is too weak, they might be asked to provide a stronger one
878  // as a followup step. That is a form with only two fields, 'password' and 'retype',
879  // and they should behave more like account creation.
880  $passwordRequest = AuthenticationRequest::getRequestByClass( $this->authRequests,
881  PasswordAuthenticationRequest::class );
882  $changePassword = $passwordRequest && $passwordRequest->action == AuthManager::ACTION_CHANGE;
883  $fieldDefinitions = [
884  'username' => (
885  [
886  'label-raw' => $this->msg( 'userlogin-yourname' )->escaped() . $secureLoginLink,
887  'id' => 'wpName1',
888  'placeholder-message' => 'userlogin-yourname-ph',
889  ] + ( $changePassword ? [
890  // There is no username field on the AuthManager level when changing
891  // passwords. Fake one because password
892  'baseField' => 'password',
893  'nodata' => true,
894  'readonly' => true,
895  'cssclass' => 'mw-htmlform-hidden-field',
896  ] : [] )
897  ),
898  'password' => (
899  $changePassword ? [
900  'autocomplete' => 'new-password',
901  'placeholder-message' => 'createacct-yourpassword-ph',
902  'help-message' => 'createacct-useuniquepass',
903  ] : [
904  'id' => 'wpPassword1',
905  'autocomplete' => 'current-password',
906  'placeholder-message' => 'userlogin-yourpassword-ph',
907  ]
908  ),
909  'retype' => [
910  'type' => 'password',
911  'autocomplete' => 'new-password',
912  'placeholder-message' => 'createacct-yourpasswordagain-ph',
913  ],
914  'domain' => [],
915  'rememberMe' => [
916  // option for saving the user token to a cookie
917  'type' => 'check',
918  'cssclass' => 'mw-userlogin-rememberme',
919  'name' => 'wpRemember',
920  'label-message' => $this->msg( 'userlogin-remembermypassword' )
921  ->numParams( $expirationDays ),
922  'id' => 'wpRemember',
923  ],
924  'loginattempt' => [
925  // submit button
926  'type' => 'submit',
927  'default' => $this->msg( 'pt-login-' . $continuePart . 'button' )->text(),
928  'id' => 'wpLoginAttempt',
929  'weight' => 100,
930  ],
931  'linkcontainer' => [
932  // help link
933  'type' => 'info',
934  'cssclass' => 'mw-form-related-link-container mw-userlogin-help',
935  // 'id' => 'mw-userlogin-help', // FIXME HTMLInfoField ignores this
936  'raw' => true,
937  'default' => Html::element( 'a', [
938  'href' => Skin::makeInternalOrExternalUrl( $this->msg( 'helplogin-url' )
939  ->inContentLanguage()
940  ->text() ),
941  ], $this->msg( 'userlogin-helplink2' )->text() ),
942  'weight' => 200,
943  ],
944  // button for ResetPasswordSecondaryAuthenticationProvider
945  'skipReset' => [
946  'weight' => 110,
947  'flags' => [],
948  ],
949  ];
950  }
951 
952  $fieldDefinitions['username'] += [
953  'type' => 'text',
954  'name' => 'wpName',
955  'cssclass' => 'loginText',
956  'size' => 20,
957  'autocomplete' => 'username',
958  // 'required' => true,
959  ];
960  $fieldDefinitions['password'] += [
961  'type' => 'password',
962  // 'label-message' => 'userlogin-yourpassword', // would override the changepassword label
963  'name' => 'wpPassword',
964  'cssclass' => 'loginPassword',
965  'size' => 20,
966  // 'required' => true,
967  ];
968 
969  if ( $this->mEntryError ) {
970  $fieldDefinitions['entryError'] = [
971  'type' => 'info',
972  'default' => Html::rawElement( 'div', [ 'class' => $this->mEntryErrorType . 'box', ],
973  $this->mEntryError ),
974  'raw' => true,
975  'rawrow' => true,
976  'weight' => -100,
977  ];
978  }
979  if ( !$this->showExtraInformation() ) {
980  unset( $fieldDefinitions['linkcontainer'], $fieldDefinitions['signupend'] );
981  }
982  if ( $this->isSignup() && $this->showExtraInformation() ) {
983  // blank signup footer for site customization
984  // uses signupend-https for HTTPS requests if it's not blank, signupend otherwise
985  $signupendMsg = $this->msg( 'signupend' );
986  $signupendHttpsMsg = $this->msg( 'signupend-https' );
987  if ( !$signupendMsg->isDisabled() ) {
988  $usingHTTPS = $this->getRequest()->getProtocol() === 'https';
989  $signupendText = ( $usingHTTPS && !$signupendHttpsMsg->isBlank() )
990  ? $signupendHttpsMsg->parse() : $signupendMsg->parse();
991  $fieldDefinitions['signupend'] = [
992  'type' => 'info',
993  'raw' => true,
994  'default' => Html::rawElement( 'div', [ 'id' => 'signupend' ], $signupendText ),
995  'weight' => 225,
996  ];
997  }
998  }
999  if ( !$this->isSignup() && $this->showExtraInformation() ) {
1000  $passwordReset = MediaWikiServices::getInstance()->getPasswordReset();
1001  if ( $passwordReset->isAllowed( $this->getUser() )->isGood() ) {
1002  $fieldDefinitions['passwordReset'] = [
1003  'type' => 'info',
1004  'raw' => true,
1005  'cssclass' => 'mw-form-related-link-container',
1006  'default' => $this->getLinkRenderer()->makeLink(
1007  SpecialPage::getTitleFor( 'PasswordReset' ),
1008  $this->msg( 'userlogin-resetpassword-link' )->text()
1009  ),
1010  'weight' => 230,
1011  ];
1012  }
1013 
1014  // Don't show a "create account" link if the user can't.
1015  if ( $this->showCreateAccountLink() ) {
1016  // link to the other action
1017  $linkTitle = $this->getTitleFor( $this->isSignup() ? 'Userlogin' : 'CreateAccount' );
1018  $linkq = $this->getReturnToQueryStringFragment();
1019  // Pass any language selection on to the mode switch link
1020  if ( $this->mLanguage ) {
1021  $linkq .= '&uselang=' . urlencode( $this->mLanguage );
1022  }
1023  $isRegistered = $this->getUser()->isRegistered();
1024 
1025  $fieldDefinitions['createOrLogin'] = [
1026  'type' => 'info',
1027  'raw' => true,
1028  'linkQuery' => $linkq,
1029  'default' => function ( $params ) use ( $isRegistered, $linkTitle ) {
1030  return Html::rawElement( 'div',
1031  [ 'id' => 'mw-createaccount' . ( !$isRegistered ? '-cta' : '' ),
1032  'class' => ( $isRegistered ? 'mw-form-related-link-container' : 'mw-ui-vform-field' ) ],
1033  ( $isRegistered ? '' : $this->msg( 'userlogin-noaccount' )->escaped() )
1034  . Html::element( 'a',
1035  [
1036  'id' => 'mw-createaccount-join' . ( $isRegistered ? '-loggedin' : '' ),
1037  'href' => $linkTitle->getLocalURL( $params['linkQuery'] ),
1038  'class' => ( $isRegistered ? '' : 'mw-ui-button' ),
1039  'tabindex' => 100,
1040  ],
1041  $this->msg(
1042  $isRegistered ? 'userlogin-createanother' : 'userlogin-joinproject'
1043  )->text()
1044  )
1045  );
1046  },
1047  'weight' => 235,
1048  ];
1049  }
1050  }
1051 
1052  return $fieldDefinitions;
1053  }
1054 
1064  protected function hasSessionCookie() {
1066 
1067  return $wgDisableCookieCheck || (
1069  $this->getRequest()->getSession()->getId() === (string)$wgInitialSessionId
1070  );
1071  }
1072 
1078  protected function getReturnToQueryStringFragment() {
1079  $returnto = '';
1080  if ( $this->mReturnTo !== '' ) {
1081  $returnto = 'returnto=' . wfUrlencode( $this->mReturnTo );
1082  if ( $this->mReturnToQuery !== '' ) {
1083  $returnto .= '&returntoquery=' . wfUrlencode( $this->mReturnToQuery );
1084  }
1085  }
1086  return $returnto;
1087  }
1088 
1094  private function showCreateAccountLink() {
1095  if ( $this->isSignup() ) {
1096  return true;
1097  } elseif ( $this->getContext()->getAuthority()->isAllowed( 'createaccount' ) ) {
1098  return true;
1099  } else {
1100  return false;
1101  }
1102  }
1103 
1104  protected function getTokenName() {
1105  return $this->isSignup() ? 'wpCreateaccountToken' : 'wpLoginToken';
1106  }
1107 
1114  protected function makeLanguageSelector() {
1115  $msg = $this->msg( 'loginlanguagelinks' )->inContentLanguage();
1116  if ( $msg->isBlank() ) {
1117  return '';
1118  }
1119  $langs = explode( "\n", $msg->text() );
1120  $links = [];
1121  foreach ( $langs as $lang ) {
1122  $lang = trim( $lang, '* ' );
1123  $parts = explode( '|', $lang );
1124  if ( count( $parts ) >= 2 ) {
1125  $links[] = $this->makeLanguageSelectorLink( $parts[0], trim( $parts[1] ) );
1126  }
1127  }
1128 
1129  return count( $links ) > 0 ? $this->msg( 'loginlanguagelabel' )->rawParams(
1130  $this->getLanguage()->pipeList( $links ) )->escaped() : '';
1131  }
1132 
1141  protected function makeLanguageSelectorLink( $text, $lang ) {
1142  if ( $this->getLanguage()->getCode() == $lang ) {
1143  // no link for currently used language
1144  return htmlspecialchars( $text );
1145  }
1146  $query = [ 'uselang' => $lang ];
1147  if ( $this->mReturnTo !== '' ) {
1148  $query['returnto'] = $this->mReturnTo;
1149  $query['returntoquery'] = $this->mReturnToQuery;
1150  }
1151 
1152  $attr = [];
1153  $targetLanguage = MediaWikiServices::getInstance()->getLanguageFactory()
1154  ->getLanguage( $lang );
1155  $attr['lang'] = $attr['hreflang'] = $targetLanguage->getHtmlCode();
1156 
1157  return $this->getLinkRenderer()->makeKnownLink(
1158  $this->getPageTitle(),
1159  $text,
1160  $attr,
1161  $query
1162  );
1163  }
1164 
1165  protected function getGroupName() {
1166  return 'login';
1167  }
1168 
1173  protected function postProcessFormDescriptor( &$formDescriptor, $requests ) {
1174  // Pre-fill username (if not creating an account, T46775).
1175  if (
1176  isset( $formDescriptor['username'] ) &&
1177  !isset( $formDescriptor['username']['default'] ) &&
1178  !$this->isSignup()
1179  ) {
1180  $user = $this->getUser();
1181  if ( $user->isRegistered() ) {
1182  $formDescriptor['username']['default'] = $user->getName();
1183  } else {
1184  $formDescriptor['username']['default'] =
1185  $this->getRequest()->getSession()->suggestLoginUsername();
1186  }
1187  }
1188 
1189  // don't show a submit button if there is nothing to submit (i.e. the only form content
1190  // is other submit buttons, for redirect flows)
1191  if ( !$this->needsSubmitButton( $requests ) ) {
1192  unset( $formDescriptor['createaccount'], $formDescriptor['loginattempt'] );
1193  }
1194 
1195  if ( !$this->isSignup() ) {
1196  // FIXME HACK don't focus on non-empty field
1197  // maybe there should be an autofocus-if similar to hide-if?
1198  if (
1199  isset( $formDescriptor['username'] )
1200  && empty( $formDescriptor['username']['default'] )
1201  && !$this->getRequest()->getCheck( 'wpName' )
1202  ) {
1203  $formDescriptor['username']['autofocus'] = true;
1204  } elseif ( isset( $formDescriptor['password'] ) ) {
1205  $formDescriptor['password']['autofocus'] = true;
1206  }
1207  }
1208 
1209  $this->addTabIndex( $formDescriptor );
1210  }
1211 }
LoginSignupSpecialPage\getTokenName
getTokenName()
Returns the name of the CSRF token (under which it should be found in the POST or GET data).
Definition: LoginSignupSpecialPage.php:1104
SpecialPage\getPageTitle
getPageTitle( $subpage=false)
Get a self-referential title object.
Definition: SpecialPage.php:743
LoginSignupSpecialPage\$mEntryErrorType
$mEntryErrorType
Definition: LoginSignupSpecialPage.php:48
LoginSignupSpecialPage\setRequest
setRequest(array $data, $wasPosted=null)
Override the POST data, GET data from the real request is preserved.
Definition: LoginSignupSpecialPage.php:93
SpecialPage\msg
msg( $key,... $params)
Wrapper around wfMessage that sets the current context.
Definition: SpecialPage.php:911
Title\newFromText
static newFromText( $text, $defaultNamespace=NS_MAIN)
Create a new Title from text, such as what one would find in a link.
Definition: Title.php:415
LoginSignupSpecialPage\postProcessFormDescriptor
postProcessFormDescriptor(&$formDescriptor, $requests)
Definition: LoginSignupSpecialPage.php:1173
StatusValue\newFatal
static newFatal( $message,... $parameters)
Factory function for fatal errors.
Definition: StatusValue.php:70
AuthManagerSpecialPage\addTabIndex
addTabIndex(&$formDescriptor)
Adds a sequential tabindex starting from 1 to all form elements.
Definition: AuthManagerSpecialPage.php:627
PROTO_HTTPS
const PROTO_HTTPS
Definition: Defines.php:193
SpecialPage\getOutput
getOutput()
Get the OutputPage being used for this instance.
Definition: SpecialPage.php:789
LoginSignupSpecialPage\$mReturnTo
$mReturnTo
Definition: LoginSignupSpecialPage.php:39
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:186
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:37
LoginSignupSpecialPage\showSuccessPage
showSuccessPage( $type, $title, $msgname, $injected_html, $extraMessages)
Show the success page.
Definition: LoginSignupSpecialPage.php:439
LoginSignupSpecialPage\$mReturnToQuery
$mReturnToQuery
Definition: LoginSignupSpecialPage.php:43
LoginSignupSpecialPage\showCreateAccountLink
showCreateAccountLink()
Whether the login/create account form should display a link to the other form (in addition to whateve...
Definition: LoginSignupSpecialPage.php:1094
LoginSignupSpecialPage\load
load( $subPage)
Load data from request.
Definition: LoginSignupSpecialPage.php:125
$wgUseMediaWikiUIEverywhere
$wgUseMediaWikiUIEverywhere
Temporary variable that applies MediaWiki UI wherever it can be supported.
Definition: DefaultSettings.php:3774
wfUrlencode
wfUrlencode( $s)
We want some things to be included as literal characters in our title URLs for prettiness,...
Definition: GlobalFunctions.php:292
SpecialPage\checkPermissions
checkPermissions()
Checks if userCanExecute, and if not throws a PermissionsError.
Definition: SpecialPage.php:357
LoginSignupSpecialPage\makeLanguageSelectorLink
makeLanguageSelectorLink( $text, $lang)
Create a language selector link for a particular language Links back to this page preserving type and...
Definition: LoginSignupSpecialPage.php:1141
LoginSignupSpecialPage\beforeExecute
beforeExecute( $subPage)
Definition: LoginSignupSpecialPage.php:206
AuthManagerSpecialPage\fieldInfoToFormDescriptor
fieldInfoToFormDescriptor(array $requests, array $fieldInfo, $action)
Turns a field info array into a form descriptor.
Definition: AuthManagerSpecialPage.php:671
Sanitizer\validateEmail
static validateEmail( $addr)
Does a string look like an e-mail address?
Definition: Sanitizer.php:1713
MediaWiki\Auth\AuthManager\beginAuthentication
beginAuthentication(array $reqs, $returnToUrl)
Start an authentication flow.
Definition: AuthManager.php:307
User\newFromName
static newFromName( $name, $validate='valid')
Definition: User.php:602
LoginSignupSpecialPage\$mStickHTTPS
$mStickHTTPS
Definition: LoginSignupSpecialPage.php:45
SpecialPage\getTitleFor
static getTitleFor( $name, $subpage=false, $fragment='')
Get a localised Title object for a specified special page name If you don't need a full Title object,...
Definition: SpecialPage.php:107
SpecialPage\getAuthority
getAuthority()
Shortcut to get the Authority executing this instance.
Definition: SpecialPage.php:809
SpecialPage\getLanguage
getLanguage()
Shortcut to get user's language.
Definition: SpecialPage.php:829
$success
$success
Definition: NoLocalSettings.php:42
MediaWiki\Auth\AuthManager\getAuthenticationSessionData
getAuthenticationSessionData( $key, $default=null)
Fetch authentication data from the current session.
Definition: AuthManager.php:2286
SpecialPage\getName
getName()
Get the name of this Special Page.
Definition: SpecialPage.php:179
AuthManagerSpecialPage
A special page subclass for authentication-related special pages.
Definition: AuthManagerSpecialPage.php:18
LoginSignupSpecialPage\setSessionUserForCurrentRequest
setSessionUserForCurrentRequest()
Replace some globals to make sure the fact that the user has just been logged in is reflected in the ...
Definition: LoginSignupSpecialPage.php:486
LoginHelper
Helper functions for the login form that need to be shared with other special pages (such as CentralA...
Definition: LoginHelper.php:10
$wgLang
$wgLang
Definition: Setup.php:807
LoginSignupSpecialPage\getReturnToQueryStringFragment
getReturnToQueryStringFragment()
Returns a string that can be appended to the URL (without encoding) to preserve the return target.
Definition: LoginSignupSpecialPage.php:1078
SpecialPage\$authManager
AuthManager null $authManager
Definition: SpecialPage.php:88
AuthManagerSpecialPage\trySubmit
trySubmit()
Attempts to do an authentication step with the submitted data.
Definition: AuthManagerSpecialPage.php:416
wfAppendQuery
wfAppendQuery( $url, $query)
Append a query string to an existing URL, which may or may not already have query string parameters a...
Definition: GlobalFunctions.php:422
MediaWiki\Auth\PasswordAuthenticationRequest
This is a value object for authentication requests with a username and password.
Definition: PasswordAuthenticationRequest.php:30
AuthManagerSpecialPage\$subPage
string $subPage
Subpage of the special page.
Definition: AuthManagerSpecialPage.php:39
LoginSignupSpecialPage\$mEntryError
$mEntryError
Definition: LoginSignupSpecialPage.php:47
DerivativeContext
An IContextSource implementation which will inherit context from another source but allow individual ...
Definition: DerivativeContext.php:33
SpecialPage\getConfig
getConfig()
Shortcut to get main config object.
Definition: SpecialPage.php:877
$wgLoginLanguageSelector
$wgLoginLanguageSelector
Show a bar of language selection links in the user login and user registration forms; edit the "login...
Definition: DefaultSettings.php:3647
MediaWiki\Logger\LoggerFactory
PSR-3 logger instance factory.
Definition: LoggerFactory.php:45
MediaWiki\Auth\AuthManager\canCreateAccounts
canCreateAccounts()
Determine whether accounts can be created.
Definition: AuthManager.php:960
Status\wrap
static wrap( $sv)
Succinct helper method to wrap a StatusValue.
Definition: Status.php:62
LoginSignupSpecialPage\logAuthResult
logAuthResult( $success, $status=null)
Logs to the authmanager-stats channel.
LoginSignupSpecialPage
Holds shared logic for login and account creation pages.
Definition: LoginSignupSpecialPage.php:38
SpecialPage\getFullTitle
getFullTitle()
Return the full title, including $par.
Definition: SpecialPage.php:887
LoginSignupSpecialPage\$proxyAccountCreation
bool $proxyAccountCreation
True if the user if creating an account for someone else.
Definition: LoginSignupSpecialPage.php:61
MediaWiki\Auth\AuthenticationResponse
This is a value object to hold authentication response data.
Definition: AuthenticationResponse.php:37
AuthManagerSpecialPage\loadAuth
loadAuth( $subPage, $authAction=null, $reset=false)
Load or initialize $authAction, $authRequests and $subPage.
Definition: AuthManagerSpecialPage.php:250
LoginSignupSpecialPage\$mPosted
$mPosted
Definition: LoginSignupSpecialPage.php:40
LoginSignupSpecialPage\mainLoginForm
mainLoginForm(array $requests, $msg='', $msgtype='error')
Definition: LoginSignupSpecialPage.php:518
MediaWiki\Auth\AuthManager\canAuthenticateNow
canAuthenticateNow()
Indicate whether user authentication is possible.
Definition: AuthManager.php:285
MediaWiki\Auth\AuthManager\setAuthenticationSessionData
setAuthenticationSessionData( $key, $data)
Store authentication in the current session.
Definition: AuthManager.php:2269
$title
$title
Definition: testCompression.php:38
SpecialPage\setHeaders
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
Definition: SpecialPage.php:617
SpecialPage\getUser
getUser()
Shortcut to get the User executing this instance.
Definition: SpecialPage.php:799
LoginSignupSpecialPage\makeLanguageSelector
makeLanguageSelector()
Produce a bar of links which allow the user to select another language during login/registration but ...
Definition: LoginSignupSpecialPage.php:1114
LoginSignupSpecialPage\hasSessionCookie
hasSessionCookie()
Check if a session cookie is present.
Definition: LoginSignupSpecialPage.php:1064
LoginSignupSpecialPage\loadRequestParameters
loadRequestParameters()
Load basic request parameters for this Special page.
Definition: LoginSignupSpecialPage.php:101
LoginSignupSpecialPage\$mFromHTTP
$mFromHTTP
Definition: LoginSignupSpecialPage.php:46
SpecialPage\getContext
getContext()
Gets the context this SpecialPage is executed in.
Definition: SpecialPage.php:763
LoginSignupSpecialPage\$mLoaded
$mLoaded
Definition: LoginSignupSpecialPage.php:50
StatusValue\newGood
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:82
LoginSignupSpecialPage\$mAction
$mAction
Definition: LoginSignupSpecialPage.php:41
MediaWiki\Session\SessionManager
This serves as the entry point to the MediaWiki session handling system.
Definition: SessionManager.php:83
LoginSignupSpecialPage\canBypassForm
canBypassForm(&$button_name)
Determine if the login form can be bypassed.
Definition: LoginSignupSpecialPage.php:403
LoginSignupSpecialPage\$mLanguage
$mLanguage
Definition: LoginSignupSpecialPage.php:42
LoginSignupSpecialPage\$mToken
$mToken
Definition: LoginSignupSpecialPage.php:44
AuthManagerSpecialPage\mergeDefaultFormDescriptor
static mergeDefaultFormDescriptor(array $fieldInfo, array $formDescriptor, array $defaultFormDescriptor)
Apply defaults to a form descriptor, without creating non-existend fields.
Definition: AuthManagerSpecialPage.php:805
wfEscapeWikiText
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
Definition: GlobalFunctions.php:1456
LoginSignupSpecialPage\$authForm
HTMLForm $authForm
Definition: LoginSignupSpecialPage.php:66
LoginSignupSpecialPage\getPageHtml
getPageHtml( $formHtml)
Add page elements which are outside the form.
Definition: LoginSignupSpecialPage.php:588
RequestContext\getMain
static getMain()
Get the RequestContext object associated with the main request.
Definition: RequestContext.php:484
AuthManagerSpecialPage\getDefaultAction
getDefaultAction( $subPage)
Get the default action for this special page, if none is given via URL/POST data.
MediaWiki\Auth\AuthManager
This serves as the entry point to the authentication system.
Definition: AuthManager.php:96
AuthManagerSpecialPage\getContinueAction
getContinueAction( $action)
Gets the _CONTINUE version of an action.
Definition: AuthManagerSpecialPage.php:298
$wgEmailConfirmToEdit
$wgEmailConfirmToEdit
Should editors be required to have a validated e-mail address before being allowed to edit?
Definition: DefaultSettings.php:5939
LoginSignupSpecialPage\isSignup
isSignup()
LoginSignupSpecialPage\__construct
__construct( $name, $restriction='')
Definition: LoginSignupSpecialPage.php:85
LoginSignupSpecialPage\$reasonValidatorResult
$reasonValidatorResult
Definition: LoginSignupSpecialPage.php:53
SpecialPage\getLinkRenderer
getLinkRenderer()
Definition: SpecialPage.php:1027
$wgDisableCookieCheck
$wgDisableCookieCheck
By default, MediaWiki checks if the client supports cookies during the login process,...
Definition: DefaultSettings.php:7182
AuthManagerSpecialPage\isActionAllowed
isActionAllowed( $action)
Checks whether AuthManager is ready to perform the action.
Definition: AuthManagerSpecialPage.php:321
LoginSignupSpecialPage\getGroupName
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
Definition: LoginSignupSpecialPage.php:1165
LoginSignupSpecialPage\showReturnToPage
showReturnToPage( $type, $returnTo='', $returnToQuery='', $stickHTTPS=false)
Add a "return to" link or redirect to it.
Definition: LoginSignupSpecialPage.php:475
$wgInitialSessionId
if(MW_ENTRY_POINT==='index') MediaWiki Session SessionId null $wgInitialSessionId
The persistent session ID (if any) loaded at startup.
Definition: Setup.php:729
AuthManagerSpecialPage\needsSubmitButton
needsSubmitButton(array $requests)
Returns true if the form built from the given AuthenticationRequests needs a submit button.
Definition: AuthManagerSpecialPage.php:589
SpecialPage\getAuthManager
getAuthManager()
Definition: SpecialPage.php:519
Html\rawElement
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:212
SpecialPage\setContext
setContext( $context)
Sets the context this SpecialPage is executed in.
Definition: SpecialPage.php:753
LoginSignupSpecialPage\getPreservedParams
getPreservedParams( $withToken=false)
Returns URL query parameters which can be used to reload the page (or leave and return) while preserv...
Definition: LoginSignupSpecialPage.php:192
AuthManagerSpecialPage\isContinued
isContinued()
Returns true if this is not the first step of the authentication.
Definition: AuthManagerSpecialPage.php:285
AuthManagerSpecialPage\getRequest
getRequest()
Get the WebRequest being used for this instance.
Definition: AuthManagerSpecialPage.php:72
LoginSignupSpecialPage\$mLoadedRequest
$mLoadedRequest
Definition: LoginSignupSpecialPage.php:51
AuthManagerSpecialPage\getToken
getToken()
Returns the CSRF token.
Definition: AuthManagerSpecialPage.php:648
LoginSignupSpecialPage\$mSecureLoginUrl
$mSecureLoginUrl
Definition: LoginSignupSpecialPage.php:52
LoginSignupSpecialPage\$targetUser
User $targetUser
FIXME another flag for passing data.
Definition: LoginSignupSpecialPage.php:63
LoginSignupSpecialPage\execute
execute( $subPage)
Definition: LoginSignupSpecialPage.php:216
Html\element
static element( $element, $attribs=[], $contents='')
Identical to rawElement(), but HTML-escapes $contents (like Xml::element()).
Definition: Html.php:234
LoginSignupSpecialPage\successfulAction
successfulAction( $direct=false, $extraMessages=null)
LoginSignupSpecialPage\$securityLevel
string $securityLevel
Definition: LoginSignupSpecialPage.php:56
LoginSignupSpecialPage\onAuthChangeFormFields
onAuthChangeFormFields(array $requests, array $fieldInfo, array &$formDescriptor, $action)
Change the form descriptor that determines how a field will look in the authentication form....
Definition: LoginSignupSpecialPage.php:705
ErrorPageError
An error page which can definitely be safely rendered using the OutputPage.
Definition: ErrorPageError.php:30
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:68
LoginHelper\getValidErrorMessages
static getValidErrorMessages()
Returns an array of all valid error messages.
Definition: LoginHelper.php:41
$wgSecureLogin
$wgSecureLogin
This is to let user authenticate using https when they come from http.
Definition: DefaultSettings.php:5782
LoginSignupSpecialPage\showExtraInformation
showExtraInformation()
Show extra information such as password recovery information, link from login to signup,...
Definition: LoginSignupSpecialPage.php:718
HTMLForm\factory
static factory( $displayFormat,... $arguments)
Construct a HTMLForm object for given display type.
Definition: HTMLForm.php:327
MediaWiki\Auth\AuthenticationRequest
This is a value object for authentication requests.
Definition: AuthenticationRequest.php:38
LoginSignupSpecialPage\getAuthForm
getAuthForm(array $requests, $action, $msg='', $msgType='error')
Generates a form from the given request.
Definition: LoginSignupSpecialPage.php:652
Skin\makeInternalOrExternalUrl
static makeInternalOrExternalUrl( $name)
If url string starts with http, consider as external URL, else internal.
Definition: Skin.php:1325
LoginSignupSpecialPage\getFieldDefinitions
getFieldDefinitions()
Create a HTMLForm descriptor for the core login fields.
Definition: LoginSignupSpecialPage.php:727
HTMLForm
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition: HTMLForm.php:144
$type
$type
Definition: testCompression.php:52