Skip to content

Commit

Permalink
Add full fetch result to host result
Browse files Browse the repository at this point in the history
  • Loading branch information
spaze committed May 13, 2024
1 parent 866dfeb commit 97f687e
Show file tree
Hide file tree
Showing 5 changed files with 91 additions and 12 deletions.
6 changes: 4 additions & 2 deletions bin/checksecuritytxt.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use Spaze\SecurityTxt\Check\SecurityTxtCheckHostResultFactory;
use Spaze\SecurityTxt\Fetcher\HttpClients\SecurityTxtFetcherFopenClient;
use Spaze\SecurityTxt\Fetcher\SecurityTxtFetcher;
use Spaze\SecurityTxt\Fetcher\SecurityTxtFetchResultFactory;
use Spaze\SecurityTxt\Json\SecurityTxtJson;
use Spaze\SecurityTxt\Parser\SecurityTxtParser;
use Spaze\SecurityTxt\Parser\SecurityTxtUrlParser;
Expand Down Expand Up @@ -42,8 +43,9 @@
$urlParser = new SecurityTxtUrlParser();
$consolePrinter = new ConsolePrinter();
$securitytxtFactory = new SecurityTxtFactory();
$violationFactory = new SecurityTxtJson();
$checkHostResultFactory = new SecurityTxtCheckHostResultFactory($securitytxtFactory, $violationFactory);
$json = new SecurityTxtJson();
$fetchResultFactory = new SecurityTxtFetchResultFactory($json);
$checkHostResultFactory = new SecurityTxtCheckHostResultFactory($securitytxtFactory, $json, $fetchResultFactory);
$checkHost = new SecurityTxtCheckHost($parser, $urlParser, $fetcher, $checkHostResultFactory);
$checkHostCli = new SecurityTxtCheckHostCli($consolePrinter, $checkHost);

Expand Down
13 changes: 11 additions & 2 deletions src/Check/SecurityTxtCheckHostResult.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,27 +4,29 @@
namespace Spaze\SecurityTxt\Check;

use JsonSerializable;
use Spaze\SecurityTxt\Fetcher\SecurityTxtFetchResult;
use Spaze\SecurityTxt\SecurityTxt;
use Spaze\SecurityTxt\Violations\SecurityTxtSpecViolation;

