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