summaryrefslogtreecommitdiff
path: root/src/controller/UserController.php
diff options
context:
space:
mode:
Diffstat (limited to 'src/controller/UserController.php')
-rw-r--r--src/controller/UserController.php360
1 files changed, 360 insertions, 0 deletions
diff --git a/src/controller/UserController.php b/src/controller/UserController.php
new file mode 100644
index 0000000..50e8bf7
--- /dev/null
+++ b/src/controller/UserController.php
@@ -0,0 +1,360 @@
1<?php
2// src/controller/PasswordController.php
3//
4// test mot de passe et captcha
5
6declare(strict_types=1);
7
8use Doctrine\ORM\EntityManager;
9use App\Entity\User;
10use App\Entity\Log;
11
12class UserController
13{
14 static public function existUsers(EntityManager $entityManager): bool
15 {
16 // optimiser ça si possible, on veut juste savoir si la table est vide ou non
17 $users = $entityManager->getRepository(User::class)->findAll();
18
19 if(count($users) === 0) // table vide
20 {
21 $_SESSION['user'] = '';
22 $_SESSION['admin'] = false;
23
24 return false;
25 }
26 else{
27 return true;
28 }
29 }
30
31 static public function createUser(EntityManager $entityManager)
32 {
33 // test mauvais paramètres
34 if(!isset($_POST['login']) || empty($_POST['login'])
35 || !isset($_POST['password']) || empty($_POST['password'])
36 || !isset($_POST['password_confirmation']) || empty($_POST['password_confirmation'])
37 || !isset($_POST['create_user_hidden']) || !empty($_POST['create_user_hidden']))
38 {
39 header('Location: ' . new URL);
40 die;
41 }
42
43 unset($_SESSION['user']);
44
45 $captcha_solution = (isset($_SESSION['captcha']) && is_int($_SESSION['captcha'])) ? $_SESSION['captcha'] : 0;
46 $captcha_try = isset($_POST['captcha']) ? Captcha::controlInput($_POST['captcha']) : 0;
47 unset($_SESSION['captcha']);
48
49 $error = '';
50 if($captcha_try == 0)
51 {
52 $error = 'error_non_valid_captcha';
53 }
54 elseif($captcha_solution == 0) // ne peut pas arriver, si?
55 {
56 $error = 'captcha_server_error';
57 }
58 elseif($captcha_try != $captcha_solution) // le test!
59 {
60 $error = 'bad_solution_captcha';
61 }
62 elseif($_POST['password'] !== $_POST['password_confirmation'])
63 {
64 $error = 'different_passwords';
65 }
66 else
67 {
68 $login = self::removeSpacesTabsCRLF(htmlspecialchars($_POST['login']));
69 $password = self::removeSpacesTabsCRLF(htmlspecialchars($_POST['password']));
70
71 // self::removeSpacesTabsCRLF prévient la validation par erreur d'une chaine "vide"
72
73 // conformité
74 if(!empty($password) && !empty($login)
75 && $password === $_POST['password'] && $login === $_POST['login'])
76 {
77 // enregistrement et redirection
78 $password = password_hash($password, PASSWORD_DEFAULT);
79 $user = new App\Entity\User($login, $password);
80 $entityManager->persist($user);
81 $entityManager->flush();
82
83 header('Location: ' . new URL);
84 die;
85 }
86 else{
87 $error = 'forbidden_characters';
88 }
89 }
90
91 $url = empty($error) ? new URL : new URL(['error' => $error]);
92 header('Location: ' . $url);
93 die;
94 }
95
96 static public function connect(EntityManager $entityManager): void
97 {
98 if($_SESSION['admin']) // déjà connecté?
99 {
100 header('Location: ' . new URL);
101 die;
102 }
103
104 $_SESSION['user'] = '';
105 $_SESSION['admin'] = false;
106
107 $captcha_solution = (isset($_SESSION['captcha']) && is_int($_SESSION['captcha'])) ? $_SESSION['captcha'] : 0;
108 $captcha_try = isset($_POST['captcha']) ? Captcha::controlInput($_POST['captcha']) : 0;
109 unset($_SESSION['captcha']);
110
111 $error = '';
112 if($captcha_try == 0)
113 {
114 $error = 'error_non_valid_captcha';
115 }
116 elseif($captcha_solution == 0) // pas censé se produire
117 {
118 $error = 'captcha_server_error';
119 }
120 elseif($captcha_try != $captcha_solution) // le test!
121 {
122 $error = 'bad_solution_captcha';
123 }
124 elseif(!isset($_POST['login']) || empty($_POST['login'])
125 || !isset($_POST['password']) || empty($_POST['password']))
126 {
127 $error = 'bad_login_or_password';
128 }
129 else // c'est OK
130 {
131 $login = trim($_POST['login']);
132 $password = trim($_POST['password']);
133 $user = self::getUser($login, $entityManager);
134
135 // enregistrement et redirection
136 if(!empty($user) && $login === $user->getLogin() && password_verify($password, $user->getPassword()))
137 {
138 $log = new Log(true);
139 $entityManager->persist($log);
140 $entityManager->flush();
141
142 // protection fixation de session, si l'attaquant crée un cookie de session, il est remplacé
143 session_regenerate_id(true);
144
145 $_SESSION['user'] = $login;
146 $_SESSION['admin'] = true;
147
148 $url = new URL(isset($_GET['from']) ? ['page' => $_GET['from']] : []);
149 isset($_GET['id']) ? $url->addParams(['id' => $_GET['id']]) : '';
150 header('Location: ' . $url);
151 die;
152 }
153 else
154 {
155 $log = new Log(false);
156 $entityManager->persist($log);
157 $entityManager->flush();
158 $error = 'bad_login_or_password';
159 }
160 }
161
162 // tous les cas sauf connexion réussie
163 sleep(1); // défense basique à la force brute
164 $url = new URL(isset($_GET['from']) ? ['page' => 'connexion', 'from' => $_GET['from']] : []);
165 isset($_GET['id']) ? $url->addParams(['id' => $_GET['id']]) : '';
166 !empty($error) ? $url->addParams(['error' => $error]) : '';
167 header('Location: ' . $url);
168 die;
169 }
170
171 static public function disconnect(): void
172 {
173 // nettoyage complet
174 $_SESSION = []; // mémoire vive
175 session_destroy(); // fichier côté serveur
176 setcookie('PHPSESSID', '', time() - 86400, '/'); // cookie de session
177
178 // retour même page
179 $url = new URL;
180 isset($_GET['from']) ? $url->addParams(['page' => $_GET['from']]) : '';
181 isset($_GET['id']) ? $url->addParams(['id' => $_GET['id']]) : '';
182 header('Location: ' . $url);
183 die;
184 }
185
186 static public function updateUsername(EntityManager $entityManager): void
187 {
188 if(!$_SESSION['admin']) // superflux, fait dans le routeur
189 {
190 self::disconnect();
191 }
192
193 $captcha_solution = (isset($_SESSION['captcha']) && is_int($_SESSION['captcha'])) ? $_SESSION['captcha'] : 0;
194 $captcha_try = isset($_POST['captcha']) ? Captcha::controlInput($_POST['captcha']) : 0;
195 unset($_SESSION['captcha']);
196
197 $url = new URL(['page' => 'user_edit']);
198 isset($_GET['from']) ? $url->addParams(['from' => $_GET['from']]) : null;
199
200 $error = '';
201 if(!isset($_POST['old_login']) || empty($_POST['old_login'])
202 || !isset($_POST['password']) || empty($_POST['password'])
203 || !isset($_POST['new_login']) || empty($_POST['new_login'])
204 || !isset($_POST['modify_username_hidden']) || !empty($_POST['modify_username_hidden']))
205 {
206 $error = 'bad_login_or_password';
207 }
208 elseif($captcha_try != $captcha_solution) // le test!
209 {
210 $error = 'bad_solution_captcha';
211 }
212 else
213 {
214 // sécurisation de la saisie
215 $old_login = $_POST['old_login'];
216 $password = $_POST['password'];
217 $new_login = self::removeSpacesTabsCRLF(htmlspecialchars($_POST['new_login']));
218 // removeSpacesTabsCRLF pour éviter d'enregistrer une chaîne vide
219
220 // tests de conformité
221 if($old_login !== $_POST['old_login'] || $password !== $_POST['password'] || $new_login !== $_POST['new_login'])
222 {
223 $error = 'forbidden_characters';
224 }
225 elseif($old_login !== $_SESSION['user']){
226 $error = 'bad_login_or_password';
227 }
228 elseif($old_login === $new_login){
229 $error = 'same_username_as_before';
230 }
231 else
232 {
233 $user = self::getUser($old_login, $entityManager);
234
235 if(password_verify($password, $user->getPassword()))
236 {
237 $user->setLogin($new_login);
238 $entityManager->flush();
239 $_SESSION['user'] = $new_login;
240
241 $url->addParams(['success_login' => 'new_login']);
242 $error = '';
243 }
244 else
245 {
246 $error = 'bad_login_or_password';
247 }
248 }
249 }
250
251 if(!empty($error)){
252 sleep(1);
253 $url->addParams(['error_login' => $error]);
254 }
255
256 header('Location: ' . $url);
257 die;
258 }
259
260 static public function updatePassword(EntityManager $entityManager): void
261 {
262 if(!$_SESSION['admin']) // superflux, fait dans le routeur
263 {
264 self::disconnect();
265 }
266
267 $captcha_solution = (isset($_SESSION['captcha']) && is_int($_SESSION['captcha'])) ? $_SESSION['captcha'] : 0;
268 $captcha_try = isset($_POST['captcha']) ? Captcha::controlInput($_POST['captcha']) : 0;
269 unset($_SESSION['captcha']);
270
271 $url = new URL(['page' => 'user_edit']);
272 isset($_GET['from']) ? $url->addParams(['from' => $_GET['from']]) : null;
273
274 $error = '';
275 if(!isset($_POST['login']) || empty($_POST['login'])
276 || !isset($_POST['old_password']) || empty($_POST['old_password'])
277 || !isset($_POST['new_password']) || empty($_POST['new_password'])
278 || !isset($_POST['modify_password_hidden']) || !empty($_POST['modify_password_hidden']))
279 {
280 $error = 'bad_login_or_password';
281 }
282 elseif($captcha_try != $captcha_solution) // le test!
283 {
284 $error = 'bad_solution_captcha';
285 }
286 else
287 {
288 // sécurisation de la saisie
289 $login = $_POST['login'];
290 $old_password = $_POST['old_password'];
291 $new_password = self::removeSpacesTabsCRLF(htmlspecialchars($_POST['new_password']));
292 // removeSpacesTabsCRLF pour éviter d'enregistrer une chaîne vide
293
294 // tests de conformité
295 if($login !== $_POST['login'] || $old_password !== $_POST['old_password'] || $new_password !== $_POST['new_password'])
296 {
297 $error = 'forbidden_characters';
298 }
299 elseif($login !== $_SESSION['user']){
300 $error = 'bad_login_or_password';
301 }
302 elseif($old_password === $new_password){
303 $error = 'same_password_as_before';
304 }
305 else
306 {
307 $user = self::getUser($login, $entityManager);
308
309 if(password_verify($old_password, $user->getPassword()))
310 {
311 $new_password = password_hash($new_password, PASSWORD_DEFAULT);
312 $user->setPassword($new_password);
313 $entityManager->flush();
314
315 $url->addParams(['success_password' => 'new_password']);
316 $error = '';
317 }
318 else
319 {
320 $error = 'bad_login_or_password';
321 }
322 }
323 }
324
325 if(!empty($error)){
326 sleep(1);
327 $url->addParams(['error_password' => $error]);
328 }
329
330 header('Location: ' . $url);
331 die;
332 }
333
334 static private function getUser(string $login, EntityManager $entityManager): ?User
335 {
336 $users = $entityManager->getRepository('App\Entity\User')->findBy(['login' => $login]);
337
338 if(count($users) === 0)
339 {
340 $_SESSION['user'] = '';
341 $_SESSION['admin'] = false;
342 }
343
344 foreach($users as $user)
345 {
346 if($user->getLogin() === $login)
347 {
348 return $user;
349 }
350 }
351 return null;
352 }
353
354 // erreurs à la création des mots de passe
355 static private function removeSpacesTabsCRLF(string $chaine): string
356 {
357 $cibles = [' ', "\t", "\n", "\r"]; // doubles quotes !!
358 return(str_replace($cibles, '', $chaine));
359 }
360} \ No newline at end of file