class SecurityTxtCheckHostResult implements JsonSerializable
{

/**
* @param list<SecurityTxtSpecViolation> $fileWarnings
* @param array<string, list<string>> $redirects
* @param list<SecurityTxtSpecViolation> $fetchErrors
* @param list<SecurityTxtSpecViolation> $fetchWarnings
* @param array<int, list<SecurityTxtSpecViolation>> $lineErrors
* @param array<int, list<SecurityTxtSpecViolation>> $lineWarnings
* @param list<SecurityTxtSpecViolation> $fileErrors
* @param list<SecurityTxtSpecViolation> $fileWarnings
* @param list<SecurityTxtSpecViolation> $fetchErrors
*/
public function __construct(
private readonly string $host,
private readonly ?array $redirects,
private readonly ?string $constructedUrl,
private readonly ?string $finalUrl,
private readonly ?string $contents,
private readonly ?SecurityTxtFetchResult $fetchResult,
private readonly array $fetchErrors,
private readonly array $fetchWarnings,
private readonly array $lineErrors,
Expand Down Expand Up @@ -171,6 +173,12 @@ public function getExpiresWarningThreshold(): ?int
}


public function getFetchResult(): ?SecurityTxtFetchResult
{
return $this->fetchResult;
}


/**
* @return array<string, mixed>
*/
Expand All @@ -183,6 +191,7 @@ public function jsonSerialize(): array
'constructedUrl' => $this->getConstructedUrl(),
'finalUrl' => $this->getFinalUrl(),
'contents' => $this->getContents(),
'fetchResult' => $this->getFetchResult(),
'fetchErrors' => $this->getFetchErrors(),
'fetchWarnings' => $this->getFetchWarnings(),
'lineErrors' => $this->getLineErrors(),
Expand Down
4 changes: 4 additions & 0 deletions src/Check/SecurityTxtCheckHostResultFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
namespace Spaze\SecurityTxt\Check;

use Spaze\SecurityTxt\Check\Exceptions\SecurityTxtCannotParseJsonException;
use Spaze\SecurityTxt\Fetcher\SecurityTxtFetchResultFactory;
use Spaze\SecurityTxt\Json\SecurityTxtJson;
use Spaze\SecurityTxt\Parser\SecurityTxtParseResult;
use Spaze\SecurityTxt\SecurityTxtFactory;
Expand All @@ -14,6 +15,7 @@ class SecurityTxtCheckHostResultFactory
public function __construct(
private readonly SecurityTxtFactory $securityTxtFactory,
private readonly SecurityTxtJson $securityTxtJson,
private readonly SecurityTxtFetchResultFactory $securityTxtFetchResultFactory,
) {
}

Expand All @@ -26,6 +28,7 @@ public function create(string $host, SecurityTxtParseResult $parseResult): Secur
$parseResult->getFetchResult()?->getConstructedUrl(),
$parseResult->getFetchResult()?->getFinalUrl(),
$parseResult->getFetchResult()?->getContents(),
$parseResult->getFetchResult(),
$parseResult->getFetchErrors(),
$parseResult->getFetchWarnings(),
$parseResult->getLineErrors(),
Expand Down Expand Up @@ -130,6 +133,7 @@ public function createFromJsonValues(array $values): SecurityTxtCheckHostResult
$values['constructedUrl'],
$values['finalUrl'],
$values['contents'],
$this->securityTxtFetchResultFactory->createFromJsonValues($values['fetchResult']),
$this->securityTxtJson->createViolationsFromJsonValues(array_values($values['fetchErrors'])),
$this->securityTxtJson->createViolationsFromJsonValues(array_values($values['fetchWarnings'])),
$lineErrors,
Expand Down
23 changes: 18 additions & 5 deletions tests/Check/SecurityTxtCheckHostResultFactoryTest.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ namespace Spaze\SecurityTxt\Check;
use DateInterval;
use DateTimeImmutable;
use ReflectionProperty;
use Spaze\SecurityTxt\Fetcher\SecurityTxtFetchResult;
use Spaze\SecurityTxt\Fetcher\SecurityTxtFetchResultFactory;
use Spaze\SecurityTxt\Fields\Expires;
use Spaze\SecurityTxt\Fields\SecurityTxtField;
use Spaze\SecurityTxt\Json\SecurityTxtJson;
Expand All @@ -32,8 +34,9 @@ class SecurityTxtCheckHostResultFactoryTest extends TestCase
public function testCreateFromJson(): void
{
$securityTxtFactory = new SecurityTxtFactory();
$violationFactory = new SecurityTxtJson();
$resultFactory = new SecurityTxtCheckHostResultFactory($securityTxtFactory, $violationFactory);
$json = new SecurityTxtJson();
$fetchResultFactory = new SecurityTxtFetchResultFactory($json);
$resultFactory = new SecurityTxtCheckHostResultFactory($securityTxtFactory, $json, $fetchResultFactory);
$expectedResult = $this->getResult();
$actualResult = $resultFactory->createFromJsonValues(json_decode(json_encode($expectedResult), true));
$this->setExpiresInterval($expectedResult);
Expand All @@ -55,14 +58,24 @@ class SecurityTxtCheckHostResultFactoryTest extends TestCase
$securityTxt = new SecurityTxt(SecurityTxtValidationLevel::AllowInvalidValuesSilently);
$dateTime = new DateTimeImmutable('2022-08-08T02:40:54+00:00');
$securityTxt->setExpires(new Expires($dateTime));
return new SecurityTxtCheckHostResult(
'www.example.com',
['http://example.com' => ['https://example.com', 'https://www.example.com']],
$fetchResult = new SecurityTxtFetchResult(
'http://www.example.com/.well-known/security.txt',
'https://www.example.com/.well-known/security.txt',
['http://example.com' => ['https://example.com', 'https://www.example.com']],
"Hi-ring: https://example.com/hiring\nExpires: " . $dateTime->format(DATE_RFC3339),
[new SecurityTxtSchemeNotHttps('http://example.com')],
[new SecurityTxtWellKnownPathOnly()],
);

return new SecurityTxtCheckHostResult(
'www.example.com',
$fetchResult->getRedirects(),
$fetchResult->getConstructedUrl(),
$fetchResult->getFinalUrl(),
$fetchResult->getContents(),
$fetchResult,
$fetchResult->getErrors(),
$fetchResult->getWarnings(),
[2 => [new SecurityTxtLineNoEol('Contact: https://example.com/contact')]],
[1 => [new SecurityTxtPossibelFieldTypo('Hi-ring', SecurityTxtField::Hiring->value, 'Hi-ring: https://example.com/hiring')]],
[new SecurityTxtNoContact()],
Expand Down
57 changes: 54 additions & 3 deletions tests/Check/SecurityTxtCheckHostTest.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ declare(strict_types = 1);
namespace Spaze\SecurityTxt\Check;

use DateTimeImmutable;
use Spaze\SecurityTxt\Fetcher\SecurityTxtFetchResult;
use Spaze\SecurityTxt\Fields\Expires;
use Spaze\SecurityTxt\Fields\SecurityTxtField;
use Spaze\SecurityTxt\SecurityTxt;
Expand Down Expand Up @@ -45,6 +46,47 @@ class SecurityTxtCheckHostTest extends TestCase
'constructedUrl' => 'http://www.example.com/.well-known/security.txt',
'finalUrl' => 'https://www.example.com/.well-known/security.txt',
'contents' => "Hi-ring: https://example.com/hiring\nExpires: " . $this->expires->format(DATE_RFC3339),
'fetchResult' => [
'class' => 'Spaze\SecurityTxt\Fetcher\SecurityTxtFetchResult',
'constructedUrl' => 'http://www.example.com/.well-known/security.txt',
'finalUrl' => 'https://www.example.com/.well-known/security.txt',
'redirects' => [
'http://example.com' => ['https://example.com', 'https://www.example.com'],
],
'contents' => "Hi-ring: https://example.com/hiring\nExpires: " . $this->expires->format(DATE_RFC3339),
'errors' => [
[
'class' => 'Spaze\SecurityTxt\Violations\SecurityTxtSchemeNotHttps',
'params' => ['http://example.com'],
'message' => 'The file at `http://example.com` must use HTTPS',
'messageFormat' => 'The file at `%s` must use HTTPS',
'messageValues' => ['http://example.com'],
'since' => 'draft-foudil-securitytxt-06',
'correctValue' => 'https://example.com',
'howToFix' => 'Use HTTPS to serve the `security.txt` file',
'howToFixFormat' => 'Use HTTPS to serve the `security.txt` file',
'howToFixValues' => [],
'specSection' => '3',
'seeAlsoSections' => [],
],
],
'warnings' => [
[
'class' => 'Spaze\SecurityTxt\Violations\SecurityTxtWellKnownPathOnly',
'params' => [],
'message' => '`security.txt` not found at the top-level path',
'messageFormat' => '`security.txt` not found at the top-level path',
'messageValues' => [],
'since' => 'draft-foudil-securitytxt-02',
'correctValue' => null,
'howToFix' => 'Redirect the top-level file to the one under the `/.well-known/` path',
'howToFixFormat' => 'Redirect the top-level file to the one under the `/.well-known/` path',
'howToFixValues' => [],
'specSection' => '3',
'seeAlsoSections' => [],
],
],
],
'fetchErrors' => [
[
'class' => SecurityTxtSchemeNotHttps::class,
Expand Down Expand Up @@ -171,14 +213,23 @@ class SecurityTxtCheckHostTest extends TestCase
{
$securityTxt = new SecurityTxt();
$securityTxt->setExpires(new Expires($this->expires));
return new SecurityTxtCheckHostResult(
'www.example.com',
['http://example.com' => ['https://example.com', 'https://www.example.com']],
$fetchResult = new SecurityTxtFetchResult(
'http://www.example.com/.well-known/security.txt',
'https://www.example.com/.well-known/security.txt',
['http://example.com' => ['https://example.com', 'https://www.example.com']],
"Hi-ring: https://example.com/hiring\nExpires: " . $this->expires->format(DATE_RFC3339),
[new SecurityTxtSchemeNotHttps('http://example.com')],
[new SecurityTxtWellKnownPathOnly()],
);
return new SecurityTxtCheckHostResult(
'www.example.com',
$fetchResult->getRedirects(),
$fetchResult->getConstructedUrl(),
$fetchResult->getFinalUrl(),
$fetchResult->getContents(),
$fetchResult,
$fetchResult->getErrors(),
$fetchResult->getWarnings(),
[2 => [new SecurityTxtLineNoEol('Contact: https://example.com/contact')]],
[1 => [new SecurityTxtPossibelFieldTypo('Hi-ring', SecurityTxtField::Hiring->value, 'Hi-ring: https://example.com/hiring')]],
[new SecurityTxtNoContact()],
Expand Down

0 comments on commit 97f687e

Please sign in to comment.