Merge pull request #26760 from nextcloud/backport/26259/stable21

[stable21] Validate the website field input to be a valid URL
This commit is contained in:
Roeland Jago Douma 2021-04-26 20:42:06 +02:00 committed by GitHub
commit 4082318616
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 59 additions and 0 deletions

View File

@ -491,6 +491,9 @@ class UsersController extends Controller {
if ($e->getMessage() === IAccountManager::PROPERTY_PHONE) { if ($e->getMessage() === IAccountManager::PROPERTY_PHONE) {
throw new \InvalidArgumentException($this->l10n->t('Unable to set invalid phone number')); throw new \InvalidArgumentException($this->l10n->t('Unable to set invalid phone number'));
} }
if ($e->getMessage() === IAccountManager::PROPERTY_WEBSITE) {
throw new \InvalidArgumentException($this->l10n->t('Unable to set invalid website'));
}
throw new \InvalidArgumentException($this->l10n->t('Some account data was invalid')); throw new \InvalidArgumentException($this->l10n->t('Some account data was invalid'));
} }
} }

View File

@ -120,6 +120,25 @@ class AccountManager implements IAccountManager {
throw new \InvalidArgumentException(self::PROPERTY_PHONE); throw new \InvalidArgumentException(self::PROPERTY_PHONE);
} }
/**
*
* @param string $input
* @return string
* @throws \InvalidArgumentException When the website did not have http(s) as protocol or the host name was empty
*/
protected function parseWebsite(string $input): string {
$parts = parse_url($input);
if (!isset($parts['scheme']) || ($parts['scheme'] !== 'https' && $parts['scheme'] !== 'http')) {
throw new \InvalidArgumentException(self::PROPERTY_WEBSITE);
}
if (!isset($parts['host']) || $parts['host'] === '') {
throw new \InvalidArgumentException(self::PROPERTY_WEBSITE);
}
return $input;
}
/** /**
* update user record * update user record
* *
@ -155,6 +174,17 @@ class AccountManager implements IAccountManager {
} }
} }
if (isset($data[self::PROPERTY_WEBSITE]) && $data[self::PROPERTY_WEBSITE]['value'] !== '') {
try {
$data[self::PROPERTY_WEBSITE]['value'] = $this->parseWebsite($data[self::PROPERTY_WEBSITE]['value']);
} catch (\InvalidArgumentException $e) {
if ($throwOnData) {
throw $e;
}
$data[self::PROPERTY_WEBSITE]['value'] = '';
}
}
$allowedScopes = [ $allowedScopes = [
self::SCOPE_PRIVATE, self::SCOPE_PRIVATE,
self::SCOPE_LOCAL, self::SCOPE_LOCAL,

View File

@ -455,4 +455,30 @@ class AccountManagerTest extends TestCase {
self::assertEquals($phoneNumber, self::invokePrivate($instance, 'parsePhoneNumber', [$phoneInput])); self::assertEquals($phoneNumber, self::invokePrivate($instance, 'parsePhoneNumber', [$phoneInput]));
} }
} }
public function dataParseWebsite(): array {
return [
['https://nextcloud.com', 'https://nextcloud.com'],
['http://nextcloud.com', 'http://nextcloud.com'],
['ftp://nextcloud.com', null],
['//nextcloud.com/', null],
['https:///?query', null],
];
}
/**
* @dataProvider dataParseWebsite
* @param string $websiteInput
* @param string|null $websiteOutput
*/
public function testParseWebsite(string $websiteInput, ?string $websiteOutput): void {
$instance = $this->getInstance();
if ($websiteOutput === null) {
$this->expectException(\InvalidArgumentException::class);
self::invokePrivate($instance, 'parseWebsite', [$websiteInput]);
} else {
self::assertEquals($websiteOutput, self::invokePrivate($instance, 'parseWebsite', [$websiteInput]));
}
}
} }