MediaWiki  1.34.0
OATHManage.php
Go to the documentation of this file.
1 <?php
2 
21 
28 use OOUI\ButtonWidget;
29 use OOUI\HorizontalLayout;
30 use Message;
31 use Html;
32 use OOUI\HtmlSnippet;
33 use OOUI\PanelLayout;
34 use SpecialPage;
35 use OOUI\LabelWidget;
36 use HTMLForm;
37 use ConfigException;
38 use MWException;
40 use UserNotLoggedIn;
41 
42 class OATHManage extends SpecialPage {
43  const ACTION_ENABLE = 'enable';
44  const ACTION_DISABLE = 'disable';
45 
49  protected $auth;
53  protected $userRepo;
57  protected $authUser;
61  protected $action;
65  protected $requestedModule;
66 
73  public function __construct() {
74  parent::__construct( 'OATHManage', 'oathauth-enable' );
75 
76  $services = MediaWikiServices::getInstance();
77  $this->auth = $services->getService( 'OATHAuth' );
78  $this->userRepo = $services->getService( 'OATHUserRepository' );
79  $this->authUser = $this->userRepo->findByUser( $this->getUser() );
80  }
81 
86  public function execute( $subPage ) {
87  $this->getOutput()->enableOOUI();
88  $this->setAction();
89  $this->setModule();
90 
91  parent::execute( $subPage );
92 
93  if ( $this->requestedModule instanceof IModule ) {
94  // Performing an action on a requested module
95  $this->clearPage();
96  if ( $this->shouldShowDisableWarning() ) {
97  return $this->showDisableWarning();
98  }
99  return $this->addModuleHTML( $this->requestedModule );
100  }
101 
102  $this->addGeneralHelp();
103  if ( $this->hasEnabled() ) {
104  $this->addEnabledHTML();
105  if ( $this->hasAlternativeModules() ) {
106  $this->addAlternativesHTML();
107  }
108  return;
109  }
110  $this->nothingEnabled();
111  }
112 
117  public function checkPermissions() {
118  $this->requireLogin();
119 
120  $canEnable = $this->getUser()->isAllowed( 'oathauth-enable' );
121 
122  if ( $this->action === static::ACTION_ENABLE && !$canEnable ) {
123  $this->displayRestrictionError();
124  }
125 
126  if ( !$this->hasEnabled() && !$canEnable ) {
127  // No enabled module and cannot enable - nothing to do
128  $this->displayRestrictionError();
129  }
130 
131  if ( $this->action === static::ACTION_ENABLE && !$this->getRequest()->wasPosted() ) {
132  // Trying to change the 2FA method (one is already enabled)
133  $this->checkLoginSecurityLevel( 'oathauth-enable' );
134  }
135  }
136 
137  private function setAction() {
138  $this->action = $this->getRequest()->getVal( 'action', '' );
139  }
140 
141  private function setModule() {
142  $moduleKey = $this->getRequest()->getVal( 'module', '' );
143  $this->requestedModule = $this->auth->getModuleByKey( $moduleKey );
144  }
145 
146  private function hasEnabled() {
147  return $this->authUser->getModule() instanceof IModule;
148  }
149 
150  private function getEnabled() {
151  return $this->hasEnabled() ? $this->authUser->getModule() : null;
152  }
153 
154  private function addEnabledHTML() {
155  $this->addHeading( wfMessage( 'oathauth-ui-enabled-module' ) );
156  $this->addModuleHTML( $this->getEnabled() );
157  }
158 
159  private function addAlternativesHTML() {
160  $this->addHeading( wfMessage( 'oathauth-ui-not-enabled-modules' ) );
161  $this->addInactiveHTML();
162  }
163 
164  private function nothingEnabled() {
165  $this->addHeading( wfMessage( 'oathauth-ui-available-modules' ) );
166  $this->addInactiveHTML();
167  }
168 
169  private function addInactiveHTML() {
170  foreach ( $this->auth->getAllModules() as $key => $module ) {
171  if ( $this->isModuleEnabled( $module ) ) {
172  continue;
173  }
174  $this->addModuleHTML( $module );
175  }
176  }
177 
178  private function addGeneralHelp() {
179  $this->getOutput()->addHTML( wfMessage(
180  'oathauth-ui-general-help'
181  )->parseAsBlock() );
182  }
183 
184  private function addModuleHTML( IModule $module ) {
185  if ( $this->isModuleRequested( $module ) ) {
186  return $this->addCustomContent( $module );
187  }
188 
189  $panel = $this->getGenericContent( $module );
190  if ( $this->isModuleEnabled( $module ) ) {
191  $this->addCustomContent( $module, $panel );
192  }
193 
194  return $this->getOutput()->addHTML( (string)$panel );
195  }
196 
203  private function getGenericContent( IModule $module ) {
204  $modulePanel = new PanelLayout( [
205  'framed' => true,
206  'expanded' => false,
207  'padded' => true
208  ] );
209  $headerLayout = new HorizontalLayout();
210 
211  $label = new LabelWidget( [
212  'label' => $module->getDisplayName()->text()
213  ] );
214  if ( $this->shouldShowGenericButtons() ) {
215  $button = new ButtonWidget( [
216  'label' => $this->isModuleEnabled( $module ) ?
217  wfMessage( 'oathauth-disable-generic' )->text() :
218  wfMessage( 'oathauth-enable-generic' )->text(),
219  'href' => $this->getOutput()->getTitle()->getLocalURL( [
220  'action' => $this->isModuleEnabled( $module ) ?
221  static::ACTION_DISABLE : static::ACTION_ENABLE,
222  'module' => $module->getName(),
223  'warn' => 1
224  ] )
225  ] );
226  $headerLayout->addItems( [ $button ] );
227  }
228  $headerLayout->addItems( [ $label ] );
229 
230  $modulePanel->appendContent( $headerLayout );
231  $modulePanel->appendContent( new HtmlSnippet(
232  $module->getDescriptionMessage()->parseAsBlock()
233  ) );
234  return $modulePanel;
235  }
236 
241  private function addCustomContent( IModule $module, $panel = null ) {
242  $form = $module->getManageForm( $this->action, $this->authUser, $this->userRepo );
243  if ( $form === null || !$this->isValidFormType( $form ) ) {
244  return;
245  }
246  $form->setTitle( $this->getOutput()->getTitle() );
247  $this->ensureRequiredFormFields( $form, $module );
248  $form->setSubmitCallback( [ $form, 'onSubmit' ] );
249  if ( $form->show( $panel ) ) {
250  $form->onSuccess();
251  }
252  }
253 
254  private function addHeading( Message $message ) {
255  $this->getOutput()->addHTML( Html::element( 'h2', [], $message->text() ) );
256  }
257 
258  private function shouldShowGenericButtons() {
259  if ( !$this->requestedModule instanceof IModule ) {
260  return true;
261  }
262  if ( !$this->isGenericAction() ) {
263  return true;
264  }
265  return false;
266  }
267 
268  private function isModuleRequested( IModule $module ) {
269  if ( $this->requestedModule instanceof IModule ) {
270  if ( $this->requestedModule->getName() === $module->getName() ) {
271  return true;
272  }
273  }
274  return false;
275  }
276 
277  private function isModuleEnabled( IModule $module ) {
278  if ( $this->getEnabled() instanceof IModule ) {
279  return $this->getEnabled()->getName() === $module->getName();
280  }
281  return false;
282  }
283 
290  private function isValidFormType( $form ) {
291  if ( !( $form instanceof HTMLForm ) ) {
292  return false;
293  }
294  $implements = class_implements( $form );
295  if ( !isset( $implements[IManageForm::class] ) ) {
296  return false;
297  }
298 
299  return true;
300  }
301 
306  private function ensureRequiredFormFields( IManageForm &$form, IModule $module ) {
307  if ( !$form->hasField( 'module' ) ) {
308  $form->addHiddenField( 'module', $module->getName() );
309  }
310  if ( !$form->hasField( 'action' ) ) {
311  $form->addHiddenField( 'action', $this->action );
312  }
313  }
314 
319  private function clearPage() {
320  if ( $this->isGenericAction() ) {
321  $displayName = $this->requestedModule->getDisplayName();
322  $pageTitle = $this->isModuleEnabled( $this->requestedModule ) ?
323  wfMessage( 'oathauth-disable-page-title', $displayName )->text() :
324  wfMessage( 'oathauth-enable-page-title', $displayName )->text();
325  $this->getOutput()->setPageTitle( $pageTitle );
326  }
327 
328  $this->getOutput()->clearHTML();
329  $this->getOutput()->addBacklinkSubtitle( $this->getOutput()->getTitle() );
330  }
331 
336  private function isGenericAction() {
337  return in_array( $this->action, [ static::ACTION_ENABLE, static::ACTION_DISABLE ] );
338  }
339 
340  private function hasAlternativeModules() {
341  foreach ( $this->auth->getAllModules() as $key => $module ) {
342  if ( !$this->isModuleEnabled( $module ) ) {
343  return true;
344  }
345  }
346  return false;
347  }
348 
349  private function shouldShowDisableWarning() {
350  return (bool)$this->getRequest()->getVal( 'warn', false ) &&
351  $this->requestedModule instanceof IModule &&
352  $this->getEnabled() instanceof IModule;
353  }
354 
355  private function showDisableWarning() {
356  $panel = new PanelLayout( [
357  'padded' => true,
358  'framed' => true,
359  'expanded' => false
360  ] );
361  $headerMessage = $this->isSwitch() ?
362  wfMessage( 'oathauth-switch-method-warning-header' ) :
363  wfMessage( 'oathauth-disable-method-warning-header' );
364  $genericMessage = $this->isSwitch() ?
365  wfMessage(
366  'oathauth-switch-method-warning',
367  $this->getEnabled()->getDisplayName(),
368  $this->requestedModule->getDisplayName()
369  ) :
370  wfMessage( 'oathauth-disable-method-warning', $this->getEnabled()->getDisplayName() );
371 
372  $panel->appendContent( new HtmlSnippet(
373  $genericMessage->parseAsBlock()
374  ) );
375 
376  $customMessage = $this->getEnabled()->getDisableWarningMessage();
377  if ( $customMessage instanceof Message ) {
378  $panel->appendContent( new HtmlSnippet(
379  $customMessage->parseAsBlock()
380  ) );
381  }
382 
383  $button = new ButtonWidget( [
384  'label' => wfMessage( 'oathauth-disable-method-warning-button-label' )->plain(),
385  'href' => $this->getOutput()->getTitle()->getLocalURL( [
386  'action' => $this->action,
387  'module' => $this->requestedModule->getName()
388  ] ),
389  'flags' => [ 'primary', 'progressive' ]
390  ] );
391  $panel->appendContent( $button );
392 
393  $this->getOutput()->setPageTitle( $headerMessage );
394  $this->getOutput()->addHTML( $panel->toString() );
395  }
396 
397  private function isSwitch() {
398  return $this->requestedModule instanceof IModule &&
399  $this->action === static::ACTION_ENABLE &&
400  $this->getEnabled() instanceof IModule;
401  }
402 
403 }
MediaWiki\Extension\OATHAuth\Special\OATHManage\__construct
__construct()
Initializes a page to manage available 2FA modules.
Definition: OATHManage.php:73
MediaWiki\Extension\OATHAuth\Special\OATHManage\isGenericAction
isGenericAction()
Actions enable and disable are generic and all modules must implement them, while all other actions a...
Definition: OATHManage.php:336
MediaWiki\Extension\OATHAuth\OATHUser
Class representing a user from OATH's perspective.
Definition: OATHUser.php:28
SpecialPage\getOutput
getOutput()
Get the OutputPage being used for this instance.
Definition: SpecialPage.php:719
MediaWiki\MediaWikiServices
MediaWikiServices is the service locator for the application scope of MediaWiki.
Definition: MediaWikiServices.php:117
MediaWiki\Extension\OATHAuth\Special\OATHManage\clearPage
clearPage()
When performing an action on a module (like enable/disable), page should contain only form for that a...
Definition: OATHManage.php:319
MediaWiki\getTitle
getTitle()
Get the Title object that we'll be acting on, as specified in the WebRequest.
Definition: MediaWiki.php:137
MediaWiki\Extension\OATHAuth\Special\OATHManage\$authUser
OATHUser $authUser
Definition: OATHManage.php:57
UserNotLoggedIn
Redirect a user to the login page.
Definition: UserNotLoggedIn.php:53
MediaWiki\Extension\OATHAuth\Special\OATHManage\nothingEnabled
nothingEnabled()
Definition: OATHManage.php:164
SpecialPage\displayRestrictionError
displayRestrictionError()
Output an error message telling the user what access level they have to have.
Definition: SpecialPage.php:304
MediaWiki\Extension\OATHAuth\IModule\getManageForm
getManageForm( $action, OATHUser $user, OATHUserRepository $repo)
wfMessage
wfMessage( $key,... $params)
This is the function for getting translated interface messages.
Definition: GlobalFunctions.php:1264
MediaWiki\Extension\OATHAuth\Special\OATHManage\isModuleEnabled
isModuleEnabled(IModule $module)
Definition: OATHManage.php:277
PermissionsError
Show an error when a user tries to do something they do not have the necessary permissions for.
Definition: PermissionsError.php:30
Message
MediaWiki\Extension\OATHAuth\HTMLForm\IManageForm\hasField
hasField( $fieldname)
MediaWiki\Extension\OATHAuth\Special\OATHManage\$action
string $action
Definition: OATHManage.php:61
MediaWiki\Extension\OATHAuth\Special\OATHManage\setModule
setModule()
Definition: OATHManage.php:141
MediaWiki\Extension\OATHAuth\Special\OATHManage\addModuleHTML
addModuleHTML(IModule $module)
Definition: OATHManage.php:184
MediaWiki\Extension\OATHAuth\Special\OATHManage\showDisableWarning
showDisableWarning()
Definition: OATHManage.php:355
MediaWiki\Extension\OATHAuth\Special\OATHManage\addHeading
addHeading(Message $message)
Definition: OATHManage.php:254
MediaWiki\MediaWikiServices\getInstance
static getInstance()
Returns the global default instance of the top level service locator.
Definition: MediaWikiServices.php:138
MediaWiki\Extension\OATHAuth\Special\OATHManage\ACTION_ENABLE
const ACTION_ENABLE
Definition: OATHManage.php:43
MediaWiki\Extension\OATHAuth\OATHUserRepository
Definition: OATHUserRepository.php:33
MediaWiki\Extension\OATHAuth\Special\OATHManage\hasAlternativeModules
hasAlternativeModules()
Definition: OATHManage.php:340
MWException
MediaWiki exception.
Definition: MWException.php:26
MediaWiki\Extension\OATHAuth\OATHAuth
Definition: OATHAuth.php:14
SpecialPage\checkLoginSecurityLevel
checkLoginSecurityLevel( $level=null)
Verifies that the user meets the security level, possibly reauthenticating them in the process.
Definition: SpecialPage.php:406
MediaWiki\Extension\OATHAuth\Special\OATHManage\getEnabled
getEnabled()
Definition: OATHManage.php:150
MediaWiki\Extension\OATHAuth\IModule\getDescriptionMessage
getDescriptionMessage()
Return Message object for the short text to be displayed as description.
MediaWiki\Extension\OATHAuth\Special\OATHManage\setAction
setAction()
Definition: OATHManage.php:137
MediaWiki\Extension\OATHAuth\Special\OATHManage\hasEnabled
hasEnabled()
Definition: OATHManage.php:146
MediaWiki\Extension\OATHAuth\Special\OATHManage\isValidFormType
isValidFormType( $form)
Checks if given form instance fulfills required conditions.
Definition: OATHManage.php:290
ConfigException
Exceptions for config failures.
Definition: ConfigException.php:28
SpecialPage\getUser
getUser()
Shortcut to get the User executing this instance.
Definition: SpecialPage.php:729
MediaWiki\Extension\OATHAuth\Special\OATHManage\addGeneralHelp
addGeneralHelp()
Definition: OATHManage.php:178
MediaWiki\Extension\OATHAuth\Special\OATHManage
Definition: OATHManage.php:42
MediaWiki\Extension\OATHAuth\Special\OATHManage\addEnabledHTML
addEnabledHTML()
Definition: OATHManage.php:154
MediaWiki\Extension\OATHAuth\IModule\getDisplayName
getDisplayName()
SpecialPage\requireLogin
requireLogin( $reasonMsg='exception-nologin-text', $titleMsg='exception-nologin')
If the user is not logged in, throws UserNotLoggedIn error.
Definition: SpecialPage.php:345
MediaWiki\Extension\OATHAuth\Special\OATHManage\ACTION_DISABLE
const ACTION_DISABLE
Definition: OATHManage.php:44
MediaWiki\Extension\OATHAuth\Special
This program is free software; you can redistribute it and/or modify it under the terms of the GNU Ge...
Definition: DisableOATHForUser.php:3
SpecialPage
Parent class for all special pages.
Definition: SpecialPage.php:37
MediaWiki\Extension\OATHAuth\Special\OATHManage\$auth
OATHAuth $auth
Definition: OATHManage.php:49
SpecialPage\getRequest
getRequest()
Get the WebRequest being used for this instance.
Definition: SpecialPage.php:709
MediaWiki\Extension\OATHAuth\HTMLForm\IManageForm\addHiddenField
addHiddenField( $name, $value, array $attribs=[])
MediaWiki\Extension\OATHAuth\Special\OATHManage\ensureRequiredFormFields
ensureRequiredFormFields(IManageForm &$form, IModule $module)
Definition: OATHManage.php:306
MediaWiki\Extension\OATHAuth\Special\OATHManage\getGenericContent
getGenericContent(IModule $module)
Get the panel with generic content for a module.
Definition: OATHManage.php:203
MediaWiki\Extension\OATHAuth\Special\OATHManage\addInactiveHTML
addInactiveHTML()
Definition: OATHManage.php:169
MediaWiki\Extension\OATHAuth\Special\OATHManage\addAlternativesHTML
addAlternativesHTML()
Definition: OATHManage.php:159
MediaWiki\Extension\OATHAuth\Special\OATHManage\$requestedModule
IModule $requestedModule
Definition: OATHManage.php:65
MediaWiki\Extension\OATHAuth\Special\OATHManage\$userRepo
OATHUserRepository $userRepo
Definition: OATHManage.php:53
MediaWiki\Extension\OATHAuth\Special\OATHManage\shouldShowDisableWarning
shouldShowDisableWarning()
Definition: OATHManage.php:349
MediaWiki\Extension\OATHAuth\HTMLForm\IManageForm
Definition: IManageForm.php:10
MediaWiki\Extension\OATHAuth\Special\OATHManage\shouldShowGenericButtons
shouldShowGenericButtons()
Definition: OATHManage.php:258
MediaWiki\Extension\OATHAuth\IModule\getName
getName()
Name of the module.
MediaWiki\Extension\OATHAuth\Special\OATHManage\checkPermissions
checkPermissions()
Definition: OATHManage.php:117
MediaWiki\Extension\OATHAuth\Special\OATHManage\isModuleRequested
isModuleRequested(IModule $module)
Definition: OATHManage.php:268
MediaWiki\Extension\OATHAuth\Special\OATHManage\isSwitch
isSwitch()
Definition: OATHManage.php:397
MediaWiki\Extension\OATHAuth\Special\OATHManage\addCustomContent
addCustomContent(IModule $module, $panel=null)
Definition: OATHManage.php:241
HTMLForm
Object handling generic submission, CSRF protection, layout and other logic for UI forms in a reusabl...
Definition: HTMLForm.php:131
MediaWiki\Extension\OATHAuth\Special\OATHManage\execute
execute( $subPage)
Definition: OATHManage.php:86
MediaWiki\Extension\OATHAuth\IModule
Definition: IModule.php:9