Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
10 / 10
100.00% covered (success)
100.00%
5 / 5
CRAP
100.00% covered (success)
100.00%
1 / 1
AbstractUrlReputationProvider
100.00% covered (success)
100.00%
9 / 9
100.00% covered (success)
100.00%
5 / 5
8
100.00% covered (success)
100.00%
1 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 checkIp
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 checkDomain
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 checkUrl
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
2
 isMockMode
100.00% covered (success)
100.00%
3 / 3
100.00% covered (success)
100.00%
1 / 1
3
 queryRemoteUrl
n/a
0 / 0
n/a
0 / 0
0
1<?php
2
3declare(strict_types=1);
4
5/** @license For full copyright and license information, please see the LICENSE.md file. */
6
7namespace App\Modules\Integrations\Infrastructure\Provider;
8
9defined('AMMONLY_APP') || exit('Direct script access is forbidden.');
10
11use App\Modules\Integrations\Domain\Contract\IntegrationProviderInterface;
12use App\Modules\Integrations\Domain\Contract\SecurityCheckResult;
13use App\Modules\Integrations\Infrastructure\Security\SsrfProtectionClientInterface;
14
15/**
16 * Base abstract class for URL and threat reputation security providers.
17 *
18 * Encapsulates mock fallback mode, IP/domain forwarding, and HTTP client dependencies.
19 *
20 * @package App\Modules\Integrations\Infrastructure\Provider
21 */
22abstract class AbstractUrlReputationProvider implements IntegrationProviderInterface
23{
24    /**
25     * AbstractUrlReputationProvider constructor.
26     *
27     * @param SsrfProtectionClientInterface $httpClient   SSRF-protected HTTP client.
28     * @param DemoMockSecurityProvider      $mockProvider Fallback mock provider for sandbox environments.
29     */
30    public function __construct(
31        protected readonly SsrfProtectionClientInterface $httpClient,
32        protected readonly DemoMockSecurityProvider $mockProvider
33    ) {
34    }
35
36    /** {@inheritdoc} */
37    public function checkIp(string $ip, ?string $apiKey, array $config = []): SecurityCheckResult
38    {
39        return $this->mockProvider->checkIp($ip, $apiKey, $config);
40    }
41
42    /** {@inheritdoc} */
43    public function checkDomain(string $domain, ?string $apiKey, array $config = []): SecurityCheckResult
44    {
45        return $this->checkUrl('https://' . $domain, $apiKey, $config);
46    }
47
48    /** {@inheritdoc} */
49    public function checkUrl(string $url, ?string $apiKey, array $config = []): SecurityCheckResult
50    {
51        if ($this->isMockMode($apiKey, $config)) {
52            return $this->mockProvider->checkUrl($url, $apiKey, $config);
53        }
54
55        return $this->queryRemoteUrl($url, $apiKey, $config);
56    }
57
58    /**
59     * Determines whether mock simulation mode should be used.
60     *
61     * @param string|null          $apiKey API key or token.
62     * @param array<string, mixed> $config Provider configuration options.
63     * @return bool True if mock mode is active.
64     */
65    protected function isMockMode(?string $apiKey, array $config): bool
66    {
67        return !empty($config['mock_mode'])
68            || empty($apiKey)
69            || str_starts_with((string) $apiKey, 'demo_');
70    }
71
72    /**
73     * Queries remote reputation endpoint for the given URL.
74     *
75     * @param string               $url    Target URL.
76     * @param string|null          $apiKey Provider API token.
77     * @param array<string, mixed> $config Provider configuration options.
78     * @return SecurityCheckResult Check outcome.
79     */
80    abstract protected function queryRemoteUrl(string $url, ?string $apiKey, array $config): SecurityCheckResult;
81}