Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
100.00% covered (success)
100.00%
302 / 302
100.00% covered (success)
100.00%
11 / 11
CRAP
100.00% covered (success)
100.00%
1 / 1
phpbb_feed_http_auth_subscriber_test
100.00% covered (success)
100.00%
302 / 302
100.00% covered (success)
100.00%
11 / 11
11
100.00% covered (success)
100.00%
1 / 1
 setUp
100.00% covered (success)
100.00%
35 / 35
100.00% covered (success)
100.00%
1 / 1
1
 test_subscriber_events
100.00% covered (success)
100.00%
2 / 2
100.00% covered (success)
100.00%
1 / 1
1
 test_non_feed_route_skipped
100.00% covered (success)
100.00%
20 / 20
100.00% covered (success)
100.00%
1 / 1
1
 test_insecure_connection_skipped
100.00% covered (success)
100.00%
22 / 22
100.00% covered (success)
100.00%
1 / 1
1
 test_http_auth_disabled
100.00% covered (success)
100.00%
19 / 19
100.00% covered (success)
100.00%
1 / 1
1
 test_user_already_logged_in
100.00% covered (success)
100.00%
23 / 23
100.00% covered (success)
100.00%
1 / 1
1
 test_no_credentials
100.00% covered (success)
100.00%
31 / 31
100.00% covered (success)
100.00%
1 / 1
1
 test_valid_credentials
100.00% covered (success)
100.00%
35 / 35
100.00% covered (success)
100.00%
1 / 1
1
 test_valid_credentials_base64
100.00% covered (success)
100.00%
33 / 33
100.00% covered (success)
100.00%
1 / 1
1
 test_too_many_attempts
100.00% covered (success)
100.00%
41 / 41
100.00% covered (success)
100.00%
1 / 1
1
 test_wrong_credentials
