$tenant, 'token' => $machineToken]. */ function g7bActiveMachineToken(): array { $tenant = Tenant::factory()->create([ 'contact_email' => 'g7b-machine-tenant-'.uniqid().'@example.ru', ]); User::factory()->create([ 'tenant_id' => $tenant->id, 'is_active' => true, ]); $adminId = DB::table('saas_admin_users')->insertGetId([ 'email' => 'admin-g7b-'.uniqid().'@liderra.ru', 'full_name' => 'G7B Machine Admin', 'password_hash' => '$2y$04$dummy-hash-for-test', 'role' => 'support', 'is_active' => true, 'sso_provider' => 'local', 'is_break_glass' => false, ]); $init = test()->postJson('/api/admin/impersonation/init', [ 'tenant_id' => $tenant->id, 'requested_by' => $adminId, 'reason' => str_repeat('основание для теста машинного ключа ', 2), ])->assertOk()->json(); $verify = test()->postJson('/api/admin/impersonation/verify', [ 'token_id' => $init['token_id'], 'code' => $init['_dev_plain_code'], ])->assertOk()->json(); // Сбрасываем сессию и auth-state Laravel после verify, чтобы следующие // запросы шли только через машинный ключ, не через cookie/session-auth. test()->flushSession(); Auth::logout(); return [ 'tenant' => $tenant, 'token' => $verify['machine_token'], ]; } it('машинный ключ авторизует чтение сделок в периметре тенанта', function () { ['token' => $token] = g7bActiveMachineToken(); $this->withHeader('Authorization', 'Bearer '.$token) ->getJson('/api/deals') ->assertOk(); }); it('битый/несуществующий ключ не авторизует', function () { $this->withHeader('Authorization', 'Bearer lpimp_999999_deadbeefdeadbeef') ->getJson('/api/deals') ->assertUnauthorized(); }); it('машинный ключ НЕ авторизует опасные группы (ключи/деньги)', function () { ['token' => $token] = g7bActiveMachineToken(); $this->withHeader('Authorization', 'Bearer '.$token) ->getJson('/api/api-keys') ->assertUnauthorized(); $this->withHeader('Authorization', 'Bearer '.$token) ->postJson('/api/billing/topup', []) ->assertUnauthorized(); }); it('при активном impersonation вход в админ-зону запрещён (bearer)', function () { ['token' => $token] = g7bActiveMachineToken(); $this->withHeader('Authorization', 'Bearer '.$token) ->getJson('/api/admin/tenants')->assertForbidden(); }); it('обычная cookie-сессия по-прежнему работает на разрешённой группе', function () { $tenant = Tenant::factory()->create(); $user = User::factory()->create([ 'tenant_id' => $tenant->id, 'is_active' => true, ]); $this->actingAs($user) ->withHeader('X-Tenant-Id', (string) $user->tenant_id) ->getJson('/api/deals') ->assertOk(); });