JWTUserProvider   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 52
Duplicated Lines 0 %

Importance

Changes 3
Bugs 0 Features 0
Metric Value
eloc 16
c 3
b 0
f 0
dl 0
loc 52
rs 10
wmc 9

7 Methods

Rating   Name   Duplication   Size   Complexity  
A findTenant() 0 3 1
A __construct() 0 2 1
A loadUserByIdentifier() 0 9 2
A getDecodedToken() 0 11 2
A refreshUser() 0 3 1
A loadUserByUsername() 0 3 1
A supportsClass() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace AtlassianConnectBundle\Security;
6
7
use AtlassianConnectBundle\Entity\TenantInterface;
8
use AtlassianConnectBundle\Repository\TenantRepositoryInterface;
9
use Firebase\JWT\JWT;
10
use Firebase\JWT\Key;
11
use Symfony\Component\Security\Core\Exception\AuthenticationException;
12
use Symfony\Component\Security\Core\Exception\UnsupportedUserException;
13
use Symfony\Component\Security\Core\Exception\UserNotFoundException;
14
use Symfony\Component\Security\Core\User\UserInterface;
15
16
class JWTUserProvider implements JWTUserProviderInterface
17
{
18
    public function __construct(private TenantRepositoryInterface $repository)
19
    {
20
    }
21
22
    public function getDecodedToken(string $jwt): object
23
    {
24
        try {
25
            $bodyb64 = explode('.', $jwt)[1];
26
            $decodedToken = json_decode(JWT::urlsafeB64Decode($bodyb64));
27
28
            JWT::decode($jwt, new Key($this->findTenant($decodedToken->iss)->getSharedSecret(), 'HS256'));
29
30
            return $decodedToken;
31
        } catch (\Throwable $e) {
32
            throw new AuthenticationException('Failed to parse token');
33
        }
34
    }
35
36
    public function loadUserByUsername(string $username): UserInterface
37
    {
38
        return $this->loadUserByIdentifier($username);
39
    }
40
41
    public function refreshUser(UserInterface $user): void
42
    {
43
        throw new UnsupportedUserException('Refresh prohibited');
44
    }
45
46
    /**
47
     * @param string|mixed $class
48
     */
49
    public function supportsClass($class): bool
50
    {
51
        return is_subclass_of($class, TenantInterface::class);
52
    }
53
54
    public function loadUserByIdentifier(string $identifier): UserInterface
55
    {
56
        $tenant = $this->findTenant($identifier);
57
58
        if (!$tenant) {
59
            throw new UserNotFoundException('Can\t find tenant with such username');
60
        }
61
62
        return $tenant;
63
    }
64
65
    private function findTenant(string $clientKey): ?TenantInterface
66
    {
67
        return $this->repository->findByClientKey($clientKey);
68
    }
69
}
70