aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--apps/settings/lib/Controller/CheckSetupController.php1
-rw-r--r--apps/settings/tests/Controller/CheckSetupControllerTest.php1
-rw-r--r--build/integration/features/provisioning-v1.feature4
-rw-r--r--config/config.sample.php10
-rw-r--r--core/js/setupchecks.js6
-rw-r--r--core/js/tests/specs/setupchecksSpec.js69
-rw-r--r--lib/private/Accounts/AccountManager.php48
7 files changed, 125 insertions, 14 deletions
diff --git a/apps/settings/lib/Controller/CheckSetupController.php b/apps/settings/lib/Controller/CheckSetupController.php
index 7929e9c3962..1ebeb41adfb 100644
--- a/apps/settings/lib/Controller/CheckSetupController.php
+++ b/apps/settings/lib/Controller/CheckSetupController.php
@@ -752,6 +752,7 @@ Raw output
PhpOutputBuffering::class => ['pass' => $phpOutputBuffering->run(), 'description' => $phpOutputBuffering->description(), 'severity' => $phpOutputBuffering->severity()],
LegacySSEKeyFormat::class => ['pass' => $legacySSEKeyFormat->run(), 'description' => $legacySSEKeyFormat->description(), 'severity' => $legacySSEKeyFormat->severity(), 'linkToDocumentation' => $legacySSEKeyFormat->linkToDocumentation()],
CheckUserCertificates::class => ['pass' => $checkUserCertificates->run(), 'description' => $checkUserCertificates->description(), 'severity' => $checkUserCertificates->severity(), 'elements' => $checkUserCertificates->elements()],
+ 'isDefaultPhoneRegionSet' => $this->config->getSystemValueString('default_phone_region', '') !== '',
]
);
}
diff --git a/apps/settings/tests/Controller/CheckSetupControllerTest.php b/apps/settings/tests/Controller/CheckSetupControllerTest.php
index 43ec984041c..965d7586343 100644
--- a/apps/settings/tests/Controller/CheckSetupControllerTest.php
+++ b/apps/settings/tests/Controller/CheckSetupControllerTest.php
@@ -605,6 +605,7 @@ class CheckSetupControllerTest extends TestCase {
'OCA\Settings\SetupChecks\LegacySSEKeyFormat' => ['pass' => true, 'description' => 'The old server-side-encryption format is enabled. We recommend disabling this.', 'severity' => 'warning', 'linkToDocumentation' => ''],
'OCA\Settings\SetupChecks\CheckUserCertificates' => ['pass' => false, 'description' => 'There are some user imported SSL certificates present, that are not used anymore with Nextcloud 21. They can be imported on the command line via "occ security:certificates:import" command. Their paths inside the data directory are shown below.', 'severity' => 'warning', 'elements' => ['a', 'b']],
'imageMagickLacksSVGSupport' => false,
+ 'isDefaultPhoneRegionSet' => false,
]
);
$this->assertEquals($expected, $this->checkSetupController->check());
diff --git a/build/integration/features/provisioning-v1.feature b/build/integration/features/provisioning-v1.feature
index eefaa574e03..123e58a869c 100644
--- a/build/integration/features/provisioning-v1.feature
+++ b/build/integration/features/provisioning-v1.feature
@@ -76,7 +76,7 @@ Feature: provisioning
And the HTTP status code should be "200"
And sending "PUT" to "/cloud/users/brand-new-user" with
| key | phone |
- | value | 0711 / 25 24 28-90 |
+ | value | +49 711 / 25 24 28-90 |
And the OCS status code should be "100"
And the HTTP status code should be "200"
And sending "PUT" to "/cloud/users/brand-new-user" with
@@ -108,7 +108,7 @@ Feature: provisioning
And user "phone-user" exists
And sending "PUT" to "/cloud/users/phone-user" with
| key | phone |
- | value | 0711 / 25 24 28-90 |
+ | value | +49 711 / 25 24 28-90 |
And the OCS status code should be "100"
And the HTTP status code should be "200"
Then search users by phone for region "DE" with
diff --git a/config/config.sample.php b/config/config.sample.php
index 2710fbf5fdb..8adb5bf2168 100644
--- a/config/config.sample.php
+++ b/config/config.sample.php
@@ -195,6 +195,16 @@ $CONFIG = [
'default_locale' => 'en_US',
/**
+ * This sets the default region for phone numbers on your Nextcloud server,
+ * using ISO 3166-1 country codes such as ``DE`` for Germany, ``FR`` for France, …
+ * It is required to allow inserting phone numbers in the user profiles starting
+ * without the country code (e.g. +49 for Germany).
+ *
+ * No default value!
+ */
+'default_phone_region' => 'EN',
+
+/**
* With this setting a locale can be forced for all users. If a locale is
* forced, the users are also unable to change their locale in the personal
* settings. If users shall be unable to change their locale, but users have
diff --git a/core/js/setupchecks.js b/core/js/setupchecks.js
index 214f148fa94..22c8589f73b 100644
--- a/core/js/setupchecks.js
+++ b/core/js/setupchecks.js
@@ -216,6 +216,12 @@
type: OC.SetupChecks.MESSAGE_TYPE_WARNING
});
}
+ if (!data.isDefaultPhoneRegionSet) {
+ messages.push({
+ msg: t('core', 'Your installation has no default phone region set. This is required to be able to validate phone numbers in the profile settings without a country code. To allow numbers without a country code, please add "default_phone_region" with the respective ISO 3166-1 code of the wished region.'),
+ type: OC.SetupChecks.MESSAGE_TYPE_INFO
+ });
+ }
if (data.cronErrors.length > 0) {
var listOfCronErrors = "";
data.cronErrors.forEach(function(element){
diff --git a/core/js/tests/specs/setupchecksSpec.js b/core/js/tests/specs/setupchecksSpec.js
index a0a3c2a4ba9..c3cddb88a9d 100644
--- a/core/js/tests/specs/setupchecksSpec.js
+++ b/core/js/tests/specs/setupchecksSpec.js
@@ -251,6 +251,7 @@ describe('OC.SetupChecks tests', function() {
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
+ isDefaultPhoneRegionSet: true,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true,
reverseProxyGeneratedURL: 'https://server',
})
@@ -306,6 +307,7 @@ describe('OC.SetupChecks tests', function() {
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
+ isDefaultPhoneRegionSet: true,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true,
reverseProxyGeneratedURL: 'https://server',
})
@@ -362,6 +364,7 @@ describe('OC.SetupChecks tests', function() {
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
+ isDefaultPhoneRegionSet: true,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true,
reverseProxyGeneratedURL: 'https://server',
})
@@ -416,6 +419,7 @@ describe('OC.SetupChecks tests', function() {
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
+ isDefaultPhoneRegionSet: true,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true,
reverseProxyGeneratedURL: 'https://server',
})
@@ -468,6 +472,7 @@ describe('OC.SetupChecks tests', function() {
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
+ isDefaultPhoneRegionSet: true,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true,
reverseProxyGeneratedURL: 'https://server',
})
@@ -522,6 +527,7 @@ describe('OC.SetupChecks tests', function() {
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
+ isDefaultPhoneRegionSet: true,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true,
reverseProxyGeneratedURL: 'https://server',
})
@@ -574,6 +580,7 @@ describe('OC.SetupChecks tests', function() {
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
+ isDefaultPhoneRegionSet: true,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true,
reverseProxyGeneratedURL: 'https://server',
})
@@ -626,6 +633,7 @@ describe('OC.SetupChecks tests', function() {
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
+ isDefaultPhoneRegionSet: true,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true,
reverseProxyGeneratedURL: 'https://server',
})
@@ -678,6 +686,7 @@ describe('OC.SetupChecks tests', function() {
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
+ isDefaultPhoneRegionSet: true,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true,
reverseProxyGeneratedURL: 'https://server',
})
@@ -751,6 +760,7 @@ describe('OC.SetupChecks tests', function() {
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
+ isDefaultPhoneRegionSet: true,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true,
reverseProxyGeneratedURL: 'https://server',
})
@@ -804,6 +814,7 @@ describe('OC.SetupChecks tests', function() {
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
+ isDefaultPhoneRegionSet: true,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true,
reverseProxyGeneratedURL: 'https://server',
})
@@ -857,6 +868,7 @@ describe('OC.SetupChecks tests', function() {
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
+ isDefaultPhoneRegionSet: true,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true,
reverseProxyGeneratedURL: 'https://server',
})
@@ -910,6 +922,7 @@ describe('OC.SetupChecks tests', function() {
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
+ isDefaultPhoneRegionSet: true,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true,
reverseProxyGeneratedURL: 'https://server',
})
@@ -962,6 +975,7 @@ describe('OC.SetupChecks tests', function() {
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: true,
+ isDefaultPhoneRegionSet: true,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true,
reverseProxyGeneratedURL: 'https://server',
})
@@ -1014,6 +1028,7 @@ describe('OC.SetupChecks tests', function() {
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
+ isDefaultPhoneRegionSet: true,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true,
reverseProxyDocs: 'https://docs.nextcloud.com/foo/bar.html',
reverseProxyGeneratedURL: 'http://server',
@@ -1067,6 +1082,7 @@ describe('OC.SetupChecks tests', function() {
recommendedPHPModules: [],
pendingBigIntConversionColumns: [],
isMysqlUsedWithoutUTF8MB4: false,
+ isDefaultPhoneRegionSet: true,
isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: false,
reverseProxyGeneratedURL: 'https://server',
})
@@ -1080,6 +1096,59 @@ describe('OC.SetupChecks tests', function() {
done();
});
});
+
+ it('should return an info if there is no default phone region', function(done) {
+ var async = OC.SetupChecks.checkSetup();
+
+ suite.server.requests[0].respond(
+ 200,
+ {
+ 'Content-Type': 'application/json',
+ },
+ JSON.stringify({
+ hasFileinfoInstalled: true,
+ isGetenvServerWorking: true,
+ isReadOnlyConfig: false,
+ hasWorkingFileLocking: true,
+ hasValidTransactionIsolationLevel: true,
+ suggestedOverwriteCliURL: '',
+ isRandomnessSecure: true,
+ securityDocs: 'https://docs.owncloud.org/myDocs.html',
+ serverHasInternetConnectionProblems: false,
+ isMemcacheConfigured: true,
+ forwardedForHeadersWorking: true,
+ isCorrectMemcachedPHPModuleInstalled: true,
+ hasPassedCodeIntegrityCheck: true,
+ isOpcacheProperlySetup: true,
+ hasOpcacheLoaded: true,
+ isSettimelimitAvailable: true,
+ hasFreeTypeSupport: true,
+ missingIndexes: [],
+ missingPrimaryKeys: [],
+ missingColumns: [],
+ cronErrors: [],
+ cronInfo: {
+ diffInSeconds: 0
+ },
+ isMemoryLimitSufficient: true,
+ appDirsWithDifferentOwner: [],
+ recommendedPHPModules: [],
+ pendingBigIntConversionColumns: [],
+ isMysqlUsedWithoutUTF8MB4: false,
+ isDefaultPhoneRegionSet: false,
+ isEnoughTempSpaceAvailableIfS3PrimaryStorageIsUsed: true,
+ reverseProxyGeneratedURL: 'https://server',
+ })
+ );
+
+ async.done(function( data, s, x ){
+ expect(data).toEqual([{
+ msg: 'Your installation has no default phone region set. This is required to be able to validate phone numbers in the profile settings without a country code. To allow numbers without a country code, please add "default_phone_region" with the respective ISO 3166-1 code of the wished region.',
+ type: OC.SetupChecks.MESSAGE_TYPE_INFO
+ }]);
+ done();
+ });
+ });
});
describe('checkGeneric', function() {
diff --git a/lib/private/Accounts/AccountManager.php b/lib/private/Accounts/AccountManager.php
index 4f4a146bdd9..8640ce269ea 100644
--- a/lib/private/Accounts/AccountManager.php
+++ b/lib/private/Accounts/AccountManager.php
@@ -39,6 +39,7 @@ use OCP\Accounts\IAccount;
use OCP\Accounts\IAccountManager;
use OCP\BackgroundJob\IJobList;
use OCP\DB\QueryBuilder\IQueryBuilder;
+use OCP\IConfig;
use OCP\IDBConnection;
use OCP\IUser;
use Psr\Log\LoggerInterface;
@@ -60,6 +61,9 @@ class AccountManager implements IAccountManager {
/** @var IDBConnection database connection */
private $connection;
+ /** @var IConfig */
+ private $config;
+
/** @var string table name */
private $table = 'accounts';
@@ -76,16 +80,47 @@ class AccountManager implements IAccountManager {
private $logger;
public function __construct(IDBConnection $connection,
+ IConfig $config,
EventDispatcherInterface $eventDispatcher,
IJobList $jobList,
LoggerInterface $logger) {
$this->connection = $connection;
+ $this->config = $config;
$this->eventDispatcher = $eventDispatcher;
$this->jobList = $jobList;
$this->logger = $logger;
}
/**
+ * @param string $input
+ * @return string Provided phone number in E.164 format when it was a valid number
+ * @throws \InvalidArgumentException When the phone number was invalid or no default region is set and the number doesn't start with a country code
+ */
+ protected function parsePhoneNumber(string $input): string {
+ $defaultRegion = $this->config->getSystemValueString('default_phone_region', '');
+
+ if ($defaultRegion === '') {
+ // When no default region is set, only +49… numbers are valid
+ if (strpos($input, '+') !== 0) {
+ throw new \InvalidArgumentException(self::PROPERTY_PHONE);
+ }
+
+ $defaultRegion = 'EN';
+ }
+
+ $phoneUtil = PhoneNumberUtil::getInstance();
+ try {
+ $phoneNumber = $phoneUtil->parse($input, $defaultRegion);
+ if ($phoneNumber instanceof PhoneNumber && $phoneUtil->isValidNumber($phoneNumber)) {
+ return $phoneUtil->format($phoneNumber, PhoneNumberFormat::E164);
+ }
+ } catch (NumberParseException $e) {
+ }
+
+ throw new \InvalidArgumentException(self::PROPERTY_PHONE);
+ }
+
+ /**
* update user record
*
* @param IUser $user
@@ -98,18 +133,7 @@ class AccountManager implements IAccountManager {
$updated = true;
if (isset($data[self::PROPERTY_PHONE])) {
- $phoneUtil = PhoneNumberUtil::getInstance();
- try {
- $phoneValue = $data[self::PROPERTY_PHONE]['value'];
- $phoneNumber = $phoneUtil->parse($phoneValue, 'DE'); // FIXME need a reasonable default
- if ($phoneNumber instanceof PhoneNumber && $phoneUtil->isValidNumber($phoneNumber)) {
- $data[self::PROPERTY_PHONE]['value'] = $phoneUtil->format($phoneNumber, PhoneNumberFormat::E164);
- } else {
- throw new \InvalidArgumentException(self::PROPERTY_PHONE);
- }
- } catch (NumberParseException $e) {
- throw new \InvalidArgumentException(self::PROPERTY_PHONE);
- }
+ $data[self::PROPERTY_PHONE]['value'] = $this->parsePhoneNumber($data[self::PROPERTY_PHONE]['value']);
}
if (empty($userData)) {