Completed
Push — master ( 0d1193...76ec59 )
by
unknown
15s
created

tests/LoginHandlerTest.php (2 issues)

1
<?php
2
3
namespace SilverStripe\TOTP\Tests;
4
5
use OTPHP\TOTPInterface;
6
use PHPUnit_Framework_MockObject_MockObject;
7
use SilverStripe\Control\HTTPRequest;
8
use SilverStripe\Control\Session;
9
use SilverStripe\Core\Environment;
10
use SilverStripe\Core\Injector\Injector;
11
use SilverStripe\Dev\SapphireTest;
12
use SilverStripe\MFA\Extension\MemberExtension;
13
use SilverStripe\MFA\Model\RegisteredMethod;
14
use SilverStripe\MFA\Service\EncryptionAdapterInterface;
15
use SilverStripe\MFA\Store\SessionStore;
16
use SilverStripe\MFA\Store\StoreInterface;
17
use SilverStripe\Security\Member;
18
use SilverStripe\TOTP\LoginHandler;
19
use SilverStripe\TOTP\Method;
20
21
class LoginHandlerTest extends SapphireTest
22
{
23
    protected $usesDatabase = true;
24
25
    /**
26
     * @var HTTPRequest
27
     */
28
    protected $request;
29
30
    /**
31
     * @var StoreInterface
32
     */
33
    protected $store;
34
35
    /**
36
     * @var LoginHandler
37
     */
38
    protected $handler;
39
40
    /**
41
     * @var Member&MemberExtension
42
     */
43
    protected $member;
44
45
    protected function setUp()
46
    {
47
        parent::setUp();
48
49
        $this->request = new HTTPRequest('GET', '/');
50
        $this->request->setSession(new Session([]));
51
        $this->store = new SessionStore($this->request);
0 ignored issues
show
$this->request of type SilverStripe\Control\HTTPRequest is incompatible with the type SilverStripe\Security\Member|null expected by parameter $member of SilverStripe\MFA\Store\SessionStore::__construct(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

51
        $this->store = new SessionStore(/** @scrutinizer ignore-type */ $this->request);
Loading history...
52
        $this->handler = new LoginHandler();
53
54
        // Mock environment variable for encryption key
55
        Environment::setEnv('SS_MFA_SECRET_KEY', 'foobar123');
56
57
        // Mock the encryption adapter to return the plaintext input
58
        $encryptionAdapter = $this->createMock(EncryptionAdapterInterface::class);
59
        $encryptionAdapter->expects($this->any())->method('decrypt')->willReturnArgument(0);
60
        Injector::inst()->registerService($encryptionAdapter, EncryptionAdapterInterface::class);
61
62
        // Create a registered method and attach it to the member
63
        $registeredMethod = new RegisteredMethod();
64
        $registeredMethod->MethodClassName = Method::class;
65
        $registeredMethod->Data = json_encode(['secret' => 'ABCD1234']);
66
        $registeredMethod->write();
67
68
        $memberID = $this->logInWithPermission();
69
        $this->member = Member::get()->byID($memberID);
70
        $this->member->RegisteredMFAMethods()->add($registeredMethod);
71
    }
72
73
    public function testStartWithNoSecret()
74
    {
75
        $method = $this->member->RegisteredMFAMethods()->first();
76
        $method->Data = json_encode([]);
77
        $method->write();
78
79
        $result = $this->handler->start($this->store, $method);
80
        $this->assertFalse($result['enabled']);
81
    }
82
83
    public function testStartWithNoEncryptionKey()
84
    {
85
        Environment::setEnv('SS_MFA_SECRET_KEY', '');
86
        $result = $this->handler->start($this->store, $this->member->RegisteredMFAMethods()->first());
87
        $this->assertFalse($result['enabled']);
88
    }
89
90
    public function testStartSuccess()
91
    {
92
        $result = $this->handler->start($this->store, $this->member->RegisteredMFAMethods()->first());
93
        $this->assertTrue($result['enabled']);
94
        $this->assertGreaterThan(1, $result['codeLength']);
95
        $this->assertSame('ABCD1234', $this->store->getState()['secret']);
96
    }
97
98
    public function testVerify()
99
    {
100
        $this->request->setBody(json_encode(['code' => '135246']));
101
        /** @var LoginHandler&PHPUnit_Framework_MockObject_MockObject $handler */
102
        $handler = $this->getMockBuilder(LoginHandler::class)
103
            ->setMethods(['getTotp'])
104
            ->getMock();
105
106
        $handler->expects($this->once())->method('getTotp')->willReturn(
107
            $totp = $this->createMock(TOTPInterface::class)
108
        );
109
        $totp->expects($this->once())->method('verify')->with('135246')->willReturn(true);
110
111
        $result = $handler->verify($this->request, $this->store, $this->member->RegisteredMFAMethods()->first());
0 ignored issues
show
The method verify() does not exist on PHPUnit_Framework_MockObject_MockObject. Did you maybe mean __phpunit_verify()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

111
        /** @scrutinizer ignore-call */ 
112
        $result = $handler->verify($this->request, $this->store, $this->member->RegisteredMFAMethods()->first());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
112
        $this->assertTrue($result, 'Mocked TOTP verification with the right argument should return true');
113
    }
114
}
115