Passed
Push — master ( c38baa...79425f )
by Bukashk0zzz
57s queued 11s
created

testItSendsAResponseOnAuthenticationFailure()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 0
dl 0
loc 6
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types = 1);
2
3
namespace AtlassianConnectBundle\Tests\Security;
4
5
use AtlassianConnectBundle\Entity\Tenant;
6
use AtlassianConnectBundle\Security\JWTAuthenticator;
7
use AtlassianConnectBundle\Security\JWTUserProviderInterface;
8
use Doctrine\Common\Persistence\ObjectRepository;
9
use Doctrine\ORM\EntityManagerInterface;
10
use PHPUnit\Framework\MockObject\MockObject;
11
use PHPUnit\Framework\TestCase;
12
use Symfony\Component\HttpFoundation\Request;
13
use Symfony\Component\HttpKernel\KernelInterface;
14
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
15
use Symfony\Component\Security\Core\Exception\AuthenticationException;
16
use Symfony\Component\Security\Core\User\UserInterface;
17
use Symfony\Component\Security\Core\User\UserProviderInterface;
18
19
/**
20
 * Class JWTAuthenticatorTest
21
 */
22
final class JWTAuthenticatorTest extends TestCase
23
{
24
    /**
25
     * @var KernelInterface|MockObject
26
     */
27
    private $kernel;
28
29
    /**
30
     * @var EntityManagerInterface|MockObject
31
     */
32
    private $em;
33
34
    /**
35
     * @var string
36
     */
37
    private $tenantEntityClass;
38
39
    /**
40
     * @var int
41
     */
42
    private $devTenant;
43
44
    /**
45
     * @var JWTAuthenticator
46
     */
47
    private $jwtAuthenticator;
48
49
    /**
50
     * Setup method
51
     */
52
    public function setUp(): void
53
    {
54
        $this->kernel = $this->createMock(KernelInterface::class);
55
        $this->em = $this->createMock(EntityManagerInterface::class);
56
        $this->tenantEntityClass = Tenant::class;
57
        $this->devTenant = 1;
58
59
        $this->jwtAuthenticator = new JWTAuthenticator(
60
            $this->kernel,
61
            $this->em,
62
            $this->tenantEntityClass,
63
            $this->devTenant
64
        );
65
    }
66
67
    /**
68
     * Test start method
69
     */
70
    public function testItSendsA401WhenNoAuthenticationHeaderIsSet(): void
71
    {
72
        $response = $this->jwtAuthenticator->start(new Request());
73
74
        $this->assertEquals('Authentication header required', $response->getContent());
75
        $this->assertEquals(401, $response->getStatusCode());
76
    }
77
78
    /**
79
     * Tests if the request is supported
80
     */
81
    public function testSupportsRequest(): void
82
    {
83
        $request = new Request(['jwt' => 'token']);
84
        $this->assertTrue($this->jwtAuthenticator->supports($request));
85
86
        $request = new Request();
87
        $request->headers->set('authorization', 'jwt token');
88
        $this->assertTrue($this->jwtAuthenticator->supports($request));
89
90
        $request = new Request();
91
92
        $this->kernel
93
            ->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not exist on Symfony\Component\HttpKernel\KernelInterface. ( Ignorable by Annotation )

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

93
            ->/** @scrutinizer ignore-call */ 
94
              expects($this->once())

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...
94
            ->method('getEnvironment')
95
            ->willReturn('dev');
96
97
        $this->assertTrue($this->jwtAuthenticator->supports($request));
98
    }
99
100
    /**
101
     * Tests if the request is not supportd
102
     */
103
    public function testDoesNotSupportRequest(): void
104
    {
105
        $request = new Request();
106
        $this->assertFalse($this->jwtAuthenticator->supports($request));
107
    }
108
109
    /**
110
     * Test if the getCredentials method returns a valid array
111
     */
112
    public function testGetsCredentials(): void
113
    {
114
        $request = new Request(['jwt' => 'token']);
115
        $credentials = $this->jwtAuthenticator->getCredentials($request);
116
        $this->assertIsArray($credentials);
117
        $this->assertArrayHasKey('jwt', $credentials);
118
        $this->assertEquals('token', $credentials['jwt']);
119
120
        $request = new Request();
121
        $request->headers->set('authorization', 'jwt token');
122
        $credentials = $this->jwtAuthenticator->getCredentials($request);
123
        $this->assertIsArray($credentials);
124
        $this->assertArrayHasKey('jwt', $credentials);
125
        $this->assertEquals('token', $credentials['jwt']);
126
    }
127
128
    /**
129
     * Test if the getCredentials method returns null when no jwt token is passed
130
     */
131
    public function testGetsCredentialsTokenDoesNotExist(): void
132
    {
133
        $this->kernel
134
            ->expects($this->once())
135
            ->method('getEnvironment')
136
            ->willReturn('prod');
137
138
        $request = new Request();
139
        $credentials = $this->jwtAuthenticator->getCredentials($request);
140
        $this->assertNull($credentials);
141
    }
142
143
    /**
144
     * Test if the getCredentials method can get the credentials in dev mode
145
     */
146
    public function testGetsCredentialsOnDevTenant(): void
147
    {
148
        $tenant = new Tenant();
149
        $tenant->setClientKey('client_key');
150
        $tenant->setSharedSecret('shared_secret');
151
152
        $repository = $this->createMock(ObjectRepository::class);
153
        $repository
154
            ->expects($this->once())
155
            ->method('find')
156
            ->with(1)
157
            ->willReturn($tenant);
158
159
        $this->em
160
            ->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not exist on Doctrine\ORM\EntityManagerInterface. ( Ignorable by Annotation )

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

160
            ->/** @scrutinizer ignore-call */ 
161
              expects($this->once())

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...
161
            ->method('getRepository')
162
            ->willReturn($repository);
163
164
        $this->kernel
165
            ->expects($this->once())
166
            ->method('getEnvironment')
167
            ->willReturn('dev');
168
169
        $request = new Request();
170
        $credentials = $this->jwtAuthenticator->getCredentials($request);
171
        $this->assertIsArray($credentials);
172
        $this->assertArrayHasKey('jwt', $credentials);
173
        $this->assertIsString($credentials['jwt']);
174
    }
175
176
    /**
177
     * @expectedException \RuntimeException
178
     */
179
    public function testItFailsWhenNoTenantExists(): void
180
    {
181
        $repository = $this->createMock(ObjectRepository::class);
182
        $repository
183
            ->expects($this->once())
184
            ->method('find')
185
            ->with(1)
186
            ->willReturn(null);
187
188
        $this->em
189
            ->expects($this->once())
190
            ->method('getRepository')
191
            ->willReturn($repository);
192
193
        $this->kernel
194
            ->expects($this->once())
195
            ->method('getEnvironment')
196
            ->willReturn('dev');
197
198
        $request = new Request();
199
        $this->jwtAuthenticator->getCredentials($request);
200
    }
201
202
    /**
203
     * @expectedException \InvalidArgumentException
204
     * @expectedExceptionMessage UserProvider must implement AtlassianConnectBundle\Security\JWTUserProviderInterface
205
     */
206
    public function testGetUserGetsInvalidUserProvider(): void
207
    {
208
        $userProvider = $this->createMock(UserProviderInterface::class);
209
210
        $this->jwtAuthenticator->getUser('credentials', $userProvider);
211
    }
212
213
    /**
214
     * @expectedException \Symfony\Component\Security\Core\Exception\AuthenticationException
215
     * @expectedExceptionMessage API Key "token" does not exist.
216
     */
217
    public function testGetUserWithoutClientKeyThrowsException(): void
218
    {
219
        $token = [
220
            'sub' => 'username',
221
            'iss' => null,
222
        ];
223
224
        $userProvider = $this->createMock(JWTUserProviderInterface::class);
225
        $userProvider
226
            ->expects($this->once())
227
            ->method('getDecodedToken')
228
            ->willReturn((object) $token);
229
230
        $this->jwtAuthenticator->getUser(['jwt' => 'token'], $userProvider);
231
    }
232
233
    /**
234
     * Test if a user gets fetched
235
     */
236
    public function testGetsUser(): void
237
    {
238
        $token = [
239
            'iss' => 'iss',
240
            'sub' => 'username',
241
        ];
242
243
        $tenant = new Tenant();
244
245
        $userProvider = $this->createMock(JWTUserProviderInterface::class);
246
        $userProvider
247
            ->expects($this->once())
248
            ->method('getDecodedToken')
249
            ->willReturn((object) $token);
250
251
        $userProvider
252
            ->expects($this->once())
253
            ->method('loadUserByUsername')
254
            ->with('iss')
255
            ->willReturn($tenant);
256
257
        $user = $this->jwtAuthenticator->getUser(['jwt' => 'token'], $userProvider);
258
259
        $this->assertInstanceOf(Tenant::class, $user);
260
        $this->assertEquals('username', $tenant->getUsername());
261
    }
262
263
    /**
264
     * test checkCredentials method
265
     */
266
    public function testItChecksCredentials(): void
267
    {
268
        $this->assertTrue($this->jwtAuthenticator->checkCredentials(null, $this->createMock(UserInterface::class)));
269
    }
270
271
    /**
272
     * test onAuthenticationFailure Method
273
     */
274
    public function testItSendsAResponseOnAuthenticationFailure(): void
275
    {
276
        $response = $this->jwtAuthenticator->onAuthenticationFailure(new Request(), new AuthenticationException('Error'));
277
278
        $this->assertEquals('Authentication Failed: Error', $response->getContent());
279
        $this->assertEquals(403, $response->getStatusCode());
280
    }
281
282
    /**
283
     * test onAuthenticationSuccess method
284
     */
285
    public function testItDoesNotSendAResponseOnAuthenticationSuccess(): void
286
    {
287
        $this->assertNull($this->jwtAuthenticator->onAuthenticationSuccess(new Request(), $this->createMock(TokenInterface::class), 'main'));
0 ignored issues
show
Bug introduced by
Are you sure the usage of $this->jwtAuthenticator-...erface::class), 'main') targeting AtlassianConnectBundle\S...AuthenticationSuccess() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
288
    }
289
290
    /**
291
     * test supportsRememberMe method
292
     */
293
    public function testItDoesNotSupportRememberMeFunctionality(): void
294
    {
295
        $this->assertFalse($this->jwtAuthenticator->supportsRememberMe());
296
    }
297
}
298