diff --git a/docs/api/rest-api.md b/docs/api/rest-api.md index b1639473..9386dd00 100644 --- a/docs/api/rest-api.md +++ b/docs/api/rest-api.md @@ -23,8 +23,9 @@ Demo wiki example: [neowiki.dev/w/rest.php/specs/v0/module/-](https://neowiki.de ## Permissions -Read endpoints enforce the caller's per-page `read` permission: page protection, restricted namespaces, read -whitelists, and permission extensions all apply. When you may not read a page, its read endpoints respond as if +The Subject, Schema, Layout, Mapping and RDF read endpoints enforce the caller's per-page `read` permission: read +whitelists and permission extensions apply. (MediaWiki's `read` action ignores page protection and +`$wgNamespaceProtection`, so neither restricts these endpoints.) When you may not read a page, they respond as if the data were absent — a `null` value, an empty list, or a `404` — rather than with a `403`. Treat a not-found response as "not available": it may mean the data does not exist, or that you may not read it. diff --git a/tests/phpunit/Persistence/MediaWiki/DatabaseSchemaNameLookupTest.php b/tests/phpunit/Persistence/MediaWiki/DatabaseSchemaNameLookupTest.php index 84931000..64df338e 100644 --- a/tests/phpunit/Persistence/MediaWiki/DatabaseSchemaNameLookupTest.php +++ b/tests/phpunit/Persistence/MediaWiki/DatabaseSchemaNameLookupTest.php @@ -141,6 +141,19 @@ public function testUnreadableSchemaNamesAreOmitted(): void { ); } + public function testUnreadableSchemaNamesAreOmittedFromSearchResults(): void { + $denyFirstMatch = static fn ( string $permission, ?PageIdentity $page = null ): bool => + $page === null || $page->getDBkey() !== 'SchemaNameLookupTest21'; + + $names = array_map( + static fn ( TitleValue $title ): string => $title->getText(), + $this->getLookup( $this->mockRegisteredAuthority( $denyFirstMatch ) ) + ->getSchemaNamesMatching( 'SchemaNameLookupTest2', 10 ) + ); + + $this->assertSame( [ 'SchemaNameLookupTest22' ], $names ); + } + public function testGateUsesBindingAuthorizeRead(): void { // probablyCan is a UI-hint check that skips the expensive ACL hook; the filter must // use the binding authorizeRead with the 'read' action. Reverting fails this test.