Passed
Push — master ( d41875...74fcd0 )
by Simon
01:35
created

BackupCodeTest::testBackupCodeConfigDefault()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 18
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 18
rs 9.4285
c 0
b 0
f 0
cc 2
eloc 11
nc 2
nop 0
1
<?php
2
3
namespace Firesphere\BootstrapMFA\Tests;
4
5
use Firesphere\BootstrapMFA\Models\BackupCode;
6
use Firesphere\BootstrapMFA\Generators\CodeGenerator;
7
use Firesphere\BootstrapMFA\Tests\Helpers\CodeHelper;
8
use SilverStripe\Control\Controller;
9
use SilverStripe\Control\Session;
10
use SilverStripe\Core\Config\Config;
11
use SilverStripe\Core\Injector\Injector;
12
use SilverStripe\Dev\Debug;
13
use SilverStripe\Dev\SapphireTest;
14
use SilverStripe\Security\Member;
15
use SilverStripe\Security\IdentityStore;
16
use SilverStripe\Security\Security;
17
18
class BackupCodeTest extends SapphireTest
19
{
20
    protected static $fixture_file = '../fixtures/member.yml';
21
22
    protected function setUp()
23
    {
24
        // Set to an idiotic length so we don't accidentally hit
25
        // a alphanumeric that due to fluke of randomness
26
        // only contains numbers, etc.
27
        Config::modify()->set(CodeGenerator::class, 'length', 100);
28
29
        return parent::setUp(); // TODO: Change the autogenerated stub
30
    }
31
32
    public function testWarningEmail()
33
    {
34
        $member = $this->objFromFixture(Member::class, 'member1');
35
36
        BackupCode::sendWarningEmail($member);
37
38
        $this->assertEmailSent($member->Email);
39
    }
40
41
    public function testWarningMailNotSameUser()
42
    {
43
        $admin = $this->objFromFixture(Member::class, 'member2');
44
        Security::setCurrentUser($admin);
45
46
        $member = $this->objFromFixture(Member::class, 'member1');
47
48
        BackupCode::generateTokensForMember($member);
49
50
        $this->assertEmailSent($member->Email);
51
    }
52
53
    public function testCodesGenerated()
54
    {
55
        $member = $this->objFromFixture(Member::class, 'member1');
56
        Security::setCurrentUser($member);
57
58
        BackupCode::get()->removeAll();
59
60
        BackupCode::generateTokensForMember($member);
61
62
        $codes = BackupCode::get()->filter(['MemberID' => $member->ID]);
63
64
        $this->assertGreaterThan(0, $codes->count());
65
66
        $codesFromValid = BackupCode::getValidTokensForMember($member);
67
68
        $this->assertEquals($codes->count(), $codesFromValid->count());
69
    }
70
71
    public function testCanEdit()
72
    {
73
        $backup = Injector::inst()->get(BackupCode::class);
74
75
        $this->assertFalse($backup->canEdit());
76
    }
77
78
    public function testExpiry()
79
    {
80
        $member = $this->objFromFixture(Member::class, 'member1');
81
        Security::setCurrentUser($member);
82
83
        BackupCode::generateTokensForMember($member);
84
        /** @var BackupCode $code */
85
        $code = BackupCode::get()->filter(['MemberID' => $member->ID])->first();
86
87
        $code = $code->expire();
88
89
        $this->assertTrue((bool)$code->Used);
90
91
        $code = BackupCode::get()->byID($code->ID);
92
93
        $this->assertTrue((bool)$code->Used);
94
    }
95
96
    public function testTokenLimit()
97
    {
98
        /** @var Member $member */
99
        $member = $this->objFromFixture(Member::class, 'member1');
100
        Injector::inst()->get(IdentityStore::class)->logIn($member);
101
        BackupCode::generateTokensForMember($member);
102
103
        $codes = CodeHelper::getCodesFromSession();
104
        // Default length
105
        $this->assertEquals(15, count($codes));
106
107
        Config::modify()->set(BackupCode::class, 'token_limit', 10);
108
109
        BackupCode::generateTokensForMember($member);
110
        $codes = CodeHelper::getCodesFromSession();
111
        $this->assertEquals(10, count($codes));
112
    }
113
114
    public function testBackupCodeConfigNumeric()
115
    {
116
        Config::modify()->set(BackupCode::class, 'token_limit', 3);
117
        Config::modify()->set(CodeGenerator::class, 'length', 10);
118
        Config::modify()->set(CodeGenerator::class, 'type', 'numeric');
119
120
        /** @var Member $member */
121
        $member = $this->objFromFixture(Member::class, 'member1');
122
        Injector::inst()->get(IdentityStore::class)->logIn($member);
123
        BackupCode::generateTokensForMember($member);
124
125
        $codes = CodeHelper::getCodesFromSession();
126
127
        // Actual testing
128
        foreach ($codes as $code) {
129
            $this->assertEquals(10, strlen($code));
130
            $this->assertTrue(is_numeric($code));
131
        }
132
    }
133
134
    public function testBackupCodeConfigAlpha()
135
    {
136
        Config::modify()->set(BackupCode::class, 'token_limit', 3);
137
        Config::modify()->set(CodeGenerator::class, 'type', 'characters');
138
        Config::modify()->set(CodeGenerator::class, 'case', 'mixed');
139
140
        /** @var Member $member */
141
        $member = $this->objFromFixture(Member::class, 'member1');
142
        Injector::inst()->get(IdentityStore::class)->logIn($member);
143
        BackupCode::generateTokensForMember($member);
144
145
        $codes = CodeHelper::getCodesFromSession();
146
147
        // Actual testing
148
        foreach ($codes as $code) {
149
            $this->assertTrue(ctype_alpha($code));
150
            $this->assertFalse(is_numeric($code));
151
            $this->assertFalse(ctype_upper($code));
152
            $this->assertFalse(ctype_lower($code));
153
        }
154
    }
155
156
    public function testBackupCodeConfigAlphaUpper()
157
    {
158
        Config::modify()->set(BackupCode::class, 'token_limit', 3);
159
        Config::modify()->set(CodeGenerator::class, 'type', 'characters');
160
        Config::modify()->set(CodeGenerator::class, 'case', 'upper');
161
162
        /** @var Member $member */
163
        $member = $this->objFromFixture(Member::class, 'member1');
164
        Injector::inst()->get(IdentityStore::class)->logIn($member);
165
        BackupCode::generateTokensForMember($member);
166
167
        $codes = CodeHelper::getCodesFromSession();
168
169
        // Actual testing
170
        foreach ($codes as $code) {
171
            $this->assertFalse(is_numeric($code));
172
            $this->assertTrue(ctype_alpha($code));
173
            $this->assertTrue(ctype_upper($code));
174
        }
175
    }
176
177
    public function testBackupCodeConfigAlphaLower()
178
    {
179
        Config::modify()->set(BackupCode::class, 'token_limit', 3);
180
        Config::modify()->set(CodeGenerator::class, 'type', 'characters');
181
        Config::modify()->set(CodeGenerator::class, 'case', 'lower');
182
183
        /** @var Member $member */
184
        $member = $this->objFromFixture(Member::class, 'member1');
185
        Injector::inst()->get(IdentityStore::class)->logIn($member);
186
        BackupCode::generateTokensForMember($member);
187
188
        $codes = CodeHelper::getCodesFromSession();
189
190
        // Actual testing
191
        foreach ($codes as $code) {
192
            $this->assertFalse(is_numeric($code));
193
            $this->assertTrue(ctype_alpha($code));
194
            $this->assertTrue(ctype_lower($code));
195
        }
196
    }
197
198
    public function testBackupCodeConfigDefault()
199
    {
200
        Config::modify()->set(BackupCode::class, 'token_limit', 3);
201
        Config::modify()->set(CodeGenerator::class, 'type', 'bla');
202
        Config::modify()->set(CodeGenerator::class, 'case', 'bla');
203
204
        /** @var Member $member */
205
        $member = $this->objFromFixture(Member::class, 'member1');
206
        Injector::inst()->get(IdentityStore::class)->logIn($member);
207
        BackupCode::generateTokensForMember($member);
208
209
        $codes = CodeHelper::getCodesFromSession();
210
211
        // Actual testing
212
        foreach ($codes as $code) {
213
            $this->assertTrue(is_numeric($code));
214
            $this->assertEquals('mixed', CodeGenerator::inst()->getCase());
215
            $this->assertEquals('numeric', CodeGenerator::inst()->getType());
216
        }
217
    }
218
}
219