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
    /**
32
     * The singleton instance.
33
     *
34
     * @var \SimpleSAML\Module\webauthn\WebAuthn\AAGUID
35
     */
36
    protected static AAGUID $instance;
37
38
39
    /**
40
     * AAGUID constructor.
41
     */
42
    protected function __construct()
43
    {
44
        $config = new SSPConfig();
45
        $path = $config->getConfigDir() . '/' . self::AAGUID_CONFIG_FILE;
46
        if (!file_exists($path)) {
47
            Logger::warning("Missing AAGUID configuration file ($path). No device will be recognized.");
48
            return;
49
        }
50
51
        $data = file_get_contents($path);
52
        $json = json_decode($data, true);
53
        if (!is_array($json)) {
54
            // there was probably an error decoding the config, log the error and pray for the best
55
            Logger::warning('Broken configuration file "' . $path . '": could not JSON-decode it.');
56
        } else {
57
            $this->dictionary = $json;
58
        }
59
    }
60
61
62
    /**
63
     * Get the singleton instance of the AAGUID dictionary.
64
     *
65
     * @return self
66
     */
67
    public static function getInstance(): self
68
    {
69
        if (!isset(self::$instance)) {
70
            self::$instance = new self();
71
        }
72
        return self::$instance;
73
    }
74
75
76
    /**
77
     * Determine if an AAGUID is known
78
     *
79
     * @param string $aaguid The AAGUID that we want to check.
80
     *
81
     * @return bool True if we know about this token, false otherwise.
82
     */
83
    public function hasToken(string $aaguid): bool
84
    {
85
        $lowerAaguid = strtolower($aaguid);
86
        if (array_key_exists($lowerAaguid, $this->dictionary)) {
87
            return true;
88
        } else {
89
            Logger::info("AAGUID $lowerAaguid not found in dictionary, device is unknown.");
90
            return false;
91
        }
92
    }
93
94
95
    /**
96
     * Get the information for a given AAGUID.
97
     *
98
     * @param string $aaguid The AAGUID we want to get.
99
     *
100
     * @return array An array containing information about the given AAGUID, or an empty array if that AAGUID is
101
     * unknown.
102
     */
103
    public function get(string $aaguid): array
104
    {
105
        if (!$this->hasToken($aaguid)) {
106
            return [];
107
        }
108
        return $this->dictionary[$aaguid];
109
    }
110
}
111