diff --git a/app/Http/Controllers/Backend/WikiReadOnlyController.php b/app/Http/Controllers/Backend/WikiReadOnlyController.php new file mode 100644 index 00000000..0fae6196 --- /dev/null +++ b/app/Http/Controllers/Backend/WikiReadOnlyController.php @@ -0,0 +1,45 @@ +validate([ + 'domain' => 'required|string', + 'readOnly' => 'required|boolean', + ]); + + $domain = $validated['domain']; + $readOnly = $validated['readOnly']; + + $wiki = Wiki::where('domain', $domain)->first(); + if (!$wiki) { + return response()->json([ + 'error' => "Wiki not found for domain '$domain'", + ], 404); + } + + if ($readOnly) { + $wiki->setSetting('wgReadOnly', 'This wiki is currently read-only.'); + + return response()->json([ + 'success' => true, + 'domain' => $domain, + 'message' => 'Wiki set to read-only successfully.', + ]); + } else { + $wiki->deleteSetting('wgReadOnly'); + + return response()->json([ + 'success' => true, + 'domain' => $domain, + 'message' => 'Read-only setting successfully removed for wiki.', + ]); + } + } +} diff --git a/app/Wiki.php b/app/Wiki.php index 109c5588..8807653f 100644 --- a/app/Wiki.php +++ b/app/Wiki.php @@ -159,4 +159,15 @@ public function getDomainDecodedAttribute(): string { public function wikiLatestProfile() { return $this->hasOne(WikiProfile::class)->latestOfMany(); } + + public function setSetting(string $name, string $value): void { + $this->settings()->updateOrCreate( + ['name' => $name], + ['value' => $value] + ); + } + + public function deleteSetting(string $name): ?string { + return $this->settings()->where('name', $name)->delete(); + } } diff --git a/routes/backend.php b/routes/backend.php index 478a4036..b1499068 100644 --- a/routes/backend.php +++ b/routes/backend.php @@ -10,6 +10,8 @@ // GET $router->get('healthz', fn () => "It's Alive"); $router->get('getWikiHostsForDomain', ['uses' => 'MediaWikiHostsController@getWikiHostsForDomain']); +// PUT +$router->put('setWikiReadOnly', ['uses' => 'WikiReadOnlyController@setWikiReadOnly']); $router->group(['prefix' => 'ingress'], function () use ($router) { // GET diff --git a/tests/Routes/Backend/WikiReadOnlyControllerTest.php b/tests/Routes/Backend/WikiReadOnlyControllerTest.php new file mode 100644 index 00000000..2f531dd0 --- /dev/null +++ b/tests/Routes/Backend/WikiReadOnlyControllerTest.php @@ -0,0 +1,70 @@ +putJson($this->route, [ + 'domain' => 'nonexistent.wikibase.cloud', + 'readOnly' => true, + ]); + + $response->assertStatus(404) + ->assertJson([ + 'error' => "Wiki not found for domain 'nonexistent.wikibase.cloud'", + ]); + } + + public function testSetWikiToReadOnly() { + $wiki = Wiki::factory()->create([ + 'domain' => 'somewiki.wikibase.cloud', + ]); + + $response = $this->putJson($this->route, [ + 'domain' => 'somewiki.wikibase.cloud', + 'readOnly' => true, + ]); + + $response->assertStatus(200) + ->assertJson([ + 'success' => true, + 'domain' => 'somewiki.wikibase.cloud', + 'message' => 'Wiki set to read-only successfully.', + ]); + + $this->assertSame( + 'This wiki is currently read-only.', + WikiSetting::whereWikiId($wiki->id)->whereName('wgReadOnly')->first()->value + ); + + } + + public function testDeleteSettingForReadOnlyFalse() { + $wiki = Wiki::factory()->create([ + 'domain' => 'somewiki.wikibase.cloud', + ]); + $wiki->setSetting('wgReadOnly', 'test'); + + $this->putJson($this->route, [ + 'domain' => $wiki->domain, + 'readOnly' => false, + ]) + ->assertStatus(200) + ->assertJson(['message' => 'Read-only setting successfully removed for wiki.']); + + $this->assertNull( + WikiSetting::whereWikiId($wiki->id) + ->whereName('wgReadOnly') + ->first(), + ); + } +}