MediaWiki  master
AuthManagerSpecialPage.php
Go to the documentation of this file.
1 <?php
2 
9 
17 abstract class AuthManagerSpecialPage extends SpecialPage {
21  protected static $allowedActions = [
22  AuthManager::ACTION_LOGIN, AuthManager::ACTION_LOGIN_CONTINUE,
23  AuthManager::ACTION_CREATE, AuthManager::ACTION_CREATE_CONTINUE,
24  AuthManager::ACTION_LINK, AuthManager::ACTION_LINK_CONTINUE,
25  AuthManager::ACTION_CHANGE, AuthManager::ACTION_REMOVE, AuthManager::ACTION_UNLINK,
26  ];
27 
29  protected static $messages = [];
30 
32  protected $authAction;
33 
35  protected $authRequests;
36 
38  protected $subPage;
39 
41  protected $isReturn;
42 
44  protected $savedRequest;
45 
59  public function onAuthChangeFormFields(
60  array $requests, array $fieldInfo, array &$formDescriptor, $action
61  ) {
62  return true;
63  }
64 
69  protected function getLoginSecurityLevel() {
70  return $this->getName();
71  }
72 
73  public function getRequest() {
74  return $this->savedRequest ?: $this->getContext()->getRequest();
75  }
76 
87  protected function setRequest( array $data, $wasPosted = null ) {
88  $request = $this->getContext()->getRequest();
89  if ( $wasPosted === null ) {
90  $wasPosted = $request->wasPosted();
91  }
92  $this->savedRequest = new DerivativeRequest( $request, $data + $request->getQueryValues(),
93  $wasPosted );
94  }
95 
102  protected function beforeExecute( $subPage ) {
103  $this->getOutput()->disallowUserJs();
104 
105  return $this->handleReturnBeforeExecute( $subPage )
106  && $this->handleReauthBeforeExecute( $subPage );
107  }
108 
125  protected function handleReturnBeforeExecute( $subPage ) {
126  $authManager = MediaWikiServices::getInstance()->getAuthManager();
127  $key = 'AuthManagerSpecialPage:return:' . $this->getName();
128 
129  if ( $subPage === 'return' ) {
130  $this->loadAuth( $subPage );
131  $preservedParams = $this->getPreservedParams( false );
132 
133  // FIXME save POST values only from request
134  $authData = array_diff_key( $this->getRequest()->getValues(),
135  $preservedParams, [ 'title' => 1 ] );
136  $authManager->setAuthenticationSessionData( $key, $authData );
137 
138  $url = $this->getPageTitle()->getFullURL( $preservedParams, false, PROTO_HTTPS );
139  $this->getOutput()->redirect( $url );
140  return false;
141  }
142 
143  $authData = $authManager->getAuthenticationSessionData( $key );
144  if ( $authData ) {
145  $authManager->removeAuthenticationSessionData( $key );
146  $this->isReturn = true;
147  $this->setRequest( $authData, true );
148  }
149 
150  return true;
151  }
152 
163  protected function handleReauthBeforeExecute( $subPage ) {
164  $authManager = MediaWikiServices::getInstance()->getAuthManager();
165  $request = $this->getRequest();
166  $key = 'AuthManagerSpecialPage:reauth:' . $this->getName();
167 
168  $securityLevel = $this->getLoginSecurityLevel();
169  if ( $securityLevel ) {
170  $securityStatus = $authManager->securitySensitiveOperationStatus( $securityLevel );
171  if ( $securityStatus === AuthManager::SEC_REAUTH ) {
172  $queryParams = array_diff_key( $request->getQueryValues(), [ 'title' => true ] );
173 
174  if ( $request->wasPosted() ) {
175  // unique ID in case the same special page is open in multiple browser tabs
176  $uniqueId = MWCryptRand::generateHex( 6 );
177  $key .= ':' . $uniqueId;
178 
179  $queryParams = [ 'authUniqueId' => $uniqueId ] + $queryParams;
180  $authData = array_diff_key( $request->getValues(),
181  $this->getPreservedParams( false ), [ 'title' => 1 ] );
182  $authManager->setAuthenticationSessionData( $key, $authData );
183  }
184 
185  $title = SpecialPage::getTitleFor( 'Userlogin' );
186  $url = $title->getFullURL( [
187  'returnto' => $this->getFullTitle()->getPrefixedDBkey(),
188  'returntoquery' => wfArrayToCgi( $queryParams ),
189  'force' => $securityLevel,
190  ], false, PROTO_HTTPS );
191 
192  $this->getOutput()->redirect( $url );
193  return false;
194  } elseif ( $securityStatus !== AuthManager::SEC_OK ) {
195  throw new ErrorPageError( 'cannotauth-not-allowed-title', 'cannotauth-not-allowed' );
196  }
197  }
198 
199  $uniqueId = $request->getVal( 'authUniqueId' );
200  if ( $uniqueId ) {
201  $key .= ':' . $uniqueId;
202  $authData = $authManager->getAuthenticationSessionData( $key );
203  if ( $authData ) {
204  $authManager->removeAuthenticationSessionData( $key );
205  $this->setRequest( $authData, true );
206  }
207  }
208 
209  return true;
210  }
211 
218  abstract protected function getDefaultAction( $subPage );
219 
226  protected function messageKey( $defaultKey ) {
227  return array_key_exists( $defaultKey, static::$messages )
228  ? static::$messages[$defaultKey] : $defaultKey;
229  }
230 
236  protected function getRequestBlacklist() {
237  return [];
238  }
239 
250  protected function loadAuth( $subPage, $authAction = null, $reset = false ) {
251  // Do not load if already loaded, to cut down on the number of getAuthenticationRequests
252  // calls. This is important for requests which have hidden information so any
253  // getAuthenticationRequests call would mean putting data into some cache.
254  if (
255  !$reset && $this->subPage === $subPage && $this->authAction
256  && ( !$authAction || $authAction === $this->authAction )
257  ) {
258  return;
259  }
260 
261  $request = $this->getRequest();
262  $this->subPage = $subPage;
263  $this->authAction = $authAction ?: $request->getText( 'authAction' );
264  if ( !in_array( $this->authAction, static::$allowedActions, true ) ) {
265  $this->authAction = $this->getDefaultAction( $subPage );
266  if ( $request->wasPosted() ) {
267  $continueAction = $this->getContinueAction( $this->authAction );
268  if ( in_array( $continueAction, static::$allowedActions, true ) ) {
269  $this->authAction = $continueAction;
270  }
271  }
272  }
273 
274  $allReqs = MediaWikiServices::getInstance()->getAuthManager()->getAuthenticationRequests(
275  $this->authAction, $this->getUser() );
276  $this->authRequests = array_filter( $allReqs, function ( $req ) {
277  return !in_array( get_class( $req ), $this->getRequestBlacklist(), true );
278  } );
279  }
280 
285  protected function isContinued() {
286  return in_array( $this->authAction, [
287  AuthManager::ACTION_LOGIN_CONTINUE,
288  AuthManager::ACTION_CREATE_CONTINUE,
289  AuthManager::ACTION_LINK_CONTINUE,
290  ], true );
291  }
292 
298  protected function getContinueAction( $action ) {
299  switch ( $action ) {
300  case AuthManager::ACTION_LOGIN:
301  $action = AuthManager::ACTION_LOGIN_CONTINUE;
302  break;
303  case AuthManager::ACTION_CREATE:
304  $action = AuthManager::ACTION_CREATE_CONTINUE;
305  break;
306  case AuthManager::ACTION_LINK:
307  $action = AuthManager::ACTION_LINK_CONTINUE;
308  break;
309  }
310  return $action;
311  }
312 
321  protected function isActionAllowed( $action ) {
322  $authManager = MediaWikiServices::getInstance()->getAuthManager();
323  if ( !in_array( $action, static::$allowedActions, true ) ) {
324  throw new InvalidArgumentException( 'invalid action: ' . $action );
325  }
326 
327  // calling getAuthenticationRequests can be expensive, avoid if possible
328  $requests = ( $action === $this->authAction ) ? $this->authRequests
329  : $authManager->getAuthenticationRequests( $action );
330  if ( !$requests ) {
331  // no provider supports this action in the current state
332  return false;
333  }
334 
335  switch ( $action ) {
336  case AuthManager::ACTION_LOGIN:
337  case AuthManager::ACTION_LOGIN_CONTINUE:
338  return $authManager->canAuthenticateNow();
339  case AuthManager::ACTION_CREATE:
340  case AuthManager::ACTION_CREATE_CONTINUE:
341  return $authManager->canCreateAccounts();
342  case AuthManager::ACTION_LINK:
343  case AuthManager::ACTION_LINK_CONTINUE:
344  return $authManager->canLinkAccounts();
345  case AuthManager::ACTION_CHANGE:
346  case AuthManager::ACTION_REMOVE:
347  case AuthManager::ACTION_UNLINK:
348  return true;
349  default:
350  // should never reach here but makes static code analyzers happy
351  throw new InvalidArgumentException( 'invalid action: ' . $action );
352  }
353  }
354 
361  protected function performAuthenticationStep( $action, array $requests ) {
362  if ( !in_array( $action, static::$allowedActions, true ) ) {
363  throw new InvalidArgumentException( 'invalid action: ' . $action );
364  }
365 
366  $authManager = MediaWikiServices::getInstance()->getAuthManager();
367  $returnToUrl = $this->getPageTitle( 'return' )
368  ->getFullURL( $this->getPreservedParams( true ), false, PROTO_HTTPS );
369 
370  switch ( $action ) {
371  case AuthManager::ACTION_LOGIN:
372  return $authManager->beginAuthentication( $requests, $returnToUrl );
373  case AuthManager::ACTION_LOGIN_CONTINUE:
374  return $authManager->continueAuthentication( $requests );
375  case AuthManager::ACTION_CREATE:
376  return $authManager->beginAccountCreation( $this->getUser(), $requests,
377  $returnToUrl );
378  case AuthManager::ACTION_CREATE_CONTINUE:
379  return $authManager->continueAccountCreation( $requests );
380  case AuthManager::ACTION_LINK:
381  return $authManager->beginAccountLink( $this->getUser(), $requests, $returnToUrl );
382  case AuthManager::ACTION_LINK_CONTINUE:
383  return $authManager->continueAccountLink( $requests );
384  case AuthManager::ACTION_CHANGE:
385  case AuthManager::ACTION_REMOVE:
386  case AuthManager::ACTION_UNLINK:
387  if ( count( $requests ) > 1 ) {
388  throw new InvalidArgumentException( 'only one auth request can be changed at a time' );
389  } elseif ( !$requests ) {
390  throw new InvalidArgumentException( 'no auth request' );
391  }
392  $req = reset( $requests );
393  $status = $authManager->allowsAuthenticationDataChange( $req );
394  $this->getHookRunner()->onChangeAuthenticationDataAudit( $req, $status );
395  if ( !$status->isGood() ) {
396  return AuthenticationResponse::newFail( $status->getMessage() );
397  }
398  $authManager->changeAuthenticationData( $req );
399  return AuthenticationResponse::newPass();
400  default:
401  // should never reach here but makes static code analyzers happy
402  throw new InvalidArgumentException( 'invalid action: ' . $action );
403  }
404  }
405 
416  protected function trySubmit() {
417  $status = false;
418 
419  $form = $this->getAuthForm( $this->authRequests, $this->authAction );
420  $form->setSubmitCallback( [ $this, 'handleFormSubmit' ] );
421 
422  if ( $this->getRequest()->wasPosted() ) {
423  // handle tokens manually; $form->tryAuthorizedSubmit only works for logged-in users
424  $requestTokenValue = $this->getRequest()->getVal( $this->getTokenName() );
425  $sessionToken = $this->getToken();
426  if ( $sessionToken->wasNew() ) {
427  return Status::newFatal( $this->messageKey( 'authform-newtoken' ) );
428  } elseif ( !$requestTokenValue ) {
429  return Status::newFatal( $this->messageKey( 'authform-notoken' ) );
430  } elseif ( !$sessionToken->match( $requestTokenValue ) ) {
431  return Status::newFatal( $this->messageKey( 'authform-wrongtoken' ) );
432  }
433 
434  $form->prepareForm();
435  $status = $form->trySubmit();
436 
437  // HTMLForm submit return values are a mess; let's ensure it is false or a Status
438  // FIXME this probably should be in HTMLForm
439  if ( $status === true ) {
440  // not supposed to happen since our submit handler should always return a Status
441  throw new UnexpectedValueException( 'HTMLForm::trySubmit() returned true' );
442  } elseif ( $status === false ) {
443  // form was not submitted; nothing to do
444  } elseif ( $status instanceof Status ) {
445  // already handled by the form; nothing to do
446  } elseif ( $status instanceof StatusValue ) {
447  // in theory not an allowed return type but nothing stops the submit handler from
448  // accidentally returning it so best check and fix
449  $status = Status::wrap( $status );
450  } elseif ( is_string( $status ) ) {
451  $status = Status::newFatal( new RawMessage( '$1', [ $status ] ) );
452  } elseif ( is_array( $status ) ) {
453  if ( is_string( reset( $status ) ) ) {
454  $status = Status::newFatal( ...$status );
455  } elseif ( is_array( reset( $status ) ) ) {
456  $ret = Status::newGood();
457  foreach ( $status as $message ) {
458  $ret->fatal( ...$message );
459  }
460  $status = $ret;
461  } else {
462  throw new UnexpectedValueException( 'invalid HTMLForm::trySubmit() return value: '
463  . 'first element of array is ' . gettype( reset( $status ) ) );
464  }
465  } else {
466  // not supposed to happen but HTMLForm does not actually verify the return type
467  // from the submit callback; better safe then sorry
468  throw new UnexpectedValueException( 'invalid HTMLForm::trySubmit() return type: '
469  . gettype( $status ) );
470  }
471 
472  if ( ( !$status || !$status->isOK() ) && $this->isReturn ) {
473  // This is awkward. There was a form validation error, which means the data was not
474  // passed to AuthManager. Normally we would display the form with an error message,
475  // but for the data we received via the redirect flow that would not be helpful at all.
476  // Let's just submit the data to AuthManager directly instead.
477  LoggerFactory::getInstance( 'authentication' )
478  ->warning( 'Validation error on return', [ 'data' => $form->mFieldData,
479  'status' => $status->getWikiText( false, false, 'en' ) ] );
480  $status = $this->handleFormSubmit( $form->mFieldData );
481  }
482  }
483 
484  $changeActions = [
485  AuthManager::ACTION_CHANGE, AuthManager::ACTION_REMOVE, AuthManager::ACTION_UNLINK
486  ];
487  if ( in_array( $this->authAction, $changeActions, true ) && $status && !$status->isOK() ) {
488  $this->getHookRunner()->onChangeAuthenticationDataAudit( reset( $this->authRequests ), $status );
489  }
490 
491  return $status;
492  }
493 
500  public function handleFormSubmit( $data ) {
501  $requests = AuthenticationRequest::loadRequestsFromSubmission( $this->authRequests, $data );
502  $response = $this->performAuthenticationStep( $this->authAction, $requests );
503 
504  // we can't handle FAIL or similar as failure here since it might require changing the form
505  return Status::newGood( $response );
506  }
507 
516  protected function getPreservedParams( $withToken = false ) {
517  $params = [];
518  if ( $this->authAction !== $this->getDefaultAction( $this->subPage ) ) {
519  $params['authAction'] = $this->getContinueAction( $this->authAction );
520  }
521  if ( $withToken ) {
522  $params[$this->getTokenName()] = $this->getToken()->toString();
523  }
524  return $params;
525  }
526 
534  protected function getAuthFormDescriptor( $requests, $action ) {
535  $fieldInfo = AuthenticationRequest::mergeFieldInfo( $requests );
536  $formDescriptor = $this->fieldInfoToFormDescriptor( $requests, $fieldInfo, $action );
537 
538  $this->addTabIndex( $formDescriptor );
539 
540  return $formDescriptor;
541  }
542 
549  protected function getAuthForm( array $requests, $action ) {
550  $formDescriptor = $this->getAuthFormDescriptor( $requests, $action );
551  $context = $this->getContext();
552  if ( $context->getRequest() !== $this->getRequest() ) {
553  // We have overridden the request, need to make sure the form uses that too.
554  $context = new DerivativeContext( $this->getContext() );
555  $context->setRequest( $this->getRequest() );
556  }
557  $form = HTMLForm::factory( 'ooui', $formDescriptor, $context );
558  $form->setAction( $this->getFullTitle()->getFullURL( $this->getPreservedParams() ) );
559  $form->addHiddenField( $this->getTokenName(), $this->getToken()->toString() );
560  $form->addHiddenField( 'authAction', $this->authAction );
561  $form->suppressDefaultSubmit( !$this->needsSubmitButton( $requests ) );
562 
563  return $form;
564  }
565 
570  protected function displayForm( $status ) {
571  if ( $status instanceof StatusValue ) {
572  $status = Status::wrap( $status );
573  }
574  $form = $this->getAuthForm( $this->authRequests, $this->authAction );
575  $form->prepareForm()->displayForm( $status );
576  }
577 
589  protected function needsSubmitButton( array $requests ) {
590  $customSubmitButtonPresent = false;
591 
592  // Secondary and preauth providers always need their data; they will not care what button
593  // is used, so they can be ignored. So can OPTIONAL buttons createdby primary providers;
594  // that's the point in being optional. Se we need to check whether all primary providers
595  // have their own buttons and whether there is at least one button present.
596  foreach ( $requests as $req ) {
597  if ( $req->required === AuthenticationRequest::PRIMARY_REQUIRED ) {
598  if ( $this->hasOwnSubmitButton( $req ) ) {
599  $customSubmitButtonPresent = true;
600  } else {
601  return true;
602  }
603  }
604  }
605  return !$customSubmitButtonPresent;
606  }
607 
613  protected function hasOwnSubmitButton( AuthenticationRequest $req ) {
614  foreach ( $req->getFieldInfo() as $field => $info ) {
615  if ( $info['type'] === 'button' ) {
616  return true;
617  }
618  }
619  return false;
620  }
621 
627  protected function addTabIndex( &$formDescriptor ) {
628  $i = 1;
629  foreach ( $formDescriptor as $field => &$definition ) {
630  $class = false;
631  if ( array_key_exists( 'class', $definition ) ) {
632  $class = $definition['class'];
633  } elseif ( array_key_exists( 'type', $definition ) ) {
634  $class = HTMLForm::$typeMappings[$definition['type']];
635  }
636  if ( $class !== HTMLInfoField::class ) {
637  $definition['tabindex'] = $i;
638  $i++;
639  }
640  }
641  }
642 
648  protected function getToken() {
649  return $this->getRequest()->getSession()->getToken( 'AuthManagerSpecialPage:'
650  . $this->getName() );
651  }
652 
658  protected function getTokenName() {
659  return 'wpAuthToken';
660  }
661 
671  protected function fieldInfoToFormDescriptor( array $requests, array $fieldInfo, $action ) {
672  $formDescriptor = [];
673  foreach ( $fieldInfo as $fieldName => $singleFieldInfo ) {
674  $formDescriptor[$fieldName] = self::mapSingleFieldInfo( $singleFieldInfo, $fieldName );
675  }
676 
677  $requestSnapshot = serialize( $requests );
678  $this->onAuthChangeFormFields( $requests, $fieldInfo, $formDescriptor, $action );
679  $this->getHookRunner()->onAuthChangeFormFields( $requests, $fieldInfo,
680  $formDescriptor, $action );
681  if ( $requestSnapshot !== serialize( $requests ) ) {
682  LoggerFactory::getInstance( 'authentication' )->warning(
683  'AuthChangeFormFields hook changed auth requests' );
684  }
685 
686  // Process the special 'weight' property, which is a way for AuthChangeFormFields hook
687  // subscribers (who only see one field at a time) to influence ordering.
688  self::sortFormDescriptorFields( $formDescriptor );
689 
690  return $formDescriptor;
691  }
692 
700  protected static function mapSingleFieldInfo( $singleFieldInfo, $fieldName ) {
701  $type = self::mapFieldInfoTypeToFormDescriptorType( $singleFieldInfo['type'] );
702  $descriptor = [
703  'type' => $type,
704  // Do not prefix input name with 'wp'. This is important for the redirect flow.
705  'name' => $fieldName,
706  ];
707 
708  if ( $type === 'submit' && isset( $singleFieldInfo['label'] ) ) {
709  $descriptor['default'] = $singleFieldInfo['label']->plain();
710  } elseif ( $type !== 'submit' ) {
711  $descriptor += array_filter( [
712  // help-message is omitted as it is usually not really useful for a web interface
713  'label-message' => self::getField( $singleFieldInfo, 'label' ),
714  ] );
715 
716  if ( isset( $singleFieldInfo['options'] ) ) {
717  $descriptor['options'] = array_flip( array_map( function ( $message ) {
719  return $message->parse();
720  }, $singleFieldInfo['options'] ) );
721  }
722 
723  if ( isset( $singleFieldInfo['value'] ) ) {
724  $descriptor['default'] = $singleFieldInfo['value'];
725  }
726 
727  if ( empty( $singleFieldInfo['optional'] ) ) {
728  $descriptor['required'] = true;
729  }
730  }
731 
732  return $descriptor;
733  }
734 
741  protected static function sortFormDescriptorFields( array &$formDescriptor ) {
742  $i = 0;
743  foreach ( $formDescriptor as &$field ) {
744  $field['__index'] = $i++;
745  }
746  uasort( $formDescriptor, function ( $first, $second ) {
747  return self::getField( $first, 'weight', 0 ) <=> self::getField( $second, 'weight', 0 )
748  ?: $first['__index'] <=> $second['__index'];
749  } );
750  foreach ( $formDescriptor as &$field ) {
751  unset( $field['__index'] );
752  }
753  }
754 
762  protected static function getField( array $array, $fieldName, $default = null ) {
763  if ( array_key_exists( $fieldName, $array ) ) {
764  return $array[$fieldName];
765  } else {
766  return $default;
767  }
768  }
769 
776  protected static function mapFieldInfoTypeToFormDescriptorType( $type ) {
777  $map = [
778  'string' => 'text',
779  'password' => 'password',
780  'select' => 'select',
781  'checkbox' => 'check',
782  'multiselect' => 'multiselect',
783  'button' => 'submit',
784  'hidden' => 'hidden',
785  'null' => 'info',
786  ];
787  if ( !array_key_exists( $type, $map ) ) {
788  throw new \LogicException( 'invalid field type: ' . $type );
789  }
790  return $map[$type];
791  }
792 }
AuthManagerSpecialPage\$isReturn
bool $isReturn
True if the current request is a result of returning from a redirect flow.
Definition: AuthManagerSpecialPage.php:41
DerivativeRequest
Similar to FauxRequest, but only fakes URL parameters and method (POST or GET) and use the base reque...
Definition: DerivativeRequest.php:36
SpecialPage\getPageTitle
getPageTitle( $subpage=false)
Get a self-referential title object.
Definition: SpecialPage.php:697
HTMLForm\$typeMappings
static $typeMappings
Definition: HTMLForm.php:139
AuthManagerSpecialPage\displayForm
displayForm( $status)
Display the form.
Definition: AuthManagerSpecialPage.php:570
StatusValue
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition: StatusValue.php:43
AuthManagerSpecialPage\handleReauthBeforeExecute
handleReauthBeforeExecute( $subPage)
Handle redirection when the user needs to (re)authenticate.
Definition: AuthManagerSpecialPage.php:163
StatusValue\newFatal
static newFatal( $message,... $parameters)
Factory function for fatal errors.
Definition: StatusValue.php:70
AuthManagerSpecialPage\getTokenName
getTokenName()
Returns the name of the CSRF token (under which it should be found in the POST or GET data).
Definition: AuthManagerSpecialPage.php:658
AuthManagerSpecialPage\addTabIndex
addTabIndex(&$formDescriptor)
Adds a sequential tabindex starting from 1 to all form elements.
Definition: AuthManagerSpecialPage.php:627
AuthManagerSpecialPage\getAuthFormDescriptor
getAuthFormDescriptor( $requests, $action)
Generates a HTMLForm descriptor array from a set of authentication requests.
Definition: AuthManagerSpecialPage.php:534
AuthManagerSpecialPage\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: AuthManagerSpecialPage.php:59
SpecialPage\getOutput
getOutput()
Get the OutputPage being used for this instance.
Definition: SpecialPage.php:744
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:154
AuthManagerSpecialPage\fieldInfoToFormDescriptor
fieldInfoToFormDescriptor(array $requests, array $fieldInfo, $action)
Turns a field info array into a form descriptor.
Definition: AuthManagerSpecialPage.php:671
AuthManagerSpecialPage\sortFormDescriptorFields
static sortFormDescriptorFields(array &$formDescriptor)
Sort the fields of a form descriptor by their 'weight' property.
Definition: AuthManagerSpecialPage.php:741
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
AuthManagerSpecialPage\handleFormSubmit
handleFormSubmit( $data)
Submit handler callback for HTMLForm.
Definition: AuthManagerSpecialPage.php:500
AuthManagerSpecialPage\getAuthForm
getAuthForm(array $requests, $action)
Stable to override.
Definition: AuthManagerSpecialPage.php:549
serialize
serialize()
Definition: ApiMessageTrait.php:138
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
AuthManagerSpecialPage\$authRequests
AuthenticationRequest[] $authRequests
Definition: AuthManagerSpecialPage.php:35
AuthManagerSpecialPage\getField
static getField(array $array, $fieldName, $default=null)
Get an array value, or a default if it does not exist.
Definition: AuthManagerSpecialPage.php:762
Status
Generic operation result class Has warning/error list, boolean status and arbitrary value.
Definition: Status.php:44
AuthManagerSpecialPage\trySubmit
trySubmit()
Attempts to do an authentication step with the submitted data.
Definition: AuthManagerSpecialPage.php:416
AuthManagerSpecialPage\getLoginSecurityLevel
getLoginSecurityLevel()
Stable to override.
Definition: AuthManagerSpecialPage.php:69
AuthManagerSpecialPage\$subPage
string $subPage
Subpage of the special page.
Definition: AuthManagerSpecialPage.php:38
AuthManagerSpecialPage\performAuthenticationStep
performAuthenticationStep( $action, array $requests)
Definition: AuthManagerSpecialPage.php:361
DerivativeContext
An IContextSource implementation which will inherit context from another source but allow individual ...
Definition: DerivativeContext.php:31
AuthManagerSpecialPage\mapFieldInfoTypeToFormDescriptorType
static mapFieldInfoTypeToFormDescriptorType( $type)
Maps AuthenticationRequest::getFieldInfo() types to HTMLForm types.
Definition: AuthManagerSpecialPage.php:776
SpecialPage\getHookRunner
getHookRunner()
Definition: SpecialPage.php:1010
AuthManagerSpecialPage\getPreservedParams
getPreservedParams( $withToken=false)
Returns URL query parameters which can be used to reload the page (or leave and return) while preserv...
Definition: AuthManagerSpecialPage.php:516
MediaWiki\Logger\LoggerFactory
PSR-3 logger instance factory.
Definition: LoggerFactory.php:45
AuthManagerSpecialPage\messageKey
messageKey( $defaultKey)
Return custom message key.
Definition: AuthManagerSpecialPage.php:226
AuthManagerSpecialPage\$authAction
string $authAction
one of the AuthManager::ACTION_* constants.
Definition: AuthManagerSpecialPage.php:32
Status\wrap
static wrap( $sv)
Succinct helper method to wrap a StatusValue.
Definition: Status.php:62
SpecialPage\getFullTitle
getFullTitle()
Return the full title, including $par.
Definition: SpecialPage.php:804
MediaWiki\Auth\AuthenticationResponse
This is a value object to hold authentication response data.
Definition: AuthenticationResponse.php:37
AuthManagerSpecialPage\loadAuth
loadAuth( $subPage, $authAction=null, $reset=false)
Load or initialize $authAction, $authRequests and $subPage.
Definition: AuthManagerSpecialPage.php:250
MediaWiki\Auth\AuthenticationRequest\getFieldInfo
getFieldInfo()
Fetch input field info.
$title
$title
Definition: testCompression.php:38
SpecialPage\getUser
getUser()
Shortcut to get the User executing this instance.
Definition: SpecialPage.php:754
AuthManagerSpecialPage\handleReturnBeforeExecute
handleReturnBeforeExecute( $subPage)
Handle redirection from the /return subpage.
Definition: AuthManagerSpecialPage.php:125
PROTO_HTTPS
const PROTO_HTTPS
Definition: Defines.php:209
SpecialPage\getContext
getContext()
Gets the context this SpecialPage is executed in.
Definition: SpecialPage.php:717
AuthManagerSpecialPage\$messages
static array $messages
Customized messages.
Definition: AuthManagerSpecialPage.php:29
AuthManagerSpecialPage\$allowedActions
static string[] $allowedActions
The list of actions this special page deals with.
Definition: AuthManagerSpecialPage.php:21
StatusValue\newGood
static newGood( $value=null)
Factory function for good results.
Definition: StatusValue.php:82
SpecialPage
Parent class for all special pages.
Definition: SpecialPage.php:41
AuthManagerSpecialPage\mapSingleFieldInfo
static mapSingleFieldInfo( $singleFieldInfo, $fieldName)
Maps an authentication field configuration for a single field (as returned by AuthenticationRequest::...
Definition: AuthManagerSpecialPage.php:700
MWCryptRand\generateHex
static generateHex( $chars)
Generate a run of cryptographically random data and return it in hexadecimal string format.
Definition: MWCryptRand.php:36
AuthManagerSpecialPage\setRequest
setRequest(array $data, $wasPosted=null)
Override the POST data, GET data from the real request is preserved.
Definition: AuthManagerSpecialPage.php:87
AuthManagerSpecialPage\hasOwnSubmitButton
hasOwnSubmitButton(AuthenticationRequest $req)
Checks whether the given AuthenticationRequest has its own submit button.
Definition: AuthManagerSpecialPage.php:613
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
WebRequest
The WebRequest class encapsulates getting at data passed in the URL or via a POSTed form stripping il...
Definition: WebRequest.php:42
AuthManagerSpecialPage\beforeExecute
beforeExecute( $subPage)
Stable to override.
Definition: AuthManagerSpecialPage.php:102
AuthManagerSpecialPage\isActionAllowed
isActionAllowed( $action)
Checks whether AuthManager is ready to perform the action.
Definition: AuthManagerSpecialPage.php:321
AuthManagerSpecialPage\needsSubmitButton
needsSubmitButton(array $requests)
Returns true if the form built from the given AuthenticationRequests needs a submit button.
Definition: AuthManagerSpecialPage.php:589
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
AuthManagerSpecialPage\getToken
getToken()
Returns the CSRF token.
Definition: AuthManagerSpecialPage.php:648
AuthManagerSpecialPage\getRequestBlacklist
getRequestBlacklist()
Allows blacklisting certain request types.
Definition: AuthManagerSpecialPage.php:236
MediaWiki\Session\Token
Value object representing a CSRF token.
Definition: Token.php:32
RawMessage
Variant of the Message class.
Definition: RawMessage.php:35
ErrorPageError
An error page which can definitely be safely rendered using the OutputPage.
Definition: ErrorPageError.php:30
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
AuthManagerSpecialPage\$savedRequest
WebRequest null $savedRequest
If set, will be used instead of the real request.
Definition: AuthManagerSpecialPage.php:44
wfArrayToCgi
wfArrayToCgi( $array1, $array2=null, $prefix='')
This function takes one or two arrays as input, and returns a CGI-style string, e....
Definition: GlobalFunctions.php:346
$type
$type
Definition: testCompression.php:52