Completed
Push — master ( b97427...e235cc )
by Raffael
30:35 queued 26:08
created

RequestChallengeFactory   A

Complexity

Total Complexity 4

Size/Duplication

Total Lines 81
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 2

Test Coverage

Coverage 0%

Importance

Changes 0
Metric Value
wmc 4
lcom 1
cbo 2
dl 0
loc 81
ccs 0
cts 38
cp 0
rs 10
c 0
b 0
f 0

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 6 1
A create() 0 28 1
A getOne() 0 12 2
1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * balloon
7
 *
8
 * @copyright   Copryright (c) 2012-2019 gyselroth GmbH (https://gyselroth.com)
9
 * @license     GPL-3.0 https://opensource.org/licenses/GPL-3.0
10
 */
11
12
namespace Balloon\App\Webauthn\RequestChallenge;
13
14
use Balloon\App\Webauthn\CredentialRepository;
15
use Balloon\Server\User;
16
use MongoDB\BSON\ObjectIdInterface;
17
use MongoDB\BSON\UTCDateTime;
18
use MongoDB\Database;
19
use Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientInputs;
20
use Webauthn\PublicKeyCredentialDescriptor;
21
use Webauthn\PublicKeyCredentialRequestOptions;
22
23
class RequestChallengeFactory
24
{
25
    /**
26
     * Database.
27
     *
28
     * @var Database
29
     */
30
    protected $db;
31
32
    /**
33
     * AuthenticationExtensionsClientInputs.
34
     *
35
     * @var AuthenticationExtensionsClientInputs
36
     */
37
    protected $auth_extensions;
38
39
    /**
40
     * CredentialRepository.
41
     *
42
     * @var CredentialRepository
43
     */
44
    protected $repository;
45
46
    /**
47
     * Initialize.
48
     */
49
    public function __construct(Database $db, AuthenticationExtensionsClientInputs $auth_extensions, CredentialRepository $repository)
50
    {
51
        $this->db = $db;
52
        $this->auth_extensions = $auth_extensions;
53
        $this->repository = $repository;
54
    }
55
56
    /**
57
     * Token endpoint.
58
     */
59
    public function create(ObjectIdInterface $user, string $domain): array
60
    {
61
        $registeredPublicKeyCredentialDescriptors = iterator_to_array($this->repository->getDescriptorsByUser($user));
62
63
        // Public Key Credential Request Options
64
        $key = new PublicKeyCredentialRequestOptions(
65
            random_bytes(32),                                                           // Challenge
66
            60000,                                                                      // Timeout
67
            $domain,                                                          // Relying Party ID
68
            $registeredPublicKeyCredentialDescriptors,                                  // Registered PublicKeyCredentialDescriptor classes
69
            PublicKeyCredentialRequestOptions::USER_VERIFICATION_REQUIREMENT_PREFERRED, // User verification requirement
70
            $this->auth_extensions
71
        );
72
73
        $data = json_decode(json_encode($key));
74
75
        $record = [
76
            'created' => new UTCDateTime(),
77
            'owner' => $user,
78
            'key' => $data,
79
        ];
80
81
        $result = $this->db->request_challenges->insertOne($record);
82
        $record['id'] = $result->getInsertedId();
83
        $record['key'] = $key;
84
85
        return $record;
86
    }
87
88
    /**
89
     * Get challenge.
90
     */
91
    public function getOne(ObjectIdInterface $challenge): PublicKeyCredentialRequestOptions
92
    {
93
        $challenge = $this->db->request_challenges->findOne([
94
            '_id' => $challenge,
95
        ]);
96
97
        if ($challenge === null) {
98
            throw new Exception\NotFound('challenge not found');
99
        }
100
101
        return PublicKeyCredentialRequestOptions::createfromArray($challenge['key']);
102
    }
103
}
104