JWTSecurityHelper::getJWTToken()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 13
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 3
eloc 6
c 1
b 0
f 0
nc 3
nop 1
dl 0
loc 13
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AtlassianConnectBundle\Security;
6
7
use AtlassianConnectBundle\Repository\TenantRepositoryInterface;
8
use AtlassianConnectBundle\Service\QSHGenerator;
9
use Firebase\JWT\JWT;
10
use Symfony\Component\HttpFoundation\Request;
11
12
final class JWTSecurityHelper implements JWTSecurityHelperInterface
13
{
14
    public function __construct(
15
        private TenantRepositoryInterface $repository,
16
        private ?int $devTenant,
17
        private string $environment
18
    ) {
19
    }
20
21
    public function supportsRequest(Request $request): bool
22
    {
23
        return $request->query->has('jwt') ||
24
            $request->headers->has('authorization') ||
25
            ($this->devTenant && 'dev' === $this->environment);
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->devTenant of type integer|null is loosely compared to true; this is ambiguous if the integer can be 0. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
26
    }
27
28
    public function getJWTToken(Request $request): ?string
29
    {
30
        if ($request->query->has('jwt')) {
31
            return (string) $request->query->get('jwt');
32
        }
33
34
        $headerJWT = $this->findJWTInHeader($request);
35
36
        if ($headerJWT) {
37
            return $headerJWT;
38
        }
39
40
        return $this->findTenantJWT($request);
41
    }
42
43
    private function findJWTInHeader(Request $request): ?string
44
    {
45
        if ($request->headers->has('authorization')) {
46
            $authorizationHeaderArray = explode(' ', $request->headers->get('authorization'));
47
48
            if (\count($authorizationHeaderArray) > 1) {
49
                return $authorizationHeaderArray[1];
50
            }
51
        }
52
53
        return null;
54
    }
55
56
    private function findTenantJWT(Request $request): ?string
57
    {
58
        if (!$this->devTenant || 'dev' !== $this->environment) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->devTenant of type integer|null is loosely compared to false; this is ambiguous if the integer can be 0. You might want to explicitly use === null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
59
            return null;
60
        }
61
62
        $tenant = $this->repository->findById($this->devTenant);
63
64
        if (!$tenant) {
65
            throw new \RuntimeException(sprintf('Cant find tenant with id %s - please set atlassian_connect.dev_tenant to false to disable dedicated dev tenant OR add valid id', $this->devTenant));
66
        }
67
68
        return JWT::encode([
69
            'iss' => $tenant->getClientKey(),
70
            'iat' => time(),
71
            'exp' => strtotime('+1 day'),
72
            'qsh' => QSHGenerator::generate($request->getRequestUri(), 'GET'),
73
            'sub' => 'admin',
74
        ], $tenant->getSharedSecret(), 'HS256');
75
    }
76
}
77