diff --git a/app/Http/Controllers/WikiSettingController.php b/app/Http/Controllers/WikiSettingController.php index a96692ec..8e8b4f99 100644 --- a/app/Http/Controllers/WikiSettingController.php +++ b/app/Http/Controllers/WikiSettingController.php @@ -13,10 +13,14 @@ class WikiSettingController extends Controller { /** * @return (SettingWikibaseManifestEquivEntities|string)[][] */ - private function getSettingValidations(): array { + private function getSettingValidations(bool $allowModernSkin = false): array { // FIXME: this list is evil and should be kept in sync with the model in Wiki.php?! (mostly) + $defaultSkinValidation = $allowModernSkin + ? 'in:vector,modern,timeless' + : 'in:vector,timeless'; + return [ - 'wgDefaultSkin' => ['required', 'string', 'in:vector,modern,timeless'], + 'wgDefaultSkin' => ['required', 'string', $defaultSkinValidation], 'wwExtEnableConfirmAccount' => ['required', 'boolean'], 'wwExtEnableWikibaseLexeme' => ['required', 'boolean'], 'wwWikibaseStringLengthString' => ['required', 'integer', 'between:400,2500'], @@ -40,10 +44,17 @@ public function update($setting, Request $request) { 'setting' => 'required|string|in:' . implode(',', array_keys($settingValidations)), ]); $settingName = $request->input('setting'); + $wiki = $request->attributes->get('wiki'); + + if ($settingName === 'wgDefaultSkin' && $request->input('value') === 'modern') { + $hasModernDefault = $wiki->settings() + ->where('name', 'wgDefaultSkin') + ->value('value') === 'modern'; + $settingValidations = $this->getSettingValidations($hasModernDefault); + } $request->validate(['value' => $settingValidations[$settingName]]); $value = $request->input('value'); - $wiki = $request->attributes->get('wiki'); WikiSetting::updateOrCreate( [ diff --git a/tests/Routes/Wiki/SettingUpdateTest.php b/tests/Routes/Wiki/SettingUpdateTest.php index 5f9f1e4b..2808fcf0 100644 --- a/tests/Routes/Wiki/SettingUpdateTest.php +++ b/tests/Routes/Wiki/SettingUpdateTest.php @@ -102,8 +102,28 @@ public function testValidSetting($settingName, $settingValue, $expectedStored) { ); } + public function testExistingModernDefaultCanBeRetained(): void { + $user = User::factory()->create(['verified' => true]); + $wiki = Wiki::factory('nodb')->create(); + WikiManager::factory()->create(['wiki_id' => $wiki->id, 'user_id' => $user->id]); + WikiSetting::factory()->create([ + 'wiki_id' => $wiki->id, + 'name' => 'wgDefaultSkin', + 'value' => 'modern', + ]); + + $this->actingAs($user, 'api') + ->json('POST', str_replace('foo', 'wgDefaultSkin', $this->route), [ + 'wiki' => $wiki->id, + 'setting' => 'wgDefaultSkin', + 'value' => 'modern', + ]) + ->assertStatus(200); + } + public static function provideValidSettingsBadValues() { yield ['wgDefaultSkin', 'foo']; + yield ['wgDefaultSkin', 'modern']; yield ['wwExtEnableConfirmAccount', 'foo']; yield ['wwWikibaseStringLengthString', 12]; yield ['wwWikibaseStringLengthMonolingualText', 12];