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

CreationChallengeFactory::create()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 54

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 54
ccs 0
cts 40
cp 0
rs 9.0036
c 0
b 0
f 0
cc 1
nc 1
nop 2
crap 2

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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\CreationChallenge;
13
14
use Balloon\Server\User;
15
use Cose\Algorithms;
16
use MongoDB\BSON\ObjectIdInterface;
17
use MongoDB\BSON\UTCDateTime;
18
use MongoDB\Database;
19
use Webauthn\AuthenticationExtensions\AuthenticationExtensionsClientInputs;
20
use Webauthn\AuthenticatorSelectionCriteria;
21
use Webauthn\PublicKeyCredentialCreationOptions;
22
use Webauthn\PublicKeyCredentialParameters;
23
use Webauthn\PublicKeyCredentialRpEntity;
24
use Webauthn\PublicKeyCredentialUserEntity;
25
26
class CreationChallengeFactory
27
{
28
    /**
29
     * Database.
30
     *
31
     * @var Database
32
     */
33
    protected $db;
34
35
    /**
36
     * AuthenticationExtensionsClientInputs.
37
     *
38
     * @var AuthenticationExtensionsClientInputs
39
     */
40
    protected $auth_extensions;
41
42
    /**
43
     * AuthenticatorSelectionCriteria.
44
     *
45
     * @var AuthenticatorSelectionCriteria
46
     */
47
    protected $auth_criteria;
48
49
    /**
50
     * Initialize.
51
     */
52
    public function __construct(Database $db, AuthenticationExtensionsClientInputs $auth_extensions, AuthenticatorSelectionCriteria $auth_criteria)
53
    {
54
        $this->db = $db;
55
        $this->auth_extensions = $auth_extensions;
56
        $this->auth_criteria = $auth_criteria;
57
    }
58
59
    /**
60
     * Token endpoint.
61
     */
62
    public function create(User $user, string $domain): array
63
    {
64
        // RP Entity
65
        $rpEntity = new PublicKeyCredentialRpEntity(
66
            'balloon',
67
            $domain,
68
            null
69
        );
70
71
        // User Entity
72
        $userEntity = new PublicKeyCredentialUserEntity(
73
            $user->getUsername(),
74
            (string) $user->getId(),
75
            $user->getUsername(),
76
            null
77
        );
78
79
        // Challenge
80
        $challenge = random_bytes(32);
81
82
        // Public Key Credential Parameters
83
        $publicKeyCredentialParametersList = [
84
            new PublicKeyCredentialParameters('public-key', Algorithms::COSE_ALGORITHM_ES256),
85
        ];
86
87
        // Timeout
88
        $timeout = 60000;
89
90
        $key = new PublicKeyCredentialCreationOptions(
91
            $rpEntity,
92
            $userEntity,
93
            $challenge,
94
            $publicKeyCredentialParametersList,
95
            $timeout,
96
            [],
97
            $this->auth_criteria,
98
            PublicKeyCredentialCreationOptions::ATTESTATION_CONVEYANCE_PREFERENCE_NONE,
99
            $this->auth_extensions
100
        );
101
102
        $data = json_decode(json_encode($key));
103
104
        $record = [
105
            'created' => new UTCDateTime(),
106
            'owner' => $user->getId(),
107
            'key' => $data,
108
        ];
109
110
        $result = $this->db->creation_challenges->insertOne($record);
111
        $record['id'] = $result->getInsertedId();
112
        $record['key'] = $key;
113
114
        return $record;
115
    }
116
117
    /**
118
     * Get challenge.
119
     */
120
    public function getOne(ObjectIdInterface $id): PublicKeyCredentialCreationOptions
121
    {
122
        $challenge = $this->db->creation_challenges->findOne([
123
            '_id' => $id,
124
        ]);
125
126
        if ($challenge === null) {
127
            throw new Exception\NotFound('creation challenge not found');
128
        }
129
130
        return PublicKeyCredentialCreationOptions::createfromArray($challenge['key']);
131
    }
132
}
133