mirror of
https://github.com/NNTmux/newznab-tmux.git
synced 2026-08-29 09:18:54 +00:00
143 lines
4.8 KiB
PHP
143 lines
4.8 KiB
PHP
<?php
|
|
|
|
declare(strict_types=1);
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Facades\Search;
|
|
use Illuminate\Database\Schema\Blueprint;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Illuminate\Support\Facades\Schema;
|
|
use Tests\TestCase;
|
|
|
|
class FailedReleasesControllerSecurityTest extends TestCase
|
|
{
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
config([
|
|
'app.key' => 'base64:'.base64_encode(random_bytes(32)),
|
|
'cache.default' => 'array',
|
|
'database.default' => 'sqlite',
|
|
'database.connections.sqlite.database' => ':memory:',
|
|
'session.driver' => 'array',
|
|
]);
|
|
DB::purge();
|
|
DB::reconnect();
|
|
$this->createSchema();
|
|
$this->seedSettings();
|
|
}
|
|
|
|
public function test_failed_callback_rejects_userid_without_session_or_api_token(): void
|
|
{
|
|
$this->createUser(1, 'rss-token');
|
|
Search::shouldReceive('searchReleases')->never();
|
|
$this->get(route('failed', [
|
|
'guid' => 'failed-guid',
|
|
'userid' => 1,
|
|
]))->assertStatus(401)
|
|
->assertHeader('X-DNZB-RCode', 401);
|
|
}
|
|
|
|
public function test_failed_callback_uses_api_token_user_and_preserves_token_for_alternate_download(): void
|
|
{
|
|
$this->createUser(1, 'rss-token');
|
|
$this->createUser(999, 'other-token');
|
|
$this->createRelease(10, 'failed-guid', 'Show.Name.1080p.WEB-DL-GROUP', 5000, '2026-06-11 00:00:00');
|
|
$this->createRelease(20, 'alternate-guid', 'Show.Name.1080p.PROPER-GROUP', 5000, '2026-06-12 00:00:00');
|
|
Search::shouldReceive('searchReleases')
|
|
->once()
|
|
->with('Show.Name.1080p', 10)
|
|
->andReturn([20]);
|
|
$response = $this->get(route('failed', [
|
|
'guid' => 'failed-guid',
|
|
'userid' => 999,
|
|
'api_token' => 'rss-token',
|
|
]));
|
|
$response->assertOk();
|
|
$this->assertSame(
|
|
url('/getnzb').'?id=alternate-guid&r=rss-token',
|
|
$response->headers->get('Location'),
|
|
);
|
|
$this->assertDatabaseHas('dnzb_failures', [
|
|
'release_id' => 10,
|
|
'users_id' => 1,
|
|
'failed' => 1,
|
|
]);
|
|
$this->assertDatabaseMissing('dnzb_failures', [
|
|
'release_id' => 10,
|
|
'users_id' => 999,
|
|
]);
|
|
}
|
|
|
|
private function createSchema(): void
|
|
{
|
|
Schema::create('settings', function (Blueprint $table): void {
|
|
$table->string('name')->primary();
|
|
$table->text('value')->nullable();
|
|
});
|
|
Schema::create('users', function (Blueprint $table): void {
|
|
$table->increments('id');
|
|
$table->string('username');
|
|
$table->string('email')->unique();
|
|
$table->string('password');
|
|
$table->unsignedInteger('roles_id')->default(1);
|
|
$table->string('api_token')->nullable();
|
|
$table->boolean('verified')->default(true);
|
|
$table->timestamp('email_verified_at')->nullable();
|
|
$table->rememberToken();
|
|
$table->timestamps();
|
|
$table->softDeletes();
|
|
});
|
|
Schema::create('releases', function (Blueprint $table): void {
|
|
$table->increments('id');
|
|
$table->string('guid')->unique();
|
|
$table->string('searchname');
|
|
$table->unsignedInteger('categories_id');
|
|
$table->timestamp('postdate')->nullable();
|
|
});
|
|
Schema::create('dnzb_failures', function (Blueprint $table): void {
|
|
$table->increments('id');
|
|
$table->unsignedInteger('release_id');
|
|
$table->unsignedInteger('users_id');
|
|
$table->boolean('failed')->default(true);
|
|
});
|
|
}
|
|
|
|
private function seedSettings(): void
|
|
{
|
|
DB::table('settings')->insert([
|
|
['name' => 'innerfileblacklist', 'value' => ''],
|
|
['name' => 'categorizeforeign', 'value' => '0'],
|
|
['name' => 'catwebdl', 'value' => '0'],
|
|
]);
|
|
}
|
|
|
|
private function createUser(int $id, string $apiToken): void
|
|
{
|
|
DB::table('users')->insert([
|
|
'id' => $id,
|
|
'username' => 'user'.$id,
|
|
'email' => 'user'.$id.'@example.test',
|
|
'password' => 'unused',
|
|
'roles_id' => 1,
|
|
'api_token' => $apiToken,
|
|
'verified' => true,
|
|
'email_verified_at' => now(),
|
|
'created_at' => now(),
|
|
'updated_at' => now(),
|
|
]);
|
|
}
|
|
|
|
private function createRelease(int $id, string $guid, string $searchName, int $categoryId, string $postDate): void
|
|
{
|
|
DB::table('releases')->insert([
|
|
'id' => $id,
|
|
'guid' => $guid,
|
|
'searchname' => $searchName,
|
|
'categories_id' => $categoryId,
|
|
'postdate' => $postDate,
|
|
]);
|
|
}
|
|
}
|