Passed
Push — master ( f0e418...035269 )
by Rogier
01:48
created

DomainValidation::challengeSucceeded()   B

Complexity

Conditions 7
Paths 4

Size

Total Lines 24
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 12
c 0
b 0
f 0
dl 0
loc 24
rs 8.8333
cc 7
nc 4
nop 2
1
<?php
2
3
namespace Rogierw\RwAcme\Endpoints;
4
5
use Rogierw\RwAcme\DTO\AccountData;
6
use Rogierw\RwAcme\DTO\DomainValidationData;
7
use Rogierw\RwAcme\DTO\OrderData;
8
use Rogierw\RwAcme\Exceptions\DomainValidationException;
9
use Rogierw\RwAcme\Http\Response;
10
use Rogierw\RwAcme\Support\Arr;
11
use Rogierw\RwAcme\Support\JsonWebKey;
12
13
class DomainValidation extends Endpoint
14
{
15
    const TYPE_HTTP = 'http-01';
16
    const TYPE_DNS = 'dns-01';
17
18
    /** @return DomainValidationData[] */
19
    public function status(OrderData $orderData, string $type = 'all'): array
0 ignored issues
show
Unused Code introduced by
The parameter $type is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

19
    public function status(OrderData $orderData, /** @scrutinizer ignore-unused */ string $type = 'all'): array

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
20
    {
21
        $data = [];
22
23
        foreach ($orderData->domainValidationUrls as $domainValidationUrl) {
24
            $response = $this->client
25
                ->getHttpClient()
26
                ->post(
27
                    $domainValidationUrl,
28
                    $this->createKeyId($orderData->accountUrl, $domainValidationUrl)
29
                );
30
31
            if ($response->getHttpResponseCode() === 200) {
32
                $data[] = DomainValidationData::fromResponse($response);
33
            }
34
        }
35
36
        return $data;
37
    }
38
39
    /** @param DomainValidationData[] $challenges */
40
    public function getFileValidationData(array $challenges): array
41
    {
42
        $thumbprint = JsonWebKey::thumbprint(JsonWebKey::compute($this->getAccountPrivateKey()));
43
44
        $authorizations = [];
45
        foreach ($challenges as $domainValidationData) {
46
            if ($domainValidationData->dns['status'] === 'pending') {
47
                $authorizations[] = [
48
                    'type' => self::TYPE_HTTP,
49
                    'identifier' => $domainValidationData->identifier['value'],
50
                    'filename' => $domainValidationData->file['token'],
51
                    'content' => $domainValidationData->file['token'] . '.' . $thumbprint,
52
                ];
53
            }
54
        }
55
56
        return $authorizations;
57
    }
58
59
    public function start(AccountData $accountData, DomainValidationData $domainValidation): Response
60
    {
61
        $this->client->logger(
62
            'info',
63
            'Start HTTP challenge for ' . Arr::get($domainValidation->identifier, 'value', '')
64
        );
65
66
        $thumbprint = JsonWebKey::thumbprint(JsonWebKey::compute($this->getAccountPrivateKey()));
67
68
        $payload = [
69
            'keyAuthorization' => $domainValidation->file['token'] . '.' . $thumbprint,
70
        ];
71
72
        $data = $this->createKeyId($accountData->url, $domainValidation->file['url'], $payload);
73
74
        return $this->client->getHttpClient()->post($domainValidation->file['url'], $data);
75
    }
76
77
    public function challengeSucceeded(OrderData $orderData, string $challengeType): bool
78
    {
79
        if ($challengeType !== self::TYPE_HTTP) {
80
            throw DomainValidationException::invalidChallengeType($challengeType);
81
        }
82
83
        $count = 0;
84
        while (($status = $this->status($orderData)) && $count < 4) {
85
            if ($challengeType === self::TYPE_HTTP && $this->httpChallengeSucceeded($status)) {
86
                break;
87
            }
88
89
            if ($count === 3) {
90
                return false;
91
            }
92
93
            $this->client->logger('info', 'Challenge is not valid yet. Another attempt in 5 seconds.');
94
95
            sleep(5);
96
97
            $count++;
98
        }
99
100
        return true;
101
    }
102
103
    /** @param DomainValidationData[] $domainValidation */
104
    private function httpChallengeSucceeded(array $domainValidation): bool
105
    {
106
        // Verify if all HTTP challenges has been passed.
107
        foreach ($domainValidation as $status) {
108
            $this->client->logger('info', "Check HTTP challenge of {$status->identifier['value']}.");
109
110
            if (!$status->isValid()) {
111
                return false;
112
            }
113
        }
114
115
        $this->client->logger('info', 'HTTP challenge has been passed.');
116
117
        return true;
118
    }
119
}
120