Completed
Push — EZP-26146-location-swap-urlali... ( 334d77...8d4853 )
by
unknown
63:56 queued 37:49
created

CsrfListenerTest::testSessionRequests()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 7
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
c 0
b 0
f 0
nc 1
nop 1
dl 0
loc 7
rs 9.4285
1
<?php
2
3
/**
4
 * File containing the RestValueResponseListener class.
5
 *
6
 * @copyright Copyright (C) eZ Systems AS. All rights reserved.
7
 * @license For full copyright and license information view LICENSE file distributed with this source code.
8
 *
9
 * @version //autogentag//
10
 */
11
namespace eZ\Bundle\EzPublishRestBundle\Tests\EventListener;
12
13
use PHPUnit_Framework_MockObject_MockObject;
14
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
15
use Symfony\Component\HttpFoundation\ParameterBag;
16
use Symfony\Component\HttpFoundation\Request;
17
use Symfony\Component\HttpKernel\Event\GetResponseEvent;
18
use Symfony\Component\Form\Extension\Csrf\CsrfProvider\CsrfProviderInterface;
19
use eZ\Bundle\EzPublishRestBundle\EventListener\CsrfListener;
20
use Symfony\Component\HttpKernel\KernelEvents;
21
use Symfony\Component\Security\Csrf\CsrfToken;
22
23
class CsrfListenerTest extends EventListenerTest
24
{
25
    const VALID_TOKEN = 'valid';
26
    const INVALID_TOKEN = 'invalid';
27
    const INTENTION = 'rest';
28
29
    /** @var EventDispatcherInterface */
30
    protected $eventDispatcherMock;
31
32
    /**
33
     * If set to null before initializing mocks, Request::getSession() is expected not to be called.
34
     *
35
     * @var \Symfony\Component\HttpFoundation\Session\SessionInterface
36
     */
37
    protected $sessionMock;
38
39
    protected $sessionIsStarted = true;
40
41
    protected $csrfTokenHeaderValue = self::VALID_TOKEN;
42
43
    /**
44
     * Route returned by Request::get( '_route' )
45
     * If set to false, get( '_route' ) is expected not to be called.
46
     *
47
     * @var string
48
     */
49
    protected $route = 'ezpublish_rest_something';
50
51
    /**
52
     * If set to false, Request::getRequestMethod() is expected not to be called.
53
     */
54
    protected $requestMethod = 'POST';
55
56
    public function provideExpectedSubscribedEventTypes()
57
    {
58
        return array(
59
            array(array(KernelEvents::REQUEST)),
60
        );
61
    }
62
63
    public function testIsNotRestRequest()
64
    {
65
        $this->isRestRequest = false;
66
67
        $this->requestMethod = false;
0 ignored issues
show
Documentation Bug introduced by
The property $requestMethod was declared of type string, but false is of type false. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
68
        $this->sessionMock = false;
0 ignored issues
show
Documentation Bug introduced by
It seems like false of type false is incompatible with the declared type object<Symfony\Component...ssion\SessionInterface> of property $sessionMock.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
69
        $this->route = false;
0 ignored issues
show
Documentation Bug introduced by
The property $route was declared of type string, but false is of type false. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
70
        $this->csrfTokenHeaderValue = null;
71
72
        $listener = $this->getEventListener();
73
        $listener->onKernelRequest($this->getEventMock());
0 ignored issues
show
Documentation introduced by
$this->getEventMock() is of type null|object<Symfony\Comp...entDispatcherInterface>, but the function expects a object<Symfony\Component...Event\GetResponseEvent>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
74
    }
75
76 View Code Duplication
    public function testCsrfDisabled()
77
    {
78
        $this->requestMethod = false;
0 ignored issues
show
Documentation Bug introduced by
The property $requestMethod was declared of type string, but false is of type false. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
79
        $this->sessionMock = false;
0 ignored issues
show
Documentation Bug introduced by
It seems like false of type false is incompatible with the declared type object<Symfony\Component...ssion\SessionInterface> of property $sessionMock.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
80
        $this->route = false;
0 ignored issues
show
Documentation Bug introduced by
The property $route was declared of type string, but false is of type false. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
81
        $this->csrfTokenHeaderValue = null;
82
83
        $this->getEventListener(false)->onKernelRequest($this->getEventMock());
0 ignored issues
show
Documentation introduced by
$this->getEventMock() is of type null|object<Symfony\Comp...entDispatcherInterface>, but the function expects a object<Symfony\Component...Event\GetResponseEvent>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
84
    }
85
86 View Code Duplication
    public function testNoSessionStarted()
87
    {
88
        $this->sessionIsStarted = false;
89
90
        $this->requestMethod = false;
0 ignored issues
show
Documentation Bug introduced by
The property $requestMethod was declared of type string, but false is of type false. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
91
        $this->route = false;
0 ignored issues
show
Documentation Bug introduced by
The property $route was declared of type string, but false is of type false. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
92
        $this->csrfTokenHeaderValue = null;
93
94
        $this->getEventListener()->onKernelRequest($this->getEventMock());
0 ignored issues
show
Documentation introduced by
$this->getEventMock() is of type null|object<Symfony\Comp...entDispatcherInterface>, but the function expects a object<Symfony\Component...Event\GetResponseEvent>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
95
    }
96
97
    /**
98
     * Tests that method CSRF check don't apply to are indeed ignored.
99
     *
100
     * @param string $ignoredMethod
101
     * @dataProvider getIgnoredRequestMethods
102
     */
103
    public function testIgnoredRequestMethods($ignoredMethod)
104
    {
105
        $this->requestMethod = $ignoredMethod;
106
        $this->route = false;
0 ignored issues
show
Documentation Bug introduced by
The property $route was declared of type string, but false is of type false. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
107
        $this->csrfTokenHeaderValue = null;
108
109
        $this->getEventListener()->onKernelRequest($this->getEventMock());
0 ignored issues
show
Documentation introduced by
$this->getEventMock() is of type null|object<Symfony\Comp...entDispatcherInterface>, but the function expects a object<Symfony\Component...Event\GetResponseEvent>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
110
    }
111
112
    public function getIgnoredRequestMethods()
113
    {
114
        return array(
115
            array('GET'),
116
            array('HEAD'),
117
            array('OPTIONS'),
118
        );
119
    }
120
121
    /**
122
     * @dataProvider provideSessionRoutes
123
     */
124
    public function testSessionRequests($route)
125
    {
126
        $this->route = $route;
127
        $this->csrfTokenHeaderValue = null;
128
129
        $this->getEventListener()->onKernelRequest($this->getEventMock());
0 ignored issues
show
Documentation introduced by
$this->getEventMock() is of type null|object<Symfony\Comp...entDispatcherInterface>, but the function expects a object<Symfony\Component...Event\GetResponseEvent>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
130
    }
131
132
    public static function provideSessionRoutes()
133
    {
134
        return [
135
            ['ezpublish_rest_createSession'],
136
            ['ezpublish_rest_refreshSession'],
137
            ['ezpublish_rest_deleteSession'],
138
        ];
139
    }
140
141
    /**
142
     * @expectedException \eZ\Publish\Core\Base\Exceptions\UnauthorizedException
143
     */
144
    public function testNoHeader()
145
    {
146
        $this->csrfTokenHeaderValue = false;
147
148
        $this->getEventListener()->onKernelRequest($this->getEventMock());
0 ignored issues
show
Documentation introduced by
$this->getEventMock() is of type null|object<Symfony\Comp...entDispatcherInterface>, but the function expects a object<Symfony\Component...Event\GetResponseEvent>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
149
    }
150
151
    /**
152
     * @expectedException \eZ\Publish\Core\Base\Exceptions\UnauthorizedException
153
     */
154
    public function testInvalidToken()
155
    {
156
        $this->csrfTokenHeaderValue = self::INVALID_TOKEN;
157
158
        $this->getEventListener()->onKernelRequest($this->getEventMock());
0 ignored issues
show
Documentation introduced by
$this->getEventMock() is of type null|object<Symfony\Comp...entDispatcherInterface>, but the function expects a object<Symfony\Component...Event\GetResponseEvent>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
159
    }
160
161
    public function testValidToken()
162
    {
163
        $this->getEventDispatcherMock()
164
            ->expects($this->once())
165
            ->method('dispatch');
166
167
        $this->getEventListener()->onKernelRequest($this->getEventMock());
0 ignored issues
show
Documentation introduced by
$this->getEventMock() is of type null|object<Symfony\Comp...entDispatcherInterface>, but the function expects a object<Symfony\Component...Event\GetResponseEvent>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
168
    }
169
170
    /**
171
     * @return CsrfProviderInterface|PHPUnit_Framework_MockObject_MockObject
172
     */
173
    protected function getCsrfProviderMock()
174
    {
175
        $provider = $this->getMock('\Symfony\Component\Security\Csrf\CsrfTokenManagerInterface');
176
        $provider->expects($this->any())
177
            ->method('isTokenValid')
178
            ->will(
179
                $this->returnCallback(
180
                    function (CsrfToken $token) {
181
                        if ($token == new CsrfToken(self::INTENTION, self::VALID_TOKEN)) {
182
                            return true;
183
                        }
184
185
                        return false;
186
                    }
187
                )
188
            );
189
190
        return $provider;
191
    }
192
193
    /**
194
     * @return PHPUnit_Framework_MockObject_MockObject|GetResponseEvent
195
     */
196 View Code Duplication
    protected function getEventMock($class = null)
197
    {
198
        if (!isset($this->eventMock)) {
199
            parent::getEventMock('Symfony\Component\HttpKernel\Event\GetResponseEvent');
200
201
            $this->eventMock
0 ignored issues
show
Bug introduced by
The method expects cannot be called on $this->eventMock (of type null).

Methods can only be called on objects. This check looks for methods being called on variables that have been inferred to never be objects.

Loading history...
202
                ->expects($this->any())
203
                ->method('getRequestType')
204
                ->will($this->returnValue($this->requestType));
205
        }
206
207
        return $this->eventMock;
208
    }
209
210
    /**
211
     * @return \Symfony\Component\HttpFoundation\Session\SessionInterface|PHPUnit_Framework_MockObject_MockObject
212
     */
213
    protected function getSessionMock()
214
    {
215
        if (!isset($this->sessionMock)) {
216
            $this->sessionMock = $this->getMock('Symfony\Component\HttpFoundation\Session\SessionInterface');
217
            $this->sessionMock
218
                ->expects($this->atLeastOnce())
219
                ->method('isStarted')
220
                ->will($this->returnValue($this->sessionIsStarted));
221
        }
222
223
        return $this->sessionMock;
224
    }
225
226
    /**
227
     * @return ParameterBag|PHPUnit_Framework_MockObject_MockObject
228
     */
229
    protected function getRequestHeadersMock()
230
    {
231
        if (!isset($this->requestHeadersMock)) {
232
            $this->requestHeadersMock = parent::getRequestHeadersMock();
233
234
            if ($this->csrfTokenHeaderValue === null) {
235
                $this->requestHeadersMock
236
                    ->expects($this->never())
237
                    ->method('has');
238
239
                $this->requestHeadersMock
240
                    ->expects($this->never())
241
                    ->method('get');
242
            } else {
243
                $this->requestHeadersMock
244
                    ->expects($this->atLeastOnce())
245
                    ->method('has')
246
                    ->with(CsrfListener::CSRF_TOKEN_HEADER)
247
                    ->will($this->returnValue(true));
248
249
                $this->requestHeadersMock
250
                    ->expects($this->atLeastOnce())
251
                    ->method('get')
252
                    ->with(CsrfListener::CSRF_TOKEN_HEADER)
253
                    ->will($this->returnValue($this->csrfTokenHeaderValue));
254
            }
255
        }
256
257
        return $this->requestHeadersMock;
258
    }
259
260
    /**
261
     * @return PHPUnit_Framework_MockObject_MockObject|Request
262
     */
263
    protected function getRequestMock()
264
    {
265
        if (!isset($this->requestMock)) {
266
            $this->requestMock = parent::getRequestMock();
267
268 View Code Duplication
            if ($this->sessionMock === false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
269
                $this->requestMock
270
                    ->expects($this->never())
271
                    ->method('getSession');
272
            } else {
273
                $this->requestMock
274
                    ->expects($this->atLeastOnce())
275
                    ->method('getSession')
276
                    ->will($this->returnValue($this->getSessionMock()));
277
            }
278
279 View Code Duplication
            if ($this->route === false) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
280
                $this->requestMock
281
                    ->expects($this->never())
282
                    ->method('get');
283
            } else {
284
                $this->requestMock
285
                    ->expects($this->atLeastOnce())
286
                    ->method('get')
287
                    ->with('_route')
288
                    ->will($this->returnValue($this->route));
289
            }
290
        }
291
292
        return $this->requestMock;
293
    }
