fix(core): harden settlement and wallet integration
This commit is contained in:
74
tests/Unit/WalletApiRequestGuardTest.php
Normal file
74
tests/Unit/WalletApiRequestGuardTest.php
Normal file
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
use Illuminate\Http\Client\PendingRequest;
|
||||
use App\Support\Integration\WalletApiRequestGuard;
|
||||
use App\Support\Integration\WalletApiUrlSanitizer;
|
||||
|
||||
test('wallet api sanitizer rejects private and reserved literal addresses', function (string $url): void {
|
||||
expect(WalletApiUrlSanitizer::normalizeAndValidate($url))->toBeNull();
|
||||
})->with([
|
||||
'ipv4 loopback' => 'https://127.0.0.1',
|
||||
'ipv4 shortened notation' => 'https://127.1',
|
||||
'ipv4 decimal integer notation' => 'https://2130706433',
|
||||
'ipv4 hexadecimal notation' => 'https://0x7f000001',
|
||||
'ipv4 octal notation' => 'https://0177.0.0.1',
|
||||
'ipv4 private' => 'https://10.0.0.1',
|
||||
'ipv4 link local' => 'https://169.254.169.254',
|
||||
'ipv4 cgnat' => 'https://100.64.0.1',
|
||||
'ipv4 documentation' => 'https://192.0.2.1',
|
||||
'ipv6 loopback' => 'https://[::1]',
|
||||
'ipv6 unique local' => 'https://[fd00::1]',
|
||||
'ipv6 link local' => 'https://[fe80::1]',
|
||||
'ipv6 nat64 private target' => 'https://[64:ff9b::a00:1]',
|
||||
'ipv6 protocol assignment' => 'https://[2001::1]',
|
||||
'ipv6 documentation' => 'https://[2001:db8::1]',
|
||||
]);
|
||||
|
||||
test('wallet api guard rejects hostname when any dns answer is non-public', function (): void {
|
||||
fakeWalletApiDns([
|
||||
'wallet.example.test' => ['93.184.216.34', '10.0.0.8'],
|
||||
], []);
|
||||
|
||||
expect(app(WalletApiRequestGuard::class)->guard('https://wallet.example.test', 10))
|
||||
->toBeNull();
|
||||
});
|
||||
|
||||
test('wallet api guard rejects unresolved hostname', function (): void {
|
||||
fakeWalletApiDns([], []);
|
||||
|
||||
expect(app(WalletApiRequestGuard::class)->guard('https://missing.example.test', 10))
|
||||
->toBeNull();
|
||||
});
|
||||
|
||||
test('wallet api guard accepts public ipv4 and ipv6 dns answers and bounds connect timeout', function (): void {
|
||||
fakeWalletApiDns([
|
||||
'wallet.example.test' => ['93.184.216.34', '2606:4700:4700::1111'],
|
||||
], []);
|
||||
|
||||
$endpoint = app(WalletApiRequestGuard::class)->guard('https://wallet.example.test:8443', 120);
|
||||
|
||||
expect($endpoint)->not->toBeNull()
|
||||
->and($endpoint?->baseUrl)->toBe('https://wallet.example.test:8443')
|
||||
->and($endpoint?->port)->toBe(8443)
|
||||
->and($endpoint?->pinnedIp)->toBe('93.184.216.34')
|
||||
->and($endpoint?->totalTimeoutSeconds)->toBe(120)
|
||||
->and($endpoint?->connectTimeoutSeconds)->toBe(5);
|
||||
|
||||
$pending = $endpoint?->request(['Authorization' => 'Bearer secret']);
|
||||
$optionsProperty = new ReflectionProperty(PendingRequest::class, 'options');
|
||||
$options = $optionsProperty->getValue($pending);
|
||||
|
||||
expect($options['allow_redirects'] ?? null)->toBeFalse()
|
||||
->and($options['proxy'] ?? null)->toBe('')
|
||||
->and($options['timeout'] ?? null)->toBe(120)
|
||||
->and($options['connect_timeout'] ?? null)->toBe(5)
|
||||
->and($options['curl'][CURLOPT_RESOLVE] ?? null)
|
||||
->toBe(['wallet.example.test:8443:93.184.216.34']);
|
||||
});
|
||||
|
||||
test('wallet api sanitizer accepts normal public literals', function (): void {
|
||||
expect(WalletApiUrlSanitizer::normalizeAndValidate('https://93.184.216.34'))
|
||||
->toBe('https://93.184.216.34')
|
||||
->and(WalletApiUrlSanitizer::normalizeAndValidate('https://[2606:4700:4700::1111]'))
|
||||
->toBe('https://[2606:4700:4700::1111]');
|
||||
});
|
||||
Reference in New Issue
Block a user