diff --git a/lib/Controller/RegisterController.php b/lib/Controller/RegisterController.php index 51bfdb7..7211645 100644 --- a/lib/Controller/RegisterController.php +++ b/lib/Controller/RegisterController.php @@ -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); diff --git a/lib/Events/AFormEvent.php b/lib/Events/AFormEvent.php new file mode 100644 index 0000000..7566f47 --- /dev/null +++ b/lib/Events/AFormEvent.php @@ -0,0 +1,53 @@ + + * + * @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 . + * + */ + +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; + } +} diff --git a/lib/Events/PassedFormEvent.php b/lib/Events/PassedFormEvent.php new file mode 100644 index 0000000..0fead42 --- /dev/null +++ b/lib/Events/PassedFormEvent.php @@ -0,0 +1,42 @@ + + * + * @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 . + * + */ + +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; + } +} diff --git a/lib/Events/ShowFormEvent.php b/lib/Events/ShowFormEvent.php new file mode 100644 index 0000000..764f381 --- /dev/null +++ b/lib/Events/ShowFormEvent.php @@ -0,0 +1,28 @@ + + * + * @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 . + * + */ + +namespace OCA\Registration\Events; + +class ShowFormEvent extends AFormEvent { +} diff --git a/lib/Events/ValidateFormEvent.php b/lib/Events/ValidateFormEvent.php new file mode 100644 index 0000000..217c551 --- /dev/null +++ b/lib/Events/ValidateFormEvent.php @@ -0,0 +1,44 @@ + + * + * @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 . + * + */ + +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; + } +}