Passed
Push — master ( e7e3c4...d0e289 )
by Rogier
01:26
created

Account   A

Complexity

Total Complexity 14

Size/Duplication

Total Lines 89
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 14
eloc 43
dl 0
loc 89
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A initAccountDirectory() 0 12 4
A create() 0 28 3
A buildContactPayload() 0 4 1
A get() 0 22 2
A exists() 0 12 4
1
<?php
2
3
namespace Rogierw\RwAcme\Endpoints;
4
5
use Rogierw\RwAcme\DTO\AccountData;
6
use Rogierw\RwAcme\Support\CryptRSA;
7
use Rogierw\RwAcme\Support\JsonWebSignature;
8
use RuntimeException;
9
10
class Account extends Endpoint
11
{
12
    public function exists(): bool
13
    {
14
        if (!is_dir($this->client->getAccountKeysPath())) {
15
            return false;
16
        }
17
18
        if (is_file($this->client->getAccountKeysPath() . 'private.pem')
19
            && is_file($this->client->getAccountKeysPath() . 'public.pem')) {
20
            return true;
21
        }
22
23
        return false;
24
    }
25
26
    public function create(): AccountData
27
    {
28
        $this->initAccountDirectory();
29
30
        $payload = [
31
            'contact'              => $this->buildContactPayload($this->client->getAccountEmail()),
32
            'termsOfServiceAgreed' => true,
33
        ];
34
35
        $newAccountUrl = $this->client->directory()->newAccount();
36
37
        $signedPayload = JsonWebSignature::generate(
38
            $payload,
39
            $newAccountUrl,
40
            $this->client->nonce()->getNew(),
41
            $this->client->getAccountKeysPath()
42
        );
43
44
        $response = $this->client->getHttpClient()->post(
45
            $newAccountUrl,
46
            $signedPayload
47
        );
48
49
        if ($response->getHttpResponseCode() === 201 && array_key_exists('Location', $response->getRawHeaders())) {
50
            return AccountData::fromResponse($response);
51
        }
52
53
        throw new RuntimeException('Creating account failed.');
54
    }
55
56
    public function get(): AccountData
57
    {
58
        if (!$this->exists()) {
59
            throw new RuntimeException('Account keys not found.');
60
        }
61
62
        $payload = [
63
            'onlyReturnExisting' => true,
64
        ];
65
66
        $newAccountUrl = $this->client->directory()->newAccount();
67
68
        $signedPayload = JsonWebSignature::generate(
69
            $payload,
70
            $newAccountUrl,
71
            $this->client->nonce()->getNew(),
72
            $this->client->getAccountKeysPath()
73
        );
74
75
        $response = $this->client->getHttpClient()->post($newAccountUrl, $signedPayload);
76
77
        return AccountData::fromResponse($response);
78
    }
79
80
    private function initAccountDirectory(string $keyType = 'RSA'): void
81
    {
82
        if ($keyType !== 'RSA') {
83
            throw new RuntimeException('Key type is not supported.');
84
        }
85
86
        if (!is_dir($this->client->getAccountKeysPath())) {
87
            mkdir($this->client->getAccountKeysPath());
88
        }
89
90
        if ($keyType === 'RSA') {
91
            CryptRSA::generate($this->client->getAccountKeysPath());
92
        }
93
    }
94
95
    private function buildContactPayload(string $email): array
96
    {
97
        return [
98
            'mailto:' . $email,
99
        ];
100
    }
101
}
102