Completed
Pull Request — master (#18)
by Valentyn
02:52
created

AuthService::getTokenByRequest()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 1

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 3
cts 3
cp 1
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 3
nc 1
nop 1
crap 1
1
<?php
2
declare(strict_types=1);
3
4
namespace App\Service\User;
5
6
use App\Entity\ApiToken;
7
use App\Entity\User;
8
use App\Repository\UserRepository;
9
use App\Request\User\AuthUserRequest;
10
use Doctrine\ORM\EntityManagerInterface;
11
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
12
use Symfony\Component\Security\Core\Exception\BadCredentialsException;
13
use Symfony\Component\Translation\TranslatorInterface;
14
15
class AuthService
16
{
17
    /**
18
     * @var EntityManagerInterface
19
     */
20
    private $entityManager;
21
22
    /**
23
     * @var UserRepository
24
     */
25
    private $userRepository;
26
27
    /**
28
     * @var TranslatorInterface
29
     */
30
    private $translator;
31
32
    /**
33
     * @var UserPasswordEncoderInterface
34
     */
35
    private $passwordEncoder;
36
37 8
    public function __construct(
38
        EntityManagerInterface $entityManager,
39
        UserRepository $userRepository,
40
        TranslatorInterface $translator,
41
        UserPasswordEncoderInterface $passwordEncoder
42
    )
43
    {
44 8
        $this->entityManager = $entityManager;
45 8
        $this->userRepository = $userRepository;
46 8
        $this->translator = $translator;
47 8
        $this->passwordEncoder = $passwordEncoder;
48 8
    }
49
50 8
    public function getTokenByRequest(AuthUserRequest $request): ApiToken
51
    {
52 8
        $credentials = $request->get('credentials');
53
54 8
        return $this->getTokenByCredentials($credentials['username'], $credentials['password']);
55
    }
56
57 8
    public function getTokenByCredentials(string $username, string $password): ApiToken
58
    {
59 8
        $user = $this->findUserByCredentials($username, $password);
60 4
        $apiToken = $this->createApiTokenForUser($user);
61
62 4
        return $apiToken;
63
    }
64
65 4
    private function createApiTokenForUser(User $user): ApiToken
66
    {
67 4
        $apiToken = new ApiToken($user);
68
69 4
        $this->entityManager->persist($apiToken);
70 4
        $this->entityManager->flush();
71
72 4
        return $apiToken;
73
    }
74
75 8
    private function findUserByCredentials(string $username, string $password): User
76
    {
77 8
        $user = $this->userRepository->loadUserByUsername($username);
78
79 8
        if ($user === null) {
80 2
            throw new BadCredentialsException(
81 2
                $this->translator->trans('user_with_this_username_not_exist', [
82 2
                    'username' => $username,
83 2
                ], 'users')
84
            );
85
        }
86
87 6
        if ($this->isPasswordValid($password, $user) === false) {
0 ignored issues
show
Compatibility introduced by
$user of type object<Symfony\Component...ore\User\UserInterface> is not a sub-type of object<App\Entity\User>. It seems like you assume a concrete implementation of the interface Symfony\Component\Security\Core\User\UserInterface to be always present.

This check looks for parameters that are defined as one type in their type hint or doc comment but seem to be used as a narrower type, i.e an implementation of an interface or a subclass.

Consider changing the type of the parameter or doing an instanceof check before assuming your parameter is of the expected type.

Loading history...
88 2
            throw new BadCredentialsException(
89 2
                $this->translator->trans('wrong_password', [], 'users')
90
            );
91
        }
92
93 4
        return $user;
94
    }
95
96 6
    private function isPasswordValid(string $password, User $user): bool
97
    {
98 6
        return $user->isPasswordValid($password, $this->passwordEncoder);
99
    }
100
}