BastionSSO/tests/Feature/ServerSystemUserManagementTest.php

168 lines
5.7 KiB
PHP

<?php
namespace Tests\Feature;
use App\Models\ServerResource;
use App\Models\ServerUserBinding;
use App\Models\User;
use Illuminate\Foundation\Testing\RefreshDatabase;
use Illuminate\Http\Client\Request;
use Illuminate\Support\Facades\Http;
use Spatie\Permission\Models\Role;
use Tests\TestCase;
class ServerSystemUserManagementTest extends TestCase
{
use RefreshDatabase;
public function test_admin_can_read_server_system_user_meta(): void
{
Http::preventStrayRequests();
Http::fake([
'http://node.test/users' => Http::response([
['username' => 'alice', 'uid' => 1000, 'gid' => 1000, 'home_dir' => '/home/alice', 'shell' => '/bin/bash'],
]),
'http://node.test/groups' => Http::response([
['groupname' => 'dev', 'gid' => 1000, 'members' => ['alice']],
]),
'http://node.test/users/alice/groups' => Http::response(['username' => 'alice', 'groups' => ['dev']]),
]);
$admin = $this->admin();
$server = $this->server();
ServerUserBinding::query()->create([
'user_id' => $admin->id,
'server_resource_id' => $server->id,
'username' => 'alice',
'remote_exists' => true,
]);
$response = $this->actingAs($admin, 'api')->getJson('/servers/'.$server->id.'/system-users/meta');
$response
->assertOk()
->assertJsonPath('code', 0)
->assertJsonPath('data.users.0.username', 'alice')
->assertJsonPath('data.groups.0.groupname', 'dev')
->assertJsonPath('data.user_groups.alice.0', 'dev');
}
public function test_creating_user_can_create_remote_server_account_and_binding(): void
{
Http::preventStrayRequests();
Http::fake([
'http://node.test/users' => Http::response(['status' => 'ok', 'message' => 'User created.'], 201),
]);
$admin = $this->admin();
$server = $this->server();
$response = $this->actingAs($admin, 'api')->postJson('/users', [
'nickname' => 'Alice',
'email' => 'alice@example.com',
'phone' => '13800138000',
'password' => 'secret123',
'server_bindings' => [[
'server_resource_id' => $server->id,
'username' => 'alice',
'create_remote' => true,
'groups' => [],
]],
]);
$response->assertCreated()->assertJsonPath('code', 0);
$user = User::query()->where('email', 'alice@example.com')->firstOrFail();
$this->assertDatabaseHas('server_user_bindings', [
'user_id' => $user->id,
'server_resource_id' => $server->id,
'username' => 'alice',
'remote_exists' => true,
]);
Http::assertSent(function (Request $request): bool {
return $request->method() === 'POST'
&& $request->url() === 'http://node.test/users'
&& $request['username'] === 'alice'
&& is_string($request['password_hash'])
&& str_starts_with($request['password_hash'], '$6$');
});
}
public function test_deleting_sso_user_does_not_delete_remote_server_user(): void
{
Http::fake();
$admin = $this->admin();
$server = $this->server();
$target = User::factory()->create();
ServerUserBinding::query()->create([
'user_id' => $target->id,
'server_resource_id' => $server->id,
'username' => 'target',
'remote_exists' => true,
]);
$response = $this->actingAs($admin, 'api')->deleteJson('/users/'.$target->id);
$response->assertOk()->assertJsonPath('code', 0);
$this->assertDatabaseMissing('server_user_bindings', ['user_id' => $target->id]);
Http::assertNothingSent();
}
public function test_server_list_includes_bound_username_without_exposing_token(): void
{
$admin = $this->admin();
$server = $this->server();
$resource = ServerResource::query()->create([
'parent_id' => $server->id,
'name' => 'ssh',
'display_name' => 'SSH',
'internal_ip' => '10.0.0.10',
'asset_id' => 1,
'account_id' => 2,
'protocols' => ['SSH'],
'is_active' => true,
]);
ServerUserBinding::query()->create([
'user_id' => $admin->id,
'server_resource_id' => $server->id,
'username' => 'admin',
'remote_exists' => true,
]);
$response = $this->actingAs($admin, 'api')->getJson('/servers');
$response
->assertOk()
->assertJsonPath('data.data.0.user_api_configured', true)
->assertJsonMissingPath('data.data.0.user_api_token');
$resourcePayload = collect($response->json('data.data'))->firstWhere('id', $resource->id);
$this->assertSame('admin', $resourcePayload['server_username'] ?? null);
}
private function admin(): User
{
$user = User::factory()->create();
Role::query()->firstOrCreate(['name' => 'admin', 'guard_name' => 'api']);
$user->assignRole('admin');
return $user;
}
private function server(): ServerResource
{
return ServerResource::query()->create([
'name' => 'server01',
'display_name' => 'Server 01',
'internal_ip' => '10.0.0.10',
'user_api_base_url' => 'http://node.test',
'user_api_token' => 'secret-token',
'asset_id' => 1,
'account_id' => null,
'protocols' => [],
'is_active' => true,
]);
}
}