GoogleAuthenticator::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 9
ccs 5
cts 5
cp 1
rs 9.9666
c 0
b 0
f 0
cc 1
nc 1
nop 3
crap 1
1
<?php
2
3
/** @noinspection DuplicatedCode */
4
5
declare(strict_types=1);
6
7
/*
8
 * This file is part of the zibios/sharep.
9
 *
10
 * (c) Zbigniew Ślązak
11
 */
12
13
namespace App\Security\GuardAuthenticator;
14
15
use App\Entity\Access\GoogleIdentity;
16
use App\Entity\Access\User;
17
use App\Entity\Parking\Member;
18
use App\Enum\Functional\RoleEnum;
19
use Doctrine\ORM\EntityManagerInterface;
20
use KnpU\OAuth2ClientBundle\Client\ClientRegistry;
21
use KnpU\OAuth2ClientBundle\Client\Provider\GoogleClient;
22
use KnpU\OAuth2ClientBundle\Security\Authenticator\SocialAuthenticator;
23
use League\OAuth2\Client\Provider\GoogleUser;
24
use League\OAuth2\Client\Token\AccessToken;
25
use Symfony\Component\HttpFoundation\JsonResponse;
26
use Symfony\Component\HttpFoundation\RedirectResponse;
27
use Symfony\Component\HttpFoundation\Request;
28
use Symfony\Component\HttpFoundation\Response;
29
use Symfony\Component\Routing\Router;
30
use Symfony\Component\Routing\RouterInterface;
31
use Symfony\Component\Security\Core\Authentication\Token\TokenInterface;
32
use Symfony\Component\Security\Core\Exception\AuthenticationException;
33
use Symfony\Component\Security\Core\User\UserProviderInterface;
34
35
class GoogleAuthenticator extends SocialAuthenticator
36
{
37
    /**
38
     * @var ClientRegistry
39
     */
40
    protected $clientRegistry;
41
42
    /**
43
     * @var EntityManagerInterface
44
     */
45
    protected $entityManager;
46
    /**
47
     * @var Router
48
     */
49
    protected $router;
50
51 21
    public function __construct(
52
        ClientRegistry $clientRegistry,
53
        EntityManagerInterface $entityManager,
54
        RouterInterface $router
55
    ) {
56 21
        $this->clientRegistry = $clientRegistry;
57 21
        $this->entityManager = $entityManager;
58 21
        $this->router = $router;
0 ignored issues
show
Documentation Bug introduced by
$router is of type object<Symfony\Component\Routing\RouterInterface>, but the property $router was declared to be of type object<Symfony\Component\Routing\Router>. Are you sure that you always receive this specific sub-class here, or does it make sense to add an instanceof check?

Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a given class or a super-class is assigned to a property that is type hinted more strictly.

Either this assignment is in error or an instanceof check should be added for that assignment.

class Alien {}

class Dalek extends Alien {}

class Plot
{
    /** @var  Dalek */
    public $villain;
}

$alien = new Alien();
$plot = new Plot();
if ($alien instanceof Dalek) {
    $plot->villain = $alien;
}
Loading history...
59 21
    }
60
61 3
    public function start(
62
        Request $request,
63
        AuthenticationException $authException = null
64
    ): Response {
65 3
        return new Response('No authorized!', 403);
66
    }
67
68 21
    public function supports(Request $request): bool
69
    {
70 21
        return 'oauth2_google_check' === $request->attributes->get('_route') && $request->isMethod('GET');
71
    }
72
73
    public function getCredentials(Request $request): AccessToken
74
    {
75
        return $this->fetchAccessToken($this->getGoogleClient());
76
    }
77
78
    /**
79
     * @param AccessToken $credentials
80
     */
81
    public function getUser($credentials, UserProviderInterface $userProvider): ?User
82
    {
83
        /** @var GoogleUser $googleUser */
84
        $googleUser = $this->getGoogleClient()->fetchUserFromToken($credentials);
85
86
        /** @var User $user */
87
        $user = $this->entityManager
88
            ->getRepository(User::class)
89
            ->findOneBy(['email' => $googleUser->getEmail()]);
90
91
        if (!$user) {
92
            return null;
93
        }
94
95
        $googleIdentity = $user->getGoogleIdentity();
96
        if (!$googleIdentity) {
97
            $googleIdentity = new GoogleIdentity($user, $googleUser->getId(), $googleUser->getEmail());
98
        }
99
        $googleIdentity->setName($googleUser->getName());
100
        $googleIdentity->setGivenName($googleUser->getFirstName());
101
        $googleIdentity->setFamilyName($googleUser->getLastName());
102
        $googleIdentity->setPicture($googleUser->getAvatar());
103
        $googleIdentity->setLocale($googleUser->getLocale());
104
105
        $member = $user->getMember();
106
        if (!$member) {
107
            $member = new Member($googleIdentity->getName(), RoleEnum::MEMBER(), $user);
108
        }
109
        $member->setName($googleIdentity->getName());
110
111
        $this->entityManager->persist($googleIdentity);
112
        $this->entityManager->persist($member);
113
        $this->entityManager->persist($user);
114
        $this->entityManager->flush();
115
116
        return $user;
117
    }
118
119
    public function onAuthenticationFailure(
120
        Request $request,
121
        AuthenticationException $exception
122
    ): JsonResponse {
123
        return new JsonResponse(
124
            [
125
                'message' => strtr(
126
                    $exception->getMessageKey(),
127
                    $exception->getMessageData()
128
                ),
129
            ],
130
            JsonResponse::HTTP_FORBIDDEN
131
        );
132
    }
133
134
    /**
135
     * @param string $providerKey The provider (i.e. firewall) key
136
     */
137
    public function onAuthenticationSuccess(
138
        Request $request,
139
        TokenInterface $token,
140
        $providerKey
141
    ): ?Response {
142
        return new RedirectResponse(
143
            $this->router->generate('site_page_contact'),
144
            Response::HTTP_TEMPORARY_REDIRECT
145
        );
146
    }
147
148
    private function getGoogleClient(): GoogleClient
149
    {
150
        /** @var GoogleClient $client */
151
        $client = $this->clientRegistry->getClient('google');
152
153
        return $client;
154
    }
155
}
156