96 lines
4.1 KiB
PHP
96 lines
4.1 KiB
PHP
<?php
|
|
|
|
namespace Tests\Feature;
|
|
|
|
use App\Enums\SystemRole;
|
|
use App\Models\Device;
|
|
use App\Models\DeviceCredential;
|
|
use App\Models\DeviceType;
|
|
use App\Models\DeviceVendor;
|
|
use App\Models\User;
|
|
use App\Services\TenantProvisioningService;
|
|
use Database\Seeders\DeviceCatalogSeeder;
|
|
use Database\Seeders\RolePermissionSeeder;
|
|
use Illuminate\Foundation\Testing\RefreshDatabase;
|
|
use Illuminate\Support\Facades\DB;
|
|
use Tests\TestCase;
|
|
|
|
class DeviceInventoryTest extends TestCase
|
|
{
|
|
use RefreshDatabase;
|
|
|
|
protected function setUp(): void
|
|
{
|
|
parent::setUp();
|
|
$this->seed([RolePermissionSeeder::class, DeviceCatalogSeeder::class]);
|
|
}
|
|
|
|
public function test_tenant_admin_can_create_device_and_other_tenant_cannot_see_it(): void
|
|
{
|
|
[$tenantA, $adminA] = $this->tenant('tenant-a');
|
|
[, $adminB] = $this->tenant('tenant-b');
|
|
$vendor = DeviceVendor::where('slug', 'mikrotik')->firstOrFail();
|
|
$type = DeviceType::where('slug', 'router')->firstOrFail();
|
|
|
|
$this->actingAs($adminA)->post(route('devices.store'), [
|
|
'name' => 'Router Jakarta', 'management_address' => 'router.example.test',
|
|
'management_port' => 8728, 'connection_type' => 'routeros_api',
|
|
'device_vendor_id' => $vendor->id, 'device_type_id' => $type->id,
|
|
'initial_username' => 'admin', 'initial_password' => '',
|
|
'remove_legacy_users_on_activation' => true,
|
|
])->assertRedirect(route('devices.index'));
|
|
|
|
$device = Device::withoutGlobalScope('tenant')->firstOrFail();
|
|
$this->assertSame($tenantA->id, $device->tenant_id);
|
|
$credential = DeviceCredential::withoutGlobalScope('tenant')->where('device_id', $device->id)->firstOrFail();
|
|
$this->assertSame('admin', $credential->username);
|
|
$this->assertSame('', $credential->password);
|
|
$this->assertTrue($device->remove_legacy_users_on_activation);
|
|
$this->actingAs($adminB)->get(route('devices.show', $device))->assertNotFound();
|
|
}
|
|
|
|
public function test_tenant_user_create_access_follows_tenant_policy(): void
|
|
{
|
|
[$tenant, $admin] = $this->tenant('tenant-a');
|
|
setPermissionsTeamId($tenant->id);
|
|
$user = User::factory()->for($tenant)->create();
|
|
$user->assignRole(SystemRole::TenantUser->value);
|
|
$tenant->devicePolicy()->update(['tenant_user_can_create' => false]);
|
|
|
|
$this->actingAs($user)->get(route('devices.create'))->assertForbidden();
|
|
$this->actingAs($admin)->put(route('device-policy.update'), [
|
|
'tenant_user_can_create' => true, 'tenant_user_can_update_own' => true,
|
|
'tenant_user_can_delete_own' => false,
|
|
])->assertRedirect();
|
|
$this->actingAs($user)->get(route('devices.create'))->assertOk();
|
|
}
|
|
|
|
public function test_device_password_is_encrypted_and_hidden(): void
|
|
{
|
|
[$tenant, $admin] = $this->tenant('tenant-a');
|
|
$device = Device::create([
|
|
'tenant_id' => $tenant->id, 'name' => 'Router', 'device_vendor_id' => DeviceVendor::first()->id,
|
|
'device_type_id' => DeviceType::first()->id, 'management_address' => '10.0.0.1',
|
|
'management_port' => 22, 'connection_type' => 'ssh', 'created_by' => $admin->id,
|
|
]);
|
|
$credential = DeviceCredential::create([
|
|
'tenant_id' => $tenant->id, 'device_id' => $device->id, 'name' => 'Management',
|
|
'username' => 'admin', 'password' => 'DeviceSecret!123', 'connection_type' => 'ssh',
|
|
]);
|
|
|
|
$this->assertNotSame('DeviceSecret!123', DB::table('device_credentials')->value('password'));
|
|
$this->assertSame('DeviceSecret!123', $credential->password);
|
|
$this->assertArrayNotHasKey('password', $credential->toArray());
|
|
}
|
|
|
|
private function tenant(string $slug): array
|
|
{
|
|
$tenant = app(TenantProvisioningService::class)->createWithOwner([
|
|
'name' => strtoupper($slug), 'slug' => $slug, 'owner_name' => 'Admin '.$slug,
|
|
'owner_email' => $slug.'@test.local', 'owner_password' => 'Strong!Password123',
|
|
]);
|
|
|
|
return [$tenant, User::withoutGlobalScope('tenant')->where('tenant_id', $tenant->id)->firstOrFail()];
|
|
}
|
|
}
|