Convert to HookHandler

Bug: T270971
Change-Id: Idf8dad4872a220624b4355a8a9b5e9a02d0e442c
This commit is contained in:
Reedy 2020-12-31 03:48:41 +00:00
parent 1d97d5ef1b
commit 85d6681fef
6 changed files with 169 additions and 283 deletions

View file

@ -1,6 +1,6 @@
{
"name": "OATHAuth",
"version": "0.4.4",
"version": "0.5.0",
"author": [
"Ryan Lane",
"Robert Vogel <vogel@hallowelt.com>",
@ -10,7 +10,7 @@
"descriptionmsg": "oathauth-desc",
"type": "other",
"requires": {
"MediaWiki": ">= 1.32.0"
"MediaWiki": ">= 1.35.0"
},
"license-name": "GPL-2.0-or-later AND GPL-3.0-or-later",
"attributes": {
@ -41,10 +41,20 @@
"OATHAuthAlias": "OATHAuth.alias.php"
},
"Hooks": {
"AuthChangeFormFields": "\\MediaWiki\\Extension\\OATHAuth\\Hook\\AuthChangeFormFields\\TOTPExtendTokenField::callback",
"AuthChangeFormFields": "main",
"LoadExtensionSchemaUpdates": "\\MediaWiki\\Extension\\OATHAuth\\Hook\\LoadExtensionSchemaUpdates\\UpdateTables::callback",
"GetPreferences": "\\MediaWiki\\Extension\\OATHAuth\\Hook\\GetPreferences\\AuthModule::callback",
"getUserPermissionsErrors": "\\MediaWiki\\Extension\\OATHAuth\\Hook\\GetUserPermissionsErrors\\CheckExclusiveRights::callback"
"GetPreferences": "main",
"getUserPermissionsErrors": "main"
},
"HookHandlers": {
"main": {
"class": "\\MediaWiki\\Extension\\OATHAuth\\Hook\\HookHandler",
"services": [
"OATHUserRepository",
"PermissionManager",
"MainConfig"
]
}
},
"MessagesDirs": {
"OATHAuth": [

View file

@ -1,80 +0,0 @@
<?php
namespace MediaWiki\Extension\OATHAuth\Hook\AuthChangeFormFields;
use MediaWiki\Auth\AuthenticationRequest;
class TOTPExtendTokenField {
/**
* @var AuthenticationRequest[]
*/
protected $requests;
/**
* @var array
*/
protected $fieldInfo;
/**
* @var array
*/
protected $formDescriptor;
/**
* @var string
*/
protected $action;
/**
* @param AuthenticationRequest[] $requests
* @param array $fieldInfo
* @param array &$formDescriptor
* @param string $action
* @return bool
*/
public static function callback( $requests, $fieldInfo, &$formDescriptor, $action ) {
$handler = new static(
$requests,
$fieldInfo,
$formDescriptor,
$action
);
return $handler->execute();
}
/**
* @param AuthenticationRequest[] $requests
* @param array $fieldInfo
* @param array &$formDescriptor
* @param string $action
*/
protected function __construct( $requests, $fieldInfo, &$formDescriptor, $action ) {
$this->requests = $requests;
$this->fieldInfo = $fieldInfo;
$this->formDescriptor = &$formDescriptor;
$this->action = $action;
}
protected function execute() {
if ( $this->shouldSkip() ) {
return true;
}
$this->formDescriptor['OATHToken'] += [
'cssClass' => 'loginText',
'id' => 'wpOATHToken',
'size' => 20,
'dir' => 'ltr',
'autofocus' => true,
'persistent' => false,
'autocomplete' => false,
'spellcheck' => false,
];
return true;
}
protected function shouldSkip() {
return !isset( $this->fieldInfo['OATHToken'] );
}
}

View file

@ -1,86 +0,0 @@
<?php
namespace MediaWiki\Extension\OATHAuth\Hook\GetPreferences;
use MediaWiki\Extension\OATHAuth\OATHUserRepository;
use MediaWiki\MediaWikiServices;
use OOUI\ButtonWidget;
use OOUI\HorizontalLayout;
use OOUI\LabelWidget;
use SpecialPage;
use User;
class AuthModule {
/**
* @var OATHUserRepository
*/
protected $userRepo;
/**
* @var \User
*/
protected $user;
/**
* @var array
*/
protected $preferences;
/**
* @param User $user
* @param array &$preferences
* @return bool
*/
public static function callback( $user, &$preferences ) {
$userRepo = MediaWikiServices::getInstance()->getService( 'OATHUserRepository' );
$handler = new static( $userRepo, $user, $preferences );
return $handler->execute();
}
/**
* @param OATHUserRepository $userRepo
* @param User $user
* @param array &$preferences
*/
protected function __construct( $userRepo, $user, &$preferences ) {
$this->userRepo = $userRepo;
$this->user = $user;
$this->preferences = &$preferences;
}
protected function execute() {
$oathUser = $this->userRepo->findByUser( $this->user );
// If there is no existing module in user, and the user is not allowed to enable it,
// we have nothing to show.
if ( $oathUser->getModule() === null && !$this->user->isAllowed( 'oathauth-enable' ) ) {
return true;
}
$module = $oathUser->getModule();
$moduleLabel = $module === null ?
wfMessage( 'oauthauth-ui-no-module' ) :
$module->getDisplayName();
$manageButton = new ButtonWidget( [
'href' => SpecialPage::getTitleFor( 'OATHManage' )->getLocalURL(),
'label' => wfMessage( 'oathauth-ui-manage' )->text()
] );
$currentModuleLabel = new LabelWidget( [
'label' => $moduleLabel->text()
] );
$control = new HorizontalLayout( [
'items' => [
$currentModuleLabel,
$manageButton
]
] );
$this->preferences['oathauth-module'] = [
'type' => 'info',
'raw' => true,
'default' => (string)$control,
'label-message' => 'oathauth-prefs-label',
'section' => 'personal/info', ];
return true;
}
}

View file

@ -1,109 +0,0 @@
<?php
namespace MediaWiki\Extension\OATHAuth\Hook\GetUserPermissionsErrors;
use ConfigException;
use MediaWiki\Extension\OATHAuth\OATHAuth;
use MediaWiki\Session\Session;
use RequestContext;
use Title;
use User;
class CheckExclusiveRights {
/**
* Array of rights that a user should only have
* if they authenticated with 2FA
*
* @var array
*/
protected $exclusiveRights;
/**
* @var Session
*/
protected $session;
/**
* @var Title
*/
protected $title;
/**
* @var User
*/
protected $user;
/**
* @var string
*/
protected $action;
/**
* @var string|array
*/
protected $result;
/**
* @param Title $title
* @param User $user
* @param string $action
* @param array &$result
* @return bool
* @throws ConfigException
*/
public static function callback( $title, $user, $action, &$result ) {
$config = RequestContext::getMain()->getConfig();
if ( !$config->has( 'OATHExclusiveRights' ) ) {
return true;
}
$session = $user->getRequest()->getSession();
$exclusiveRights = $config->get( 'OATHExclusiveRights' );
$handler = new static( $exclusiveRights, $session, $title, $user, $action, $result );
return $handler->execute();
}
/**
* @param array $exclusiveRights
* @param Session $session
* @param Title $title
* @param User $user
* @param string $action
* @param array &$result
*/
protected function __construct( $exclusiveRights, $session, $title, $user, $action, &$result ) {
$this->exclusiveRights = $exclusiveRights;
$this->session = $session;
$this->title = $title;
$this->user = $user;
$this->action = $action;
$this->result = &$result;
}
/**
* Take away user rights if not authenticated with 2FA
*
* @return bool
*/
protected function execute() {
if ( !$this->authenticatedOver2FA() && $this->actionBlocked() ) {
$this->addError();
return false;
}
return true;
}
/**
* @return bool
*/
private function authenticatedOver2FA() {
return (bool)$this->session->get( OATHAuth::AUTHENTICATED_OVER_2FA, false );
}
private function actionBlocked() {
return in_array( $this->action, $this->exclusiveRights );
}
private function addError() {
$this->result = 'oathauth-action-exclusive-to-2fa';
}
}

153
src/Hook/HookHandler.php Normal file
View file

@ -0,0 +1,153 @@
<?php
namespace MediaWiki\Extension\OATHAuth\Hook;
use Config;
use MediaWiki\Auth\AuthenticationRequest;
use MediaWiki\Extension\OATHAuth\OATHAuth;
use MediaWiki\Extension\OATHAuth\OATHUserRepository;
use MediaWiki\Permissions\Hook\GetUserPermissionsErrorsHook;
use MediaWiki\Permissions\PermissionManager;
use MediaWiki\Preferences\Hook\GetPreferencesHook;
use MediaWiki\SpecialPage\Hook\AuthChangeFormFieldsHook;
use OOUI\ButtonWidget;
use OOUI\HorizontalLayout;
use OOUI\LabelWidget;
use SpecialPage;
use Title;
use User;
class HookHandler implements
AuthChangeFormFieldsHook,
GetPreferencesHook,
getUserPermissionsErrorsHook
{
/**
* @var OATHUserRepository
*/
private $userRepo;
/**
* @var PermissionManager
*/
private $permissionManager;
/**
* @var Config
*/
private $config;
/**
* @param OATHUserRepository $userRepo
* @param PermissionManager $permissionManager
* @param Config $config
*/
public function __construct( $userRepo, $permissionManager, $config ) {
$this->userRepo = $userRepo;
$this->permissionManager = $permissionManager;
$this->config = $config;
}
/**
* @param AuthenticationRequest[] $requests
* @param array $fieldInfo
* @param array &$formDescriptor
* @param string $action
*
* @return bool
*/
public function onAuthChangeFormFields( $requests, $fieldInfo, &$formDescriptor, $action ) {
if ( !isset( $fieldInfo['OATHToken'] ) ) {
return true;
}
$formDescriptor['OATHToken'] += [
'cssClass' => 'loginText',
'id' => 'wpOATHToken',
'size' => 20,
'dir' => 'ltr',
'autofocus' => true,
'persistent' => false,
'autocomplete' => false,
'spellcheck' => false,
];
return true;
}
/**
* @param User $user
* @param array &$preferences
*
* @return bool
*/
public function onGetPreferences( $user, &$preferences ) {
$oathUser = $this->userRepo->findByUser( $user );
// If there is no existing module in user, and the user is not allowed to enable it,
// we have nothing to show.
if (
$oathUser->getModule() === null &&
!$this->permissionManager->userHasRight( $user, 'oathauth-enable' )
) {
return true;
}
$module = $oathUser->getModule();
$moduleLabel = $module === null ?
wfMessage( 'oauthauth-ui-no-module' ) :
$module->getDisplayName();
$manageButton = new ButtonWidget( [
'href' => SpecialPage::getTitleFor( 'OATHManage' )->getLocalURL(),
'label' => wfMessage( 'oathauth-ui-manage' )->text()
] );
$currentModuleLabel = new LabelWidget( [
'label' => $moduleLabel->text()
] );
$control = new HorizontalLayout( [
'items' => [
$currentModuleLabel,
$manageButton
]
] );
$preferences['oathauth-module'] = [
'type' => 'info',
'raw' => true,
'default' => (string)$control,
'label-message' => 'oathauth-prefs-label',
'section' => 'personal/info',
];
return true;
}
/**
* @param Title $title
* @param User $user
* @param string $action
* @param string &$result
*
* @return bool
*/
public function onGetUserPermissionsErrors( $title, $user, $action, &$result ) {
if ( !$this->config->has( 'OATHExclusiveRights' ) ) {
return true;
}
// TODO: Get the session from somewhere more... sane?
$session = $user->getRequest()->getSession();
if (
!(bool)$session->get( OATHAuth::AUTHENTICATED_OVER_2FA, false ) &&
in_array( $action, $this->config->get( 'OATHExclusiveRights' ) )
) {
$result = 'oathauth-action-exclusive-to-2fa';
return false;
}
return true;
}
}

View file

@ -25,7 +25,7 @@ class UpdateTables {
* @return bool
*/
public static function callback( $updater ) {
$dir = dirname( dirname( dirname( __DIR__ ) ) );
$dir = dirname( __DIR__, 3 );
$handler = new static( $updater, $dir );
return $handler->execute();
}
@ -188,8 +188,6 @@ class UpdateTables {
);
}
}
return true;
}
/**