Passed
Pull Request — master (#41)
by Paweł
05:10
created

ApiUsersController::checkEmail()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 18
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 8
c 0
b 0
f 0
dl 0
loc 18
rs 10
cc 4
nc 3
nop 3
1
<?php
2
3
declare(strict_types=1);
4
5
namespace App\Controller;
6
7
use App\Event\UserCreateEvent;
8
use App\Event\UserPasswordChangeRequestEvent;
9
use App\Form\ErrorHandler;
10
use App\Form\RegisterUserType;
11
use App\Form\UserEmailType;
12
use App\Form\UserPasswordResetRequestType;
13
use App\Form\UserPasswordResetType;
14
use App\Manager\UserManagerInterface;
15
use App\Repository\UserRepositoryInterface;
16
use Doctrine\ORM\EntityManagerInterface;
17
use SWP\Component\Common\Exception\NotFoundHttpException;
18
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
19
use Symfony\Component\EventDispatcher\EventDispatcherInterface;
20
use Symfony\Component\Form\FormFactoryInterface;
21
use Symfony\Component\HttpFoundation\JsonResponse;
22
use Symfony\Component\HttpFoundation\Request;
23
use Symfony\Component\HttpFoundation\Response;
24
use Symfony\Component\Security\Core\Authentication\Token\Storage\TokenStorageInterface;
25
use Symfony\Component\Serializer\SerializerInterface;
26
27
final class ApiUsersController extends AbstractController
28
{
29
    protected $serializer;
30
31
    public function __construct(SerializerInterface $serializer)
32
    {
33
        $this->serializer = $serializer;
34
    }
35
36
    public function getCurrentUser(): Response
37
    {
38
        return new Response($this->serializer->serialize($this->getUser(), 'json', [
39
            'groups' => [
40
                'user_details',
41
                'course_details',
42
            ],
43
        ]));
44
    }
45
46
    public function registerOrUpdateUser(
47
        Request $request,
48
        FormFactoryInterface $formFactory,
49
        EntityManagerInterface $entityManager,
50
        UserManagerInterface $userManager,
51
        TokenStorageInterface $tokenStorage,
52
        EventDispatcherInterface $eventDispatcher
53
    ): Response {
54
        if (!$request->request->has('email')) {
55
            return new JsonResponse(['message' => 'User email is not provided'], Response::HTTP_BAD_REQUEST);
56
        }
57
58
        $user = $userManager->getOrCreateUser($request->request->get('email'));
59
        $form = $formFactory->create(RegisterUserType::class, $user);
60
        $form->handleRequest($request);
61
        if ($form->isSubmitted() && $form->isValid()) {
62
            if (null !== $courseTitleOrSku = $form->get('course')->getData()) {
63
                $userManager->addCourseByTitleOrSku($user, $courseTitleOrSku);
64
            }
65
66
            $newUser = false;
67
            if (!$entityManager->contains($user)) {
68
                $entityManager->persist($user);
69
                $newUser = true;
70
            }
71
72
            $entityManager->flush();
73
            $tokenStorage->getToken()->setUser($user);
74
75
            if ($newUser) {
76
                $eventDispatcher->dispatch(new UserCreateEvent($user));
77
            }
78
79
            return new Response($this->serializer->serialize($user, 'json', ['groups' => ['user_details']]), Response::HTTP_CREATED);
80
        }
81
82
        return new Response($this->serializer->serialize(ErrorHandler::getErrorsFromForm($form), 'json'), Response::HTTP_BAD_REQUEST);
83
    }
84
85
    public function requestPasswordReset(
86
        Request $request,
87
        FormFactoryInterface $formFactory,
88
        EntityManagerInterface $entityManager,
89
        UserManagerInterface $userManager,
90
        UserRepositoryInterface $userRepository,
91
        EventDispatcherInterface $eventDispatcher
92
    ): Response {
93
        $form = $formFactory->create(UserPasswordResetRequestType::class, []);
94
        $form->handleRequest($request);
95
        if ($form->isSubmitted() && $form->isValid()) {
96
            $user = $userRepository->getOneByEmail($form->getData()['email']);
97
            if (null === $user) {
98
                throw new NotFoundHttpException('User was not found');
99
            }
100
            $userManager->setGeneratedPasswordResetToken($user);
101
            $entityManager->flush();
102
103
            $eventDispatcher->dispatch(new UserPasswordChangeRequestEvent($user));
104
105
            return new JsonResponse(['success' => true]);
106
        }
107
108
        return new Response($this->serializer->serialize(ErrorHandler::getErrorsFromForm($form), 'json'), Response::HTTP_BAD_REQUEST);
109
    }
110
111
    public function requestPassword(
112
        Request $request,
113
        FormFactoryInterface $formFactory,
114
        EntityManagerInterface $entityManager,
115
        UserManagerInterface $userManager,
116
        UserRepositoryInterface $userRepository
117
    ): Response {
118
        $form = $formFactory->create(UserPasswordResetType::class, []);
119
        $form->handleRequest($request);
120
        if ($form->isSubmitted() && $form->isValid()) {
121
            $user = $userRepository->getOneByPasswordResetToken($request->query->get('token'));
122
            if (null === $user) {
123
                throw new NotFoundHttpException('User was not found');
124
            }
125
126
            $data = $form->getData();
127
            if ($data['password'] !== $data['repeatedPassword']) {
128
                throw new \InvalidArgumentException('Passwords are not equal');
129
            }
130
131
            $userManager->resetPassword($user, $data['password']);
132
            $entityManager->flush();
133
134
            return new Response($this->serializer->serialize($user, 'json', ['groups' => ['user_details']]), Response::HTTP_OK);
135
        }
136
137
        return new Response($this->serializer->serialize(ErrorHandler::getErrorsFromForm($form), 'json'), Response::HTTP_BAD_REQUEST);
138
    }
139
140
    public function checkEmail(
141
        Request $request,
142
        FormFactoryInterface $formFactory,
143
        UserRepositoryInterface $userRepository
144
    ): Response {
145
        $form = $formFactory->create(UserEmailType::class, []);
146
        $form->handleRequest($request);
147
        if ($form->isSubmitted() && $form->isValid()) {
148
            $user = $userRepository->getOneByEmail($form->getData()['email']);
149
150
            if (null !== $user) {
151
                return new Response($this->serializer->serialize($user, 'json', ['groups' => ['user_details']]), Response::HTTP_OK);
152
            }
153
154
            return new Response(null, Response::HTTP_NOT_FOUND);
155
        }
156
157
        return new Response($this->serializer->serialize(ErrorHandler::getErrorsFromForm($form), 'json'), Response::HTTP_BAD_REQUEST);
158
    }
159
}
160