Passed
Pull Request — master (#32)
by Robbie
02:20
created

testCannotSkipWhenMFAIsRequiredWithNoGracePeriod()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace SilverStripe\MFA\Tests\Service;
4
5
use PHPUnit_Framework_MockObject_MockObject;
6
use SilverStripe\Control\HTTPRequest;
7
use SilverStripe\Dev\SapphireTest;
8
use SilverStripe\MFA\Extension\MemberExtension;
9
use SilverStripe\MFA\Service\MethodRegistry;
10
use SilverStripe\MFA\Service\SchemaGenerator;
11
use SilverStripe\MFA\Store\StoreInterface;
12
use SilverStripe\MFA\Tests\Stub\BasicMath\Method as BasicMathMethod;
13
use SilverStripe\ORM\FieldType\DBDatetime;
14
use SilverStripe\Security\Member;
15
use SilverStripe\SiteConfig\SiteConfig;
16
17
class SchemaGeneratorTest extends SapphireTest
18
{
19
    protected static $fixture_file = 'SchemaGeneratorTest.yml';
20
21
    /**
22
     * @var HTTPRequest|PHPUnit_Framework_MockObject_MockObject
23
     */
24
    protected $request;
25
26
    /**
27
     * @var StoreInterface|PHPUnit_Framework_MockObject_MockObject
28
     */
29
    protected $store;
30
31
    /**
32
     * @var SchemaGenerator
33
     */
34
    protected $generator;
35
36
    protected function setUp()
37
    {
38
        parent::setUp();
39
40
        DBDatetime::set_mock_now('2019-01-25 12:00:00');
41
42
        $this->setSiteConfig(['MFAEnabled' => true]);
43
44
        $this->request = $this->createMock(HTTPRequest::class);
45
        $this->store = $this->createMock(StoreInterface::class);
46
47
        MethodRegistry::config()->set('methods', [
48
            BasicMathMethod::class,
49
        ]);
50
51
        $this->generator = new SchemaGenerator($this->request, $this->store);
52
    }
53
54
    /**
55
     * @expectedException \SilverStripe\MFA\Exception\MemberNotFoundException
56
     */
57
    public function testGetMemberThrowsExceptionWithoutMember()
58
    {
59
        $this->logOut();
60
        $this->generator->getMember();
61
    }
62
63
    public function testGetSchema()
64
    {
65
        $this->logInAs('sally_smith');
66
67
        $schema = $this->generator->getSchema();
68
69
        $this->assertArrayHasKey('registeredMethods', $schema);
70
        $this->assertNotEmpty($schema['registeredMethods']);
71
        $this->assertArrayHasKey('availableMethods', $schema);
72
        $this->assertNotEmpty($schema['availableMethods']);
73
        $this->assertArrayHasKey('defaultMethod', $schema);
74
        $this->assertNotEmpty($schema['defaultMethod']);
75
76
        $this->assertSame('backup-codes', $schema['registeredMethods'][0]['urlSegment']);
77
        $this->assertSame('basic-math', $schema['availableMethods'][0]['urlSegment']);
78
        $this->assertSame('backup-codes', $schema['defaultMethod']);
79
    }
80
81
    public function testCannotSkipWhenMFAIsRequiredWithNoGracePeriod()
82
    {
83
        $this->setSiteConfig(['MFARequired' => true]);
84
85
        $schema = $this->generator->getSchema();
86
        $this->assertFalse($schema['canSkip']);
87
    }
88
89
    public function testCanSkipWhenMFAIsRequiredWithGracePeriodExpiringInFuture()
90
    {
91
        $this->setSiteConfig(['MFARequired' => true, 'MFAGracePeriodExpires' => '2019-01-30']);
92
93
        $schema = $this->generator->getSchema();
94
        $this->assertTrue($schema['canSkip']);
95
    }
96
97
    public function testCannotSkipWhenMFAIsRequiredWithGracePeriodExpiringInPast()
98
    {
99
        $this->setSiteConfig(['MFARequired' => true, 'MFAGracePeriodExpires' => '2018-12-25']);
100
101
        $schema = $this->generator->getSchema();
102
        $this->assertFalse($schema['canSkip']);
103
    }
104
105
    public function testCannotSkipWhenMemberHasRegisteredAuthenticationMethodsSetUp()
106
    {
107
        $this->setSiteConfig(['MFARequired' => false]);
108
        // Sally has "backup codes" as a registered authentication method already
109
        $this->logInAs('sally_smith');
110
111
        $schema = $this->generator->getSchema();
112
        $this->assertFalse($schema['canSkip']);
113
    }
114
115
    public function testCanSkipWhenMFAIsOptional()
116
    {
117
        $this->setSiteConfig(['MFARequired' => false]);
118
        // Anonymous admin user
119
        $this->logInWithPermission();
120
121
        $schema = $this->generator->getSchema();
122
        $this->assertTrue($schema['canSkip']);
123
    }
124
125
    public function testShouldRedirectToMFAWhenMFAIsRequired()
126
    {
127
        $this->setSiteConfig(['MFARequired' => true]);
128
        $this->logInAs('sally_smith');
129
130
        $schema = $this->generator->getSchema();
131
        $this->assertTrue($schema['shouldRedirect']);
132
    }
133
134
    public function testShouldRedirectToMFAWhenMFAIsOptionalAndHasNotBeenSkipped()
135
    {
136
        $this->setSiteConfig(['MFARequired' => false]);
137
138
        /** @var Member|MemberExtension $member */
139
        $member = $this->objFromFixture(Member::class, 'sally_smith');
140
        $member->HasSkippedMFARegistration = false;
141
        $member->write();
142
        $this->logInAs($member);
143
144
        $schema = $this->generator->getSchema();
145
        $this->assertTrue($schema['shouldRedirect']);
146
    }
147
148
    public function testShouldNotRedirectToMFAWhenMFAIsOptionalAndHasBeenSkipped()
149
    {
150
        $this->setSiteConfig(['MFARequired' => false]);
151
152
        /** @var Member|MemberExtension $member */
153
        $member = $this->objFromFixture(Member::class, 'sally_smith');
154
        $member->HasSkippedMFARegistration = true;
155
        $member->write();
156
        $this->logInAs($member);
157
158
        $schema = $this->generator->getSchema();
159
        $this->assertFalse($schema['shouldRedirect']);
160
    }
161
162
    /**
163
     * Helper method for changing the current SiteConfig values
164
     *
165
     * @param array $data
166
     */
167
    protected function setSiteConfig(array $data)
168
    {
169
        $siteConfig = SiteConfig::current_site_config();
170
        $siteConfig->update($data);
171
        $siteConfig->write();
172
    }
173
}
174