100.00% covered (success)
100.00%
41 / 41
100.00% covered (success)
100.00%
1 / 1
1
1<?php
2
3use phpbb\config\config;
4use phpbb\feed\event\http_auth_subscriber;
5use phpbb\request\request_interface;
6use Symfony\Component\HttpFoundation\Response;
7
8/**
9 *
10 * This file is part of the phpBB Forum Software package.
11 *
12 * @copyright (c) phpBB Limited <https://www.phpbb.com>
13 * @license GNU General Public License, version 2 (GPL-2.0)
14 *
15 * For full copyright and license information, please see
16 * the docs/CREDITS.txt file.
17 *
18 */
19
20class phpbb_feed_http_auth_subscriber_test extends \phpbb_test_case
21{
22    /** @var \PHPUnit\Framework\MockObject\MockObject|\phpbb\auth\auth */
23    protected $auth;
24
25    /** @var \PHPUnit\Framework\MockObject\MockObject|config */
26    protected $config;
27
28    /** @var \PHPUnit\Framework\MockObject\MockObject|\phpbb\language\language */
29    protected $language;
30
31    /** @var \PHPUnit\Framework\MockObject\MockObject|\phpbb\request\request_interface */
32    protected $request;
33
34    /** @var \PHPUnit\Framework\MockObject\MockObject|\phpbb\user */
35    protected $user;
36
37    /** @var http_auth_subscriber */
38    protected $subscriber;
39
40    protected function setUp(): void
41    {
42        parent::setUp();
43
44        $this->auth = $this->getMockBuilder('\phpbb\auth\auth')
45            ->disableOriginalConstructor()
46            ->getMock();
47        $this->auth->method('login')
48            ->willReturnMap([
49                ['valid_user', 'valid_password', false, true, false, ['status' => LOGIN_SUCCESS]],
50                ['invalid_user', 'invalid_password', false, true, false, ['status' => LOGIN_ERROR_USERNAME]],
51                ['attempts_user', 'valid_password', false, true, false, ['status' => LOGIN_ERROR_ATTEMPTS]],
52            ]);
53
54        $this->config = new config(array(
55            'feed_http_auth' => 1,
56            'sitename' => 'Test Site',
57        ));
58
59        $this->language = $this->getMockBuilder('\phpbb\language\language')
60            ->disableOriginalConstructor()
61            ->getMock();
62        $this->language->method('lang')
63            ->willReturnMap([
64                ['NOT_AUTHORISED', 'NOT_AUTHORISED'],
65                ['LOGIN_ERROR_ATTEMPTS', 'LOGIN_ERROR_ATTEMPTS']
66            ]);
67
68        $this->request = $this->getMockBuilder('\phpbb\request\request_interface')
69            ->getMock();
70
71        $this->user = $this->getMockBuilder('\phpbb\user')
72            ->disableOriginalConstructor()
73            ->getMock();
74
75        $this->user->data = array('is_registered' => false);
76
77        $this->subscriber = new http_auth_subscriber(
78            $this->auth,
79            $this->config,
80            $this->language,
81            $this->request,
82            $this->user
83        );
84    }
85
86    public function test_subscriber_events()
87    {
88        $events = http_auth_subscriber::getSubscribedEvents();
89        $this->assertArrayHasKey(\Symfony\Component\HttpKernel\KernelEvents::REQUEST, $events);
90    }
91
92    public function test_non_feed_route_skipped()
93    {
94        $request = $this->getMockBuilder('\Symfony\Component\HttpFoundation\Request')
95            ->disableOriginalConstructor()
96            ->getMock();
97
98        $request->attributes = $this->getMockBuilder('\Symfony\Component\HttpFoundation\ParameterBag')
99            ->disableOriginalConstructor()
100            ->getMock();
101
102        $request->attributes->expects($this->once())
103            ->method('get')
104            ->with('_route')
105            ->willReturn('not_a_feed_route');
106
107        $event = $this->getMockBuilder('\Symfony\Component\HttpKernel\Event\RequestEvent')
108            ->onlyMethods(['getRequest', 'setResponse'])
109            ->disableOriginalConstructor()
110            ->getMock();
111
112        $event->expects($this->once())
113            ->method('getRequest')
114            ->willReturn($request);
115
116        $event->expects($this->never())
117            ->method('setResponse');
118
119        $this->subscriber->on_kernel_request($event);
120    }
121
122    public function test_insecure_connection_skipped()
123    {
124        $request = $this->getMockBuilder('\Symfony\Component\HttpFoundation\Request')
125            ->disableOriginalConstructor()
126            ->getMock();
127
128        $request->attributes = $this->getMockBuilder('\Symfony\Component\HttpFoundation\ParameterBag')
129            ->disableOriginalConstructor()
130            ->getMock();
131
132        $request->attributes->expects($this->once())
133            ->method('get')
134            ->with('_route')
135            ->willReturn('phpbb_feed_overall');
136
137        $request->expects($this->once())
138            ->method('isSecure')
139            ->willReturn(false);
140
141        $event = $this->getMockBuilder('\Symfony\Component\HttpKernel\Event\RequestEvent')
142            ->disableOriginalConstructor()
143            ->getMock();
144
145        $event->expects($this->once())
146            ->method('getRequest')
147            ->willReturn($request);
148
149        $event->expects($this->never())
150            ->method('setResponse');
151
152        $this->subscriber->on_kernel_request($event);
153    }
154
155    public function test_http_auth_disabled()
156    {
157        $this->config['feed_http_auth'] = 0;
158
159        $request = $this->getMockBuilder('\Symfony\Component\HttpFoundation\Request')
160            ->disableOriginalConstructor()
161            ->getMock();
162
163        $request->attributes = $this->getMockBuilder('\Symfony\Component\HttpFoundation\ParameterBag')
164            ->disableOriginalConstructor()
165            ->getMock();
166
167        $request->attributes->expects($this->never())
168            ->method('get');
169
170        $request->expects($this->never())
171            ->method('isSecure');
172
173        $event = $this->getMockBuilder('\Symfony\Component\HttpKernel\Event\RequestEvent')
174            ->disableOriginalConstructor()
175            ->getMock();
176
177        $event->expects($this->never())
178            ->method('getRequest');
179
180        $event->expects($this->never())
181            ->method('setResponse');
182
183        $this->subscriber->on_kernel_request($event);
184    }
185
186    public function test_user_already_logged_in()
187    {
188        $this->user->data = array('is_registered' => true);
189
190        $request = $this->getMockBuilder('\Symfony\Component\HttpFoundation\Request')
191            ->disableOriginalConstructor()
192            ->getMock();
193
194        $request->attributes = $this->getMockBuilder('\Symfony\Component\HttpFoundation\ParameterBag')
195            ->disableOriginalConstructor()
196            ->getMock();
197
198        $request->attributes->expects($this->once())
199            ->method('get')
200            ->with('_route')
201            ->willReturn('phpbb_feed_overall');
202
203        $request->expects($this->once())
204            ->method('isSecure')
205            ->willReturn(true);
206
207        $event = $this->getMockBuilder('\Symfony\Component\HttpKernel\Event\RequestEvent')
208            ->disableOriginalConstructor()
209            ->getMock();
210
211        $event->expects($this->once())
212            ->method('getRequest')
213            ->willReturn($request);
214
215        $event->expects($this->never())
216            ->method('setResponse');
217
218        $this->subscriber->on_kernel_request($event);
219    }
220
221    public function test_no_credentials()
222    {
223        $this->user->data = ['is_registered' => false];
224
225        $request = $this->getMockBuilder('\Symfony\Component\HttpFoundation\Request')
226            ->disableOriginalConstructor()
227            ->getMock();
228
229        $request->attributes = $this->getMockBuilder('\Symfony\Component\HttpFoundation\ParameterBag')
230            ->disableOriginalConstructor()
231            ->getMock();
232
233        $request->attributes->expects($this->once())
234            ->method('get')
235            ->with('_route')
236            ->willReturn('phpbb_feed_overall');
237
238        $request->expects($this->once())
239            ->method('isSecure')
240            ->willReturn(true);
241
242        $event = $this->getMockBuilder('\Symfony\Component\HttpKernel\Event\RequestEvent')
243            ->disableOriginalConstructor()
244            ->getMock();
245
246        $event->expects($this->once())
247            ->method('getRequest')
248            ->willReturn($request);
249
250        /** @var Response $response */
251        $response = null;
252        $event->expects($this->once())
253            ->method('setResponse')
254            ->with($this->isInstanceOf('\Symfony\Component\HttpFoundation\Response'))
255            ->willReturnCallback(function ($newResponse) use (&$response) {
256                $response = $newResponse;
257            });
258
259        $this->subscriber->on_kernel_request($event);
260
261        $this->assertEquals(Response::HTTP_UNAUTHORIZED, $response->getStatusCode());
262        $this->assertEquals('NOT_AUTHORISED', $response->getContent());
263        $this->assertTrue($response->headers->has('WWW-Authenticate'));
264    }
265
266    public function test_valid_credentials()
267    {
268        $this->user->data = ['is_registered' => false];
269
270        $request = $this->getMockBuilder('\Symfony\Component\HttpFoundation\Request')
271            ->disableOriginalConstructor()
272            ->getMock();
273
274        $request->attributes = $this->getMockBuilder('\Symfony\Component\HttpFoundation\ParameterBag')
275            ->disableOriginalConstructor()
276            ->getMock();
277
278        $request->attributes->expects($this->once())
279            ->method('get')
280            ->with('_route')
281            ->willReturn('phpbb_feed_overall');
282
283        $this->request->method('is_set')
284            ->willReturnMap([
285                ['PHP_AUTH_USER', request_interface::SERVER, true],
286                ['PHP_AUTH_PW', request_interface::SERVER, true],
287            ]);
288
289        $this->request->method('server')
290            ->willReturnMap([
291                ['PHP_AUTH_USER', '', 'valid_user'],
292                ['PHP_AUTH_PW', '', 'valid_password'],
293            ]);
294
295        $request->expects($this->once())
296            ->method('isSecure')
297            ->willReturn(true);
298
299        $event = $this->getMockBuilder('\Symfony\Component\HttpKernel\Event\RequestEvent')
300            ->disableOriginalConstructor()
301            ->getMock();
302
303        $event->expects($this->once())
304            ->method('getRequest')
305            ->willReturn($request);
306
307        /** @var Response $response */
308        $response = null;
309        $event->expects($this->never())
310            ->method('setResponse');
311
312        $this->subscriber->on_kernel_request($event);
313
314        $this->assertNull($response);
315    }
316
317    public function test_valid_credentials_base64()
318    {
319        $this->user->data = ['is_registered' => false];
320
321        $request = $this->getMockBuilder('\Symfony\Component\HttpFoundation\Request')
322            ->disableOriginalConstructor()
323            ->getMock();
324
325        $request->attributes = $this->getMockBuilder('\Symfony\Component\HttpFoundation\ParameterBag')
326            ->disableOriginalConstructor()
327            ->getMock();
328
329        $request->attributes->expects($this->once())
330            ->method('get')
331            ->with('_route')
332            ->willReturn('phpbb_feed_overall');
333
334        $this->request->method('is_set')
335            ->willReturnMap([
336                ['Authorization', request_interface::SERVER, true],
337            ]);
338
339        $this->request->method('server')
340            ->willReturnMap([
341                ['Authorization', '', 'Basic dmFsaWRfdXNlcjp2YWxpZF9wYXNzd29yZA=='],
342            ]);
343
344        $request->expects($this->once())
345            ->method('isSecure')
346            ->willReturn(true);
347
348        $event = $this->getMockBuilder('\Symfony\Component\HttpKernel\Event\RequestEvent')
349            ->disableOriginalConstructor()
350            ->getMock();
351
352        $event->expects($this->once())
353            ->method('getRequest')
354            ->willReturn($request);
355
356        /** @var Response $response */
357        $response = null;
358        $event->expects($this->never())
359            ->method('setResponse');
360
361        $this->subscriber->on_kernel_request($event);
362
363        $this->assertNull($response);
364    }
365
366    public function test_too_many_attempts()
367    {
368        $this->user->data = ['is_registered' => false];
369
370        $request = $this->getMockBuilder('\Symfony\Component\HttpFoundation\Request')
371            ->disableOriginalConstructor()
372            ->getMock();
373
374        $request->attributes = $this->getMockBuilder('\Symfony\Component\HttpFoundation\ParameterBag')
375            ->disableOriginalConstructor()
376            ->getMock();
377
378        $request->attributes->expects($this->once())
379            ->method('get')
380            ->with('_route')
381            ->willReturn('phpbb_feed_overall');
382
383        $this->request->method('is_set')
384            ->willReturnMap([
385                ['PHP_AUTH_USER', request_interface::SERVER, true],
386                ['PHP_AUTH_PW', request_interface::SERVER, true],
387            ]);
388
389        $this->request->method('server')
390            ->willReturnMap([
391                ['PHP_AUTH_USER', '', 'attempts_user'],
392                ['PHP_AUTH_PW', '', 'valid_password'],
393            ]);
394
395        $request->expects($this->once())
396            ->method('isSecure')
397            ->willReturn(true);
398
399        $event = $this->getMockBuilder('\Symfony\Component\HttpKernel\Event\RequestEvent')
400            ->disableOriginalConstructor()
401            ->getMock();
402
403        $event->expects($this->once())
404            ->method('getRequest')
405            ->willReturn($request);
406
407        /** @var Response $response */
408        $response = null;
409        $event->expects($this->once())
410            ->method('setResponse')
411            ->with($this->isInstanceOf('\Symfony\Component\HttpFoundation\Response'))
412            ->willReturnCallback(function ($newResponse) use (&$response) {
413                $response = $newResponse;
414            });
415
416        $this->subscriber->on_kernel_request($event);
417
418        $this->assertEquals(Response::HTTP_UNAUTHORIZED, $response->getStatusCode());
419        $this->assertEquals('LOGIN_ERROR_ATTEMPTS', $response->getContent());
420        $this->assertFalse($response->headers->has('WWW-Authenticate'));
421    }
422
423    public function test_wrong_credentials()
424    {
425        $this->user->data = ['is_registered' => false];
426
427        $request = $this->getMockBuilder('\Symfony\Component\HttpFoundation\Request')
428            ->disableOriginalConstructor()
429            ->getMock();
430
431        $request->attributes = $this->getMockBuilder('\Symfony\Component\HttpFoundation\ParameterBag')
432            ->disableOriginalConstructor()
433            ->getMock();
434
435        $request->attributes->expects($this->once())
436            ->method('get')
437            ->with('_route')
438            ->willReturn('phpbb_feed_overall');
439
440        $this->request->method('is_set')
441            ->willReturnMap([
442                ['PHP_AUTH_USER', request_interface::SERVER, true],
443                ['PHP_AUTH_PW', request_interface::SERVER, true],
444            ]);
445
446        $this->request->method('server')
447            ->willReturnMap([
448                ['PHP_AUTH_USER', '', 'invalid_user'],
449                ['PHP_AUTH_PW', '', 'invalid_password'],
450            ]);
451
452        $request->expects($this->once())
453            ->method('isSecure')
454            ->willReturn(true);
455
456        $event = $this->getMockBuilder('\Symfony\Component\HttpKernel\Event\RequestEvent')
457            ->disableOriginalConstructor()
458            ->getMock();
459
460        $event->expects($this->once())
461            ->method('getRequest')
462            ->willReturn($request);
463
464        /** @var Response $response */
465        $response = null;
466        $event->expects($this->once())
467            ->method('setResponse')
468            ->with($this->isInstanceOf('\Symfony\Component\HttpFoundation\Response'))
469            ->willReturnCallback(function ($newResponse) use (&$response) {
470                $response = $newResponse;
471            });
472
473        $this->subscriber->on_kernel_request($event);
474
475        $this->assertEquals(Response::HTTP_UNAUTHORIZED, $response->getStatusCode());
476        $this->assertEquals('NOT_AUTHORISED', $response->getContent());
477        $this->assertTrue($response->headers->has('WWW-Authenticate'));
478    }
479}