Passed
Push — develop ( e4d74a...4dec26 )
by BENARD
04:13
created

RegistrationController::checkIp()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 18
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 12
c 1
b 0
f 0
dl 0
loc 18
rs 9.8666
cc 3
nc 2
nop 2
1
<?php
2
3
namespace ProjetNormandie\UserBundle\Controller;
4
5
use Exception;
6
use Doctrine\Persistence\ManagerRegistry;
7
use ProjetNormandie\UserBundle\Doctrine\UserManager;
8
use ProjetNormandie\UserBundle\Util\TokenGenerator;
9
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
10
use Symfony\Component\HttpFoundation\Request;
11
use Symfony\Component\HttpFoundation\Response;
12
use ProjetNormandie\EmailBundle\Service\Mailer;
13
use Symfony\Component\Mailer\Exception\TransportExceptionInterface;
14
use Symfony\Contracts\Translation\TranslatorInterface;
15
16
class RegistrationController extends AbstractController
17
{
18
    private UserManager $userManager;
19
    private ManagerRegistry $doctrine;
20
    private TokenGenerator $tokenGenerator;
21
    private TranslatorInterface $translator;
22
    private Mailer $mailer;
23
24
    /**
25
     * RegistrationController constructor.
26
     * @param UserManager         $userManager
27
     * @param ManagerRegistry     $doctrine
28
     * @param TokenGenerator      $tokenGenerator
29
     * @param TranslatorInterface $translator
30
     * @param Mailer              $mailer
31
     */
32
    public function __construct(
33
        UserManager $userManager,
34
        ManagerRegistry $doctrine,
35
        TokenGenerator $tokenGenerator,
36
        TranslatorInterface $translator,
37
        Mailer $mailer
38
    ) {
39
        $this->userManager = $userManager;
40
        $this->doctrine = $doctrine;
41
        $this->tokenGenerator = $tokenGenerator;
42
        $this->translator = $translator;
43
        $this->mailer = $mailer;
44
    }
45
46
47
    /**
48
     * @param Request $request
49
     * @return Response
50
     * @throws Exception
51
     * @throws TransportExceptionInterface
52
     */
53
    public function register(Request $request): Response
54
    {
55
        $data = json_decode($request->getContent(), true);
56
        $email = $data['email'];
57
        $username = $data['username'];
58
        $password = $data['password'];
59
        $rules_accepted = $data['rules_accepted'] ?? false;
60
61
        // Check username
62
        if (!$rules_accepted) {
63
            return $this->getResponse(false, $this->translator->trans('registration.must_accept_rules'));
64
        }
65
66
        $this->checkIp($request, $username);
67
68
        // Check username
69
        $user = $this->userManager->findUserByUsername($username);
70
        if ($user !== null) {
71
            return $this->getResponse(false, $this->translator->trans('registration.username_exists'));
72
        }
73
74
        // Check email
75
        $user = $this->userManager->findUserByEmail($email);
76
        if ($user !== null) {
77
            return $this->getResponse(false, $this->translator->trans('registration.email_exists'));
78
        }
79
80
        $user = $this->userManager->createUser();
81
        $user->setEnabled(false);
82
        $user->setEmail($email);
83
        $user->setUsername($username);
84
        $user->setPlainPassword($password);
85
        $user->setConfirmationToken($this->tokenGenerator->generateToken());
86
87
88
        $this->userManager->updateUser($user);
89
90
        // Send email to activate account
91
        $body = sprintf(
92
            $this->translator->trans('registration.email.message'),
93
            $user->getUsername(),
94
            ($request->server->get('HTTP_ORIGIN') ?? null)  . '/en/register?token=' . $user->getConfirmationToken()
95
        );
96
97
        $this->mailer->send(
98
            sprintf($this->translator->trans('registration.email.subject'), $user->getUsername()),
99
            $body,
100
            null,
101
            $user->getEmail()
102
        );
103
104
        return $this->getResponse(true, sprintf($this->translator->trans('registration.check_email'), $email));
105
    }
106
107
108
    /**
109
     * @param Request $request
110
     * @return Response
111
     */
112
    public function confirm(Request $request): Response
113
    {
114
        $data = json_decode($request->getContent(), true);
115
        $token = $data['token'];
116
117
        $user = $this->userManager->findUserByConfirmationToken($token);
118
119
        if (null === $user) {
120
            return $this->getResponse(false, $this->translator->trans('registration.token_invalid'));
121
        }
122
123
        $user->setEnabled(true);
124
        $user->setConfirmationToken(null);
125
        $this->userManager->updateUser($user);
126
127
        return $this->getResponse(
128
            true,
129
            sprintf($this->translator->trans('registration.confirmed'), $user->getUsername())
130
        );
131
    }
132
133
    /**
134
     * @param Request $request
135
     * @param string  $username
136
     * @return Response|void
137
     * @throws TransportExceptionInterface
138
     */
139
    private function checkIp(Request $request, string $username)
140
    {
141
        // check IP
142
        $remotAddr = $request->getClientIp();
143
        $ip = $this->doctrine->getRepository('ProjetNormandie\UserBundle\Entity\Ip')
144
            ->findOneBy(array('label' => $remotAddr));
145
        if ($ip && $ip->isBanned()) {
146
            // Send alert email
147
            $body = sprintf(
148
                $this->translator->trans('ip.email.message'),
149
                $username,
150
                $remotAddr
151
            );
152
            $this->mailer->send(
153
                $this->translator->trans('ip.email.subject'),
154
                $body
155
            );
156
            return $this->getResponse(false, $this->translator->trans('registration.error'));
157
        }
158
    }
159
160
    /**
161
     * @param bool $success
162
     * @param null    $message
0 ignored issues
show
Documentation Bug introduced by
Are you sure the doc-type for parameter $message is correct as it would always require null to be passed?
Loading history...
163
     * @return Response
164
     */
165
    private function getResponse(bool $success, $message = null): Response
166
    {
167
        $response = new Response();
168
        $response->headers->set('Content-Type', 'application/json');
169
        $response->setContent(json_encode([
170
            'success' => $success,
171
            'message' => $message,
172
        ]));
173
        return $response;
174
    }
175
}
176