Passed
Pull Request — master (#13)
by Simon
02:38
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(
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
        $this->assertFalse($result->isValid());
0 ignored issues
show
Bug introduced by
The method isValid() does not exist on SilverStripe\Control\HTTPResponse. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

142
        $this->assertFalse($result->/** @scrutinizer ignore-call */ isValid());

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

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