diff options
author | Gergő Tisza <tgr.huwiki@gmail.com> | 2025-01-15 21:10:02 +0100 |
---|---|---|
committer | Bartosz Dziewoński <dziewonski@fastmail.fm> | 2025-01-20 21:54:59 +0000 |
commit | b194aaa5293c98154cb8ef52b0fa5143e4c51814 (patch) | |
tree | 7387c812eecebf4a78f7ea3cd587b04aafedfb63 /includes/Rest/Module/Module.php | |
parent | 08246012f990f64fe5f908b5fcf91e7e81ba557d (diff) | |
download | mediawikicore-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.php | 35 |
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 = []; |