aboutsummaryrefslogtreecommitdiffstats
path: root/includes/Rest/Module/Module.php
diff options
context:
space:
mode:
authorGergő Tisza <tgr.huwiki@gmail.com>2025-01-15 21:10:02 +0100
committerBartosz Dziewoński <dziewonski@fastmail.fm>2025-01-20 21:54:59 +0000
commitb194aaa5293c98154cb8ef52b0fa5143e4c51814 (patch)
tree7387c812eecebf4a78f7ea3cd587b04aafedfb63 /includes/Rest/Module/Module.php
parent08246012f990f64fe5f908b5fcf91e7e81ba557d (diff)
downloadmediawikicore-b194aaa5293c98154cb8ef52b0fa5143e4c51814.tar.gz
mediawikicore-b194aaa5293c98154cb8ef52b0fa5143e4c51814.zip
Add RestCheckCanExecute hook
Add a REST API hook that allows disabling specific endpoints or rejecting specific requests, similar to ApiCheckCanExecuteHook. Bug: T383011 Change-Id: I8518cb1ad7f00594c9f31d7bf934b1ce74f18da9
Diffstat (limited to 'includes/Rest/Module/Module.php')
-rw-r--r--includes/Rest/Module/Module.php35
1 files changed, 32 insertions, 3 deletions
diff --git a/includes/Rest/Module/Module.php b/includes/Rest/Module/Module.php
index accf693ca2c1..474181425625 100644
--- a/includes/Rest/Module/Module.php
+++ b/includes/Rest/Module/Module.php
@@ -3,10 +3,12 @@
namespace MediaWiki\Rest\Module;
use LogicException;
+use MediaWiki\HookContainer\HookContainer;
use MediaWiki\Profiler\ProfilingContext;
use MediaWiki\Rest\BasicAccess\BasicAuthorizerInterface;
use MediaWiki\Rest\CorsUtils;
use MediaWiki\Rest\Handler;
+use MediaWiki\Rest\Hook\HookRunner;
use MediaWiki\Rest\HttpException;
use MediaWiki\Rest\LocalizedHttpException;
use MediaWiki\Rest\PathTemplateMatcher\ModuleConfigurationException;
@@ -37,16 +39,18 @@ abstract class Module {
*/
public const CACHE_CONFIG_HASH_KEY = 'CONFIG-HASH';
+ private Router $router;
protected string $pathPrefix;
protected ResponseFactory $responseFactory;
private BasicAuthorizerInterface $basicAuth;
private ObjectFactory $objectFactory;
private Validator $restValidator;
private ErrorReporter $errorReporter;
- private Router $router;
+ private HookContainer $hookContainer;
private StatsFactory $stats;
private ?CorsUtils $cors = null;
+ private ?HookRunner $hookRunner = null;
/**
* @param Router $router
@@ -64,7 +68,8 @@ abstract class Module {
BasicAuthorizerInterface $basicAuth,
ObjectFactory $objectFactory,
Validator $restValidator,
- ErrorReporter $errorReporter
+ ErrorReporter $errorReporter,
+ HookContainer $hookContainer
) {
$this->router = $router;
$this->pathPrefix = $pathPrefix;
@@ -73,6 +78,7 @@ abstract class Module {
$this->objectFactory = $objectFactory;
$this->restValidator = $restValidator;
$this->errorReporter = $errorReporter;
+ $this->hookContainer = $hookContainer;
$this->stats = StatsFactory::newNull();
}
@@ -256,6 +262,29 @@ abstract class Module {
}
}
+ private function runRestCheckCanExecuteHook(
+ Handler $handler,
+ string $path,
+ RequestInterface $request
+ ): void {
+ $this->hookRunner ??= new HookRunner( $this->hookContainer );
+ $error = null;
+ $canExecute = $this->hookRunner->onRestCheckCanExecute( $this, $handler, $path, $request, $error );
+ if ( $canExecute !== ( $error === null ) ) {
+ throw new LogicException(
+ 'Hook RestCheckCanExecute returned ' . ( $canExecute ? 'true' : 'false' )
+ . ' but ' . ( $error ? 'did' : 'did not' ) . ' set an error'
+ );
+ } elseif ( $error instanceof HttpException ) {
+ throw $error;
+ } elseif ( $error ) {
+ throw new LogicException(
+ 'RestCheckCanExecute must set a HttpException when returning false, '
+ . 'but got ' . get_class( $error )
+ );
+ }
+ }
+
/**
* Find the handler for a request and execute it
*/
@@ -265,7 +294,7 @@ abstract class Module {
try {
$handler = $this->getHandlerForPath( $path, $request, true );
-
+ $this->runRestCheckCanExecuteHook( $handler, $path, $request );
$response = $this->executeHandler( $handler );
} catch ( HttpException $e ) {
$extraData = [];