1<?php
2
3declare(strict_types=1);
4
5/*
6 * The MIT License (MIT)
7 *
8 * Copyright (c) 2014-2021 Spomky-Labs
9 *
10 * This software may be modified and distributed under the terms
11 * of the MIT license.  See the LICENSE file for details.
12 */
13
14namespace Webauthn\MetadataService;
15
16use Assert\Assertion;
17use function in_array;
18use JsonSerializable;
19use function Safe\sprintf;
20
21class StatusReport implements JsonSerializable
22{
23    /**
24     * @var string
25     *
26     * @see AuthenticatorStatus
27     */
28    private $status;
29
30    /**
31     * @var string|null
32     */
33    private $effectiveDate;
34
35    /**
36     * @var string|null
37     */
38    private $certificate;
39
40    /**
41     * @var string|null
42     */
43    private $url;
44
45    /**
46     * @var string|null
47     */
48    private $certificationDescriptor;
49
50    /**
51     * @var string|null
52     */
53    private $certificateNumber;
54
55    /**
56     * @var string|null
57     */
58    private $certificationPolicyVersion;
59
60    /**
61     * @var string|null
62     */
63    private $certificationRequirementsVersion;
64
65    public function __construct(string $status, ?string $effectiveDate, ?string $certificate, ?string $url, ?string $certificationDescriptor, ?string $certificateNumber, ?string $certificationPolicyVersion, ?string $certificationRequirementsVersion)
66    {
67        Assertion::inArray($status, AuthenticatorStatus::list(), Utils::logicException('The value of the key "status" is not acceptable'));
68
69        $this->status = $status;
70        $this->effectiveDate = $effectiveDate;
71        $this->certificate = $certificate;
72        $this->url = $url;
73        $this->certificationDescriptor = $certificationDescriptor;
74        $this->certificateNumber = $certificateNumber;
75        $this->certificationPolicyVersion = $certificationPolicyVersion;
76        $this->certificationRequirementsVersion = $certificationRequirementsVersion;
77    }
78
79    public function isCompromised(): bool
80    {
81        return in_array($this->status, [
82            AuthenticatorStatus::ATTESTATION_KEY_COMPROMISE,
83            AuthenticatorStatus::USER_KEY_PHYSICAL_COMPROMISE,
84            AuthenticatorStatus::USER_KEY_REMOTE_COMPROMISE,
85            AuthenticatorStatus::USER_VERIFICATION_BYPASS,
86        ], true);
87    }
88
89    public function getStatus(): string
90    {
91        return $this->status;
92    }
93
94    public function getEffectiveDate(): ?string
95    {
96        return $this->effectiveDate;
97    }
98
99    public function getCertificate(): ?string
100    {
101        return $this->certificate;
102    }
103
104    public function getUrl(): ?string
105    {
106        return $this->url;
107    }
108
109    public function getCertificationDescriptor(): ?string
110    {
111        return $this->certificationDescriptor;
112    }
113
114    public function getCertificateNumber(): ?string
115    {
116        return $this->certificateNumber;
117    }
118
119    public function getCertificationPolicyVersion(): ?string
120    {
121        return $this->certificationPolicyVersion;
122    }
123
124    public function getCertificationRequirementsVersion(): ?string
125    {
126        return $this->certificationRequirementsVersion;
127    }
128
129    public static function createFromArray(array $data): self
130    {
131        $data = Utils::filterNullValues($data);
132        Assertion::keyExists($data, 'status', Utils::logicException('The key "status" is missing'));
133        foreach (['effectiveDate', 'certificate', 'url', 'certificationDescriptor', 'certificateNumber', 'certificationPolicyVersion', 'certificationRequirementsVersion'] as $key) {
134            if (isset($data[$key])) {
135                Assertion::nullOrString($data[$key], Utils::logicException(sprintf('The value of the key "%s" is invalid', $key)));
136            }
137        }
138
139        return new self(
140            $data['status'],
141            $data['effectiveDate'] ?? null,
142            $data['certificate'] ?? null,
143            $data['url'] ?? null,
144            $data['certificationDescriptor'] ?? null,
145            $data['certificateNumber'] ?? null,
146            $data['certificationPolicyVersion'] ?? null,
147            $data['certificationRequirementsVersion'] ?? null
148        );
149    }
150
151    public function jsonSerialize(): array
152    {
153        $data = [
154            'status' => $this->status,
155            'effectiveDate' => $this->effectiveDate,
156            'certificate' => $this->certificate,
157            'url' => $this->url,
158            'certificationDescriptor' => $this->certificationDescriptor,
159            'certificateNumber' => $this->certificateNumber,
160            'certificationPolicyVersion' => $this->certificationPolicyVersion,
161            'certificationRequirementsVersion' => $this->certificationRequirementsVersion,
162        ];
163
164        return Utils::filterNullValues($data);
165    }
166}
167