Passed
Pull Request — master (#13)
by Simon
03:37 queued 01:36
created

testYubikeyAfterSuccess()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 26
Code Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

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