MediaWiki  1.29.1
LoginSignupSpecialPage.php
Go to the documentation of this file.
1 <?php
30 
37  protected $mReturnTo;
38  protected $mPosted;
39  protected $mAction;
40  protected $mLanguage;
41  protected $mReturnToQuery;
42  protected $mToken;
43  protected $mStickHTTPS;
44  protected $mFromHTTP;
45  protected $mEntryError = '';
46  protected $mEntryErrorType = 'error';
47 
48  protected $mLoaded = false;
49  protected $mLoadedRequest = false;
50  protected $mSecureLoginUrl;
51 
53  protected $securityLevel;
54 
59  protected $targetUser;
60 
62  protected $authForm;
63 
65  protected $fakeTemplate;
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 ) {
85  global $wgUseMediaWikiUIEverywhere;
86  parent::__construct( $name );
87 
88  // Override UseMediaWikiEverywhere to true, to force login and create form to use mw ui
89  $wgUseMediaWikiUIEverywhere = true;
90  }
91 
92  protected function setRequest( array $data, $wasPosted = null ) {
93  parent::setRequest( $data, $wasPosted );
94  $this->mLoadedRequest = false;
95  }
96 
101  private function loadRequestParameters( $subPage ) {
102  if ( $this->mLoadedRequest ) {
103  return;
104  }
105  $this->mLoadedRequest = true;
106  $request = $this->getRequest();
107 
108  $this->mPosted = $request->wasPosted();
109  $this->mIsReturn = $subPage === 'return';
110  $this->mAction = $request->getVal( 'action' );
111  $this->mFromHTTP = $request->getBool( 'fromhttp', false )
112  || $request->getBool( 'wpFromhttp', false );
113  $this->mStickHTTPS = ( !$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 
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 && AuthManager::singleton()->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
208  return parent::beforeExecute( $subPage );
209  }
210 
214  public function execute( $subPage ) {
215  $authManager = AuthManager::singleton();
216  $session = SessionManager::getGlobalSession();
217 
218  // Session data is used for various things in the authentication process, so we must make
219  // sure a session cookie or some equivalent mechanism is set.
220  $session->persist();
221 
222  $this->load( $subPage );
223  $this->setHeaders();
224  $this->checkPermissions();
225 
226  // Make sure the system configuration allows log in / sign up
227  if ( !$this->isSignup() && !$authManager->canAuthenticateNow() ) {
228  if ( !$session->canSetUser() ) {
229  throw new ErrorPageError( 'cannotloginnow-title', 'cannotloginnow-text', [
230  $session->getProvider()->describe( RequestContext::getMain()->getLanguage() )
231  ] );
232  }
233  throw new ErrorPageError( 'cannotlogin-title', 'cannotlogin-text' );
234  } elseif ( $this->isSignup() && !$authManager->canCreateAccounts() ) {
235  throw new ErrorPageError( 'cannotcreateaccount-title', 'cannotcreateaccount-text' );
236  }
237 
238  /*
239  * In the case where the user is already logged in, and was redirected to
240  * the login form from a page that requires login, do not show the login
241  * page. The use case scenario for this is when a user opens a large number
242  * of tabs, is redirected to the login page on all of them, and then logs
243  * in on one, expecting all the others to work properly.
244  *
245  * However, do show the form if it was visited intentionally (no 'returnto'
246  * is present). People who often switch between several accounts have grown
247  * accustomed to this behavior.
248  *
249  * Also make an exception when force=<level> is set in the URL, which means the user must
250  * reauthenticate for security reasons.
251  */
252  if ( !$this->isSignup() && !$this->mPosted && !$this->securityLevel &&
253  ( $this->mReturnTo !== '' || $this->mReturnToQuery !== '' ) &&
254  $this->getUser()->isLoggedIn()
255  ) {
256  $this->successfulAction();
257  }
258 
259  // If logging in and not on HTTPS, either redirect to it or offer a link.
260  global $wgSecureLogin;
261  if ( $this->getRequest()->getProtocol() !== 'https' ) {
262  $title = $this->getFullTitle();
263  $query = $this->getPreservedParams( false ) + [
264  'title' => null,
265  ( $this->mEntryErrorType === 'error' ? 'error'
266  : 'warning' ) => $this->mEntryError,
267  ] + $this->getRequest()->getQueryValues();
268  $url = $title->getFullURL( $query, false, PROTO_HTTPS );
269  if ( $wgSecureLogin && !$this->mFromHTTP &&
270  wfCanIPUseHTTPS( $this->getRequest()->getIP() )
271  ) {
272  // Avoid infinite redirect
273  $url = wfAppendQuery( $url, 'fromhttp=1' );
274  $this->getOutput()->redirect( $url );
275  // Since we only do this redir to change proto, always vary
276  $this->getOutput()->addVaryHeader( 'X-Forwarded-Proto' );
277 
278  return;
279  } else {
280  // A wiki without HTTPS login support should set $wgServer to
281  // http://somehost, in which case the secure URL generated
282  // above won't actually start with https://
283  if ( substr( $url, 0, 8 ) === 'https://' ) {
284  $this->mSecureLoginUrl = $url;
285  }
286  }
287  }
288 
289  if ( !$this->isActionAllowed( $this->authAction ) ) {
290  // FIXME how do we explain this to the user? can we handle session loss better?
291  // messages used: authpage-cannot-login, authpage-cannot-login-continue,
292  // authpage-cannot-create, authpage-cannot-create-continue
293  $this->mainLoginForm( [], 'authpage-cannot-' . $this->authAction );
294  return;
295  }
296 
297  if ( $this->canBypassForm( $button_name ) ) {
298  $this->setRequest( [], true );
299  $this->getRequest()->setVal( $this->getTokenName(), $this->getToken() );
300  if ( $button_name ) {
301  $this->getRequest()->setVal( $button_name, true );
302  }
303  }
304 
305  $status = $this->trySubmit();
306 
307  if ( !$status || !$status->isGood() ) {
308  $this->mainLoginForm( $this->authRequests, $status ? $status->getMessage() : '', 'error' );
309  return;
310  }
311 
313  $response = $status->getValue();
314 
315  $returnToUrl = $this->getPageTitle( 'return' )
316  ->getFullURL( $this->getPreservedParams( true ), false, PROTO_HTTPS );
317  switch ( $response->status ) {
318  case AuthenticationResponse::PASS:
319  $this->logAuthResult( true );
320  $this->proxyAccountCreation = $this->isSignup() && !$this->getUser()->isAnon();
321  $this->targetUser = User::newFromName( $response->username );
322 
323  if (
324  !$this->proxyAccountCreation
325  && $response->loginRequest
326  && $authManager->canAuthenticateNow()
327  ) {
328  // successful registration; log the user in instantly
329  $response2 = $authManager->beginAuthentication( [ $response->loginRequest ],
330  $returnToUrl );
331  if ( $response2->status !== AuthenticationResponse::PASS ) {
332  LoggerFactory::getInstance( 'login' )
333  ->error( 'Could not log in after account creation' );
334  $this->successfulAction( true, Status::newFatal( 'createacct-loginerror' ) );
335  break;
336  }
337  }
338 
339  if ( !$this->proxyAccountCreation ) {
340  // Ensure that the context user is the same as the session user.
342  }
343 
344  $this->successfulAction( true );
345  break;
346  case AuthenticationResponse::FAIL:
347  // fall through
348  case AuthenticationResponse::RESTART:
349  unset( $this->authForm );
350  if ( $response->status === AuthenticationResponse::FAIL ) {
351  $action = $this->getDefaultAction( $subPage );
352  $messageType = 'error';
353  } else {
354  $action = $this->getContinueAction( $this->authAction );
355  $messageType = 'warning';
356  }
357  $this->logAuthResult( false, $response->message ? $response->message->getKey() : '-' );
358  $this->loadAuth( $subPage, $action, true );
359  $this->mainLoginForm( $this->authRequests, $response->message, $messageType );
360  break;
361  case AuthenticationResponse::REDIRECT:
362  unset( $this->authForm );
363  $this->getOutput()->redirect( $response->redirectTarget );
364  break;
365  case AuthenticationResponse::UI:
366  unset( $this->authForm );
367  $this->authAction = $this->isSignup() ? AuthManager::ACTION_CREATE_CONTINUE
368  : AuthManager::ACTION_LOGIN_CONTINUE;
369  $this->authRequests = $response->neededRequests;
370  $this->mainLoginForm( $response->neededRequests, $response->message, $response->messageType );
371  break;
372  default:
373  throw new LogicException( 'invalid AuthenticationResponse' );
374  }
375  }
376 
390  private function canBypassForm( &$button_name ) {
391  $button_name = null;
392  if ( $this->isContinued() ) {
393  return false;
394  }
395  $fields = AuthenticationRequest::mergeFieldInfo( $this->authRequests );
396  foreach ( $fields as $fieldname => $field ) {
397  if ( !isset( $field['type'] ) ) {
398  return false;
399  }
400  if ( !empty( $field['skippable'] ) ) {
401  continue;
402  }
403  if ( $field['type'] === 'button' ) {
404  if ( $button_name !== null ) {
405  $button_name = null;
406  return false;
407  } else {
408  $button_name = $fieldname;
409  }
410  } elseif ( $field['type'] !== 'null' ) {
411  return false;
412  }
413  }
414  return true;
415  }
416 
426  protected function showSuccessPage(
427  $type, $title, $msgname, $injected_html, $extraMessages
428  ) {
429  $out = $this->getOutput();
430  $out->setPageTitle( $title );
431  if ( $msgname ) {
432  $out->addWikiMsg( $msgname, wfEscapeWikiText( $this->getUser()->getName() ) );
433  }
434  if ( $extraMessages ) {
435  $extraMessages = Status::wrap( $extraMessages );
436  $out->addWikiText( $extraMessages->getWikiText() );
437  }
438 
439  $out->addHTML( $injected_html );
440 
441  $helper = new LoginHelper( $this->getContext() );
442  $helper->showReturnToPage( $type, $this->mReturnTo, $this->mReturnToQuery, $this->mStickHTTPS );
443  }
444 
460  public function showReturnToPage(
461  $type, $returnTo = '', $returnToQuery = '', $stickHTTPS = false
462  ) {
463  $helper = new LoginHelper( $this->getContext() );
464  $helper->showReturnToPage( $type, $returnTo, $returnToQuery, $stickHTTPS );
465  }
466 
472  protected function setSessionUserForCurrentRequest() {
474 
476  $localContext = $this->getContext();
477  if ( $context !== $localContext ) {
478  // remove AuthManagerSpecialPage context hack
479  $this->setContext( $context );
480  }
481 
482  $user = $context->getRequest()->getSession()->getUser();
483 
484  $wgUser = $user;
485  $context->setUser( $user );
486 
487  $code = $this->getRequest()->getVal( 'uselang', $user->getOption( 'language' ) );
488  $userLang = Language::factory( $code );
489  $wgLang = $userLang;
490  $context->setLanguage( $userLang );
491  }
492 
507  protected function mainLoginForm( array $requests, $msg = '', $msgtype = 'error' ) {
508  $titleObj = $this->getPageTitle();
509  $user = $this->getUser();
510  $out = $this->getOutput();
511 
512  // FIXME how to handle empty $requests - restart, or no form, just an error message?
513  // no form would be better for no session type errors, restart is better when can* fails.
514  if ( !$requests ) {
515  $this->authAction = $this->getDefaultAction( $this->subPage );
516  $this->authForm = null;
517  $requests = AuthManager::singleton()->getAuthenticationRequests( $this->authAction, $user );
518  }
519 
520  // Generic styles and scripts for both login and signup form
521  $out->addModuleStyles( [
522  'mediawiki.ui',
523  'mediawiki.ui.button',
524  'mediawiki.ui.checkbox',
525  'mediawiki.ui.input',
526  'mediawiki.special.userlogin.common.styles'
527  ] );
528  if ( $this->isSignup() ) {
529  // XXX hack pending RL or JS parse() support for complex content messages T27349
530  $out->addJsConfigVars( 'wgCreateacctImgcaptchaHelp',
531  $this->msg( 'createacct-imgcaptcha-help' )->parse() );
532 
533  // Additional styles and scripts for signup form
534  $out->addModules( [
535  'mediawiki.special.userlogin.signup.js'
536  ] );
537  $out->addModuleStyles( [
538  'mediawiki.special.userlogin.signup.styles'
539  ] );
540  } else {
541  // Additional styles for login form
542  $out->addModuleStyles( [
543  'mediawiki.special.userlogin.login.styles'
544  ] );
545  }
546  $out->disallowUserJs(); // just in case...
547 
548  $form = $this->getAuthForm( $requests, $this->authAction, $msg, $msgtype );
549  $form->prepareForm();
550 
551  $submitStatus = Status::newGood();
552  if ( $msg && $msgtype === 'warning' ) {
553  $submitStatus->warning( $msg );
554  } elseif ( $msg && $msgtype === 'error' ) {
555  $submitStatus->fatal( $msg );
556  }
557 
558  // warning header for non-standard workflows (e.g. security reauthentication)
559  if (
560  !$this->isSignup() &&
561  $this->getUser()->isLoggedIn() &&
562  $this->authAction !== AuthManager::ACTION_LOGIN_CONTINUE
563  ) {
564  $reauthMessage = $this->securityLevel ? 'userlogin-reauth' : 'userlogin-loggedin';
565  $submitStatus->warning( $reauthMessage, $this->getUser()->getName() );
566  }
567 
568  $formHtml = $form->getHTML( $submitStatus );
569 
570  $out->addHTML( $this->getPageHtml( $formHtml ) );
571  }
572 
579  protected function getPageHtml( $formHtml ) {
580  global $wgLoginLanguageSelector;
581 
582  $loginPrompt = $this->isSignup() ? '' : Html::rawElement( 'div',
583  [ 'id' => 'userloginprompt' ], $this->msg( 'loginprompt' )->parseAsBlock() );
584  $languageLinks = $wgLoginLanguageSelector ? $this->makeLanguageSelector() : '';
585  $signupStartMsg = $this->msg( 'signupstart' );
586  $signupStart = ( $this->isSignup() && !$signupStartMsg->isDisabled() )
587  ? Html::rawElement( 'div', [ 'id' => 'signupstart' ], $signupStartMsg->parseAsBlock() ) : '';
588  if ( $languageLinks ) {
589  $languageLinks = Html::rawElement( 'div', [ 'id' => 'languagelinks' ],
590  Html::rawElement( 'p', [], $languageLinks )
591  );
592  }
593 
594  $benefitsContainer = '';
595  if ( $this->isSignup() && $this->showExtraInformation() ) {
596  // messages used:
597  // createacct-benefit-icon1 createacct-benefit-head1 createacct-benefit-body1
598  // createacct-benefit-icon2 createacct-benefit-head2 createacct-benefit-body2
599  // createacct-benefit-icon3 createacct-benefit-head3 createacct-benefit-body3
600  $benefitCount = 3;
601  $benefitList = '';
602  for ( $benefitIdx = 1; $benefitIdx <= $benefitCount; $benefitIdx++ ) {
603  $headUnescaped = $this->msg( "createacct-benefit-head$benefitIdx" )->text();
604  $iconClass = $this->msg( "createacct-benefit-icon$benefitIdx" )->escaped();
605  $benefitList .= Html::rawElement( 'div', [ 'class' => "mw-number-text $iconClass" ],
606  Html::rawElement( 'h3', [],
607  $this->msg( "createacct-benefit-head$benefitIdx" )->escaped()
608  )
609  . Html::rawElement( 'p', [],
610  $this->msg( "createacct-benefit-body$benefitIdx" )->params( $headUnescaped )->escaped()
611  )
612  );
613  }
614  $benefitsContainer = Html::rawElement( 'div', [ 'class' => 'mw-createacct-benefits-container' ],
615  Html::rawElement( 'h2', [], $this->msg( 'createacct-benefit-heading' )->escaped() )
616  . Html::rawElement( 'div', [ 'class' => 'mw-createacct-benefits-list' ],
617  $benefitList
618  )
619  );
620  }
621 
622  $html = Html::rawElement( 'div', [ 'class' => 'mw-ui-container' ],
623  $loginPrompt
624  . $languageLinks
625  . $signupStart
626  . Html::rawElement( 'div', [ 'id' => 'userloginForm' ],
627  $formHtml
628  )
629  . $benefitsContainer
630  );
631 
632  return $html;
633  }
634 
643  protected function getAuthForm( array $requests, $action, $msg = '', $msgType = 'error' ) {
644  global $wgSecureLogin;
645  // FIXME merge this with parent
646 
647  if ( isset( $this->authForm ) ) {
648  return $this->authForm;
649  }
650 
651  $usingHTTPS = $this->getRequest()->getProtocol() === 'https';
652 
653  // get basic form description from the auth logic
654  $fieldInfo = AuthenticationRequest::mergeFieldInfo( $requests );
655  $fakeTemplate = $this->getFakeTemplate( $msg, $msgType );
656  $this->fakeTemplate = $fakeTemplate; // FIXME there should be a saner way to pass this to the hook
657  // this will call onAuthChangeFormFields()
658  $formDescriptor = static::fieldInfoToFormDescriptor( $requests, $fieldInfo, $this->authAction );
659  $this->postProcessFormDescriptor( $formDescriptor, $requests );
660 
661  $context = $this->getContext();
662  if ( $context->getRequest() !== $this->getRequest() ) {
663  // We have overridden the request, need to make sure the form uses that too.
664  $context = new DerivativeContext( $this->getContext() );
665  $context->setRequest( $this->getRequest() );
666  }
667  $form = HTMLForm::factory( 'vform', $formDescriptor, $context );
668 
669  $form->addHiddenField( 'authAction', $this->authAction );
670  if ( $this->mLanguage ) {
671  $form->addHiddenField( 'uselang', $this->mLanguage );
672  }
673  $form->addHiddenField( 'force', $this->securityLevel );
674  $form->addHiddenField( $this->getTokenName(), $this->getToken()->toString() );
675  if ( $wgSecureLogin ) {
676  // If using HTTPS coming from HTTP, then the 'fromhttp' parameter must be preserved
677  if ( !$this->isSignup() ) {
678  $form->addHiddenField( 'wpForceHttps', (int)$this->mStickHTTPS );
679  $form->addHiddenField( 'wpFromhttp', $usingHTTPS );
680  }
681  }
682 
683  // set properties of the form itself
684  $form->setAction( $this->getPageTitle()->getLocalURL( $this->getReturnToQueryStringFragment() ) );
685  $form->setName( 'userlogin' . ( $this->isSignup() ? '2' : '' ) );
686  if ( $this->isSignup() ) {
687  $form->setId( 'userlogin2' );
688  }
689 
690  $form->suppressDefaultSubmit();
691 
692  $this->authForm = $form;
693 
694  return $form;
695  }
696 
703  protected function getFakeTemplate( $msg, $msgType ) {
704  global $wgAuth, $wgEnableEmail, $wgHiddenPrefs, $wgEmailConfirmToEdit, $wgEnableUserEmail,
705  $wgSecureLogin, $wgPasswordResetRoutes;
706 
707  // make a best effort to get the value of fields which used to be fixed in the old login
708  // template but now might or might not exist depending on what providers are used
709  $request = $this->getRequest();
710  $data = (object)[
711  'mUsername' => $request->getText( 'wpName' ),
712  'mPassword' => $request->getText( 'wpPassword' ),
713  'mRetype' => $request->getText( 'wpRetype' ),
714  'mEmail' => $request->getText( 'wpEmail' ),
715  'mRealName' => $request->getText( 'wpRealName' ),
716  'mDomain' => $request->getText( 'wpDomain' ),
717  'mReason' => $request->getText( 'wpReason' ),
718  'mRemember' => $request->getCheck( 'wpRemember' ),
719  ];
720 
721  // Preserves a bunch of logic from the old code that was rewritten in getAuthForm().
722  // There is no code reuse to make this easier to remove .
723  // If an extension tries to change any of these values, they are out of luck - we only
724  // actually use the domain/usedomain/domainnames, extraInput and extrafields keys.
725 
726  $titleObj = $this->getPageTitle();
727  $user = $this->getUser();
728  $template = new FakeAuthTemplate();
729 
730  // Pre-fill username (if not creating an account, T46775).
731  if ( $data->mUsername == '' && $this->isSignup() ) {
732  if ( $user->isLoggedIn() ) {
733  $data->mUsername = $user->getName();
734  } else {
735  $data->mUsername = $this->getRequest()->getSession()->suggestLoginUsername();
736  }
737  }
738 
739  if ( $this->isSignup() ) {
740  // Must match number of benefits defined in messages
741  $template->set( 'benefitCount', 3 );
742 
743  $q = 'action=submitlogin&type=signup';
744  $linkq = 'type=login';
745  } else {
746  $q = 'action=submitlogin&type=login';
747  $linkq = 'type=signup';
748  }
749 
750  if ( $this->mReturnTo !== '' ) {
751  $returnto = '&returnto=' . wfUrlencode( $this->mReturnTo );
752  if ( $this->mReturnToQuery !== '' ) {
753  $returnto .= '&returntoquery=' .
754  wfUrlencode( $this->mReturnToQuery );
755  }
756  $q .= $returnto;
757  $linkq .= $returnto;
758  }
759 
760  # Don't show a "create account" link if the user can't.
761  if ( $this->showCreateAccountLink() ) {
762  # Pass any language selection on to the mode switch link
763  if ( $this->mLanguage ) {
764  $linkq .= '&uselang=' . $this->mLanguage;
765  }
766  // Supply URL, login template creates the button.
767  $template->set( 'createOrLoginHref', $titleObj->getLocalURL( $linkq ) );
768  } else {
769  $template->set( 'link', '' );
770  }
771 
772  $resetLink = $this->isSignup()
773  ? null
774  : is_array( $wgPasswordResetRoutes )
775  && in_array( true, array_values( $wgPasswordResetRoutes ), true );
776 
777  $template->set( 'header', '' );
778  $template->set( 'formheader', '' );
779  $template->set( 'skin', $this->getSkin() );
780 
781  $template->set( 'name', $data->mUsername );
782  $template->set( 'password', $data->mPassword );
783  $template->set( 'retype', $data->mRetype );
784  $template->set( 'createemailset', false ); // no easy way to get that from AuthManager
785  $template->set( 'email', $data->mEmail );
786  $template->set( 'realname', $data->mRealName );
787  $template->set( 'domain', $data->mDomain );
788  $template->set( 'reason', $data->mReason );
789  $template->set( 'remember', $data->mRemember );
790 
791  $template->set( 'action', $titleObj->getLocalURL( $q ) );
792  $template->set( 'message', $msg );
793  $template->set( 'messagetype', $msgType );
794  $template->set( 'createemail', $wgEnableEmail && $user->isLoggedIn() );
795  $template->set( 'userealname', !in_array( 'realname', $wgHiddenPrefs, true ) );
796  $template->set( 'useemail', $wgEnableEmail );
797  $template->set( 'emailrequired', $wgEmailConfirmToEdit );
798  $template->set( 'emailothers', $wgEnableUserEmail );
799  $template->set( 'canreset', $wgAuth->allowPasswordChange() );
800  $template->set( 'resetlink', $resetLink );
801  $template->set( 'canremember', $request->getSession()->getProvider()
802  ->getRememberUserDuration() !== null );
803  $template->set( 'usereason', $user->isLoggedIn() );
804  $template->set( 'cansecurelogin', ( $wgSecureLogin ) );
805  $template->set( 'stickhttps', (int)$this->mStickHTTPS );
806  $template->set( 'loggedin', $user->isLoggedIn() );
807  $template->set( 'loggedinuser', $user->getName() );
808  $template->set( 'token', $this->getToken()->toString() );
809 
810  $action = $this->isSignup() ? 'signup' : 'login';
811  $wgAuth->modifyUITemplate( $template, $action );
812 
813  $oldTemplate = $template;
814 
815  // Both Hooks::run are explicit here to make findHooks.php happy
816  if ( $this->isSignup() ) {
817  Hooks::run( 'UserCreateForm', [ &$template ] );
818  if ( $oldTemplate !== $template ) {
819  wfDeprecated( "reference in UserCreateForm hook", '1.27' );
820  }
821  } else {
822  Hooks::run( 'UserLoginForm', [ &$template ] );
823  if ( $oldTemplate !== $template ) {
824  wfDeprecated( "reference in UserLoginForm hook", '1.27' );
825  }
826  }
827 
828  return $template;
829  }
830 
831  public function onAuthChangeFormFields(
832  array $requests, array $fieldInfo, array &$formDescriptor, $action
833  ) {
834  $coreFieldDescriptors = $this->getFieldDefinitions( $this->fakeTemplate );
835  $specialFields = array_merge( [ 'extraInput' ],
836  array_keys( $this->fakeTemplate->getExtraInputDefinitions() ) );
837 
838  // keep the ordering from getCoreFieldDescriptors() where there is no explicit weight
839  foreach ( $coreFieldDescriptors as $fieldName => $coreField ) {
840  $requestField = isset( $formDescriptor[$fieldName] ) ?
841  $formDescriptor[$fieldName] : [];
842 
843  // remove everything that is not in the fieldinfo, is not marked as a supplemental field
844  // to something in the fieldinfo, is not B/C for the pre-AuthManager templates,
845  // and is not an info field or a submit button
846  if (
847  !isset( $fieldInfo[$fieldName] )
848  && (
849  !isset( $coreField['baseField'] )
850  || !isset( $fieldInfo[$coreField['baseField']] )
851  )
852  && !in_array( $fieldName, $specialFields, true )
853  && (
854  !isset( $coreField['type'] )
855  || !in_array( $coreField['type'], [ 'submit', 'info' ], true )
856  )
857  ) {
858  $coreFieldDescriptors[$fieldName] = null;
859  continue;
860  }
861 
862  // core message labels should always take priority
863  if (
864  isset( $coreField['label'] )
865  || isset( $coreField['label-message'] )
866  || isset( $coreField['label-raw'] )
867  ) {
868  unset( $requestField['label'], $requestField['label-message'], $coreField['label-raw'] );
869  }
870 
871  $coreFieldDescriptors[$fieldName] += $requestField;
872  }
873 
874  $formDescriptor = array_filter( $coreFieldDescriptors + $formDescriptor );
875  return true;
876  }
877 
884  protected function showExtraInformation() {
885  return $this->authAction !== $this->getContinueAction( $this->authAction )
887  }
888 
894  protected function getFieldDefinitions( $template ) {
895  global $wgEmailConfirmToEdit;
896 
897  $isLoggedIn = $this->getUser()->isLoggedIn();
898  $continuePart = $this->isContinued() ? 'continue-' : '';
899  $anotherPart = $isLoggedIn ? 'another-' : '';
900  $expiration = $this->getRequest()->getSession()->getProvider()->getRememberUserDuration();
901  $expirationDays = ceil( $expiration / ( 3600 * 24 ) );
902  $secureLoginLink = '';
903  if ( $this->mSecureLoginUrl ) {
904  $secureLoginLink = Html::element( 'a', [
905  'href' => $this->mSecureLoginUrl,
906  'class' => 'mw-ui-flush-right mw-secure',
907  ], $this->msg( 'userlogin-signwithsecure' )->text() );
908  }
909  $usernameHelpLink = '';
910  if ( !$this->msg( 'createacct-helpusername' )->isDisabled() ) {
911  $usernameHelpLink = Html::rawElement( 'span', [
912  'class' => 'mw-ui-flush-right',
913  ], $this->msg( 'createacct-helpusername' )->parse() );
914  }
915 
916  if ( $this->isSignup() ) {
917  $fieldDefinitions = [
918  'statusarea' => [
919  // used by the mediawiki.special.userlogin.signup.js module for error display
920  // FIXME merge this with HTMLForm's normal status (error) area
921  'type' => 'info',
922  'raw' => true,
923  'default' => Html::element( 'div', [ 'id' => 'mw-createacct-status-area' ] ),
924  'weight' => -105,
925  ],
926  'username' => [
927  'label-raw' => $this->msg( 'userlogin-yourname' )->escaped() . $usernameHelpLink,
928  'id' => 'wpName2',
929  'placeholder-message' => $isLoggedIn ? 'createacct-another-username-ph'
930  : 'userlogin-yourname-ph',
931  ],
932  'mailpassword' => [
933  // create account without providing password, a temporary one will be mailed
934  'type' => 'check',
935  'label-message' => 'createaccountmail',
936  'name' => 'wpCreateaccountMail',
937  'id' => 'wpCreateaccountMail',
938  ],
939  'password' => [
940  'id' => 'wpPassword2',
941  'placeholder-message' => 'createacct-yourpassword-ph',
942  'hide-if' => [ '===', 'wpCreateaccountMail', '1' ],
943  ],
944  'domain' => [],
945  'retype' => [
946  'baseField' => 'password',
947  'type' => 'password',
948  'label-message' => 'createacct-yourpasswordagain',
949  'id' => 'wpRetype',
950  'cssclass' => 'loginPassword',
951  'size' => 20,
952  'validation-callback' => function ( $value, $alldata ) {
953  if ( empty( $alldata['mailpassword'] ) && !empty( $alldata['password'] ) ) {
954  if ( !$value ) {
955  return $this->msg( 'htmlform-required' );
956  } elseif ( $value !== $alldata['password'] ) {
957  return $this->msg( 'badretype' );
958  }
959  }
960  return true;
961  },
962  'hide-if' => [ '===', 'wpCreateaccountMail', '1' ],
963  'placeholder-message' => 'createacct-yourpasswordagain-ph',
964  ],
965  'email' => [
966  'type' => 'email',
967  'label-message' => $wgEmailConfirmToEdit ? 'createacct-emailrequired'
968  : 'createacct-emailoptional',
969  'id' => 'wpEmail',
970  'cssclass' => 'loginText',
971  'size' => '20',
972  // FIXME will break non-standard providers
973  'required' => $wgEmailConfirmToEdit,
974  'validation-callback' => function ( $value, $alldata ) {
975  global $wgEmailConfirmToEdit;
976 
977  // AuthManager will check most of these, but that will make the auth
978  // session fail and this won't, so nicer to do it this way
979  if ( !$value && $wgEmailConfirmToEdit ) {
980  // no point in allowing registration without email when email is
981  // required to edit
982  return $this->msg( 'noemailtitle' );
983  } elseif ( !$value && !empty( $alldata['mailpassword'] ) ) {
984  // cannot send password via email when there is no email address
985  return $this->msg( 'noemailcreate' );
986  } elseif ( $value && !Sanitizer::validateEmail( $value ) ) {
987  return $this->msg( 'invalidemailaddress' );
988  }
989  return true;
990  },
991  'placeholder-message' => 'createacct-' . $anotherPart . 'email-ph',
992  ],
993  'realname' => [
994  'type' => 'text',
995  'help-message' => $isLoggedIn ? 'createacct-another-realname-tip'
996  : 'prefs-help-realname',
997  'label-message' => 'createacct-realname',
998  'cssclass' => 'loginText',
999  'size' => 20,
1000  'id' => 'wpRealName',
1001  ],
1002  'reason' => [
1003  // comment for the user creation log
1004  'type' => 'text',
1005  'label-message' => 'createacct-reason',
1006  'cssclass' => 'loginText',
1007  'id' => 'wpReason',
1008  'size' => '20',
1009  'placeholder-message' => 'createacct-reason-ph',
1010  ],
1011  'extrainput' => [], // placeholder for fields coming from the template
1012  'createaccount' => [
1013  // submit button
1014  'type' => 'submit',
1015  'default' => $this->msg( 'createacct-' . $anotherPart . $continuePart .
1016  'submit' )->text(),
1017  'name' => 'wpCreateaccount',
1018  'id' => 'wpCreateaccount',
1019  'weight' => 100,
1020  ],
1021  ];
1022  } else {
1023  $fieldDefinitions = [
1024  'username' => [
1025  'label-raw' => $this->msg( 'userlogin-yourname' )->escaped() . $secureLoginLink,
1026  'id' => 'wpName1',
1027  'placeholder-message' => 'userlogin-yourname-ph',
1028  ],
1029  'password' => [
1030  'id' => 'wpPassword1',
1031  'placeholder-message' => 'userlogin-yourpassword-ph',
1032  ],
1033  'domain' => [],
1034  'extrainput' => [],
1035  'rememberMe' => [
1036  // option for saving the user token to a cookie
1037  'type' => 'check',
1038  'name' => 'wpRemember',
1039  'label-message' => $this->msg( 'userlogin-remembermypassword' )
1040  ->numParams( $expirationDays ),
1041  'id' => 'wpRemember',
1042  ],
1043  'loginattempt' => [
1044  // submit button
1045  'type' => 'submit',
1046  'default' => $this->msg( 'pt-login-' . $continuePart . 'button' )->text(),
1047  'id' => 'wpLoginAttempt',
1048  'weight' => 100,
1049  ],
1050  'linkcontainer' => [
1051  // help link
1052  'type' => 'info',
1053  'cssclass' => 'mw-form-related-link-container mw-userlogin-help',
1054  // 'id' => 'mw-userlogin-help', // FIXME HTMLInfoField ignores this
1055  'raw' => true,
1056  'default' => Html::element( 'a', [
1057  'href' => Skin::makeInternalOrExternalUrl( wfMessage( 'helplogin-url' )
1058  ->inContentLanguage()
1059  ->text() ),
1060  ], $this->msg( 'userlogin-helplink2' )->text() ),
1061  'weight' => 200,
1062  ],
1063  // button for ResetPasswordSecondaryAuthenticationProvider
1064  'skipReset' => [
1065  'weight' => 110,
1066  'flags' => [],
1067  ],
1068  ];
1069  }
1070 
1071  $fieldDefinitions['username'] += [
1072  'type' => 'text',
1073  'name' => 'wpName',
1074  'cssclass' => 'loginText',
1075  'size' => 20,
1076  // 'required' => true,
1077  ];
1078  $fieldDefinitions['password'] += [
1079  'type' => 'password',
1080  // 'label-message' => 'userlogin-yourpassword', // would override the changepassword label
1081  'name' => 'wpPassword',
1082  'cssclass' => 'loginPassword',
1083  'size' => 20,
1084  // 'required' => true,
1085  ];
1086 
1087  if ( $template->get( 'header' ) || $template->get( 'formheader' ) ) {
1088  // B/C for old extensions that haven't been converted to AuthManager (or have been
1089  // but somebody is using the old version) and still use templates via the
1090  // UserCreateForm/UserLoginForm hook.
1091  // 'header' used by ConfirmEdit, ConfirmAccount, Persona, WikimediaIncubator, SemanticSignup
1092  // 'formheader' used by MobileFrontend
1093  $fieldDefinitions['header'] = [
1094  'type' => 'info',
1095  'raw' => true,
1096  'default' => $template->get( 'header' ) ?: $template->get( 'formheader' ),
1097  'weight' => -110,
1098  ];
1099  }
1100  if ( $this->mEntryError ) {
1101  $fieldDefinitions['entryError'] = [
1102  'type' => 'info',
1103  'default' => Html::rawElement( 'div', [ 'class' => $this->mEntryErrorType . 'box', ],
1104  $this->mEntryError ),
1105  'raw' => true,
1106  'rawrow' => true,
1107  'weight' => -100,
1108  ];
1109  }
1110  if ( !$this->showExtraInformation() ) {
1111  unset( $fieldDefinitions['linkcontainer'], $fieldDefinitions['signupend'] );
1112  }
1113  if ( $this->isSignup() && $this->showExtraInformation() ) {
1114  // blank signup footer for site customization
1115  // uses signupend-https for HTTPS requests if it's not blank, signupend otherwise
1116  $signupendMsg = $this->msg( 'signupend' );
1117  $signupendHttpsMsg = $this->msg( 'signupend-https' );
1118  if ( !$signupendMsg->isDisabled() ) {
1119  $usingHTTPS = $this->getRequest()->getProtocol() === 'https';
1120  $signupendText = ( $usingHTTPS && !$signupendHttpsMsg->isBlank() )
1121  ? $signupendHttpsMsg ->parse() : $signupendMsg->parse();
1122  $fieldDefinitions['signupend'] = [
1123  'type' => 'info',
1124  'raw' => true,
1125  'default' => Html::rawElement( 'div', [ 'id' => 'signupend' ], $signupendText ),
1126  'weight' => 225,
1127  ];
1128  }
1129  }
1130  if ( !$this->isSignup() && $this->showExtraInformation() ) {
1131  $passwordReset = new PasswordReset( $this->getConfig(), AuthManager::singleton() );
1132  if ( $passwordReset->isAllowed( $this->getUser() )->isGood() ) {
1133  $fieldDefinitions['passwordReset'] = [
1134  'type' => 'info',
1135  'raw' => true,
1136  'cssclass' => 'mw-form-related-link-container',
1137  'default' => $this->getLinkRenderer()->makeLink(
1138  SpecialPage::getTitleFor( 'PasswordReset' ),
1139  $this->msg( 'userlogin-resetpassword-link' )->text()
1140  ),
1141  'weight' => 230,
1142  ];
1143  }
1144 
1145  // Don't show a "create account" link if the user can't.
1146  if ( $this->showCreateAccountLink() ) {
1147  // link to the other action
1148  $linkTitle = $this->getTitleFor( $this->isSignup() ? 'Userlogin' :'CreateAccount' );
1149  $linkq = $this->getReturnToQueryStringFragment();
1150  // Pass any language selection on to the mode switch link
1151  if ( $this->mLanguage ) {
1152  $linkq .= '&uselang=' . $this->mLanguage;
1153  }
1154  $loggedIn = $this->getUser()->isLoggedIn();
1155 
1156  $fieldDefinitions['createOrLogin'] = [
1157  'type' => 'info',
1158  'raw' => true,
1159  'linkQuery' => $linkq,
1160  'default' => function ( $params ) use ( $loggedIn, $linkTitle ) {
1161  return Html::rawElement( 'div',
1162  [ 'id' => 'mw-createaccount' . ( !$loggedIn ? '-cta' : '' ),
1163  'class' => ( $loggedIn ? 'mw-form-related-link-container' : 'mw-ui-vform-field' ) ],
1164  ( $loggedIn ? '' : $this->msg( 'userlogin-noaccount' )->escaped() )
1165  . Html::element( 'a',
1166  [
1167  'id' => 'mw-createaccount-join' . ( $loggedIn ? '-loggedin' : '' ),
1168  'href' => $linkTitle->getLocalURL( $params['linkQuery'] ),
1169  'class' => ( $loggedIn ? '' : 'mw-ui-button' ),
1170  'tabindex' => 100,
1171  ],
1172  $this->msg(
1173  $loggedIn ? 'userlogin-createanother' : 'userlogin-joinproject'
1174  )->escaped()
1175  )
1176  );
1177  },
1178  'weight' => 235,
1179  ];
1180  }
1181  }
1182 
1183  $fieldDefinitions = $this->getBCFieldDefinitions( $fieldDefinitions, $template );
1184  $fieldDefinitions = array_filter( $fieldDefinitions );
1185 
1186  return $fieldDefinitions;
1187  }
1188 
1195  protected function getBCFieldDefinitions( $fieldDefinitions, $template ) {
1196  if ( $template->get( 'usedomain', false ) ) {
1197  // TODO probably should be translated to the new domain notation in AuthManager
1198  $fieldDefinitions['domain'] = [
1199  'type' => 'select',
1200  'label-message' => 'yourdomainname',
1201  'options' => array_combine( $template->get( 'domainnames', [] ),
1202  $template->get( 'domainnames', [] ) ),
1203  'default' => $template->get( 'domain', '' ),
1204  'name' => 'wpDomain',
1205  // FIXME id => 'mw-user-domain-section' on the parent div
1206  ];
1207  }
1208 
1209  // poor man's associative array_splice
1210  $extraInputPos = array_search( 'extrainput', array_keys( $fieldDefinitions ), true );
1211  $fieldDefinitions = array_slice( $fieldDefinitions, 0, $extraInputPos, true )
1212  + $template->getExtraInputDefinitions()
1213  + array_slice( $fieldDefinitions, $extraInputPos + 1, null, true );
1214 
1215  return $fieldDefinitions;
1216  }
1217 
1227  protected function hasSessionCookie() {
1228  global $wgDisableCookieCheck, $wgInitialSessionId;
1229 
1230  return $wgDisableCookieCheck || (
1232  $this->getRequest()->getSession()->getId() === (string)$wgInitialSessionId
1233  );
1234  }
1235 
1240  protected function getReturnToQueryStringFragment() {
1241  $returnto = '';
1242  if ( $this->mReturnTo !== '' ) {
1243  $returnto = 'returnto=' . wfUrlencode( $this->mReturnTo );
1244  if ( $this->mReturnToQuery !== '' ) {
1245  $returnto .= '&returntoquery=' . wfUrlencode( $this->mReturnToQuery );
1246  }
1247  }
1248  return $returnto;
1249  }
1250 
1256  private function showCreateAccountLink() {
1257  if ( $this->isSignup() ) {
1258  return true;
1259  } elseif ( $this->getUser()->isAllowed( 'createaccount' ) ) {
1260  return true;
1261  } else {
1262  return false;
1263  }
1264  }
1265 
1266  protected function getTokenName() {
1267  return $this->isSignup() ? 'wpCreateaccountToken' : 'wpLoginToken';
1268  }
1269 
1276  protected function makeLanguageSelector() {
1277  $msg = $this->msg( 'loginlanguagelinks' )->inContentLanguage();
1278  if ( $msg->isBlank() ) {
1279  return '';
1280  }
1281  $langs = explode( "\n", $msg->text() );
1282  $links = [];
1283  foreach ( $langs as $lang ) {
1284  $lang = trim( $lang, '* ' );
1285  $parts = explode( '|', $lang );
1286  if ( count( $parts ) >= 2 ) {
1287  $links[] = $this->makeLanguageSelectorLink( $parts[0], trim( $parts[1] ) );
1288  }
1289  }
1290 
1291  return count( $links ) > 0 ? $this->msg( 'loginlanguagelabel' )->rawParams(
1292  $this->getLanguage()->pipeList( $links ) )->escaped() : '';
1293  }
1294 
1303  protected function makeLanguageSelectorLink( $text, $lang ) {
1304  if ( $this->getLanguage()->getCode() == $lang ) {
1305  // no link for currently used language
1306  return htmlspecialchars( $text );
1307  }
1308  $query = [ 'uselang' => $lang ];
1309  if ( $this->mReturnTo !== '' ) {
1310  $query['returnto'] = $this->mReturnTo;
1311  $query['returntoquery'] = $this->mReturnToQuery;
1312  }
1313 
1314  $attr = [];
1315  $targetLanguage = Language::factory( $lang );
1316  $attr['lang'] = $attr['hreflang'] = $targetLanguage->getHtmlCode();
1317 
1318  return $this->getLinkRenderer()->makeKnownLink(
1319  $this->getPageTitle(),
1320  $text,
1321  $attr,
1322  $query
1323  );
1324  }
1325 
1326  protected function getGroupName() {
1327  return 'login';
1328  }
1329 
1333  protected function postProcessFormDescriptor( &$formDescriptor, $requests ) {
1334  // Pre-fill username (if not creating an account, T46775).
1335  if (
1336  isset( $formDescriptor['username'] ) &&
1337  !isset( $formDescriptor['username']['default'] ) &&
1338  !$this->isSignup()
1339  ) {
1340  $user = $this->getUser();
1341  if ( $user->isLoggedIn() ) {
1342  $formDescriptor['username']['default'] = $user->getName();
1343  } else {
1344  $formDescriptor['username']['default'] =
1345  $this->getRequest()->getSession()->suggestLoginUsername();
1346  }
1347  }
1348 
1349  // don't show a submit button if there is nothing to submit (i.e. the only form content
1350  // is other submit buttons, for redirect flows)
1351  if ( !$this->needsSubmitButton( $requests ) ) {
1352  unset( $formDescriptor['createaccount'], $formDescriptor['loginattempt'] );
1353  }
1354 
1355  if ( !$this->isSignup() ) {
1356  // FIXME HACK don't focus on non-empty field
1357  // maybe there should be an autofocus-if similar to hide-if?
1358  if (
1359  isset( $formDescriptor['username'] )
1360  && empty( $formDescriptor['username']['default'] )
1361  && !$this->getRequest()->getCheck( 'wpName' )
1362  ) {
1363  $formDescriptor['username']['autofocus'] = true;
1364  } elseif ( isset( $formDescriptor['password'] ) ) {
1365  $formDescriptor['password']['autofocus'] = true;
1366  }
1367  }
1368 
1369  $this->addTabIndex( $formDescriptor );
1370  }
1371 }
1372 
1380  public function execute() {
1381  throw new LogicException( 'not used' );
1382  }
1383 
1388  public function addInputItem( $name, $value, $type, $msg, $helptext = false ) {
1389  // use the same indexes as UserCreateForm just in case someone adds an item manually
1390  $this->data['extrainput'][] = [
1391  'name' => $name,
1392  'value' => $value,
1393  'type' => $type,
1394  'msg' => $msg,
1395  'helptext' => $helptext,
1396  ];
1397  }
1398 
1403  public function getExtraInputDefinitions() {
1404  $definitions = [];
1405 
1406  foreach ( $this->get( 'extrainput', [] ) as $field ) {
1407  $definition = [
1408  'type' => $field['type'] === 'checkbox' ? 'check' : $field['type'],
1409  'name' => $field['name'],
1410  'value' => $field['value'],
1411  'id' => $field['name'],
1412  ];
1413  if ( $field['msg'] ) {
1414  $definition['label-message'] = $this->getMsg( $field['msg'] );
1415  }
1416  if ( $field['helptext'] ) {
1417  $definition['help'] = $this->msgWiki( $field['helptext'] );
1418  }
1419 
1420  // the array key doesn't matter much when name is defined explicitly but
1421  // let's try and follow HTMLForm conventions
1422  $name = preg_replace( '/^wp(?=[A-Z])/', '', $field['name'] );
1423  $definitions[$name] = $definition;
1424  }
1425 
1426  if ( $this->haveData( 'extrafields' ) ) {
1427  $definitions['extrafields'] = [
1428  'type' => 'info',
1429  'raw' => true,
1430  'default' => $this->get( 'extrafields' ),
1431  ];
1432  }
1433 
1434  return $definitions;
1435  }
1436 }
1437 
1443 class LoginForm extends SpecialPage {
1444  const SUCCESS = 0;
1445  const NO_NAME = 1;
1446  const ILLEGAL = 2;
1448  const NOT_EXISTS = 4;
1449  const WRONG_PASS = 5;
1450  const EMPTY_PASS = 6;
1451  const RESET_PASS = 7;
1452  const ABORTED = 8;
1453  const CREATE_BLOCKED = 9;
1454  const THROTTLED = 10;
1455  const USER_BLOCKED = 11;
1456  const NEED_TOKEN = 12;
1457  const WRONG_TOKEN = 13;
1458  const USER_MIGRATED = 14;
1459 
1460  public static $statusCodes = [
1461  self::SUCCESS => 'success',
1462  self::NO_NAME => 'no_name',
1463  self::ILLEGAL => 'illegal',
1464  self::WRONG_PLUGIN_PASS => 'wrong_plugin_pass',
1465  self::NOT_EXISTS => 'not_exists',
1466  self::WRONG_PASS => 'wrong_pass',
1467  self::EMPTY_PASS => 'empty_pass',
1468  self::RESET_PASS => 'reset_pass',
1469  self::ABORTED => 'aborted',
1470  self::CREATE_BLOCKED => 'create_blocked',
1471  self::THROTTLED => 'throttled',
1472  self::USER_BLOCKED => 'user_blocked',
1473  self::NEED_TOKEN => 'need_token',
1474  self::WRONG_TOKEN => 'wrong_token',
1475  self::USER_MIGRATED => 'user_migrated',
1476  ];
1477 
1481  public function __construct( $request = null ) {
1482  wfDeprecated( 'LoginForm', '1.27' );
1483  parent::__construct();
1484  }
1485 
1489  public static function getValidErrorMessages() {
1491  }
1492 
1496  public static function incrementLoginThrottle( $username ) {
1497  wfDeprecated( __METHOD__, "1.27" );
1500  $throttler = new Throttler();
1501  return $throttler->increase( $username, $wgRequest->getIP(), __METHOD__ );
1502  }
1503 
1507  public static function incLoginThrottle( $username ) {
1508  wfDeprecated( __METHOD__, "1.27" );
1510  return is_array( $res ) ? true : 0;
1511  }
1512 
1516  public static function clearLoginThrottle( $username ) {
1517  wfDeprecated( __METHOD__, "1.27" );
1520  $throttler = new Throttler();
1521  return $throttler->clear( $username, $wgRequest->getIP() );
1522  }
1523 
1527  public static function getLoginToken() {
1528  wfDeprecated( __METHOD__, '1.27' );
1530  return $wgRequest->getSession()->getToken( '', 'login' )->toString();
1531  }
1532 
1536  public static function setLoginToken() {
1537  wfDeprecated( __METHOD__, '1.27' );
1538  }
1539 
1543  public static function clearLoginToken() {
1544  wfDeprecated( __METHOD__, '1.27' );
1546  $wgRequest->getSession()->resetToken( 'login' );
1547  }
1548 
1552  public static function getCreateaccountToken() {
1553  wfDeprecated( __METHOD__, '1.27' );
1555  return $wgRequest->getSession()->getToken( '', 'createaccount' )->toString();
1556  }
1557 
1561  public static function setCreateaccountToken() {
1562  wfDeprecated( __METHOD__, '1.27' );
1563  }
1564 
1568  public static function clearCreateaccountToken() {
1569  wfDeprecated( __METHOD__, '1.27' );
1571  $wgRequest->getSession()->resetToken( 'createaccount' );
1572  }
1573 }
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:1266
SpecialPage\getPageTitle
getPageTitle( $subpage=false)
Get a self-referential title object.
Definition: SpecialPage.php:628
LoginSignupSpecialPage\$mEntryErrorType
$mEntryErrorType
Definition: LoginSignupSpecialPage.php:46
LoginSignupSpecialPage\setRequest
setRequest(array $data, $wasPosted=null)
Override the POST data, GET data from the real request is preserved.
Definition: LoginSignupSpecialPage.php:92
BaseTemplate\msgWiki
msgWiki( $str)
An ugly, ugly hack.
Definition: BaseTemplate.php:47
object
globals will be eliminated from MediaWiki replaced by an application object which would be passed to constructors Whether that would be an convenient solution remains to be but certainly PHP makes such object oriented programming models easier than they were in previous versions For the time being MediaWiki programmers will have to work in an environment with some global context At the time of globals were initialised on startup by MediaWiki of these were configuration which are documented in DefaultSettings php There is no comprehensive documentation for the remaining however some of the most important ones are listed below They are typically initialised either in index php or in Setup php For a description of the see design txt $wgTitle Title object created from the request URL $wgOut OutputPage object for HTTP response $wgUser User object for the user associated with the current request $wgLang Language object selected by user preferences $wgContLang Language object associated with the wiki being viewed $wgParser Parser object Parser extensions register their hooks here $wgRequest WebRequest object
Definition: globals.txt:25
$wgUser
$wgUser
Definition: Setup.php:781
$context
error also a ContextSource you ll probably need to make sure the header is varied on and they can depend only on the ResourceLoaderContext $context
Definition: hooks.txt:2612
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:265
$template
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping $template
Definition: hooks.txt:783
LoginForm\$statusCodes
static $statusCodes
Definition: LoginSignupSpecialPage.php:1460
$request
error also a ContextSource you ll probably need to make sure the header is varied on $request
Definition: hooks.txt:2612
LoginSignupSpecialPage\postProcessFormDescriptor
postProcessFormDescriptor(&$formDescriptor, $requests)
Definition: LoginSignupSpecialPage.php:1333
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:3564
LoginForm\USER_BLOCKED
const USER_BLOCKED
Definition: LoginSignupSpecialPage.php:1455
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:603
FakeAuthTemplate\getExtraInputDefinitions
getExtraInputDefinitions()
Turns addInputItem-style field definitions into HTMLForm field definitions.
Definition: LoginSignupSpecialPage.php:1403
LoginForm\WRONG_PASS
const WRONG_PASS
Definition: LoginSignupSpecialPage.php:1449
LoginSignupSpecialPage\getBCFieldDefinitions
getBCFieldDefinitions( $fieldDefinitions, $template)
Adds fields provided via the deprecated UserLoginForm / UserCreateForm hooks.
Definition: LoginSignupSpecialPage.php:1195
LoginForm\CREATE_BLOCKED
const CREATE_BLOCKED
Definition: LoginSignupSpecialPage.php:1453
SpecialPage\getOutput
getOutput()
Get the OutputPage being used for this instance.
Definition: SpecialPage.php:675
LoginSignupSpecialPage\$mReturnTo
$mReturnTo
Definition: LoginSignupSpecialPage.php:37
$lang
if(!isset( $args[0])) $lang
Definition: testCompression.php:33
LoginForm\ILLEGAL
const ILLEGAL
Definition: LoginSignupSpecialPage.php:1446
LoginSignupSpecialPage\showSuccessPage
showSuccessPage( $type, $title, $msgname, $injected_html, $extraMessages)
Show the success page.
Definition: LoginSignupSpecialPage.php:426
captcha-old.count
count
Definition: captcha-old.py:225
LoginForm\SUCCESS
const SUCCESS
Definition: LoginSignupSpecialPage.php:1444
text
design txt This is a brief overview of the new design More thorough and up to date information is available on the documentation wiki at etc Handles the details of getting and saving to the user table of the and dealing with sessions and cookies OutputPage Encapsulates the entire HTML page that will be sent in response to any server request It is used by calling its functions to add text
Definition: design.txt:12
$returnToQuery
do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values before the output is cached my talk my contributions etc etc otherwise the built in rate limiting checks are if enabled allows for interception of redirect as a string & $returnToQuery
Definition: hooks.txt:2536
LoginSignupSpecialPage\$mReturnToQuery
$mReturnToQuery
Definition: LoginSignupSpecialPage.php:41
LoginSignupSpecialPage\showCreateAccountLink
showCreateAccountLink()
Whether the login/create account form should display a link to the other form (in addition to whateve...
Definition: LoginSignupSpecialPage.php:1256
LoginSignupSpecialPage\load
load( $subPage)
Load data from request.
Definition: LoginSignupSpecialPage.php:125
LoginForm\incLoginThrottle
static incLoginThrottle( $username)
Definition: LoginSignupSpecialPage.php:1507
$status
this hook is for auditing only RecentChangesLinked and Watchlist RecentChangesLinked and Watchlist Do not use this to implement individual filters if they are compatible with the ChangesListFilter and ChangesListFilterGroup structure use sub classes of those in conjunction with the ChangesListSpecialPageStructuredFilters hook This hook can be used to implement filters that do not implement that or custom behavior that is not an individual filter e g Watchlist and Watchlist you will want to construct new ChangesListBooleanFilter or ChangesListStringOptionsFilter objects When constructing you specify which group they belong to You can reuse existing or create your you must register them with $special registerFilterGroup removed from all revisions and log entries to which it was applied This gives extensions a chance to take it off their books as the deletion has already been partly carried out by this point or something similar the user will be unable to create the tag set $status
Definition: hooks.txt:1049
use
as see the revision history and available at free of to any person obtaining a copy of this software and associated documentation to deal in the Software without including without limitation the rights to use
Definition: MIT-LICENSE.txt:10
wfUrlencode
wfUrlencode( $s)
We want some things to be included as literal characters in our title URLs for prettiness,...
Definition: GlobalFunctions.php:371
$user
please add to it if you re going to add events to the MediaWiki code where normally authentication against an external auth plugin would be creating a account $user
Definition: hooks.txt:246
SpecialPage\checkPermissions
checkPermissions()
Checks if userCanExecute, and if not throws a PermissionsError.
Definition: SpecialPage.php:306
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:1303
LoginSignupSpecialPage\beforeExecute
beforeExecute( $subPage)
Gets called before.
Definition: LoginSignupSpecialPage.php:205
StatusValue\newFatal
static newFatal( $message)
Factory function for fatal errors.
Definition: StatusValue.php:63
$wgEnableUserEmail
$wgEnableUserEmail
Set to true to enable user-to-user e-mail.
Definition: DefaultSettings.php:1589
$params
$params
Definition: styleTest.css.php:40
LoginForm\RESET_PASS
const RESET_PASS
Definition: LoginSignupSpecialPage.php:1451
User\newFromName
static newFromName( $name, $validate='valid')
Static factory method for creation from username.
Definition: User.php:556
LoginForm\getCreateaccountToken
static getCreateaccountToken()
Definition: LoginSignupSpecialPage.php:1552
LoginSignupSpecialPage\$mStickHTTPS
$mStickHTTPS
Definition: LoginSignupSpecialPage.php:43
LoginForm\clearLoginThrottle
static clearLoginThrottle( $username)
Definition: LoginSignupSpecialPage.php:1516
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:82
LoginForm\THROTTLED
const THROTTLED
Definition: LoginSignupSpecialPage.php:1454
SpecialPage\getSkin
getSkin()
Shortcut to get the skin being used for this instance.
Definition: SpecialPage.php:695
MediaWiki\Auth\Throttler
Definition: Throttler.php:37
$res
$res
Definition: database.txt:21
$name
Allows to change the fields on the form that will be generated $name
Definition: hooks.txt:304
ContextSource\getRequest
getRequest()
Get the WebRequest object.
Definition: ContextSource.php:78
SpecialPage\getLanguage
getLanguage()
Shortcut to get user's language.
Definition: SpecialPage.php:705
$success
$success
Definition: NoLocalSettings.php:44
$type
do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values before the output is cached my talk my contributions etc etc otherwise the built in rate limiting checks are if enabled allows for interception of redirect as a string mapping parameter names to values & $type
Definition: hooks.txt:2536
SpecialPage\getName
getName()
Get the name of this Special Page.
Definition: SpecialPage.php:150
AuthManagerSpecialPage
A special page subclass for authentication-related special pages.
Definition: AuthManagerSpecialPage.php:14
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:472
LoginForm\getValidErrorMessages
static getValidErrorMessages()
Definition: LoginSignupSpecialPage.php:1489
LoginHelper
Helper functions for the login form that need to be shared with other special pages (such as CentralA...
Definition: LoginHelper.php:8
LoginForm\USER_MIGRATED
const USER_MIGRATED
Definition: LoginSignupSpecialPage.php:1458
LoginSignupSpecialPage\getReturnToQueryStringFragment
getReturnToQueryStringFragment()
Returns a string that can be appended to the URL (without encoding) to preserve the return target.
Definition: LoginSignupSpecialPage.php:1240
php
injection txt This is an overview of how MediaWiki makes use of dependency injection The design described here grew from the discussion of RFC T384 The term dependency this means that anything an object needs to operate should be injected from the the object itself should only know narrow no concrete implementation of the logic it relies on The requirement to inject everything typically results in an architecture that based on two main types of and essentially stateless service objects that use other service objects to operate on the value objects As of the beginning MediaWiki is only starting to use the DI approach Much of the code still relies on global state or direct resulting in a highly cyclical dependency which acts as the top level factory for services in MediaWiki which can be used to gain access to default instances of various services MediaWikiServices however also allows new services to be defined and default services to be redefined Services are defined or redefined by providing a callback the instantiator that will return a new instance of the service When it will create an instance of MediaWikiServices and populate it with the services defined in the files listed by thereby bootstrapping the DI framework Per $wgServiceWiringFiles lists includes ServiceWiring php
Definition: injection.txt:35
LoginForm\setLoginToken
static setLoginToken()
Definition: LoginSignupSpecialPage.php:1536
LoginForm\clearCreateaccountToken
static clearCreateaccountToken()
Definition: LoginSignupSpecialPage.php:1568
LoginForm\EMPTY_PASS
const EMPTY_PASS
Definition: LoginSignupSpecialPage.php:1450
AuthManagerSpecialPage\trySubmit
trySubmit()
Attempts to do an authentication step with the submitted data.
Definition: AuthManagerSpecialPage.php:397
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:500
FakeAuthTemplate
B/C class to try handling login/signup template modifications even though login/signup does not actua...
Definition: LoginSignupSpecialPage.php:1379
$query
null for the wiki Added should default to null in handler for backwards compatibility add a value to it if you want to add a cookie that have to vary cache options can modify $query
Definition: hooks.txt:1572
AuthManagerSpecialPage\$subPage
string $subPage
Subpage of the special page.
Definition: AuthManagerSpecialPage.php:34
LoginSignupSpecialPage\$mEntryError
$mEntryError
Definition: LoginSignupSpecialPage.php:45
DerivativeContext
An IContextSource implementation which will inherit context from another source but allow individual ...
Definition: DerivativeContext.php:31
LoginForm\ABORTED
const ABORTED
Definition: LoginSignupSpecialPage.php:1452
$html
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return an< a > element with HTML attributes $attribs and contents $html will be returned If you return $ret will be returned and may include noclasses & $html
Definition: hooks.txt:1956
SpecialPage\getConfig
getConfig()
Shortcut to get main config object.
Definition: SpecialPage.php:714
$title
namespace and then decline to actually register it file or subcat img or subcat $title
Definition: hooks.txt:934
wfDeprecated
wfDeprecated( $function, $version=false, $component=false, $callerOffset=2)
Throws a warning that $function is deprecated.
Definition: GlobalFunctions.php:1128
Status\wrap
static wrap( $sv)
Succinct helper method to wrap a StatusValue.
Definition: Status.php:55
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:36
SpecialPage\getFullTitle
getFullTitle()
Return the full title, including $par.
Definition: SpecialPage.php:724
LoginSignupSpecialPage\$proxyAccountCreation
bool $proxyAccountCreation
True if the user if creating an account for someone else.
Definition: LoginSignupSpecialPage.php:57
HTMLForm\factory
static factory( $displayFormat)
Construct a HTMLForm object for given display type.
Definition: HTMLForm.php:277
MediaWiki\Auth\AuthenticationResponse
This is a value object to hold authentication response data.
Definition: AuthenticationResponse.php:37
LoginForm\NOT_EXISTS
const NOT_EXISTS
Definition: LoginSignupSpecialPage.php:1448
AuthManagerSpecialPage\loadAuth
loadAuth( $subPage, $authAction=null, $reset=false)
Load or initialize $authAction, $authRequests and $subPage.
Definition: AuthManagerSpecialPage.php:231
LoginSignupSpecialPage\$mPosted
$mPosted
Definition: LoginSignupSpecialPage.php:38
LoginSignupSpecialPage\mainLoginForm
mainLoginForm(array $requests, $msg='', $msgtype='error')
Definition: LoginSignupSpecialPage.php:507
$wgLang
this class mediates it Skin Encapsulates a look and feel for the wiki All of the functions that render HTML and make choices about how to render it are here and are called from various other places when and is meant to be subclassed with other skins that may override some of its functions The User object contains a reference to a and so rather than having a global skin object we just rely on the global User and get the skin with $wgUser and also has some character encoding functions and other locale stuff The current user interface language is instantiated as $wgLang
Definition: design.txt:56
SpecialPage\setHeaders
setHeaders()
Sets headers - this should be called from the execute() method of all derived classes!
Definition: SpecialPage.php:484
SpecialPage\getUser
getUser()
Shortcut to get the User executing this instance.
Definition: SpecialPage.php:685
$wgEnableEmail
$wgEnableEmail
Set to true to enable the e-mail basic features: Password reminders, etc.
Definition: DefaultSettings.php:1583
LoginSignupSpecialPage\makeLanguageSelector
makeLanguageSelector()
Produce a bar of links which allow the user to select another language during login/registration but ...
Definition: LoginSignupSpecialPage.php:1276
global
when a variable name is used in a it is silently declared as a new masking the global
Definition: design.txt:93
LoginSignupSpecialPage\hasSessionCookie
hasSessionCookie()
Check if a session cookie is present.
Definition: LoginSignupSpecialPage.php:1227
LoginForm
LoginForm as a special page has been replaced by SpecialUserLogin and SpecialCreateAccount,...
Definition: LoginSignupSpecialPage.php:1443
LoginForm\__construct
__construct( $request=null)
Definition: LoginSignupSpecialPage.php:1481
LoginSignupSpecialPage\$mFromHTTP
$mFromHTTP
Definition: LoginSignupSpecialPage.php:44
string
This code would result in ircNotify being run twice when an article is and once for brion Hooks can return three possible true was required This is the default since MediaWiki *some string
Definition: hooks.txt:177
PROTO_HTTPS
const PROTO_HTTPS
Definition: Defines.php:218
LoginForm\setCreateaccountToken
static setCreateaccountToken()
Definition: LoginSignupSpecialPage.php:1561
SpecialPage\getContext
getContext()
Gets the context this SpecialPage is executed in.
Definition: SpecialPage.php:648
LoginSignupSpecialPage\$mLoaded
$mLoaded
Definition: LoginSignupSpecialPage.php:48
FakeAuthTemplate\addInputItem
addInputItem( $name, $value, $type, $msg, $helptext=false)
Extensions (AntiSpoof and TitleBlacklist) call this in response to UserCreateForm hook to add checkbo...
Definition: LoginSignupSpecialPage.php:1388
LoginSignupSpecialPage\getFakeTemplate
getFakeTemplate( $msg, $msgType)
Temporary B/C method to handle extensions using the UserLoginForm/UserCreateForm hooks.
Definition: LoginSignupSpecialPage.php:703
BaseTemplate\getMsg
getMsg( $name)
Get a Message object with its context set.
Definition: BaseTemplate.php:35
$value
$value
Definition: styleTest.css.php:45
LoginForm\WRONG_TOKEN
const WRONG_TOKEN
Definition: LoginSignupSpecialPage.php:1457
SpecialPage\msg
msg()
Wrapper around wfMessage that sets the current context.
Definition: SpecialPage.php:746
StatusValue\newGood
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:76
SpecialPage
Parent class for all special pages.
Definition: SpecialPage.php:36
LoginSignupSpecialPage\$mAction
$mAction
Definition: LoginSignupSpecialPage.php:39
MediaWiki\Session\SessionManager
This serves as the entry point to the MediaWiki session handling system.
Definition: SessionManager.php:49
LoginSignupSpecialPage\canBypassForm
canBypassForm(&$button_name)
Determine if the login form can be bypassed.
Definition: LoginSignupSpecialPage.php:390
LoginSignupSpecialPage\$mLanguage
$mLanguage
Definition: LoginSignupSpecialPage.php:40
LoginSignupSpecialPage\$mToken
$mToken
Definition: LoginSignupSpecialPage.php:42
wfEscapeWikiText
wfEscapeWikiText( $text)
Escapes the given text so that it may be output using addWikiText() without any linking,...
Definition: GlobalFunctions.php:1657
LoginSignupSpecialPage\$authForm
HTMLForm $authForm
Definition: LoginSignupSpecialPage.php:62
LoginSignupSpecialPage\getPageHtml
getPageHtml( $formHtml)
Add page elements which are outside the form.
Definition: LoginSignupSpecialPage.php:579
RequestContext\getMain
static getMain()
Static methods.
Definition: RequestContext.php:468
LoginSignupSpecialPage\$fakeTemplate
FakeAuthTemplate $fakeTemplate
Definition: LoginSignupSpecialPage.php:65
$response
this hook is for auditing only $response
Definition: hooks.txt:783
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:82
AuthManagerSpecialPage\getContinueAction
getContinueAction( $action)
Gets the _CONTINUE version of an action.
Definition: AuthManagerSpecialPage.php:279
LoginSignupSpecialPage\isSignup
isSignup()
FakeAuthTemplate\execute
execute()
Main function, used by classes that subclass QuickTemplate to show the actual HTML output.
Definition: LoginSignupSpecialPage.php:1380
QuickTemplate\haveData
haveData( $str)
Definition: QuickTemplate.php:153
SpecialPage\getLinkRenderer
getLinkRenderer()
Definition: SpecialPage.php:856
AuthManagerSpecialPage\isActionAllowed
isActionAllowed( $action)
Checks whether AuthManager is ready to perform the action.
Definition: AuthManagerSpecialPage.php:302
LoginSignupSpecialPage\getGroupName
getGroupName()
Under which header this special page is listed in Special:SpecialPages See messages 'specialpages-gro...
Definition: LoginSignupSpecialPage.php:1326
LoginSignupSpecialPage\showReturnToPage
showReturnToPage( $type, $returnTo='', $returnToQuery='', $stickHTTPS=false)
Add a "return to" link or redirect to it.
Definition: LoginSignupSpecialPage.php:460
AuthManagerSpecialPage\needsSubmitButton
needsSubmitButton(array $requests)
Returns true if the form built from the given AuthenticationRequests needs a submit button.
Definition: AuthManagerSpecialPage.php:565
$code
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output modifiable & $code
Definition: hooks.txt:783
User\getCanonicalName
static getCanonicalName( $name, $validate='valid')
Given unvalidated user input, return a canonical username, or false if the username is invalid.
Definition: User.php:1076
as
This document is intended to provide useful advice for parties seeking to redistribute MediaWiki to end users It s targeted particularly at maintainers for Linux since it s been observed that distribution packages of MediaWiki often break We ve consistently had to recommend that users seeking support use official tarballs instead of their distribution s and this often solves whatever problem the user is having It would be nice if this could such as
Definition: distributors.txt:9
Html\rawElement
static rawElement( $element, $attribs=[], $contents='')
Returns an HTML element in a string.
Definition: Html.php:209
LoginForm\NEED_TOKEN
const NEED_TOKEN
Definition: LoginSignupSpecialPage.php:1456
SpecialPage\setContext
setContext( $context)
Sets the context this SpecialPage is executed in.
Definition: SpecialPage.php:638
$requests
Allows to change the fields on the form that will be generated are created Can be used to omit specific feeds from being outputted You must not use this hook to add use OutputPage::addFeedLink() instead. & $feedLinks hooks can tweak the array to change how login etc forms should look $requests
Definition: hooks.txt:306
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
LoggerFactory
MediaWiki Logger LoggerFactory implements a PSR[0] compatible message logging system Named Psr Log LoggerInterface instances can be obtained from the MediaWiki Logger LoggerFactory::getInstance() static method. MediaWiki\Logger\LoggerFactory expects a class implementing the MediaWiki\Logger\Spi interface to act as a factory for new Psr\Log\LoggerInterface instances. The "Spi" in MediaWiki\Logger\Spi stands for "service provider interface". An SPI is an API intended to be implemented or extended by a third party. This software design pattern is intended to enable framework extension and replaceable components. It is specifically used in the MediaWiki\Logger\LoggerFactory service to allow alternate PSR-3 logging implementations to be easily integrated with MediaWiki. The service provider interface allows the backend logging library to be implemented in multiple ways. The $wgMWLoggerDefaultSpi global provides the classname of the default MediaWiki\Logger\Spi implementation to be loaded at runtime. This can either be the name of a class implementing the MediaWiki\Logger\Spi with a zero argument const ructor or a callable that will return an MediaWiki\Logger\Spi instance. Alternately the MediaWiki\Logger\LoggerFactory MediaWiki Logger LoggerFactory
Definition: logger.txt:5
AuthManagerSpecialPage\isContinued
isContinued()
Returns true if this is not the first step of the authentication.
Definition: AuthManagerSpecialPage.php:266
LoginSignupSpecialPage\loadRequestParameters
loadRequestParameters( $subPage)
Load basic request parameters for this Special page.
Definition: LoginSignupSpecialPage.php:101
true
null means default in associative array with keys and values unescaped Should be merged with default with a value of false meaning to suppress the attribute in associative array with keys and values unescaped noclasses just before the function returns a value If you return true
Definition: hooks.txt:1956
AuthManagerSpecialPage\getRequest
getRequest()
Get the WebRequest being used for this instance.
Definition: AuthManagerSpecialPage.php:63
LoginForm\NO_NAME
const NO_NAME
Definition: LoginSignupSpecialPage.php:1445
Language\factory
static factory( $code)
Get a cached or new language object for a given language code.
Definition: Language.php:183
LoginSignupSpecialPage\$mLoadedRequest
$mLoadedRequest
Definition: LoginSignupSpecialPage.php:49
AuthManagerSpecialPage\getToken
getToken()
Returns the CSRF token.
Definition: AuthManagerSpecialPage.php:623
wfMessage
either a unescaped string or a HtmlArmor object after in associative array form externallinks including delete and has completed for all link tables whether this was an auto creation default is conds Array Extra conditions for the No matching items in log is displayed if loglist is empty msgKey Array If you want a nice box with a set this to the key of the message First element is the message additional optional elements are parameters for the key that are processed with wfMessage() -> params() ->parseAsBlock() - offset Set to overwrite offset parameter in $wgRequest set to '' to unset offset - wrap String Wrap the message in html(usually something like "&lt
LoginSignupSpecialPage\$mSecureLoginUrl
$mSecureLoginUrl
Definition: LoginSignupSpecialPage.php:50
LoginSignupSpecialPage\$targetUser
User $targetUser
FIXME another flag for passing data.
Definition: LoginSignupSpecialPage.php:59
LoginSignupSpecialPage\execute
execute( $subPage)
Definition: LoginSignupSpecialPage.php:214
LoginForm\getLoginToken
static getLoginToken()
Definition: LoginSignupSpecialPage.php:1527
$wgRequest
if(! $wgDBerrorLogTZ) $wgRequest
Definition: Setup.php:639
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:53
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:831
ErrorPageError
An error page which can definitely be safely rendered using the OutputPage.
Definition: ErrorPageError.php:27
User
The User object encapsulates all of the user-specific settings (user_id, name, rights,...
Definition: User.php:50
Hooks\run
static run( $event, array $args=[], $deprecatedVersion=null)
Call hook functions defined in Hooks::register and $wgHooks.
Definition: Hooks.php:131
$username
this hook is for auditing only or null if authentication failed before getting that far $username
Definition: hooks.txt:783
LoginSignupSpecialPage\getFieldDefinitions
getFieldDefinitions( $template)
Create a HTMLForm descriptor for the core login fields.
Definition: LoginSignupSpecialPage.php:894
PasswordReset
Helper class for the password reset functionality shared by the web UI and the API.
Definition: PasswordReset.php:36
LoginHelper\getValidErrorMessages
static getValidErrorMessages()
Returns an array of all valid error messages.
Definition: LoginHelper.php:36
LoginSignupSpecialPage\showExtraInformation
showExtraInformation()
Show extra information such as password recovery information, link from login to signup,...
Definition: LoginSignupSpecialPage.php:884
BaseTemplate
New base template for a skin's template extended from QuickTemplate this class features helper method...
Definition: BaseTemplate.php:26
$wgInitialSessionId
$wgInitialSessionId
Definition: Setup.php:717
LoginForm\clearLoginToken
static clearLoginToken()
Definition: LoginSignupSpecialPage.php:1543
MediaWiki\Auth\AuthenticationRequest
This is a value object for authentication requests.
Definition: AuthenticationRequest.php:37
data
and how to run hooks for an and one after Each event has a preferably in CamelCase For ArticleDelete hook A clump of code and data that should be run when an event happens This can be either a function and a chunk of data
Definition: hooks.txt:6
LoginSignupSpecialPage\getAuthForm
getAuthForm(array $requests, $action, $msg='', $msgType='error')
Generates a form from the given request.
Definition: LoginSignupSpecialPage.php:643
Skin\makeInternalOrExternalUrl
static makeInternalOrExternalUrl( $name)
If url string starts with http, consider as external URL, else internal.
Definition: Skin.php:1132
array
the array() calling protocol came about after MediaWiki 1.4rc1.
$returnTo
do that in ParserLimitReportFormat instead use this to modify the parameters of the image and a DIV can begin in one section and end in another Make sure your code can handle that case gracefully See the EditSectionClearerLink extension for an example zero but section is usually empty its values are the globals values before the output is cached my talk my contributions etc etc otherwise the built in rate limiting checks are if enabled allows for interception of redirect & $returnTo
Definition: hooks.txt:2536
LoginForm\WRONG_PLUGIN_PASS
const WRONG_PLUGIN_PASS
Definition: LoginSignupSpecialPage.php:1447
HTMLForm
Object handling generic submission, CSRF protection, layout and other logic for UI forms.
Definition: HTMLForm.php:128
$out
this hook is for auditing only or null if authentication failed before getting that far or null if we can t even determine that probably a stub it is not rendered in wiki pages or galleries in category pages allow injecting custom HTML after the section Any uses of the hook need to handle escaping see BaseTemplate::getToolbox and BaseTemplate::makeListItem for details on the format of individual items inside of this array or by returning and letting standard HTTP rendering take place modifiable or by returning false and taking over the output $out
Definition: hooks.txt:783
LoginForm\incrementLoginThrottle
static incrementLoginThrottle( $username)
Definition: LoginSignupSpecialPage.php:1496