testAuthenticateHasNoClientKey()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 23
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 16
nc 1
nop 0
dl 0
loc 23
rs 9.7333
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AtlassianConnectBundle\Tests\Security;
6
7
use AtlassianConnectBundle\Entity\Tenant;
8
use AtlassianConnectBundle\Security\JWTAuthenticator;
9
use AtlassianConnectBundle\Security\JWTSecurityHelperInterface;
10
use AtlassianConnectBundle\Security\JWTUserProvider;
11
use AtlassianConnectBundle\Security\JWTUserProviderInterface;
12
use PHPUnit\Framework\MockObject\MockObject;
13
use PHPUnit\Framework\TestCase;
14
use Symfony\Component\HttpFoundation\Request;
15
use Symfony\Component\HttpFoundation\Response;
16
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
17
use Symfony\Component\Security\Core\Exception\AuthenticationException;
18
use Symfony\Component\Security\Core\Exception\CustomUserMessageAuthenticationException;
19
use Symfony\Component\Security\Http\Authenticator\Passport\Badge\UserBadge;
20
use Symfony\Component\Security\Http\Authenticator\Passport\SelfValidatingPassport;
21
22
final class JWTAuthenticatorTest extends TestCase
23
{
24
    private JWTUserProviderInterface|MockObject $userProvider;
25
    private JWTSecurityHelperInterface|MockObject $securityHelper;
26
    private JWTAuthenticator $jwtAuthenticator;
27
28
    protected function setUp(): void
29
    {
30
        $this->userProvider = $this->createMock(JWTUserProvider::class);
31
        $this->securityHelper = $this->createMock(JWTSecurityHelperInterface::class);
32
        $this->jwtAuthenticator = new JWTAuthenticator(
33
            $this->userProvider,
34
            $this->securityHelper
35
        );
36
    }
37
38
    public function testSupportsRequest(): void
39
    {
40
        $this->securityHelper
41
            ->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not exist on AtlassianConnectBundle\S...SecurityHelperInterface. ( Ignorable by Annotation )

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

41
            ->/** @scrutinizer ignore-call */ 
42
              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...
42
            ->method('supportsRequest')
43
            ->with($request = new Request())
44
            ->willReturn(true);
45
46
        $this->assertTrue($this->jwtAuthenticator->supports($request));
47
    }
48
49
    public function testAuthenticate(): void
50
    {
51
        $token = [
52
            'sub' => 'username',
53
            'iss' => 'key',
54
        ];
55
56
        $this->securityHelper
57
            ->expects($this->once())
58
            ->method('getJWTToken')
59
            ->with($request = new Request())
60
            ->willReturn('token');
61
62
        $this->userProvider
63
            ->expects($this->once())
0 ignored issues
show
Bug introduced by
The method expects() does not exist on AtlassianConnectBundle\S...WTUserProviderInterface. ( Ignorable by Annotation )

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

63
            ->/** @scrutinizer ignore-call */ 
64
              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...
64
            ->method('getDecodedToken')
65
            ->with('token')
66
            ->willReturn((object) $token);
67
68
        $this->userProvider
69
            ->expects($this->once())
70
            ->method('loadUserByIdentifier')
71
            ->with('key')
72
            ->willReturn($tenant = new Tenant());
73
74
        $result = $this->jwtAuthenticator->authenticate($request);
75
76
        if (class_exists(UserBadge::class)) {
77
            $this->assertEquals(
78
                new SelfValidatingPassport(new UserBadge('key')),
79
                $result
80
            );
81
        } else {
82
            $this->assertEquals(
83
                new SelfValidatingPassport($tenant),
0 ignored issues
show
Bug introduced by
$tenant of type AtlassianConnectBundle\Entity\Tenant is incompatible with the type Symfony\Component\Securi...assport\Badge\UserBadge expected by parameter $userBadge of Symfony\Component\Securi...Passport::__construct(). ( Ignorable by Annotation )

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

83
                new SelfValidatingPassport(/** @scrutinizer ignore-type */ $tenant),
Loading history...
84
                $result
85
            );
86
        }
87
    }
88
89
    public function testAuthenticateHasNoJWTToken(): void
90
    {
91
        $this->expectException(CustomUserMessageAuthenticationException::class);
92
        $this->expectExceptionMessage('JWT Token not provided');
93
94
        $this->securityHelper
95
            ->expects($this->once())
96
            ->method('getJWTToken')
97
            ->with($request = new Request())
98
            ->willReturn(null);
99
100
        $this->jwtAuthenticator->authenticate($request);
101
    }
102
103
    public function testAuthenticateHasNoClientKey(): void
104
    {
105
        $this->expectException(CustomUserMessageAuthenticationException::class);
106
        $this->expectExceptionMessage('API Key token does not exist');
107
108
        $token = [
109
            'sub' => 'username',
110
            'iss' => null,
111
        ];
112
113
        $this->securityHelper
114
            ->expects($this->once())
115
            ->method('getJWTToken')
116
            ->with($request = new Request())
117
            ->willReturn('token');
118
119
        $this->userProvider
120
            ->expects($this->once())
121
            ->method('getDecodedToken')
122
            ->with('token')
123
            ->willReturn((object) $token);
124
125
        $this->jwtAuthenticator->authenticate($request);
126
    }
127
128
    public function testItSendsAResponseOnAuthenticationFailure(): void
129
    {
130
        $response = $this->jwtAuthenticator->onAuthenticationFailure(new Request(), new AuthenticationException('Error'));
131
132
        $this->assertEquals('Authentication Failed: Error', $response->getContent());
133
        $this->assertEquals(403, $response->getStatusCode());
134
    }
135
136
    public function testItDoesNotSendAResponseOnAuthenticationSuccess(): void
137
    {
138
        $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...
139
    }
140
141
    public function testStartMethod(): void
142
    {
143
        $this->assertEquals(
144
            new Response('Authentication header required', 401),
145
            $this->jwtAuthenticator->start(new Request())
146
        );
147
    }
148
}
149