TokenController   A
last analyzed

Complexity

Total Complexity 9

Size/Duplication

Total Lines 146
Duplicated Lines 0 %

Test Coverage

Coverage 0%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 47
c 1
b 0
f 0
dl 0
loc 146
ccs 0
cts 62
cp 0
rs 10
wmc 9

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 11 1
A validateAction() 0 18 3
A loginAction() 0 31 5
1
<?php
2
3
namespace App\Controller\Api;
4
5
use App\Error\ApiError;
6
use App\Entity\User;
7
use App\Repository\UserRepository;
8
use App\Traits\JsonErrorResponse;
9
use Psr\Log\LoggerInterface;
10
use Ramsey\Uuid\Uuid;
11
use Sensio\Bundle\FrameworkExtraBundle\Configuration\ParamConverter;
12
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
13
use Symfony\Component\HttpFoundation\JsonResponse;
14
use Symfony\Component\HttpFoundation\Request;
15
use Symfony\Component\HttpFoundation\Response;
16
use Symfony\Component\Routing\Annotation\Route;
17
use Symfony\Component\Validator\ConstraintViolationListInterface;
18
use Swagger\Annotations as SWG;
19
use App\Service\JWTService;
20
use Symfony\Component\Validator\Validator\ValidatorInterface;
21
use Symfony\Component\Security\Core\Encoder\UserPasswordEncoderInterface;
22
use App\Request\LoginRequest;
23
use App\Traits\JWTHelper;
24
use App\Repository\Exception\UserNotFoundException;
25
26
class TokenController extends AbstractController
27
{
28
    use JsonErrorResponse;
29
    use JWTHelper;
0 ignored issues
show
Bug introduced by
The trait App\Traits\JWTHelper requires the property $headers which is not provided by App\Controller\Api\TokenController.
Loading history...
30
    
31
    /**
32
     * @var LoggerInterface
33
     */
34
    private $logger;
35
    /**
36
     * @var UserRepository
37
     */
38
    private $repository;
39
    /**
40
     * @var ValidatorInterface
41
     */
42
    private $validator;
43
    /**
44
     * @var JWTService
45
     */
46
    private $jwtService;
47
48
    /**
49
     * @param LoggerInterface $logger
50
     * @param UserRepository $repository
51
     * @param ValidatorInterface $validator
52
     * @param JWTService $jwtService
53
     */
54
    public function __construct(
55
        LoggerInterface $logger,
56
        UserRepository $repository,
57
        ValidatorInterface $validator,
58
        JWTService $jwtService
59
    )
60
    {
61
        $this->logger = $logger;
62
        $this->repository = $repository;
63
        $this->validator = $validator;
64
        $this->jwtService = $jwtService;
65
    }
66
    /**
67
     * @SWG\Tag(name="Security")
68
     * @SWG\Post(
69
     *     @SWG\Parameter(
70
     *          name="token",
71
     *          in="body",
72
     *          required=true,
73
     *          format="application/json",
74
     *          @SWG\Schema(
75
     *              @SWG\Property(property="token", type="string", format="JWT", example="123.456.789"),
76
     *          )
77
     *     ),
78
     *     @SWG\Response(response=200, description="New JWT"),
79
     *     @SWG\Response(response=401, description="Unauthorized because of invalid token, expired or signature error"),
80
     *     @SWG\Response(response=404, description="User not found"),
81
     *     @SWG\Response(response="422", description="Validation failed")
82
     * )
83
     * @Route("/api/jwt/validate", name="validate-token", methods={"POST"})
84
     * @return JsonResponse
85
     */
86
    public function validateAction(Request $rawRequest): JsonResponse
87
    {
88
        $token = $this->getToken($rawRequest);
89
        try {
90
            $payload = $this->jwtService->decode($token);
91
            $user = $this->repository->getUser(Uuid::fromString($payload->getId()));
92
            $newToken = $this->jwtService->generateToken($user);
93
            return $this->json(['token' => $newToken]);
94
        } catch (UserNotFoundException $e) {
95
            return $this->jsonError(ApiError::ENTITY_READ_ERROR,
96
                $e->getMessage(),
97
                Response::HTTP_NOT_FOUND
98
            );
99
        } catch (\Exception $e) {
100
            $this->logger->critical($e->getMessage());
101
            return $this->jsonError(ApiError::ENTITY_READ_ERROR,
102
                $e->getMessage(),
103
                Response::HTTP_UNAUTHORIZED
104
            );
105
        }
106
    }
107
108
    /**
109
     * @SWG\Tag(name="Security")
110
     * @SWG\Post(
111
     *     @SWG\Parameter(
112
     *          name="body",
113
     *          in="body",
114
     *          required=true,
115
     *          format="application/json",
116
     *          @SWG\Schema(
117
     *              @SWG\Property(property="email", type="string"),
118
     *              @SWG\Property(property="password", type="string")
119
     *          )
120
     *     )
121
     * )
122
     * @SWG\Response(
123
     *     response=200,
124
     *     description="JWT token",
125
     * )
126
     * @SWG\Response(
127
     *     response=404,
128
     *     description="User not found"
129
     * )
130
     * @SWG\Response(
131
     *     response=401,
132
     *     description="Invalid login/pass"
133
     * )
134
     *
135
     * @Route("/api/login", name="auth", methods={"POST"})
136
     * @ParamConverter("request", converter="fos_rest.request_body")
137
     * @param LoginRequest $request
138
     * @param UserPasswordEncoderInterface $encoder
139
     * @return JsonResponse
140
     */
141
    public function loginAction(LoginRequest $request, UserPasswordEncoderInterface $encoder, ConstraintViolationListInterface $validationErrors): JsonResponse
142
    {
143
        if ($validationErrors->count()) {
144
            return $this->jsonError(ApiError::ENTITY_VALIDATION_ERROR,
145
                'Login request validations errors',
146
                Response::HTTP_BAD_REQUEST,
147
                $this->parseFormErrors($validationErrors)
148
            );
149
        }
150
151
        try {
152
            $user = $this->repository->getUserByEmail($request->getEmail());
153
            $valid = $encoder->isPasswordValid($user, $request->getPassword());
154
            if (!$valid) {
155
                throw new \Exception('Invalid login or password');
156
            }
157
        } catch (UserNotFoundException $e) {
158
            return $this->jsonError(ApiError::ENTITY_READ_ERROR,
159
                $e->getMessage(),
160
                Response::HTTP_NOT_FOUND
161
            );
162
        } catch (\Exception $e) {
163
            $this->logger->critical($e->getMessage());
164
            return $this->jsonError(ApiError::ENTITY_READ_ERROR,
165
                $e->getMessage(),
166
                Response::HTTP_BAD_REQUEST
167
            );
168
        }
169
170
        $token = $this->jwtService->generateToken($user);
171
        return $this->json(['token' => $token]);
172
    }   
173
}
174