Passed
Pull Request — master (#13)
by Simon
01:52
created

YubikeyMemberAuthenticatorTest   A

Complexity

Total Complexity 12

Size/Duplication

Total Lines 287
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 12
dl 0
loc 287
rs 10
c 0
b 0
f 0

12 Methods

Rating   Name   Duplication   Size   Complexity  
A testNoYubikey() 0 22 1
A tearDown() 0 3 1
B testNoYubikeyLockout() 0 27 1
B testNoYubikeySuccess() 0 26 1
A setUp() 0 16 1
A testGetSetProvider() 0 11 1
A testGetLoginHandler() 0 7 1
B testYubikey() 0 29 1
A testSupportedServices() 0 6 1
B testNoYubikeyDays() 0 28 1
A testName() 0 3 1
B testYubikeyAfterSuccess() 0 26 1
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
        $result = $this->handler->validateYubikey(
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
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->NoYubikeyCount = 26;
149
        $member->Created = date('Y-m-d', strtotime('-1 year'));
150
        $member->YubiAuthEnabled = false;
151
        $member->write();
152
        $request = new HTTPRequest('POST', '/');
153
        $request->setSession(new Session(['hi' => 'bye']));
154
        $this->handler->setRequest($request);
155
        $this->handler->doLogin(
156
            [
157
158
                'Email'    => '[email protected]',
159
                'Password' => 'password',
160
            ],
161
            $this->form,
162
            $request
163
        );
164
        $result = $this->handler->validateYubikey(
0 ignored issues
show
Unused Code introduced by
The assignment to $result is dead and can be removed.
Loading history...
165
            ['yubiauth' => ''],
166
            YubikeyForm::create($this->handler),
167
            $request
168
        );
169
        $member = Member::get()->filter(['Email' => '[email protected]'])->first();
170
        $this->assertGreaterThan($failedCount, $member->FailedLoginCount);
171
    }
172
173
    /**
174
     * @todo The mock currently always returns success
175
     *
176
     * public function testDifferentYubikey()
177
     * {
178
     * $newMember = Member::create([
179
     * 'FirstName'       => 'Pete',
180
     * 'Surname'         => 'Lister',
181
     * 'Password'        => 'IronMan2005!',
182
     * 'YubiAuthEnabled' => true,
183
     * 'Yubikey'         => '1234567890abcdef'
184
     * ]);
185
     * $newMember->write();
186
     *
187
     * $member = Member::get()->filter(['Email' => '[email protected]'])->first();
188
     * $failedCount = $member->FailedLoginCount;
189
     * $member->YubiAuthEnabled = true;
190
     * $member->write();
191
     *
192
     * $request = new HTTPRequest('POST', '/');
193
     * $request->setSession(new Session(['hi' => 'bye']));
194
     * $this->handler->setRequest($request);
195
     * $this->handler->doLogin(
196
     * [
197
     *
198
     * 'Email'    => '[email protected]',
199
     * 'Password' => 'password',
200
     * ],
201
     * $this->form,
202
     * $request
203
     * );
204
     * $this->handler->validateYubikey(
205
     * ['yubiauth' => '1234567890abcdefyhde.cybcpnbiixcjkbbyd.ydenhnjkn'],
206
     * YubikeyForm::create($this->handler),
207
     * $request
208
     * );
209
     * $member = Member::get()->filter(['Email' => '[email protected]'])->first();
210
     * $this->assertGreaterThan($failedCount, $member->FailedLoginCount);
211
     * }
212
     */
213
214
    public function testYubikeyAfterSuccess()
215
    {
216
        $request = new HTTPRequest('POST', '/');
217
        $request->setSession(new Session(['hi' => 'bye']));
218
        $this->handler->setRequest($request);
219
        $member = Member::get()->filter(['Email' => '[email protected]'])->first();
220
        $member->YubiAuthEnabled = true;
221
        $member->Yubikey = 'ccccccfinfgr';
222
        $member->NoYubikeyCount = 50;
223
        $member->write();
224
        Injector::inst()->get(IdentityStore::class)->logOut();
225
        $failedLoginCount = $member->FailedLoginCount;
226
        $this->handler->doLogin(
227
            [
228
229
                'Email'    => '[email protected]',
230
                'Password' => 'password',
231
            ],
232
            $this->form,
233
            $request
234
        );
235
        $this->handler->validateYubikey(['yubiauth' => ''], YubikeyForm::create($this->handler), $request);
236
        $resultNoYubi = Security::getCurrentUser();
237
        $this->assertEquals(null, $resultNoYubi);
238
        $member = Member::get()->filter(array('Email' => '[email protected]'))->first();
239
        $this->assertGreaterThan($failedLoginCount, $member->FailedLoginCount);
240
    }
241
242
    public function testYubikey()
243
    {
244
        $request = new HTTPRequest('POST', '/');
245
        $request->setSession(new Session(['hi' => 'bye']));
246
        $this->handler->setRequest($request);
247
        $this->handler->doLogin(
248
            [
249
250
                'Email'    => '[email protected]',
251
                'Password' => 'password',
252
            ],
253
            $this->form,
254
            $request
255
        );
256
        $this->handler->validateYubikey(
257
            [
258
                // This OTP is _not_ valid in real situations
259
                'yubiauth' => 'jjjjjjucbuipyhde.cybcpnbiixcjkbbyd.ydenhnjkn'
260
            ],
261
            YubikeyForm::create($this->handler),
262
            $request
263
        );
264
        $result = Security::getCurrentUser();
265
        $this->assertEquals(Member::class, $result->ClassName);
266
        $this->assertEquals('ccccccfinfgr', $result->Yubikey);
267
        $this->assertEquals(1, $result->YubiAuthEnabled);
268
        $this->assertEquals('[email protected]', $result->Email);
269
        $this->assertEquals(true, $result->YubiAuthEnabled);
270
        $result->write();
271
    }
272
273
    public function testName()
274
    {
275
        $this->assertEquals('Yubikey 2 factor login', YubikeyMemberAuthenticator::get_name());
276
    }
277
278
    public function testGetLoginHandler()
279
    {
280
        $authenticator = new YubikeyMemberAuthenticator();
281
282
        $handler = $authenticator->getLoginHandler(Security::login_url());
283
284
        $this->assertInstanceOf(YubikeyLoginHandler::class, $handler);
285
    }
286
287
    public function testGetSetProvider()
288
    {
289
        /** @var YubikeyMemberAuthenticator $authenticator */
290
        $authenticator = new YubikeyMemberAuthenticator();
291
292
        /** @var YubikeyAuthProvider $provider */
293
        $provider = Injector::inst()->get(YubikeyAuthProvider::class);
294
295
        $authenticator->setProvider($provider);
296
297
        $this->assertInstanceOf(YubikeyAuthProvider::class, $authenticator->getProvider());
298
    }
299
300
    public function testSupportedServices()
301
    {
302
        /** @var YubikeyMemberAuthenticator $authenticator */
303
        $authenticator = new YubikeyMemberAuthenticator();
304
305
        $this->assertEquals(47, $authenticator->supportedServices());
306
    }
307
}
308