294
295
    /**
296
     * @return PHPUnit_Framework_MockObject_MockObject|EventDispatcherInterface
297
     */
298
    protected function getEventDispatcherMock()
299
    {
300
        if (!isset($this->eventDispatcherMock)) {
301
            $this->eventDispatcherMock = $this->getMock(
302
                'Symfony\Component\EventDispatcher\EventDispatcherInterface'
303
            );
304
        }
305
306
        return $this->eventDispatcherMock;
307
    }
308
309
    /**
310
     * @param bool $csrfEnabled
311
     *
312
     * @return CsrfListener
313
     */
314
    protected function getEventListener($csrfEnabled = true)
315
    {
316
        if ($csrfEnabled) {
317
            return new CsrfListener(
318
                $this->getEventDispatcherMock(),
0 ignored issues
show
Bug introduced by
It seems like $this->getEventDispatcherMock() targeting eZ\Bundle\EzPublishRestB...etEventDispatcherMock() can also be of type object<PHPUnit_Framework_MockObject_MockObject>; however, eZ\Bundle\EzPublishRestB...Listener::__construct() does only seem to accept object<Symfony\Component...entDispatcherInterface>, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
319
                $csrfEnabled,
320
                self::INTENTION,
321
                $this->getCsrfProviderMock()
0 ignored issues
show
Bug introduced by
It seems like $this->getCsrfProviderMock() targeting eZ\Bundle\EzPublishRestB...::getCsrfProviderMock() can also be of type object<PHPUnit_Framework_MockObject_MockObject>; however, eZ\Bundle\EzPublishRestB...Listener::__construct() does only seem to accept null|object<Symfony\Comp...fTokenManagerInterface>, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
322
            );
323
        }
324
325
        return new CsrfListener(
326
            $this->getEventDispatcherMock(),
0 ignored issues
show
Bug introduced by
It seems like $this->getEventDispatcherMock() targeting eZ\Bundle\EzPublishRestB...etEventDispatcherMock() can also be of type object<PHPUnit_Framework_MockObject_MockObject>; however, eZ\Bundle\EzPublishRestB...Listener::__construct() does only seem to accept object<Symfony\Component...entDispatcherInterface>, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
327
            $csrfEnabled,
328
            self::INTENTION
329
        );
330
    }
331
}
332