BackupCodeTest   A
last analyzed

Complexity

Total Complexity 17

Size/Duplication

Total Lines 199
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
eloc 94
dl 0
loc 199
rs 10
c 0
b 0
f 0
wmc 17

12 Methods

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