Passed
Push — master ( 0010e9...022bc2 )
by Thomas
11:25
created

CollectedClientData::fromJson()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 28
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 15
CRAP Score 3

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 18
nc 3
nop 1
dl 0
loc 28
ccs 15
cts 15
cp 1
crap 3
rs 9.6666
c 1
b 0
f 0
1
<?php
2
3
namespace MadWizard\WebAuthn\Dom;
4
5
use MadWizard\WebAuthn\Exception\DataValidationException;
6
use MadWizard\WebAuthn\Exception\VerificationException;
7
use MadWizard\WebAuthn\Exception\WebAuthnException;
8
use MadWizard\WebAuthn\Format\ByteBuffer;
9
use MadWizard\WebAuthn\Format\DataValidator;
10
11
final class CollectedClientData
12
{
13
    /**
14
     * @var string
15
     */
16
    private $type;
17
18
    /**
19
     * @var string
20
     */
21
    private $challenge;
22
23
    /**
24
     * @var string
25
     */
26
    private $origin;
27
28
    /**
29
     * @var TokenBinding|null
30
     */
31
    private $tokenBinding;
32
33 22
    public function __construct(string $type, string $challenge, string $origin)
34
    {
35 22
        $this->type = $type;
36 22
        $this->challenge = $challenge;
37 22
        $this->origin = $origin;
38 22
    }
39
40 2
    public function withTokenBinding(TokenBinding $tokenBinding): self
41
    {
42 2
        $copy = clone $this;
43 2
        $copy->tokenBinding = $tokenBinding;
44 2
        return $copy;
45
    }
46
47 23
    public static function fromJson(array $clientDataJson): self
48
    {
49
        try {
50 23
            DataValidator::checkArray(
51 23
                $clientDataJson,
52
                [
53 23
                    'type' => 'string',
54
                    'challenge' => 'string',
55
                    'origin' => 'string',
56
                    'tokenBinding' => '?array',
57
                ],
58 23
                false
59
            );
60 1
        } catch (DataValidationException $e) {
61 1
            throw new VerificationException('Missing data or unexpected type in clientDataJSON', 0, $e);
62
        }
63
64 22
        $clientData = new self(
65 22
            $clientDataJson['type'],
66 22
            $clientDataJson['challenge'],
67 22
            $clientDataJson['origin']
68
        );
69 22
        $tokenBindingJson = $clientDataJson['tokenBinding'] ?? null;
70
71 22
        if ($tokenBindingJson !== null) {
72 4
            $clientData = $clientData->withTokenBinding(self::parseTokenBinding($tokenBindingJson));
73
        }
74 20
        return $clientData;
75
    }
76
77 4
    private static function parseTokenBinding(array $tokenBindingJson): TokenBinding
78
    {
79
        try {
80 4
            DataValidator::checkArray(
81 4
                $tokenBindingJson,
82
                [
83 4
                    'status' => 'string',
84
                    'id' => '?string',
85
                ],
86 4
                false
87
            );
88 1
        } catch (DataValidationException $e) {
89 1
            throw new VerificationException('Missing data or unexpected type in tokenBinding', 0, $e);
90
        }
91
92
        try {
93 3
            $id = null;
94 3
            $encodedId = $tokenBindingJson['id'] ?? null;
95 3
            if ($encodedId !== null) {
96 1
                $id = ByteBuffer::fromBase64Url($encodedId);
97
            }
98 3
            return new TokenBinding($tokenBindingJson['status'], $id);
99 1
        } catch (WebAuthnException $e) {
100 1
            throw new VerificationException(sprintf('Invalid token binding: %s', $e->getMessage()), 0, $e);
101
        }
102
    }
103
104 11
    public function getType(): string
105
    {
106 11
        return $this->type;
107
    }
108
109 9
    public function getChallenge(): string
110
    {
111 9
        return $this->challenge;
112
    }
113
114 8
    public function getOrigin(): string
115
    {
116 8
        return $this->origin;
117
    }
118
119 7
    public function getTokenBinding(): ?TokenBinding
120
    {
121 7
        return $this->tokenBinding;
122
    }
123
}
124