From d140ee8d77b548108eb5ef65253b4bbd2de948a3 Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Wed, 31 Mar 2021 15:26:03 +0200 Subject: [PATCH] Add phone and display name field Signed-off-by: Joas Schilling --- css/style.css | 16 +++-- lib/Controller/RegisterController.php | 25 ++++--- lib/Service/RegistrationService.php | 100 +++++++++++++++++++++----- templates/form/user.php | 42 ++++++++--- 4 files changed, 145 insertions(+), 38 deletions(-) diff --git a/css/style.css b/css/style.css index b279483..c4f6e23 100644 --- a/css/style.css +++ b/css/style.css @@ -1,13 +1,17 @@ #body-login #email, #body-login #token, -#body-login #username, +#body-login #loginname, +#body-login #fullname, +#body-login #phone, #body-login #password { width: calc(100% - 56px); padding-left: 36px; } #email-icon, #token-icon, -#username-icon, +#loginname-icon, +#fullname-icon, +#phone-icon, #password-icon { position: absolute; left: 16px; @@ -16,8 +20,8 @@ filter: alpha(opacity=30); opacity: .3; } -#username-icon { - top: 17px; +#email-icon { + top: 27px; } input[type="submit"] { @@ -41,3 +45,7 @@ input[type="submit"] { .groupofone { position: relative; } + +.toggle-password { + top: 22px !important; +} diff --git a/lib/Controller/RegisterController.php b/lib/Controller/RegisterController.php index e495203..45d1f32 100644 --- a/lib/Controller/RegisterController.php +++ b/lib/Controller/RegisterController.php @@ -214,11 +214,13 @@ class RegisterController extends Controller { * * @param string $secret * @param string $token - * @param string $username + * @param string $loginname + * @param string $fullname + * @param string $phone * @param string $message * @return TemplateResponse */ - public function showUserForm(string $secret, string $token, string $username = '', string $message = ''): TemplateResponse { + public function showUserForm(string $secret, string $token, string $loginname = '', string $fullname = '', string $phone = '', string $password = '', string $message = ''): TemplateResponse { try { $registration = $this->validateSecretAndToken($secret, $token); } catch (RegistrationException $e) { @@ -230,8 +232,13 @@ class RegisterController extends Controller { return new TemplateResponse('registration', 'form/user', [ 'email' => $registration->getEmail(), 'email_is_login' => $this->config->getAppValue('registration', 'email_is_login', 'no') === 'yes', - 'username' => $username, + 'loginname' => $loginname, + 'fullname' => $fullname, + 'show_fullname' => $this->config->getAppValue('registration', 'enfore_fullname', 'no') === 'yes', + 'phone' => $phone, + 'show_phone' => $this->config->getAppValue('registration', 'enfore_phone', 'no') === 'yes', 'message' => $message, + 'password' => $password, 'additional_hint' => $additional_hint, ], 'guest'); } @@ -243,11 +250,13 @@ class RegisterController extends Controller { * * @param string $secret * @param string $token - * @param string $username + * @param string $loginname + * @param string $fullname + * @param string $phone * @param string $password * @return RedirectResponse|TemplateResponse */ - public function submitUserForm(string $secret, string $token, string $username, string $password): Response { + public function submitUserForm(string $secret, string $token, string $loginname, string $fullname, string $phone, string $password): Response { try { $registration = $this->validateSecretAndToken($secret, $token); } catch (RegistrationException $e) { @@ -255,13 +264,13 @@ class RegisterController extends Controller { } if ($this->config->getAppValue('registration', 'email_is_login', 'no') === 'yes') { - $username = $registration->getEmail(); + $loginname = $registration->getEmail(); } try { - $user = $this->registrationService->createAccount($registration, $username, $password); + $user = $this->registrationService->createAccount($registration, $loginname, $fullname, $phone, $password); } catch (Exception $exception) { - return $this->showUserForm($secret, $token, $username, $exception->getMessage()); + return $this->showUserForm($secret, $token, $loginname, $fullname, $phone, $password, $exception->getMessage()); } // Delete registration diff --git a/lib/Service/RegistrationService.php b/lib/Service/RegistrationService.php index 6d9ff14..89a225c 100644 --- a/lib/Service/RegistrationService.php +++ b/lib/Service/RegistrationService.php @@ -30,6 +30,10 @@ declare(strict_types=1); namespace OCA\Registration\Service; +use InvalidArgumentException; +use libphonenumber\NumberParseException; +use libphonenumber\PhoneNumber; +use libphonenumber\PhoneNumberUtil; use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Exceptions\PasswordlessTokenException; use OC\Authentication\Token\IProvider; @@ -37,6 +41,7 @@ use OC\Authentication\Token\IToken; use OCA\Registration\AppInfo\Application; use OCA\Registration\Db\Registration; use OCA\Registration\Db\RegistrationMapper; +use OCP\Accounts\IAccountManager; use OCP\AppFramework\Db\DoesNotExistException; use OCP\ILogger; use OCP\IRequest; @@ -66,6 +71,8 @@ class RegistrationService { private $registrationMapper; /** @var IUserManager */ private $userManager; + /** @var IAccountManager */ + private $accountManager; /** @var IConfig */ private $config; /** @var IGroupManager */ @@ -92,6 +99,7 @@ class RegistrationService { IURLGenerator $urlGenerator, RegistrationMapper $registrationMapper, IUserManager $userManager, + IAccountManager $accountManager, IConfig $config, IGroupManager $groupManager, ISecureRandom $random, @@ -108,6 +116,7 @@ class RegistrationService { $this->urlGenerator = $urlGenerator; $this->registrationMapper = $registrationMapper; $this->userManager = $userManager; + $this->accountManager = $accountManager; $this->config = $config; $this->groupManager = $groupManager; $this->random = $random; @@ -229,17 +238,44 @@ class RegistrationService { * @throws RegistrationException */ public function validateUsername(string $username): void { - if ($username === "") { - throw new RegistrationException($this->l10n->t('Please provide a valid user name.')); + if ($username === '') { + throw new RegistrationException($this->l10n->t('Please provide a valid login name.')); } $regex = $this->config->getAppValue($this->appName, 'username_policy_regex', ''); if ($regex && preg_match($regex, $username) === 0) { - throw new RegistrationException($this->l10n->t('Please provide a valid user name.')); + throw new RegistrationException($this->l10n->t('Please provide a valid login name.')); } if ($this->registrationMapper->usernameIsPending($username) || $this->userManager->get($username) !== null) { - throw new RegistrationException($this->l10n->t('The username you have chosen already exists.')); + throw new RegistrationException($this->l10n->t('The login name you have chosen already exists.')); + } + } + + /** + * @param string $phone + * @throws RegistrationException + */ + public function validatePhoneNumber(string $phone): void { + $defaultRegion = $this->config->getSystemValueString('default_phone_region', ''); + + if ($defaultRegion === '') { + // When no default region is set, only +49… numbers are valid + if (strpos($phone, '+') !== 0) { + throw new RegistrationException($this->l10n->t('The phone number needs to contain the country code.')); + } + + $defaultRegion = 'EN'; + } + + $phoneUtil = PhoneNumberUtil::getInstance(); + try { + $phoneNumber = $phoneUtil->parse($phone, $defaultRegion); + if (!$phoneNumber instanceof PhoneNumber || !$phoneUtil->isValidNumber($phoneNumber)) { + throw new RegistrationException($this->l10n->t('The phone number is invalid.')); + } + } catch (NumberParseException $e) { + throw new RegistrationException($this->l10n->t('The phone number is invalid.')); } } @@ -290,41 +326,53 @@ class RegistrationService { } /** - * @param $registration - * @param string|null $username + * @param Registration $registration + * @param string|null $loginName + * @param string|null $fullName + * @param string|null $phone * @param string|null $password * @return IUser - * @throws RegistrationException|InvalidTokenException + * @throws RegistrationException|InvalidArgumentException */ - public function createAccount(Registration $registration, ?string $username = null, ?string $password = null): IUser { - if ($password === null && $registration->getPassword() === null) { - $generatedPassword = $this->generateRandomDeviceToken(); - $registration->setPassword($this->crypto->encrypt($generatedPassword)); - } - - if ($username === null) { - $username = $registration->getUsername(); + public function createAccount(Registration $registration, ?string $loginName = null, ?string $fullName = null, ?string $phone = null, ?string $password = null): IUser { + if ($loginName === null) { + $loginName = $registration->getUsername(); } if ($registration->getPassword() !== null) { $password = $this->crypto->decrypt($registration->getPassword()); } - $this->validateUsername($username); + if (!$password) { + throw new RegistrationException($this->l10n->t('Please provide a password.')); + } + + $this->validateUsername($loginName); + + if ($this->config->getAppValue('registration', 'enfore_fullname', 'no') === 'yes') { + $this->validateDisplayname($fullName); + } + + if ($phone) { + $this->validatePhoneNumber($phone); + } elseif ($this->config->getAppValue('registration', 'enfore_phone', 'no') === 'yes') { + throw new RegistrationException($this->l10n->t('Please provide a valid phone number.')); + } /* TODO * createUser tests username validity once, but validateUsername already checked it, * but createUser doesn't check if there is a pending registration with that name * * And validateUsername will throw RegistrationException while - * createUser throws \InvalidTokenException in NC, \Exception in OC + * createUser throws \InvalidArgumentException */ - $user = $this->userManager->createUser($username, $password); + $user = $this->userManager->createUser($loginName, $password); if ($user === false) { throw new RegistrationException($this->l10n->t('Unable to create user, there are problems with the user backend.')); } $userId = $user->getUID(); + // Set user email try { $user->setEMailAddress($registration->getEmail()); @@ -332,6 +380,22 @@ class RegistrationService { throw new RegistrationException($this->l10n->t('Unable to set user email: ' . $e->getMessage())); } + // Set display name + if ($fullName) { + $user->setDisplayName($fullName); + } + + // Set phone number in account data + $account = $this->accountManager->getAccount($user); + $property = $account->getProperty(IAccountManager::PROPERTY_PHONE); + $account->setProperty( + IAccountManager::PROPERTY_PHONE, + $phone, + $property->getScope(), + IAccountManager::NOT_VERIFIED + ); + $this->accountManager->updateAccount($account); + // Add user to group $registeredUserGroup = $this->config->getAppValue($this->appName, 'registered_user_group', 'none'); if ($registeredUserGroup !== 'none') { diff --git a/templates/form/user.php b/templates/form/user.php index 1f953a1..5449def 100644 --- a/templates/form/user.php +++ b/templates/form/user.php @@ -19,7 +19,7 @@ script('registration', 'form'); + @@ -30,19 +30,45 @@ script('registration', 'form');

+

+ + + +

+ + + + +

- - - + + +

- + + + + +

+ + + +

+ +

- +