RegisterHandlerTest::testStart()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 19
Code Lines 14

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 1
Metric Value
cc 1
eloc 14
c 2
b 0
f 1
nc 1
nop 0
dl 0
loc 19
rs 9.7998
1
<?php
2
3
namespace SilverStripe\TOTP\Tests;
4
5
use OTPHP\TOTP;
6
use OTPHP\TOTPInterface;
7
use PHPUnit_Framework_MockObject_MockObject;
8
use SilverStripe\Control\HTTPRequest;
9
use SilverStripe\Control\Session;
10
use SilverStripe\Core\Environment;
11
use SilverStripe\Dev\SapphireTest;
12
use SilverStripe\MFA\Store\SessionStore;
13
use SilverStripe\MFA\Store\StoreInterface;
14
use SilverStripe\Security\Member;
15
use SilverStripe\SiteConfig\SiteConfig;
16
use SilverStripe\TOTP\RegisterHandler;
17
18
class RegisterHandlerTest extends SapphireTest
19
{
20
    protected $usesDatabase = true;
21
22
    /**
23
     * @var RegisterHandler
24
     */
25
    protected $handler;
26
27
    /**
28
     * @var Member
29
     */
30
    protected $member;
31
32
    protected function setUp()
33
    {
34
        parent::setUp();
35
36
        $this->handler = new RegisterHandler();
37
38
        Environment::setEnv('SS_MFA_SECRET_KEY', 'foo123');
39
40
        $memberID = $this->logInWithPermission();
41
        /** @var Member $member */
42
        $this->member = Member::get()->byID($memberID);
43
    }
44
45
    public function testStart()
46
    {
47
        $store = new SessionStore($this->member);
48
        $result = $this->handler->start($store);
49
50
        $this->assertTrue($result['enabled'], 'Method should be enabled');
51
        $this->assertContains(
52
            rawurlencode(SiteConfig::current_site_config()->Title),
53
            $result['uri'],
54
            'Site name should be stored in provisioning URI'
55
        );
56
        $this->assertContains(
57
            rawurlencode($this->member->Email),
58
            $result['uri'],
59
            'Provisioning URI should contain user email'
60
        );
61
        $this->assertNotEmpty(
62
            $store->getState()['secret'],
63
            'TOTP secret should be saved to StoreInterface'
64
        );
65
    }
66
67
    public function testRegisterWithInvalidCode()
68
    {
69
        $request = new HTTPRequest('GET', '/', [], [], json_encode(['code' => '123456']));
70
        $request->setSession(new Session([]));
71
        $store = new SessionStore($this->member);
72
        $store->setState(['secret' => base64_encode('willneverw0rk')]);
73
74
        $result = $this->handler->register($request, $store);
75
        $this->assertFalse($result->isSuccessful());
76
        $this->assertSame(
77
            'Provided code was not valid',
78
            $result->getMessage(),
79
            'Registration failure message is provided'
80
        );
81
    }
82
83
    public function testRegisterReturnsEncryptedSecret()
84
    {
85
        $request = new HTTPRequest('GET', '/', [], [], json_encode(['code' => '123456']));
86
        $request->setSession(new Session([]));
87
        $store = new SessionStore($this->member);
88
        $store->setState(['secret' => 'opensesame']);
89
90
        /** @var RegisterHandler|PHPUnit_Framework_MockObject_MockObject $handler */
91
        $handler = $this->getMockBuilder(RegisterHandler::class)
92
            ->setMethods(['getTotp'])
93
            ->getMock();
94
        $handler->expects($this->once())->method('getTotp')->willReturn(
95
            /** @var TOTP|PHPUnit_Framework_MockObject_MockObject $totpMock */
96
            $totpMock = $this->createMock(TOTPInterface::class)
97
        );
98
        $totpMock->expects($this->once())->method('verify')->with('123456')->willReturn(true);
99
100
        $result = $handler->register($request, $store);
101
        $context = $result->getContext();
102
        $this->assertNotEmpty($context['secret']);
103
        $this->assertNotContains(
104
            'opensesame',
105
            $context['secret'],
106
            'Encrypted secret should not contain the plain text secret'
107
        );
108
    }
109
}
110