Passed
Pull Request — master (#13)
by Simon
03:33 queued 01:31
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\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
    /**
173
     * @todo The mock currently always returns success
174
     *
175
    public function testDifferentYubikey()
176
    {
177
        $newMember = Member::create([
178
            'FirstName'       => 'Pete',
179
            'Surname'         => 'Lister',
180
            'Password'        => 'IronMan2005!',
181
            'YubiAuthEnabled' => true,
182
            'Yubikey'         => '1234567890abcdef'
183
        ]);
184
        $newMember->write();
185
186
        $member = Member::get()->filter(['Email' => '[email protected]'])->first();
187
        $failedCount = $member->FailedLoginCount;
188
        $member->YubiAuthEnabled = true;
189
        $member->write();
190
191
        $request = new HTTPRequest('POST', '/');
192
        $request->setSession(new Session(['hi' => 'bye']));
193
        $this->handler->setRequest($request);
194
        $this->handler->doLogin(
195
            [
196
197
                'Email'    => '[email protected]',
198
                'Password' => 'password',
199
            ],
200
            $this->form,
201
            $request
202
        );
203
        $this->handler->validateYubikey(
204
            ['yubiauth' => '1234567890abcdefyhde.cybcpnbiixcjkbbyd.ydenhnjkn'],
205
            YubikeyForm::create($this->handler),
206
            $request
207
        );
208
        $member = Member::get()->filter(['Email' => '[email protected]'])->first();
209
        $this->assertGreaterThan($failedCount, $member->FailedLoginCount);
210
    }
211
     */
212
213
    public function testYubikeyAfterSuccess()
214
    {
215
        $request = new HTTPRequest('POST', '/');
216
        $request->setSession(new Session(['hi' => 'bye']));
217
        $this->handler->setRequest($request);
218
        $member = Member::get()->filter(['Email' => '[email protected]'])->first();
219
        $member->YubiAuthEnabled = true;
220
        $member->Yubikey = 'ccccccfinfgr';
221
        $member->NoYubikeyCount = 50;
222
        $member->write();
223
        Injector::inst()->get(IdentityStore::class)->logOut();
224
        $failedLoginCount = $member->FailedLoginCount;
225
        $this->handler->doLogin(
226
            [
227
228
                'Email'    => '[email protected]',
229
                'Password' => 'password',
230
            ],
231
            $this->form,
232
            $request
233
        );
234
        $this->handler->validateYubikey(['yubiauth' => ''], YubikeyForm::create($this->handler), $request);
235
        $resultNoYubi = Security::getCurrentUser();
236
        $this->assertEquals(null, $resultNoYubi);
237
        $member = Member::get()->filter(array('Email' => '[email protected]'))->first();
238
        $this->assertGreaterThan($failedLoginCount, $member->FailedLoginCount);
239
    }
240
241
    public function testYubikey()
242
    {
243
        $request = new HTTPRequest('POST', '/');
244
        $request->setSession(new Session(['hi' => 'bye']));
245
        $this->handler->setRequest($request);
246
        $this->handler->doLogin(
247
            [
248
249
                'Email'    => '[email protected]',
250
                'Password' => 'password',
251
            ],
252
            $this->form,
253
            $request
254
        );
255
        $this->handler->validateYubikey(
256
            [
257
                // This OTP is _not_ valid in real situations
258
                'yubiauth' => 'jjjjjjucbuipyhde.cybcpnbiixcjkbbyd.ydenhnjkn'
259
            ],
260
            YubikeyForm::create($this->handler),
261
            $request
262
        );
263
        $result = Security::getCurrentUser();
264
        $this->assertEquals(Member::class, $result->ClassName);
265
        $this->assertEquals('ccccccfinfgr', $result->Yubikey);
266
        $this->assertEquals(1, $result->YubiAuthEnabled);
267
        $this->assertEquals('[email protected]', $result->Email);
268
        $this->assertEquals(true, $result->YubiAuthEnabled);
269
        $result->write();
270
    }
271
272
    public function testName()
273
    {
274
        $this->assertEquals('Yubikey 2 factor login', YubikeyMemberAuthenticator::get_name());
275
    }
276
277
    public function testGetLoginHandler()
278
    {
279
        $authenticator = new YubikeyMemberAuthenticator();
280
281
        $handler = $authenticator->getLoginHandler(Security::login_url());
282
283
        $this->assertInstanceOf(YubikeyLoginHandler::class, $handler);
284
    }
285
286
    public function testGetSetProvider()
287
    {
288
        /** @var YubikeyMemberAuthenticator $authenticator */
289
        $authenticator = new YubikeyMemberAuthenticator();
290
291
        /** @var YubikeyAuthProvider $provider */
292
        $provider = Injector::inst()->get(YubikeyAuthProvider::class);
293
294
        $authenticator->setProvider($provider);
295
296
        $this->assertInstanceOf(YubikeyAuthProvider::class, $authenticator->getProvider());
297
    }
298
299
    public function testSupportedServices()
300
    {
301
        /** @var YubikeyMemberAuthenticator $authenticator */
302
        $authenticator = new YubikeyMemberAuthenticator();
303
304
        $this->assertEquals(47, $authenticator->supportedServices());
305
    }
306
}
307