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');
+
+
+
+
+
+
+
+
+
+
-
-
-
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
-
+