Page Menu
Home
WickedGov Phorge
Search
Configure Global Search
Log In
Files
F4103109
OATHManage.php
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Flag For Later
Award Token
Size
11 KB
Referenced Files
None
Subscribers
None
OATHManage.php
View Options
<?php
/**
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
* http://www.gnu.org/copyleft/gpl.html
*/
namespace
MediaWiki\Extension\OATHAuth\Special
;
use
MediaWiki\Config\ConfigException
;
use
MediaWiki\Extension\OATHAuth\HTMLForm\IManageForm
;
use
MediaWiki\Extension\OATHAuth\IModule
;
use
MediaWiki\Extension\OATHAuth\OATHAuthModuleRegistry
;
use
MediaWiki\Extension\OATHAuth\OATHUser
;
use
MediaWiki\Extension\OATHAuth\OATHUserRepository
;
use
MediaWiki\Html\Html
;
use
MediaWiki\HTMLForm\HTMLForm
;
use
MediaWiki\Message\Message
;
use
MediaWiki\SpecialPage\SpecialPage
;
use
MWException
;
use
OOUI\ButtonWidget
;
use
OOUI\HorizontalLayout
;
use
OOUI\HtmlSnippet
;
use
OOUI\LabelWidget
;
use
OOUI\PanelLayout
;
use
PermissionsError
;
use
UserNotLoggedIn
;
class
OATHManage
extends
SpecialPage
{
public
const
ACTION_ENABLE
=
'enable'
;
public
const
ACTION_DISABLE
=
'disable'
;
protected
OATHAuthModuleRegistry
$moduleRegistry
;
protected
OATHUserRepository
$userRepo
;
protected
OATHUser
$authUser
;
/**
* @var string
*/
protected
$action
;
/**
* @var IModule|null
*/
protected
$requestedModule
;
/**
* Initializes a page to manage available 2FA modules
*
* @param OATHUserRepository $userRepo
* @param OATHAuthModuleRegistry $moduleRegistry
*
* @throws ConfigException
* @throws MWException
*/
public
function
__construct
(
OATHUserRepository
$userRepo
,
OATHAuthModuleRegistry
$moduleRegistry
)
{
// messages used: oathmanage (display "name" on Special:SpecialPages),
// right-oathauth-enable, action-oathauth-enable
parent
::
__construct
(
'OATHManage'
,
'oathauth-enable'
);
$this
->
userRepo
=
$userRepo
;
$this
->
moduleRegistry
=
$moduleRegistry
;
$this
->
authUser
=
$this
->
userRepo
->
findByUser
(
$this
->
getUser
()
);
}
/**
* @inheritDoc
*/
protected
function
getGroupName
()
{
return
'login'
;
}
/**
* @param null|string $subPage
*/
public
function
execute
(
$subPage
)
{
$this
->
getOutput
()->
enableOOUI
();
$this
->
getOutput
()->
disallowUserJs
();
$this
->
setAction
();
$this
->
setModule
();
parent
::
execute
(
$subPage
);
if
(
$this
->
requestedModule
instanceof
IModule
)
{
// Performing an action on a requested module
$this
->
clearPage
();
if
(
$this
->
shouldShowDisableWarning
()
)
{
$this
->
showDisableWarning
();
return
;
}
$this
->
addModuleHTML
(
$this
->
requestedModule
);
return
;
}
$this
->
addGeneralHelp
();
if
(
$this
->
authUser
->
isTwoFactorAuthEnabled
()
)
{
$this
->
addEnabledHTML
();
if
(
$this
->
hasAlternativeModules
()
)
{
$this
->
addAlternativesHTML
();
}
return
;
}
$this
->
nothingEnabled
();
}
/**
* @throws PermissionsError
* @throws UserNotLoggedIn
*/
public
function
checkPermissions
()
{
$this
->
requireNamedUser
();
$canEnable
=
$this
->
getUser
()->
isAllowed
(
'oathauth-enable'
);
if
(
$this
->
action
===
static
::
ACTION_ENABLE
&&
!
$canEnable
)
{
$this
->
displayRestrictionError
();
}
if
(
!
$this
->
authUser
->
isTwoFactorAuthEnabled
()
&&
!
$canEnable
)
{
// No enabled module and cannot enable - nothing to do
$this
->
displayRestrictionError
();
}
if
(
$this
->
action
===
static
::
ACTION_ENABLE
&&
!
$this
->
getRequest
()->
wasPosted
()
)
{
// Trying to change the 2FA method (one is already enabled)
$this
->
checkLoginSecurityLevel
(
'oathauth-enable'
);
}
}
private
function
setAction
():
void
{
$this
->
action
=
$this
->
getRequest
()->
getVal
(
'action'
,
''
);
}
private
function
setModule
():
void
{
$moduleKey
=
$this
->
getRequest
()->
getVal
(
'module'
,
''
);
$this
->
requestedModule
=
$this
->
moduleRegistry
->
getModuleByKey
(
$moduleKey
);
}
private
function
addEnabledHTML
():
void
{
$this
->
addHeading
(
$this
->
msg
(
'oathauth-ui-enabled-module'
)
);
$this
->
addModuleHTML
(
$this
->
authUser
->
getModule
()
);
}
private
function
addAlternativesHTML
():
void
{
$this
->
addHeading
(
$this
->
msg
(
'oathauth-ui-not-enabled-modules'
)
);
$this
->
addInactiveHTML
();
}
private
function
nothingEnabled
():
void
{
$this
->
addHeading
(
$this
->
msg
(
'oathauth-ui-available-modules'
)
);
$this
->
addInactiveHTML
();
}
private
function
addInactiveHTML
():
void
{
foreach
(
$this
->
moduleRegistry
->
getAllModules
()
as
$module
)
{
if
(
$this
->
isModuleEnabled
(
$module
)
||
!
$this
->
isModuleAvailable
(
$module
)
)
{
continue
;
}
$this
->
addModuleHTML
(
$module
);
}
}
private
function
addGeneralHelp
():
void
{
$this
->
getOutput
()->
addHTML
(
$this
->
msg
(
'oathauth-ui-general-help'
)->
parseAsBlock
()
);
}
private
function
addModuleHTML
(
?
IModule
$module
):
void
{
if
(
$module
instanceof
IModule
&&
$this
->
isModuleRequested
(
$module
)
)
{
$this
->
addCustomContent
(
$module
);
return
;
}
$panel
=
$this
->
getGenericContent
(
$module
);
if
(
$module
instanceof
IModule
&&
$this
->
isModuleEnabled
(
$module
)
)
{
$this
->
addCustomContent
(
$module
,
$panel
);
}
$this
->
getOutput
()->
addHTML
(
(
string
)
$panel
);
}
/**
* Get the panel with generic content for a module
*/
private
function
getGenericContent
(
?
IModule
$module
):
PanelLayout
{
$modulePanel
=
new
PanelLayout
(
[
'framed'
=>
true
,
'expanded'
=>
false
,
'padded'
=>
true
]
);
$headerLayout
=
new
HorizontalLayout
();
$label
=
new
LabelWidget
(
[
'label'
=>
$module
->
getDisplayName
()->
text
()
]
);
if
(
$this
->
shouldShowGenericButtons
()
)
{
$enabled
=
$module
&&
$this
->
isModuleEnabled
(
$module
);
$button
=
new
ButtonWidget
(
[
'label'
=>
$this
->
msg
(
$enabled
?
'oathauth-disable-generic'
:
'oathauth-enable-generic'
)
->
text
(),
'href'
=>
$this
->
getOutput
()->
getTitle
()->
getLocalURL
(
[
'action'
=>
$enabled
?
static
::
ACTION_DISABLE
:
static
::
ACTION_ENABLE
,
'module'
=>
$module
->
getName
(),
'warn'
=>
1
]
)
]
);
$headerLayout
->
addItems
(
[
$button
]
);
}
$headerLayout
->
addItems
(
[
$label
]
);
$modulePanel
->
appendContent
(
$headerLayout
);
$modulePanel
->
appendContent
(
new
HtmlSnippet
(
$module
->
getDescriptionMessage
()->
parseAsBlock
()
)
);
return
$modulePanel
;
}
private
function
addCustomContent
(
IModule
$module
,
?
PanelLayout
$panel
=
null
):
void
{
$form
=
$module
->
getManageForm
(
$this
->
action
,
$this
->
authUser
,
$this
->
userRepo
,
$this
->
getContext
()
);
if
(
$form
===
null
||
!
$this
->
isValidFormType
(
$form
)
)
{
return
;
}
$form
->
setTitle
(
$this
->
getOutput
()->
getTitle
()
);
$this
->
ensureRequiredFormFields
(
$form
,
$module
);
$form
->
setSubmitCallback
(
[
$form
,
'onSubmit'
]
);
if
(
$form
->
show
(
$panel
)
)
{
$form
->
onSuccess
();
}
}
private
function
addHeading
(
Message
$message
):
void
{
$this
->
getOutput
()->
addHTML
(
Html
::
element
(
'h2'
,
[],
$message
->
text
()
)
);
}
private
function
shouldShowGenericButtons
():
bool
{
return
!
$this
->
requestedModule
instanceof
IModule
||
!
$this
->
isGenericAction
();
}
private
function
isModuleRequested
(
?
IModule
$module
):
bool
{
return
(
$this
->
requestedModule
instanceof
IModule
&&
$module
instanceof
IModule
&&
$this
->
requestedModule
->
getName
()
===
$module
->
getName
()
);
}
private
function
isModuleEnabled
(
IModule
$module
):
bool
{
$enabled
=
$this
->
authUser
->
getModule
();
if
(
!
$enabled
)
{
return
false
;
}
return
$enabled
->
getName
()
===
$module
->
getName
();
}
/**
* Verifies if the module is available to be enabled
*
* @param IModule $module
* @return bool
*/
private
function
isModuleAvailable
(
IModule
$module
):
bool
{
$form
=
$module
->
getManageForm
(
static
::
ACTION_ENABLE
,
$this
->
authUser
,
$this
->
userRepo
,
$this
->
getContext
()
);
if
(
$form
===
''
)
{
return
false
;
}
return
true
;
}
/**
* Verifies if the given form instance fulfills the required conditions
*
* @param mixed $form
* @return bool
*/
private
function
isValidFormType
(
$form
):
bool
{
if
(
!(
$form
instanceof
HTMLForm
)
)
{
return
false
;
}
$implements
=
class_implements
(
$form
);
if
(
!
isset
(
$implements
[
IManageForm
::
class
]
)
)
{
return
false
;
}
return
true
;
}
private
function
ensureRequiredFormFields
(
IManageForm
$form
,
IModule
$module
):
void
{
if
(
!
$form
->
hasField
(
'module'
)
)
{
$form
->
addHiddenField
(
'module'
,
$module
->
getName
()
);
}
if
(
!
$form
->
hasField
(
'action'
)
)
{
$form
->
addHiddenField
(
'action'
,
$this
->
action
);
}
}
/**
* When performing an action on a module (like enable/disable),
* page should contain only the form for that action.
*/
private
function
clearPage
():
void
{
if
(
$this
->
isGenericAction
()
)
{
$displayName
=
$this
->
requestedModule
->
getDisplayName
();
$pageTitleMessage
=
$this
->
isModuleEnabled
(
$this
->
requestedModule
)
?
$this
->
msg
(
'oathauth-disable-page-title'
,
$displayName
)
:
$this
->
msg
(
'oathauth-enable-page-title'
,
$displayName
);
$this
->
getOutput
()->
setPageTitleMsg
(
$pageTitleMessage
);
}
$this
->
getOutput
()->
clearHTML
();
$this
->
getOutput
()->
addBacklinkSubtitle
(
$this
->
getOutput
()->
getTitle
()
);
}
/**
* The enable and disable actions are generic, and all modules must
* implement them, while all other actions are module-specific.
*/
private
function
isGenericAction
():
bool
{
return
in_array
(
$this
->
action
,
[
static
::
ACTION_ENABLE
,
static
::
ACTION_DISABLE
]
);
}
private
function
hasAlternativeModules
():
bool
{
foreach
(
$this
->
moduleRegistry
->
getAllModules
()
as
$module
)
{
if
(
!
$this
->
isModuleEnabled
(
$module
)
&&
$this
->
isModuleAvailable
(
$module
)
)
{
return
true
;
}
}
return
false
;
}
private
function
shouldShowDisableWarning
():
bool
{
return
$this
->
getRequest
()->
getBool
(
'warn'
)
&&
$this
->
requestedModule
instanceof
IModule
&&
$this
->
authUser
->
isTwoFactorAuthEnabled
();
}
private
function
showDisableWarning
():
void
{
$panel
=
new
PanelLayout
(
[
'padded'
=>
true
,
'framed'
=>
true
,
'expanded'
=>
false
]
);
$isSwitch
=
$this
->
isSwitch
();
$currentDisplayName
=
$this
->
authUser
->
getModule
()->
getDisplayName
();
$newDisplayName
=
$this
->
requestedModule
->
getDisplayName
();
$genericMessage
=
$isSwitch
?
$this
->
msg
(
'oathauth-switch-method-warning'
,
$currentDisplayName
,
$newDisplayName
)
:
$this
->
msg
(
'oathauth-disable-method-warning'
,
$currentDisplayName
);
$panel
->
appendContent
(
new
HtmlSnippet
(
$genericMessage
->
parseAsBlock
()
)
);
$customMessage
=
$this
->
authUser
->
getModule
()->
getDisableWarningMessage
();
if
(
$customMessage
instanceof
Message
)
{
$panel
->
appendContent
(
new
HtmlSnippet
(
$customMessage
->
parseAsBlock
()
)
);
}
$nextStepMessage
=
$isSwitch
?
$this
->
msg
(
'oathauth-switch-method-next-step'
,
$currentDisplayName
)
:
$this
->
msg
(
'oathauth-disable-method-next-step'
,
$currentDisplayName
,
$newDisplayName
);
$panel
->
appendContent
(
new
HtmlSnippet
(
$nextStepMessage
->
parseAsBlock
()
)
);
$button
=
new
ButtonWidget
(
[
'label'
=>
$this
->
msg
(
'oathauth-disable-method-warning-button-label'
)->
plain
(),
'href'
=>
$this
->
getOutput
()->
getTitle
()->
getLocalURL
(
[
'action'
=>
$this
->
action
,
'module'
=>
$this
->
requestedModule
->
getName
()
]
),
'flags'
=>
[
'primary'
,
'progressive'
]
]
);
$panel
->
appendContent
(
$button
);
$headerMessage
=
$isSwitch
?
$this
->
msg
(
'oathauth-switch-method-warning-header'
)
:
$this
->
msg
(
'oathauth-disable-method-warning-header'
);
$this
->
getOutput
()->
setPageTitleMsg
(
$headerMessage
);
$this
->
getOutput
()->
addHTML
(
$panel
->
toString
()
);
}
private
function
isSwitch
():
bool
{
return
$this
->
requestedModule
instanceof
IModule
&&
$this
->
action
===
static
::
ACTION_ENABLE
&&
$this
->
authUser
->
isTwoFactorAuthEnabled
();
}
}
File Metadata
Details
Attached
Mime Type
text/x-php
Expires
Tue, Aug 18, 17:45 (3 w, 3 d ago)
Storage Engine
local-disk
Storage Format
Raw Data
Storage Handle
34/05/0c319c977234e6deee08e57e1bd6
Default Alt Text
OATHManage.php (11 KB)
Attached To
Mode
rMWPROD MediaWiki Production
Attached
Detach File
Event Timeline
Log In to Comment