Skip to content

Commit 37fa0ad

Browse files
chore: Refactor registration and user creation
1 parent 5fb1728 commit 37fa0ad

File tree

20 files changed

+269
-212
lines changed

20 files changed

+269
-212
lines changed

docs/production.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,7 +367,7 @@ locale of a user created via the CLI or seeds for instance.
367367
If you need to configure a demo server (this is probably NOT the case), you can
368368
simply set the `APP_DEMO` variable to `true` in the `.env` file. It will add a
369369
banner at the top of the screen to warn users that data are reset every night.
370-
It will also consider the account with the `demo@flus.io` email as the demo
370+
It will also consider the account with the `demo@flus.fr` email as the demo
371371
account. The reset is done through a scheduled job managed by Flus.
372372

373373
## Optional: Enable subscriptions

src/Configuration.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,11 @@ class Configuration extends \Minz\Configuration
4040
*/
4141
public static array $application;
4242

43+
public static function areRegistrationsOpened(): bool
44+
{
45+
return self::$application['registrations_opened'];
46+
}
47+
4348
public static function areSubscriptionsEnabled(): bool
4449
{
4550
return self::$application['subscriptions_enabled'];

src/cli/Users.php

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -74,13 +74,20 @@ public function create(Request $request): Response
7474
$email = $request->parameters->getString('email', '');
7575
$password = $request->parameters->getString('password', '');
7676

77-
try {
78-
$user = services\UserCreator::create($username, $email, $password);
79-
} catch (services\UserCreatorError $e) {
80-
$errors = implode(' ', $e->errors());
77+
$user = new models\User();
78+
$user->setUsername($username);
79+
$user->setEmail($email);
80+
$user->setPassword($password);
81+
82+
if (!$user->validate()) {
83+
$errors = implode(' ', $user->errors());
8184
return Response::text(400, "User creation failed: {$errors}");
8285
}
8386

87+
$user->save();
88+
89+
services\UserService::initializeData($user);
90+
8491
// Immediately validate the user since we created it manually
8592
$user->validated_at = \Minz\Time::now();
8693
$user->save();

src/controllers/Registrations.php

Lines changed: 26 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace App\controllers;
44

55
use App\auth;
6+
use App\forms;
67
use App\mailers;
78
use App\models;
89
use App\services;
@@ -21,118 +22,73 @@ class Registrations extends BaseController
2122
/**
2223
* Show the registration form.
2324
*
24-
* @response 302 / if connected
25-
* @response 302 /login if registrations are closed
25+
* @response 302 /
26+
* If the user is connected.
27+
* @response 302 /login
28+
* If the registrations are closed.
2629
* @response 200
27-
*
28-
* @return \Minz\Response
30+
* On sucess.
2931
*/
3032
public function new(): Response
3133
{
3234
if (auth\CurrentUser::get()) {
3335
return Response::redirect('home');
3436
}
3537

36-
$app_conf = \App\Configuration::$application;
37-
if (!$app_conf['registrations_opened']) {
38+
if (!\App\Configuration::areRegistrationsOpened()) {
3839
return Response::redirect('login');
3940
}
4041

41-
$app_path = \App\Configuration::$app_path;
42-
$terms_path = $app_path . '/policies/terms.html';
43-
$has_terms = file_exists($terms_path);
42+
$form = new forms\Registration();
4443

4544
return Response::ok('registrations/new.phtml', [
46-
'has_terms' => $has_terms,
47-
'username' => '',
48-
'email' => '',
49-
'password' => '',
50-
'subscriptions_enabled' => $app_conf['subscriptions_enabled'],
51-
'subscriptions_host' => $app_conf['subscriptions_host'],
45+
'form' => $form,
5246
]);
5347
}
5448

5549
/**
5650
* Create a user.
5751
*
58-
* @request_param string csrf
5952
* @request_param string email
6053
* @request_param string username
6154
* @request_param string password
6255
* @request_param bool accept_terms
6356
* @request_param bool accept_contact
57+
* @request_param string csrf_token
6458
*
65-
* @response 302 / if already connected
66-
* @response 302 /login if registrations are closed
67-
* @response 400 if CSRF token is wrong
68-
* @response 400 if email, username or password is missing/invalid
69-
* @response 400 if the service has terms of service and accept_terms is false
70-
* @response 400 if email already exists
59+
* @response 302 /
60+
* If the user is connected.
61+
* @response 302 /login
62+
* If the registrations are closed.
63+
* @response 400
64+
* If at least one of the parameters is invalid.
7165
* @response 302 /onboarding
66+
* On sucess.
7267
*/
7368
public function create(Request $request): Response
7469
{
7570
if (auth\CurrentUser::get()) {
7671
return Response::redirect('home');
7772
}
7873

79-
$app_conf = \App\Configuration::$application;
80-
if (!$app_conf['registrations_opened']) {
74+
if (!\App\Configuration::areRegistrationsOpened()) {
8175
return Response::redirect('login');
8276
}
8377

84-
$app_path = \App\Configuration::$app_path;
85-
$terms_path = $app_path . '/policies/terms.html';
86-
$has_terms = file_exists($terms_path);
87-
88-
$username = $request->parameters->getString('username', '');
89-
$email = $request->parameters->getString('email', '');
90-
$password = $request->parameters->getString('password', '');
91-
$accept_terms = $request->parameters->getBoolean('accept_terms');
92-
$accept_contact = $request->parameters->getBoolean('accept_contact');
93-
$csrf = $request->parameters->getString('csrf', '');
94-
95-
if (!\App\Csrf::validate($csrf)) {
96-
return Response::badRequest('registrations/new.phtml', [
97-
'has_terms' => $has_terms,
98-
'username' => $username,
99-
'email' => $email,
100-
'password' => $password,
101-
'subscriptions_enabled' => $app_conf['subscriptions_enabled'],
102-
'subscriptions_host' => $app_conf['subscriptions_host'],
103-
'error' => _('A security verification failed: you should retry to submit the form.'),
104-
]);
105-
}
78+
$user = new models\User();
79+
$form = new forms\Registration(model: $user);
80+
$form->handleRequest($request);
10681

107-
if ($has_terms && !$accept_terms) {
82+
if (!$form->validate()) {
10883
return Response::badRequest('registrations/new.phtml', [
109-
'has_terms' => $has_terms,
110-
'username' => $username,
111-
'email' => $email,
112-
'password' => $password,
113-
'subscriptions_enabled' => $app_conf['subscriptions_enabled'],
114-
'subscriptions_host' => $app_conf['subscriptions_host'],
115-
'errors' => [
116-
'accept_terms' => _('You must accept the terms of service.'),
117-
],
84+
'form' => $form,
11885
]);
11986
}
12087

121-
try {
122-
$user = services\UserCreator::create($username, $email, $password);
123-
} catch (services\UserCreatorError $e) {
124-
return Response::badRequest('registrations/new.phtml', [
125-
'has_terms' => $has_terms,
126-
'username' => $username,
127-
'email' => $email,
128-
'password' => $password,
129-
'subscriptions_enabled' => $app_conf['subscriptions_enabled'],
130-
'subscriptions_host' => $app_conf['subscriptions_host'],
131-
'errors' => $e->errors(),
132-
]);
133-
}
88+
$user = $form->model();
89+
$user->save();
13490

135-
$user->accept_contact = $accept_contact;
91+
services\UserService::initializeData($user);
13692

13793
// Initialize the validation token
13894
$validation_token = new models\Token(1, 'day', 16);

src/forms/DemoDisabler.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ trait DemoDisabler
1515
public function checkNotDemoAccount(): void
1616
{
1717
$user = auth\CurrentUser::get();
18-
if (\App\Configuration::isDemoEnabled() && $user && $user->isDemoAccount()) {
18+
if (\App\Configuration::isDemoEnabled() && $user && $user->isDemoUser()) {
1919
$this->addError(
2020
'@base',
2121
'demo_account',

src/forms/Login.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,9 @@ class Login extends BaseForm
2727
*/
2828
public function __construct(array $default_values = [])
2929
{
30-
if (\App\Configuration::$application['demo']) {
31-
$default_values['email'] = 'demo@flus.io';
32-
$default_values['password'] = 'demo';
30+
if (\App\Configuration::isDemoEnabled()) {
31+
$default_values['email'] = models\User::DEMO_EMAIL;
32+
$default_values['password'] = models\User::DEMO_PASSWORD;
3333
}
3434

3535
parent::__construct($default_values);

src/forms/Registration.php

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
<?php
2+
3+
namespace App\forms;
4+
5+
use App\models;
6+
use App\utils;
7+
use Minz\Form;
8+
use Minz\Validable;
9+
10+
/**
11+
* @extends BaseForm<models\User>
12+
*
13+
* @author Marien Fressinaud <dev@marienfressinaud.fr>
14+
* @license http://www.gnu.org/licenses/agpl-3.0.en.html AGPL
15+
*/
16+
class Registration extends BaseForm
17+
{
18+
use utils\Memoizer;
19+
20+
#[Form\Field(bind: 'setUsername')]
21+
public string $username = '';
22+
23+
#[Form\Field(bind: 'setEmail')]
24+
public string $email = '';
25+
26+
#[Form\Field(bind: 'setPassword')]
27+
public string $password = '';
28+
29+
#[Form\Field]
30+
public bool $accept_contact = false;
31+
32+
#[Form\Field(bind: false)]
33+
public bool $accept_terms = false;
34+
35+
public int $username_max_length = models\User::USERNAME_MAX_LENGTH;
36+
37+
public function hasTerms(): bool
38+
{
39+
return $this->memoize('has_terms', function (): bool {
40+
$terms_path = \App\Configuration::$app_path . '/policies/terms.html';
41+
return file_exists($terms_path);
42+
});
43+
}
44+
45+
#[Validable\Check]
46+
public function checkTermsAreAccepted(): void
47+
{
48+
if ($this->hasTerms() && !$this->accept_terms) {
49+
$this->addError(
50+
'accept_terms',
51+
'terms_not_accepted',
52+
_('You must accept the terms of service.'),
53+
);
54+
}
55+
}
56+
}

src/forms/security/Credentials.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ class Credentials extends BaseForm
1919
{
2020
use DemoDisabler;
2121

22-
#[Form\Field(transform: '\Minz\Email::sanitize')]
22+
#[Form\Field(bind: 'setEmail')]
2323
public string $email = '';
2424

2525
#[Form\Field(bind: 'changePassword')]

src/forms/users/Profile.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414
*/
1515
class Profile extends BaseForm
1616
{
17-
#[Form\Field(transform: 'trim')]
17+
#[Form\Field(bind: 'setUsername')]
1818
public string $username = '';
1919

2020
public int $username_max_length = models\User::USERNAME_MAX_LENGTH;

src/jobs/scheduled/Cleaner.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -68,10 +68,10 @@ public function perform(): void
6868
// reinitialize the support user
6969
models\User::supportUser();
7070

71-
// Initialize a default (validated) user
72-
$user = services\UserCreator::create('Alix', 'demo@flus.io', 'demo');
73-
$user->validated_at = \Minz\Time::now();
71+
// Initialize a default user
72+
$user = models\User::demoUser();
7473
$user->save();
74+
services\UserService::initializeData($user);
7575
}
7676
}
7777
}

0 commit comments

Comments
 (0)