Passed
Push — master ( 33a29d...4282cd )
by Robbie
02:17 queued 25s
created

RegisterHandlerTest::testStart()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 1
Metric Value
cc 1
eloc 5
c 1
b 0
f 1
nc 1
nop 0
dl 0
loc 9
rs 10
1
<?php
2
3
namespace SilverStripe\WebAuthn\Tests;
4
5
use SilverStripe\Core\Injector\Injector;
6
use SilverStripe\Dev\SapphireTest;
7
use SilverStripe\MFA\Store\SessionStore;
8
use SilverStripe\Security\Member;
9
use SilverStripe\WebAuthn\RegisterHandler;
10
use Webauthn\AuthenticatorSelectionCriteria;
11
use Webauthn\PublicKeyCredentialCreationOptions;
12
13
class RegisterHandlerTest extends SapphireTest
14
{
15
    protected $usesDatabase = true;
16
17
    /**
18
     * @var RegisterHandler
19
     */
20
    protected $handler;
21
22
    /**
23
     * @var Member
24
     */
25
    protected $member;
26
27
    /**
28
     * @var array
29
     */
30
    protected $originalServer;
31
32
    protected function setUp()
33
    {
34
        parent::setUp();
35
36
        $this->handler = Injector::inst()->create(RegisterHandler::class);
37
38
        $memberID = $this->logInWithPermission();
39
        /** @var Member $member */
40
        $this->member = Member::get()->byID($memberID);
41
42
        $this->originalServer = $_SERVER;
43
44
        // Set default configuration settings
45
        RegisterHandler::config()->set(
46
            'authenticator_attachment',
47
            AuthenticatorSelectionCriteria::AUTHENTICATOR_ATTACHMENT_CROSS_PLATFORM
48
        );
49
    }
50
51
    protected function tearDown()
52
    {
53
        $_SERVER = $this->originalServer;
54
55
        parent::tearDown();
56
    }
57
58
    /**
59
     * @param string $baseUrl
60
     * @param string $expected
61
     * @dataProvider hostProvider
62
     */
63
    public function testRelyingPartyEntityDomainIncludesSilverStripeDomain(string $baseUrl, string $expected)
64
    {
65
        $_SERVER['HTTP_HOST'] = $baseUrl;
66
67
        $store = new SessionStore($this->member);
68
        $result = $this->handler->start($store);
69
        $this->assertArrayHasKey('keyData', $result);
70
71
        /** @var PublicKeyCredentialCreationOptions $options */
72
        $options = $result['keyData'];
73
        $this->assertInstanceOf(PublicKeyCredentialCreationOptions::class, $options);
74
75
        $relyingPartyEntity = $options->getRp();
76
        $this->assertSame(
77
            $expected,
78
            $relyingPartyEntity->getId(),
79
            'Relying party entity should identify the current SilverStripe domain'
80
        );
81
    }
82
83
    /**
84
     * @return array
85
     */
86
    public function hostProvider(): array
87
    {
88
        return [
89
            'domain only' => ['http://example.com', 'example.com'],
90
            'domain with port' => ['https://example.com:8080', 'example.com'],
91
            'subdomain' => ['https://www.example.com', 'www.example.com'],
92
            'subdomain with port' => ['http://my.example.com:8887', 'my.example.com'],
93
            'subfolder' => ['https://example.com/mysite', 'example.com'],
94
            'subfolder with port' => ['http://example.com:8080/mysite', 'example.com'],
95
            'subdomain with subfolder' => ['http://my.example.com/mysite', 'my.example.com'],
96
            'subdomain with port and subfolder' => ['https://my.example.com:8080/mysite', 'my.example.com'],
97
            'credentials with domain and trailing slash' => ['http://foo:[email protected]/', 'example.com'],
98
        ];
99
    }
100
101
    public function testAuthenticatorSelectionCriteriaRequiresCrossPlatformAttachmentByDefault()
102
    {
103
        $store = new SessionStore($this->member);
104
        $result = $this->handler->start($store);
105
        $this->assertArrayHasKey('keyData', $result);
106
107
        /** @var PublicKeyCredentialCreationOptions $options */
108
        $options = $result['keyData'];
109
        $this->assertInstanceOf(PublicKeyCredentialCreationOptions::class, $options);
110
111
        $authenticatorSelection = $options->getAuthenticatorSelection();
112
        $this->assertSame(
113
            AuthenticatorSelectionCriteria::AUTHENTICATOR_ATTACHMENT_CROSS_PLATFORM,
114
            $authenticatorSelection->getAuthenticatorAttachment()
115
        );
116
    }
117
118
    public function testStart()
119
    {
120
        $store = new SessionStore($this->member);
121
        $result = $this->handler->start($store);
122
        $this->assertArrayHasKey('keyData', $result);
123
124
        /** @var PublicKeyCredentialCreationOptions $options */
125
        $options = $result['keyData'];
126
        $this->assertInstanceOf(PublicKeyCredentialCreationOptions::class, $options);
127
    }
128
129
    public function testGetName()
130
    {
131
        $this->assertSame('Security key', $this->handler->getName());
132
    }
133
134
    public function testGetDescription()
135
    {
136
        $this->assertContains('A small USB device', $this->handler->getDescription());
137
    }
138
139
    public function testGetSupportLink()
140
    {
141
        RegisterHandler::config()->set('user_help_link', 'http://google.com');
142
        $this->assertSame('http://google.com', $this->handler->getSupportLink());
143
    }
144
145
    public function testGetComponent()
146
    {
147
        $this->assertSame('WebAuthnRegister', $this->handler->getComponent());
148
    }
149
}
150