mirror of
https://gerrit.wikimedia.org/r/mediawiki/extensions/OATHAuth
synced 2024-11-24 00:05:24 +00:00
Convert to HookHandler
Bug: T270971 Change-Id: Idf8dad4872a220624b4355a8a9b5e9a02d0e442c
This commit is contained in:
parent
1d97d5ef1b
commit
85d6681fef
|
@ -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": [
|
||||
|
|
|
@ -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'] );
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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
153
src/Hook/HookHandler.php
Normal 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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Reference in a new issue