Allow apps to listen to the steps and validate the form data

Signed-off-by: Joas Schilling <coding@schilljs.com>
This commit is contained in:
Joas Schilling 2021-04-09 15:05:59 +02:00
parent a1ad79f4df
commit 1e907c2664
No known key found for this signature in database
GPG Key ID: 7076EA9751AACDDA
5 changed files with 211 additions and 1 deletions

View File

@ -19,6 +19,9 @@ namespace OCA\Registration\Controller;
use Exception;
use OCA\Registration\AppInfo\Application;
use OCA\Registration\Db\Registration;
use OCA\Registration\Events\PassedFormEvent;
use OCA\Registration\Events\ShowFormEvent;
use OCA\Registration\Events\ValidateFormEvent;
use OCA\Registration\Service\LoginFlowService;
use OCA\Registration\Service\MailService;
use OCA\Registration\Service\RegistrationException;
@ -31,6 +34,7 @@ use OCP\AppFramework\Http\RedirectToDefaultAppResponse;
use OCP\AppFramework\Http\Response;
use OCP\AppFramework\Http\StandaloneTemplateResponse;
use OCP\AppFramework\Http\TemplateResponse;
use OCP\EventDispatcher\IEventDispatcher;
use OCP\IL10N;
use OCP\IRequest;
use OCP\IURLGenerator;
@ -50,6 +54,8 @@ class RegisterController extends Controller {
private $mailService;
/** @var LoginFlowService */
private $loginFlowService;
/** @var IEventDispatcher */
private $eventDispatcher;
public function __construct(
string $appName,
@ -59,7 +65,8 @@ class RegisterController extends Controller {
IConfig $config,
RegistrationService $registrationService,
LoginFlowService $loginFlowService,
MailService $mailService
MailService $mailService,
IEventDispatcher $eventDispatcher
) {
parent::__construct($appName, $request);
$this->l10n = $l10n;
@ -68,6 +75,7 @@ class RegisterController extends Controller {
$this->registrationService = $registrationService;
$this->loginFlowService = $loginFlowService;
$this->mailService = $mailService;
$this->eventDispatcher = $eventDispatcher;
}
/**
@ -96,6 +104,8 @@ class RegisterController extends Controller {
}
}
$this->eventDispatcher->dispatchTyped(new ShowFormEvent(ShowFormEvent::STEP_EMAIL));
$params = [
'email' => $email,
'message' => $message ?: $emailHint,
@ -113,6 +123,13 @@ class RegisterController extends Controller {
* @return TemplateResponse
*/
public function submitEmailForm(string $email): Response {
$validateFormEvent = new ValidateFormEvent(ValidateFormEvent::STEP_EMAIL);
$this->eventDispatcher->dispatchTyped($validateFormEvent);
if (!empty($validateFormEvent->getErrors())) {
return $this->showEmailForm($email, implode(' ', $validateFormEvent->getErrors()));
}
try {
// Registration already in progress, update token and continue with verification
$registration = $this->registrationService->getRegistrationForEmail($email);
@ -129,6 +146,8 @@ class RegisterController extends Controller {
}
if ($this->config->getAppValue($this->appName, 'disable_email_verification', 'no') === 'yes') {
$this->eventDispatcher->dispatchTyped(new PassedFormEvent(PassedFormEvent::STEP_EMAIL, $registration->getClientSecret()));
return new RedirectResponse(
$this->urlGenerator->linkToRoute(
'registration.register.showUserForm',
@ -148,6 +167,8 @@ class RegisterController extends Controller {
return $this->showEmailForm($email, $this->l10n->t('A problem occurred sending email, please contact your administrator.'));
}
$this->eventDispatcher->dispatchTyped(new PassedFormEvent(PassedFormEvent::STEP_EMAIL, $registration->getClientSecret()));
return new RedirectResponse(
$this->urlGenerator->linkToRoute(
'registration.register.showVerificationForm',
@ -171,6 +192,8 @@ class RegisterController extends Controller {
return $this->validateSecretAndTokenErrorPage();
}
$this->eventDispatcher->dispatchTyped(new ShowFormEvent(ShowFormEvent::STEP_VERIFICATION, $secret));
return new TemplateResponse('registration', 'form/verification', [
'message' => $message,
], 'guest');
@ -198,6 +221,15 @@ class RegisterController extends Controller {
return $this->validateSecretAndTokenErrorPage();
}
$validateFormEvent = new ValidateFormEvent(ValidateFormEvent::STEP_VERIFICATION, $secret);
$this->eventDispatcher->dispatchTyped($validateFormEvent);
if (!empty($validateFormEvent->getErrors())) {
return $this->showVerificationForm($secret, implode(' ', $validateFormEvent->getErrors()));
}
$this->eventDispatcher->dispatchTyped(new PassedFormEvent(PassedFormEvent::STEP_VERIFICATION, $secret));
return new RedirectResponse(
$this->urlGenerator->linkToRoute(
'registration.register.showUserForm',
@ -230,6 +262,8 @@ class RegisterController extends Controller {
$additional_hint = $this->config->getAppValue('registration', 'additional_hint');
$this->eventDispatcher->dispatchTyped(new ShowFormEvent(ShowFormEvent::STEP_USER, $secret));
return new TemplateResponse('registration', 'form/user', [
'email' => $registration->getEmail(),
'email_is_login' => $this->config->getAppValue('registration', 'email_is_login', 'no') === 'yes',
@ -270,6 +304,13 @@ class RegisterController extends Controller {
$loginname = $registration->getEmail();
}
$validateFormEvent = new ValidateFormEvent(ValidateFormEvent::STEP_USER, $secret);
$this->eventDispatcher->dispatchTyped($validateFormEvent);
if (!empty($validateFormEvent->getErrors())) {
return $this->showUserForm($secret, $token, $loginname, $fullname, $phone, $password, implode(' ', $validateFormEvent->getErrors()));
}
try {
$user = $this->registrationService->createAccount($registration, $loginname, $fullname, $phone, $password);
} catch (Exception $exception) {
@ -279,6 +320,8 @@ class RegisterController extends Controller {
// Delete registration
$this->registrationService->deleteRegistration($registration);
$this->eventDispatcher->dispatchTyped(new PassedFormEvent(PassedFormEvent::STEP_EMAIL, $secret, $user));
if ($user->isEnabled()) {
$this->registrationService->loginUser($user->getUID(), $user->getUID(), $password);

53
lib/Events/AFormEvent.php Normal file
View File

@ -0,0 +1,53 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2021 Joas Schilling <coding@schilljs.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Registration\Events;
use OCP\EventDispatcher\Event;
abstract class AFormEvent extends Event {
const STEP_EMAIL = 'email';
const STEP_VERIFICATION = 'verification';
const STEP_USER = 'user';
/** @var string */
protected $step;
/** @var string */
protected $registrationId;
public function __construct(string $step, string $registrationId = '') {
parent::__construct();
$this->step = $step;
$this->registrationId = $registrationId;
}
public function getStep(): string {
return $this->step;
}
public function getRegistrationIdentifier(): string {
return $this->registrationId;
}
}

View File

@ -0,0 +1,42 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2021 Joas Schilling <coding@schilljs.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Registration\Events;
use OCP\IUser;
class PassedFormEvent extends AFormEvent {
/** @var IUser|null */
protected $user;
public function __construct(string $step, string $registrationId = '', ?IUser $user = null) {
parent::__construct($step, $registrationId);
$this->user = $user;
}
public function getUser(): ?IUser {
return $this->user;
}
}

View File

@ -0,0 +1,28 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2021 Joas Schilling <coding@schilljs.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Registration\Events;
class ShowFormEvent extends AFormEvent {
}

View File

@ -0,0 +1,44 @@
<?php
declare(strict_types=1);
/**
* @copyright Copyright (c) 2021 Joas Schilling <coding@schilljs.com>
*
* @license GNU AGPL version 3 or any later version
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License as
* published by the Free Software Foundation, either version 3 of the
* License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*
*/
namespace OCA\Registration\Events;
class ValidateFormEvent extends AFormEvent {
/** @var string[] */
protected $errors;
public function __construct(string $step, string $registrationId = '') {
parent::__construct($step, $registrationId);
$this->errors = [];
}
public function addError(string $error): void {
$this->errors[] = $error;
}
public function getErrors(): array {
return $this->errors;
}
}