Passed
Pull Request — master (#13)
by Simon
02:00
created

testNoYubikeyDays()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 27
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 27
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 19
nc 1
nop 0
1
<?php
2
3
namespace Firesphere\YubiAuth\Tests;
4
5
use Firesphere\YubiAuth\Authenticators\YubikeyMemberAuthenticator;
6
use Firesphere\YubiAuth\Forms\YubikeyForm;
7
use Firesphere\YubiAuth\Forms\YubikeyLoginForm;
8
use Firesphere\YubiAuth\Handlers\YubikeyLoginHandler;
9
use Firesphere\YubiAuth\Providers\YubikeyAuthProvider;
10
use SilverStripe\Control\HTTPRequest;
11
use SilverStripe\Control\Session;
12
use SilverStripe\Core\Injector\Injector;
13
use SilverStripe\Dev\SapphireTest;
14
use SilverStripe\Security\IdentityStore;
15
use SilverStripe\Security\Member;
16
use SilverStripe\Security\Security;
17
use Yubikey\Validate;
18
19
class YubikeyMemberAuthenticatorTest extends SapphireTest
20
{
21
    protected static $fixture_file = '../fixtures/Member.yml';
22
23
    /**
24
     * @var YubikeyLoginHandler
25
     */
26
    protected $handler;
27
    /**
28
     * @var YubikeyLoginForm
29
     */
30
    protected $form;
31
32
    /**
33
     * @var YubikeyMemberAuthenticator
34
     */
35
    protected $authenticator;
36
37
    protected $request;
38
39
    public function setUp()
40
    {
41
        parent::setUp();
42
        $this->objFromFixture(Member::class, 'admin');
43
        $validator = new MockYubiValidate('apikey', '1234');
44
        $this->authenticator = Injector::inst()->get(YubikeyMemberAuthenticator::class);
45
        $this->handler = Injector::inst()->createWithArgs(
46
            YubikeyLoginHandler::class,
47
            [Security::login_url(), $this->authenticator]
48
        );
49
        $this->form = Injector::inst()->get(
50
            YubikeyLoginForm::class,
51
            true,
52
            [$this->handler, YubikeyMemberAuthenticator::class, '']
53
        );
54
        Injector::inst()->registerService($validator, Validate::class);
55
    }
56
57
    public function tearDown()
58
    {
59
        parent::tearDown();
60
    }
61
62
    public function testNoYubikey()
63
    {
64
        $request = new HTTPRequest('POST', '/');
65
        $request->setSession(new Session(['hi' => 'bye']));
66
        $this->handler->setRequest($request);
67
68
        $this->handler->doLogin(
69
            [
70
                'Email'    => '[email protected]',
71
                'Password' => 'password',
72
            ],
73
            $this->form,
74
            $request
75
        );
76
        $this->handler->validateYubikey(
77
            ['yubiauth' => ''],
78
            YubikeyForm::create($this->handler),
79
            $request
80
        );
81
        $member = Member::get()->filter(['Email' => '[email protected]'])->first();
82
        $this->assertGreaterThan(0, $member->NoYubikeyCount);
83
        $this->assertEquals(null, $member->Yubikey);
84
    }
85
86
    public function testNoYubikeySuccess()
87
    {
88
        /** @var Member $member */
89
        $member = Member::get()->filter(['Email' => '[email protected]'])->first();
90
        $member->NoYubikeyCount = 0;
91
        $member->YubiAuthEnabled = false;
92
        $member->write();
93
        $request = new HTTPRequest('POST', '/');
94
        $request->setSession(new Session(['hi' => 'bye']));
95
        $this->handler->setRequest($request);
96
        $this->handler->doLogin(
97
            [
98
99
                'Email'    => '[email protected]',
100
                'Password' => 'password',
101
            ],
102
            $this->form,
103
            $request
104
        );
105
        $this->handler->validateYubikey(
106
            ['yubiauth' => ''],
107
            YubikeyForm::create($this->handler),
108
            $request
109
        );
110
        $member = Member::get()->filter(['Email' => '[email protected]'])->first();
111
        $this->assertEquals(0, $member->FailedLoginCount);
112
    }
113
114
    public function testNoYubikeyLockout()
115
    {
116
        /** @var Member $member */
117
        $member = Member::get()->filter(['Email' => '[email protected]'])->first();
118
        $failedCount = $member->FailedLoginCount;
119
        $member->NoYubikeyCount = 25;
120
        $member->YubiAuthEnabled = false;
121
        $member->write();
122
        $request = new HTTPRequest('POST', '/');
123
        $request->setSession(new Session(['hi' => 'bye']));
124
        $this->handler->setRequest($request);
125
        $this->handler->doLogin(
126
            [
127
128
                'Email'    => '[email protected]',
129
                'Password' => 'password',
130
            ],
131
            $this->form,
132
            $request
133
        );
134
        $this->handler->validateYubikey(
135
            ['yubiauth' => ''],
136
            YubikeyForm::create($this->handler),
137
            $request
138
        );
139
        $member = Member::get()->filter(['Email' => '[email protected]'])->first();
140
        $this->assertGreaterThan($failedCount, $member->FailedLoginCount);
141
    }
142
143
    public function testNoYubikeyDays()
144
    {
145
        /** @var Member $member */
146
        $member = Member::get()->filter(['Email' => '[email protected]'])->first();
147
        $failedCount = $member->FailedLoginCount;
148
        $member->Created = date('Y-m-d', strtotime('-1 year'));
149
        $member->YubiAuthEnabled = false;
150
        $member->write();
151
        $request = new HTTPRequest('POST', '/');
152
        $request->setSession(new Session(['hi' => 'bye']));
153
        $this->handler->setRequest($request);
154
        $this->handler->doLogin(
155
            [
156
157
                'Email'    => '[email protected]',
158
                'Password' => 'password',
159
            ],
160
            $this->form,
161
            $request
162
        );
163
        $this->handler->validateYubikey(
164
            ['yubiauth' => ''],
165
            YubikeyForm::create($this->handler),
166
            $request
167
        );
168
        $member = Member::get()->filter(['Email' => '[email protected]'])->first();
169
        $this->assertGreaterThan($failedCount, $member->FailedLoginCount);
170
    }
171
172
    public function testDifferentYubikey()
173
    {
174
        $newMember = Member::create([
175
            'FirstName'       => 'Pete',
176
            'Surname'         => 'Lister',
177
            'Password'        => 'IronMan2005!',
178
            'YubiAuthEnabled' => true,
179
            'Yubikey'         => '1234567890abcdef'
180
        ]);
181
        $newMember->write();
182
        /** @var Member $member */
183
        $member = Member::get()->filter(['Email' => '[email protected]'])->first();
184
        $failedCount = $member->FailedLoginCount;
185
        $member->YubiAuthEnabled = true;
186
        $member->write();
187
188
        $request = new HTTPRequest('POST', '/');
189
        $request->setSession(new Session(['hi' => 'bye']));
190
        $this->handler->setRequest($request);
191
        $this->handler->doLogin(
192
            [
193
194
                'Email'    => '[email protected]',
195
                'Password' => 'password',
196
            ],
197
            $this->form,
198
            $request
199
        );
200
        $this->handler->validateYubikey(
201
            ['yubiauth' => '1234567890abcdefyhde.cybcpnbiixcjkbbyd.ydenhnjkn'],
202
            YubikeyForm::create($this->handler),
203
            $request
204
        );
205
        $member = Member::get()->filter(['Email' => '[email protected]'])->first();
206
        $this->assertGreaterThan($failedCount, $member->FailedLoginCount);
207
    }
208
209
    public function testYubikeyAfterSuccess()
210
    {
211
        $request = new HTTPRequest('POST', '/');
212
        $request->setSession(new Session(['hi' => 'bye']));
213
        $this->handler->setRequest($request);
214
        $member = Member::get()->filter(['Email' => '[email protected]'])->first();
215
        $member->YubiAuthEnabled = true;
216
        $member->Yubikey = 'ccccccfinfgr';
217
        $member->NoYubikeyCount = 50;
218
        $member->write();
219
        Injector::inst()->get(IdentityStore::class)->logOut();
220
        $failedLoginCount = $member->FailedLoginCount;
221
        $this->handler->doLogin(
222
            [
223
224
                'Email'    => '[email protected]',
225
                'Password' => 'password',
226
            ],
227
            $this->form,
228
            $request
229
        );
230
        $this->handler->validateYubikey(['yubiauth' => ''], YubikeyForm::create($this->handler), $request);
231
        $resultNoYubi = Security::getCurrentUser();
232
        $this->assertEquals(null, $resultNoYubi);
233
        $member = Member::get()->filter(array('Email' => '[email protected]'))->first();
234
        $this->assertGreaterThan($failedLoginCount, $member->FailedLoginCount);
235
    }
236
237
    public function testYubikey()
238
    {
239
        $request = new HTTPRequest('POST', '/');
240
        $request->setSession(new Session(['hi' => 'bye']));
241
        $this->handler->setRequest($request);
242
        $this->handler->doLogin(
243
            [
244
245
                'Email'    => '[email protected]',
246
                'Password' => 'password',
247
            ],
248
            $this->form,
249
            $request
250
        );
251
        $this->handler->validateYubikey(
252
            [
253
                // This OTP is _not_ valid in real situations
254
                'yubiauth' => 'jjjjjjucbuipyhde.cybcpnbiixcjkbbyd.ydenhnjkn'
255
            ],
256
            YubikeyForm::create($this->handler),
257
            $request
258
        );
259
        $result = Security::getCurrentUser();
260
        $this->assertEquals(Member::class, $result->ClassName);
261
        $this->assertEquals('ccccccfinfgr', $result->Yubikey);
262
        $this->assertEquals(1, $result->YubiAuthEnabled);
263
        $this->assertEquals('[email protected]', $result->Email);
264
        $this->assertEquals(true, $result->YubiAuthEnabled);
265
        $result->write();
266
    }
267
268
    public function testName()
269
    {
270
        $this->assertEquals('Yubikey 2 factor login', YubikeyMemberAuthenticator::get_name());
271
    }
272
273
    public function testGetLoginHandler()
274
    {
275
        $authenticator = new YubikeyMemberAuthenticator();
276
277
        $handler = $authenticator->getLoginHandler(Security::login_url());
278
279
        $this->assertInstanceOf(YubikeyLoginHandler::class, $handler);
280
    }
281
282
    public function testGetSetProvider()
283
    {
284
        /** @var YubikeyMemberAuthenticator $authenticator */
285
        $authenticator = new YubikeyMemberAuthenticator();
286
287
        /** @var YubikeyAuthProvider $provider */
288
        $provider = Injector::inst()->get(YubikeyAuthProvider::class);
289
290
        $authenticator->setProvider($provider);
291
292
        $this->assertInstanceOf(YubikeyAuthProvider::class, $authenticator->getProvider());
293
    }
294
295
    public function testSupportedServices()
296
    {
297
        /** @var YubikeyMemberAuthenticator $authenticator */
298
        $authenticator = new YubikeyMemberAuthenticator();
299
300
        $this->assertEquals(47, $authenticator->supportedServices());
301
    }
302
}
303