168 lines
5.7 KiB
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,
|
|
]);
|
|
}
|
|
}
|