AAGUID::hasToken()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 6
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 8
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleSAML\Module\webauthn\WebAuthn;
6
7
use SimpleSAML\Logger;
8
use SimpleSAML\Utils\Config as SSPConfig;
9
10
/**
11
 * Class AAGUID
12
 *
13
 * @package SimpleSAML\Module\webauthn\WebAuthn
14
 */
15
class AAGUID
16
{
17
    /**
18
     * The name of the configuration file where we should expect the AAGUID dictionary.
19
     */
20
    public const AAGUID_CONFIG_FILE = 'webauthn-aaguid.json';
21
22
23
    /**
24
     * The actual dictionary containing all known tokens.
25
     *
26
     * @var array
27
     */
28
    protected array $dictionary = [];
29
30
    /**
31
     * The singleton instance.
32
     *
33
     * @var \SimpleSAML\Module\webauthn\WebAuthn\AAGUID
34
     */
35
    protected static AAGUID $instance;
36
37
38
    /**
39
     * AAGUID constructor.
40
     */
41
    protected function __construct()
42
    {
43
        $config = new SSPConfig();
44
        $path = $config->getConfigDir() . '/' . self::AAGUID_CONFIG_FILE;
45
        if (!file_exists($path)) {
46
            Logger::warning("Missing AAGUID configuration file ($path). No device will be recognized.");
47
            return;
48
        }
49
50
        $data = file_get_contents($path);
51
        $json = json_decode($data, true);
52
        if (!is_array($json)) {
53
            // there was probably an error decoding the config, log the error and pray for the best
54
            Logger::warning('Broken configuration file "' . $path . '": could not JSON-decode it.');
55
        } else {
56
            $this->dictionary = $json;
57
        }
58
    }
59
60
61
    /**
62
     * Get the singleton instance of the AAGUID dictionary.
63
     *
64
     * @return self
65
     */
66
    public static function getInstance(): self
67
    {
68
        if (!isset(self::$instance)) {
69
            self::$instance = new self();
70
        }
71
        return self::$instance;
72
    }
73
74
75
    /**
76
     * Determine if an AAGUID is known
77
     *
78
     * @param string $aaguid The AAGUID that we want to check.
79
     *
80
     * @return bool True if we know about this token, false otherwise.
81
     */
82
    public function hasToken(string $aaguid): bool
83
    {
84
        $lowerAaguid = strtolower($aaguid);
85
        if (array_key_exists($lowerAaguid, $this->dictionary)) {
86
            return true;
87
        } else {
88
            Logger::info("AAGUID $lowerAaguid not found in dictionary, device is unknown.");
89
            return false;
90
        }
91
    }
92
93
94
    /**
95
     * Get the information for a given AAGUID.
96
     *
97
     * @param string $aaguid The AAGUID we want to get.
98
     *
99
     * @return array An array containing information about the given AAGUID, or an empty array if that AAGUID is
100
     * unknown.
101
     */
102
    public function get(string $aaguid): array
103
    {
104
        if (!$this->hasToken($aaguid)) {
105
            return [];
106
        }
107
        return $this->dictionary[$aaguid];
108
    }
109
}
110