diff --git a/.env.example b/.env.example index 8556048ac..add36ac45 100644 --- a/.env.example +++ b/.env.example @@ -23,7 +23,6 @@ REDIS_DB="2" REDIS_CACHE_DB="3" REDIS_PREFIX=wbstack_api ROUTES_LOAD_WEB=1 -ROUTES_LOAD_SANDBOX=1 ROUTES_LOAD_BACKEND=1 MAIL_MAILER=mailgun QUERY_SERVICE_HOST=wdqs:9999 diff --git a/README.md b/README.md index 8757149ac..e6443f74b 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,6 @@ The platform API comes in a few different flavours that can be toggled using environment variables: - `ROUTES_LOAD_WEB` - web routes for the public facing wbstack.com usecase -- `ROUTES_LOAD_SANDBOX` - web routes for the public facing sandbox usecase - `ROUTES_LOAD_BACKEND` - internal only API endpoints (non public) for all usecases This single application could likely be split up at some point. Everything is currently together to make use of the shared wiki management code and query service management code. diff --git a/app/Console/Kernel.php b/app/Console/Kernel.php index cca1f77ab..5e91819bd 100644 --- a/app/Console/Kernel.php +++ b/app/Console/Kernel.php @@ -11,7 +11,6 @@ use App\Jobs\PruneEventPageUpdatesTable; use App\Jobs\PruneQueryserviceBatchesTable; use App\Jobs\RequeuePendingQsBatchesJob; -use App\Jobs\SandboxCleanupJob; use App\Jobs\SendEmptyWikiNotificationsJob; use App\Jobs\UpdateQueryserviceAllowList; use App\Jobs\UpdateWikiDailyMetricJob; @@ -40,11 +39,6 @@ protected function schedule(Schedule $schedule): void { $schedule->job(new RequeuePendingQsBatchesJob())->everyFifteenMinutes()->withoutOverlapping(); $schedule->job(new FailStalledEntityImportsJob())->hourly(); - // Sandbox - // TODO this should maybe only be run when sandbox as a whole is loaded? - // TODO instead of using LOAD ROUTES, we should just have different modes? - $schedule->job(new SandboxCleanupJob())->everyFifteenMinutes()->withoutOverlapping(); - // Schedule site stat updates for each wiki and platform-summary $schedule->command('schedule:stats')->dailyAt('7:00'); diff --git a/app/Http/Controllers/Sandbox/SandboxController.php b/app/Http/Controllers/Sandbox/SandboxController.php deleted file mode 100644 index f7c9a60bc..000000000 --- a/app/Http/Controllers/Sandbox/SandboxController.php +++ /dev/null @@ -1,128 +0,0 @@ - 'required|captcha', - // TODO validate dataSet param - ]; - $validator = Validator::make($request->all(), $validation); - $validator->validate(); - - $domain = $this->generateDomain(); - $dataSet = $request->get('dataSet'); - - $wiki = null; - DB::transaction(function () use (&$wiki, $domain): void { - $wikiDbCondition = ['wiki_id' => null, 'version' => self::MW_VERSION]; - - // Fail if there is not enough storage ready - if (WikiDb::where($wikiDbCondition)->count() == 0) { - abort(503, 'No databases ready'); - } - if (QueryserviceNamespace::where('wiki_id', null)->count() == 0) { - abort(503, 'No query namespaces ready'); - } - - $wiki = Wiki::create([ - 'sitename' => 'Sandbox', - 'domain' => strtolower($domain), - ]); - - // Assign storage - $dbAssignment = DB::table('wiki_dbs')->where($wikiDbCondition)->limit(1)->update(['wiki_id' => $wiki->id]); - if (!$dbAssignment) { - abort(503, 'Database ready, but failed to assign'); - } - $nsAssignment = DB::table('queryservice_namespaces')->where(['wiki_id' => null])->limit(1)->update(['wiki_id' => $wiki->id]); - if (!$nsAssignment) { - abort(503, 'QS Namespace ready, but failed to assign'); - } - - // Create initial needed non default settings - // Docs: https://www.mediawiki.org/wiki/Manual:$wgSecretKey - WikiSetting::create([ - 'wiki_id' => $wiki->id, - 'name' => 'wgSecretKey', - 'value' => Str::random(64), - ]); - - WikiSetting::create([ - 'wiki_id' => $wiki->id, - 'name' => 'wwSandboxAutoUserLogin', - 'value' => '1', - ]); - - // Also track the domain forever in your domains table - $wikiDomain = WikiDomain::create([ - 'domain' => $wiki->domain, - 'wiki_id' => $wiki->id, - ]); - }); - - // For now only schedule this job for 1 dataSet type - // As the extension API is dumb currently - if ($dataSet === 'library') { - dispatch(new MediawikiSandboxLoadData($domain, $dataSet)); - } - - // opportunistic dispatching of jobs to make sure storage pools are topped up - dispatch(new ProvisionWikiDbJob(null, null, 10)); - dispatch(new ProvisionQueryserviceNamespaceJob(null, 10)); - - $res['success'] = true; - $res['message'] = 'Success!'; - $res['data'] = [ - 'id' => $wiki->id, - 'domain' => $wiki->domain, - ]; - - return response($res); - } - - private function generateUnusedDomain() { - $domain = $this->generateDomain(); - if (!WikiDomain::whereDomain($domain)->first()) { - return $domain; - } - - return $this->generateUnusedDomain(); - } - - private function generateDomain(): string { - $generator = new HumanPasswordGenerator(); - - $generator - ->setWordList(__DIR__ . '/words') - ->setWordCount(3) - ->setWordSeparator('-'); - - $password = $generator->generatePassword(); - - return $password . self::DOT . self::WIKIBASE_DOMAIN; - } -} diff --git a/app/Http/Controllers/Sandbox/words b/app/Http/Controllers/Sandbox/words deleted file mode 100644 index bac7aa1a6..000000000 --- a/app/Http/Controllers/Sandbox/words +++ /dev/null @@ -1,36 +0,0 @@ -cat -hat -bat -sat -rat -kat -wat -mat -cub -doe -dog -elk -fox -ram -seal -bear -calf -deer -fawn -foal -goat -hare -lion -lynx -orca -wold -bison -camel -horse -moose -otter -panda -puppy -sheep -sloth -zebra \ No newline at end of file diff --git a/app/Jobs/MediawikiSandboxLoadData.php b/app/Jobs/MediawikiSandboxLoadData.php deleted file mode 100644 index 8d2944326..000000000 --- a/app/Jobs/MediawikiSandboxLoadData.php +++ /dev/null @@ -1,63 +0,0 @@ -wikiDomain = $wikiDomain; - $this->dataSet = $dataSet; - } - - /** - * @return void - */ - public function handle(MediaWikiHostResolver $mwHostResolver) { - $data = [ - 'dataSet' => $this->dataSet, - ]; - - $curl = curl_init(); - curl_setopt_array($curl, [ - CURLOPT_URL => $mwHostResolver->getBackendHostForDomain($this->wikiDomain) . '/w/rest.php/wikibase-exampledata/v0/load', - CURLOPT_RETURNTRANSFER => true, - CURLOPT_ENCODING => '', - CURLOPT_TIMEOUT => 10 * 60, // TODO Long 10 mins (probably shouldn't keep the request open...) - CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1, - CURLOPT_CUSTOMREQUEST => 'POST', - CURLOPT_POSTFIELDS => http_build_query($data), - CURLOPT_HTTPHEADER => [ - 'content-type: application/x-www-form-urlencoded', - 'host: ' . $this->wikiDomain, - ], - ]); - - $rawResponse = curl_exec($curl); - $err = curl_error($curl); - if ($err) { - $this->fail( - new \RuntimeException('wikibase-exampledata/v0/load curl error for ' . $this->wikiDomain . ': ' . $err) - ); - - return; // safegaurd - } - - curl_close($curl); - - if (!strstr($rawResponse, 'Done!')) { - $this->fail( - new \RuntimeException('wikibase-exampledata/v0/load call for ' . $this->wikiDomain . ' was not successful:' . $rawResponse) - ); - - return; // safegaurd - } - } -} diff --git a/app/Jobs/SandboxCleanupJob.php b/app/Jobs/SandboxCleanupJob.php deleted file mode 100644 index d45b7e9b0..000000000 --- a/app/Jobs/SandboxCleanupJob.php +++ /dev/null @@ -1,13 +0,0 @@ -pluck('wiki_id')->toArray()) - ->where('created_at', '<', date('Y-m-d', strtotime('-1 week')))->delete(); - } -} diff --git a/app/Providers/RouteServiceProvider.php b/app/Providers/RouteServiceProvider.php index fa8d9f433..b5f82c193 100644 --- a/app/Providers/RouteServiceProvider.php +++ b/app/Providers/RouteServiceProvider.php @@ -33,9 +33,6 @@ public function map(): void { if (getenv('ROUTES_LOAD_WEB') == 1) { $this->mapApiRoutes(); } - if (getenv('ROUTES_LOAD_SANDBOX') == 1) { - $this->mapSandboxRoutes(); - } if (getenv('ROUTES_LOAD_BACKEND') == 1) { $this->mapBackendRoutes(); } @@ -51,11 +48,6 @@ protected function mapApiRoutes(): void { ->group(base_path('routes/api.php')); } - protected function mapSandboxRoutes(): void { - Route::namespace($this->namespace) - ->group(base_path('routes/sandbox.php')); - } - protected function mapBackendRoutes(): void { Route::prefix('backend') ->namespace($this->namespace . '\Backend') diff --git a/app/Rules/ForbiddenSubdomains.php b/app/Rules/ForbiddenSubdomains.php index b1afb8053..378840315 100644 --- a/app/Rules/ForbiddenSubdomains.php +++ b/app/Rules/ForbiddenSubdomains.php @@ -139,7 +139,6 @@ 'registration', 'resolver', 'rss', - 'sandbox', 'search', 'secure', 'server', diff --git a/composer.json b/composer.json index 369437582..aec3d2c82 100644 --- a/composer.json +++ b/composer.json @@ -13,7 +13,6 @@ "google/recaptcha": "^1.2", "guzzlehttp/guzzle": "^7.13", "guzzlehttp/psr7": "^2.9", - "hackzilla/password-generator": "^1.6", "intervention/image": "^2.5", "laravel/framework": "^11.51", "laravel/horizon": "^5.23", diff --git a/composer.lock b/composer.lock index 400f554b1..9b192b213 100644 --- a/composer.lock +++ b/composer.lock @@ -4,7 +4,7 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies", "This file is @generated automatically" ], - "content-hash": "4f87450f1479cff4b4f12411ac2cb301", + "content-hash": "6ce39c58b09730b720dcdfe4ee815ada", "packages": [ { "name": "absszero/laravel-stackdriver-error-reporting", @@ -2106,51 +2106,6 @@ ], "time": "2026-05-23T22:00:21+00:00" }, - { - "name": "hackzilla/password-generator", - "version": "1.7.0", - "source": { - "type": "git", - "url": "https://github.com/hackzilla/password-generator.git", - "reference": "743c8493d2c33ebf9496a1c3c248efeb568fe134" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/hackzilla/password-generator/zipball/743c8493d2c33ebf9496a1c3c248efeb568fe134", - "reference": "743c8493d2c33ebf9496a1c3c248efeb568fe134", - "shasum": "" - }, - "require": { - "ext-mbstring": "*", - "php": ">=8.0" - }, - "require-dev": { - "phpunit/phpunit": "^9.0" - }, - "type": "library", - "autoload": { - "psr-4": { - "Hackzilla\\PasswordGenerator\\": "" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Daniel Platt", - "email": "github@ofdan.co.uk", - "homepage": "https://www.hackzilla.org" - } - ], - "description": "Password Generator Library", - "support": { - "issues": "https://github.com/hackzilla/password-generator/issues", - "source": "https://github.com/hackzilla/password-generator/tree/1.7.0" - }, - "time": "2024-08-23T17:13:49+00:00" - }, { "name": "intervention/image", "version": "2.7.2", diff --git a/routes/sandbox.php b/routes/sandbox.php deleted file mode 100644 index b2e704eaf..000000000 --- a/routes/sandbox.php +++ /dev/null @@ -1,12 +0,0 @@ -post('sandbox/create', ['uses' => 'Sandbox\SandboxController@create']) - ->middleware('throttle:5,1');