Passed
Push — master ( aa0dec...0bd8f9 )
by Garion
02:29
created

testShouldRedirectToMFAWhenUserHasAccessToReportsOnly()   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 SilverStripe\Dev\SapphireTest;
6
use SilverStripe\MFA\Extension\MemberExtension;
7
use SilverStripe\MFA\Service\EnforcementManager;
8
use SilverStripe\MFA\Service\MethodRegistry;
9
use SilverStripe\MFA\Tests\Stub\BasicMath\Method as BasicMathMethod;
10
use SilverStripe\ORM\FieldType\DBDatetime;
11
use SilverStripe\Security\Member;
12
use SilverStripe\SiteConfig\SiteConfig;
13
14
class EnforcementManagerTest extends SapphireTest
15
{
16
    protected static $fixture_file = 'EnforcementManagerTest.yml';
17
18
    protected function setUp()
19
    {
20
        parent::setUp();
21
22
        DBDatetime::set_mock_now('2019-01-25 12:00:00');
23
24
        MethodRegistry::config()->set('methods', [
25
            BasicMathMethod::class,
26
        ]);
27
28
        EnforcementManager::config()->set('requires_admin_access', true);
29
    }
30
31
    public function testCannotSkipWhenMFAIsRequiredWithNoGracePeriod()
32
    {
33
        $this->setSiteConfig(['MFARequired' => true]);
34
35
        $member = new Member();
36
        $this->assertFalse(EnforcementManager::create()->canSkipMFA($member));
37
    }
38
39
    public function testCanSkipWhenMFAIsRequiredWithGracePeriodExpiringInFuture()
40
    {
41
        $this->setSiteConfig(['MFARequired' => true, 'MFAGracePeriodExpires' => '2019-01-30']);
42
43
        $member = new Member();
44
        $this->assertTrue(EnforcementManager::create()->canSkipMFA($member));
45
    }
46
47
    public function testCannotSkipWhenMFAIsRequiredWithGracePeriodExpiringInPast()
48
    {
49
        $this->setSiteConfig(['MFARequired' => true, 'MFAGracePeriodExpires' => '2018-12-25']);
50
51
        $member = new Member();
52
        $this->assertFalse(EnforcementManager::create()->canSkipMFA($member));
53
    }
54
55
    public function testCannotSkipWhenMemberHasRegisteredAuthenticationMethodsSetUp()
56
    {
57
        $this->setSiteConfig(['MFARequired' => false]);
58
        // Sally has "backup codes" as a registered authentication method already
59
        /** @var Member $member */
60
        $member = $this->objFromFixture(Member::class, 'sally_smith');
61
        $this->logInAs($member);
62
63
        $this->assertFalse(EnforcementManager::create()->canSkipMFA($member));
64
    }
65
66
    public function testCanSkipWhenMFAIsOptional()
67
    {
68
        $this->setSiteConfig(['MFARequired' => false]);
69
        // Anonymous admin user
70
        $memberId = $this->logInWithPermission();
71
        /** @var Member $member */
72
        $member = Member::get()->byID($memberId);
73
74
        $this->assertTrue(EnforcementManager::create()->canSkipMFA($member));
75
    }
76
77
    public function testShouldNotRedirectToMFAWhenUserDoesNotHaveCMSAccess()
78
    {
79
        /** @var Member $member */
80
        $member = $this->objFromFixture(Member::class, 'sammy_smith');
81
        $this->logInAs($member);
82
        $this->assertFalse(EnforcementManager::create()->shouldRedirectToMFA($member));
83
    }
84
85
    public function testShouldRedirectToMFAWhenUserDoesNotHaveCMSAccessButTheCheckIsDisabledWithConfig()
86
    {
87
        EnforcementManager::config()->set('requires_admin_access', false);
88
89
        /** @var Member $member */
90
        $member = $this->objFromFixture(Member::class, 'sammy_smith');
91
        $this->logInAs($member);
92
        $this->assertTrue(EnforcementManager::create()->shouldRedirectToMFA($member));
93
    }
94
95
    public function testShouldRedirectToMFAWhenUserHasAccessToReportsOnly()
96
    {
97
        /** @var Member $member */
98
        $member = $this->objFromFixture(Member::class, 'reports_user');
99
        $this->logInAs($member);
100
        $this->assertTrue(EnforcementManager::create()->shouldRedirectToMFA($member));
101
    }
102
103
    public function testShouldRedirectToMFAWhenUserHasRegisteredMFAMethod()
104
    {
105
        /** @var Member $member */
106
        $member = $this->objFromFixture(Member::class, 'sally_smith');
107
        $shouldRedirect = EnforcementManager::create()->shouldRedirectToMFA($member);
108
        $this->assertTrue($shouldRedirect);
109
    }
110
111
    public function testShouldRedirectToMFAWhenMFAIsRequired()
112
    {
113
        $this->setSiteConfig(['MFARequired' => true]);
114
        /** @var Member $member */
115
        $member = $this->objFromFixture(Member::class, 'sally_smith');
116
        $this->logInAs($member);
117
118
        $this->assertTrue(EnforcementManager::create()->shouldRedirectToMFA($member));
119
    }
120
121
    public function testShouldRedirectToMFAWhenMFAIsOptionalAndHasNotBeenSkipped()
122
    {
123
        $this->setSiteConfig(['MFARequired' => false]);
124
125
        /** @var Member|MemberExtension $member */
126
        $member = $this->objFromFixture(Member::class, 'sally_smith');
127
        $member->HasSkippedMFARegistration = false;
128
        $member->write();
129
        $this->logInAs($member);
130
131
        $this->assertTrue(EnforcementManager::create()->shouldRedirectToMFA($member));
132
    }
133
134
    public function testShouldNotRedirectToMFAWhenMFAIsOptionalAndHasBeenSkipped()
135
    {
136
        $this->setSiteConfig(['MFARequired' => false]);
137
138
        /** @var Member&MemberExtension $member */
139
        $member = $this->objFromFixture(Member::class, 'sammy_smith');
140
        $member->HasSkippedMFARegistration = true;
141
        $member->write();
142
        $this->logInAs($member);
143
144
        $this->assertFalse(EnforcementManager::create()->shouldRedirectToMFA($member));
145
    }
146
147
    /**
148
     * Helper method for changing the current SiteConfig values
149
     *
150
     * @param array $data
151
     */
152
    protected function setSiteConfig(array $data)
153
    {
154
        $siteConfig = SiteConfig::current_site_config();
155
        $siteConfig->update($data);
156
        $siteConfig->write();
157
    }
158
}
159