You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
129 lines
6.1 KiB
129 lines
6.1 KiB
|
4 days ago
|
<?php
|
||
|
|
|
||
|
|
namespace Tests\Feature;
|
||
|
|
|
||
|
|
use App\Models\Admin;
|
||
|
|
use Illuminate\Support\Facades\Cache;
|
||
|
|
use Illuminate\Support\Facades\DB;
|
||
|
|
use Illuminate\Support\Facades\Hash;
|
||
|
|
use Spatie\Permission\Models\Permission;
|
||
|
|
use Tests\TestCase;
|
||
|
|
|
||
|
|
class DisplayDashboardAccessTest extends TestCase
|
||
|
|
{
|
||
|
|
protected function setUp(): void
|
||
|
|
{
|
||
|
|
parent::setUp();
|
||
|
|
config([
|
||
|
|
'app.key' => 'base64:' . base64_encode(str_repeat('a', 32)),
|
||
|
|
'database.default' => 'sqlite',
|
||
|
|
'database.connections.sqlite.database' => ':memory:',
|
||
|
|
'cache.default' => 'array',
|
||
|
|
'session.driver' => 'array',
|
||
|
|
'audit.enabled' => false,
|
||
|
|
]);
|
||
|
|
DB::purge('sqlite');
|
||
|
|
app('migration.repository')->createRepository();
|
||
|
|
$migrations = [
|
||
|
|
'2019_12_14_000001_create_personal_access_tokens_table.php',
|
||
|
|
'2022_03_30_173108_create_permission_tables.php',
|
||
|
|
'2022_03_30_175453_create_admins_table.php',
|
||
|
|
'2022_04_06_102925_add_api_prefix_to_permissions.php',
|
||
|
|
'2022_08_18_105251_create_operate_logs_table.php',
|
||
|
|
'2024_07_17_135941_create_configs_table.php',
|
||
|
|
'2026_11_11_000001_add_display_account_to_admins.php',
|
||
|
|
];
|
||
|
|
app('migrator')->run(array_map(fn ($file) => database_path('migrations/' . $file), $migrations));
|
||
|
|
|
||
|
|
Cache::put('home_v2_data', [
|
||
|
|
'list' => ['schoolmate_total' => 42, 'internal_count' => 100],
|
||
|
|
'suzhou' => [],
|
||
|
|
'country' => [],
|
||
|
|
'monthCourses' => [[
|
||
|
|
'title' => '研修班',
|
||
|
|
'course' => ['teacher_detail' => [['name' => '带班老师', 'mobile' => '123456']]],
|
||
|
|
]],
|
||
|
|
'yearConfigs' => [],
|
||
|
|
'article' => ['internal_article'],
|
||
|
|
]);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_display_login_issues_a_read_only_cookie_and_logout_revokes_it(): void
|
||
|
|
{
|
||
|
|
$admin = Admin::create([
|
||
|
|
'username' => 'tv',
|
||
|
|
'name' => '电视驾驶舱',
|
||
|
|
'password' => Hash::make('long-test-password'),
|
||
|
|
'is_display_account' => true,
|
||
|
|
]);
|
||
|
|
|
||
|
|
$login = $this->withServerVariables(['REMOTE_ADDR' => '127.0.0.1'])
|
||
|
|
->postJson('/api/admin/auth/login', ['username' => 'tv', 'password' => 'long-test-password']);
|
||
|
|
$login->assertExactJson(['display_only' => true]);
|
||
|
|
$cookie = $login->getCookie(Admin::DISPLAY_COOKIE, false);
|
||
|
|
$this->assertTrue($cookie->isHttpOnly());
|
||
|
|
$this->assertTrue($cookie->isSecure());
|
||
|
|
$this->assertSame('strict', $cookie->getSameSite());
|
||
|
|
$this->assertStringNotContainsString('long-test-password', DB::table('operate_logs')->value('req_parameter'));
|
||
|
|
|
||
|
|
$this->withUnencryptedCookie(Admin::DISPLAY_COOKIE, $cookie->getValue())->withCredentials();
|
||
|
|
$this->postJson('/api/admin/auth/me')->assertExactJson(['display_only' => true]);
|
||
|
|
$this->getJson('/api/admin/display/dashboard')
|
||
|
|
->assertJsonPath('list.schoolmate_total', 42)
|
||
|
|
->assertJsonPath('monthCourses.0.teacher', '带班老师')
|
||
|
|
->assertJsonMissingPath('list.internal_count')
|
||
|
|
->assertJsonMissingPath('monthCourses.0.course')
|
||
|
|
->assertJsonMissingPath('article')
|
||
|
|
->assertHeader('Cache-Control', 'no-store, private');
|
||
|
|
$this->getJson('/api/admin/configs/index')->assertJsonPath('errcode', 40001);
|
||
|
|
$this->getJson('/api/admin/other/courses-home-export')->assertJsonPath('errcode', 40001);
|
||
|
|
$this->postJson('/api/admin/auth-node/save', [])->assertJsonPath('errcode', 40001);
|
||
|
|
|
||
|
|
$this->travel(Admin::DISPLAY_SESSION_MINUTES + 1)->minutes();
|
||
|
|
$this->getJson('/api/admin/display/dashboard')->assertJsonPath('errcode', 40001);
|
||
|
|
$this->travelBack();
|
||
|
|
|
||
|
|
$this->postJson('/api/admin/auth/logout')->assertCookieExpired(Admin::DISPLAY_COOKIE);
|
||
|
|
$this->assertSame(0, $admin->tokens()->count());
|
||
|
|
$this->getJson('/api/admin/display/dashboard')->assertJsonPath('errcode', 40001);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_legacy_statistics_require_admin_auth_and_display_rejects_bearer_tokens(): void
|
||
|
|
{
|
||
|
|
foreach (['home', 'home-v2', 'courses-home-export'] as $path) {
|
||
|
|
$this->getJson('/api/admin/other/' . $path)->assertJsonPath('errcode', 40001);
|
||
|
|
}
|
||
|
|
|
||
|
|
$admin = Admin::create(['name' => '后台用户']);
|
||
|
|
$token = $admin->createToken('token')->plainTextToken;
|
||
|
|
$this->withToken($token)->getJson('/api/admin/other/home-v2')->assertJsonPath('list.schoolmate_total', 42);
|
||
|
|
$this->withToken($token)->getJson('/api/admin/display/dashboard')->assertJsonPath('errcode', 40003);
|
||
|
|
|
||
|
|
$display = Admin::create(['name' => '大屏用户', 'is_display_account' => true]);
|
||
|
|
$scopedToken = $display->createToken('dashboard', [Admin::DISPLAY_ABILITY])->plainTextToken;
|
||
|
|
$this->withToken($scopedToken)->postJson('/api/admin/admin/save', [])->assertJsonPath('errcode', 40003);
|
||
|
|
$this->withToken($scopedToken)->getJson('/api/admin/display/dashboard')->assertJsonPath('errcode', 40001);
|
||
|
|
}
|
||
|
|
|
||
|
|
public function test_only_user_managers_can_create_display_accounts(): void
|
||
|
|
{
|
||
|
|
$manager = Admin::create(['name' => '用户管理员']);
|
||
|
|
$token = $manager->createToken('token')->plainTextToken;
|
||
|
|
$payload = [
|
||
|
|
'name' => '大厅电视',
|
||
|
|
'username' => 'lobby-tv',
|
||
|
|
'password' => 'long-test-password',
|
||
|
|
'is_display_account' => true,
|
||
|
|
];
|
||
|
|
|
||
|
|
$this->withToken($token)->postJson('/api/admin/admin/save', $payload)->assertJsonPath('errcode', 40003);
|
||
|
|
$permission = Permission::create(['name' => '用户管理', 'guard_name' => 'admin']);
|
||
|
|
DB::table('permissions')->where('id', $permission->id)->update(['api_prefix' => 'api/admin/admin']);
|
||
|
|
$manager->givePermissionTo($permission);
|
||
|
|
$this->withToken($token)->postJson('/api/admin/admin/save', $payload)->assertJsonPath('is_display_account', true);
|
||
|
|
$display = Admin::where('username', 'lobby-tv')->firstOrFail();
|
||
|
|
$this->assertTrue($display->isDisplayOnly());
|
||
|
|
$this->assertTrue(Hash::check($payload['password'], $display->password));
|
||
|
|
}
|
||
|
|
}
|