From 9bdf377aecc7ea1e11d60451e9d2c5a4a89157eb Mon Sep 17 00:00:00 2001 From: Joas Schilling Date: Fri, 28 Aug 2020 20:30:01 +0200 Subject: [PATCH] Add settings for blocklist and showing the domain list Signed-off-by: Joas Schilling --- lib/Controller/RegisterController.php | 20 ++++- lib/Controller/SettingsController.php | 14 +++- lib/Service/RegistrationService.php | 40 +++++++-- lib/Settings/RegistrationSettings.php | 7 +- templates/admin.php | 16 +++- .../Service/RegistrationServiceTest.php | 83 ++++++++++--------- 6 files changed, 127 insertions(+), 53 deletions(-) diff --git a/lib/Controller/RegisterController.php b/lib/Controller/RegisterController.php index 7919ff9..8d9d66d 100644 --- a/lib/Controller/RegisterController.php +++ b/lib/Controller/RegisterController.php @@ -17,6 +17,7 @@ declare(strict_types=1); namespace OCA\Registration\Controller; use Exception; +use OCA\Registration\AppInfo\Application; use OCA\Registration\Db\Registration; use OCA\Registration\Service\LoginFlowService; use OCA\Registration\Service\MailService; @@ -78,9 +79,26 @@ class RegisterController extends Controller { * @return TemplateResponse */ public function showEmailForm(string $email = '', string $message = ''): TemplateResponse { + $emailHint = ''; + if ($this->config->getAppValue(Application::APP_ID, 'show_domains', 'no') === 'yes') { + if ($this->config->getAppValue(Application::APP_ID, 'domains_is_blocklist', 'no') === 'yes') { + $emailHint = $this->l10n->t( + 'Registration is not allowed with the following domains:' + ) . ' ' . implode(', ', explode(';', + $this->config->getAppValue(Application::APP_ID, 'allowed_domains', '') + )); + } else { + $emailHint = $this->l10n->t( + 'Registration is only allowed with the following domains:' + ) . ' ' . implode(', ', explode(';', + $this->config->getAppValue(Application::APP_ID, 'allowed_domains', '') + )); + } + } + $params = [ 'email' => $email, - 'message' => $message, + 'message' => $message ?: $emailHint, ]; return new TemplateResponse('registration', 'form/email', $params, 'guest'); } diff --git a/lib/Controller/SettingsController.php b/lib/Controller/SettingsController.php index 0801e2a..889c1e2 100644 --- a/lib/Controller/SettingsController.php +++ b/lib/Controller/SettingsController.php @@ -46,9 +46,16 @@ class SettingsController extends Controller { * @param string $allowed_domains Registrations are only allowed for E-Mailadresses with these domains * @param bool|null $admin_approval_required newly registered users have to be validated by an admin * @param bool|null $email_is_login email address is forced as user id + * @param bool|null $domains_is_blocklist is the domain list an allow or block list + * @param bool|null $show_domains should the email list be shown to the user or not * @return DataResponse */ - public function admin(string $registered_user_group, string $allowed_domains, ?bool $admin_approval_required, ?bool $email_is_login) { + public function admin(string $registered_user_group, + string $allowed_domains, + ?bool $admin_approval_required, + ?bool $email_is_login, + ?bool $domains_is_blocklist, + ?bool $show_domains) { // handle domains if (($allowed_domains === '') || ($allowed_domains === null)) { $this->config->deleteAppValue($this->appName, 'allowed_domains'); @@ -56,11 +63,10 @@ class SettingsController extends Controller { $this->config->setAppValue($this->appName, 'allowed_domains', $allowed_domains); } - // handle admin validation $this->config->setAppValue($this->appName, 'admin_approval_required', $admin_approval_required ? 'yes' : 'no'); - - // handle email is login $this->config->setAppValue($this->appName, 'email_is_login', $email_is_login ? 'yes' : 'no'); + $this->config->setAppValue($this->appName, 'domains_is_blocklist', $domains_is_blocklist ? 'yes' : 'no'); + $this->config->setAppValue($this->appName, 'show_domains', $show_domains ? 'yes' : 'no'); // handle groups $groups = $this->groupmanager->search(''); diff --git a/lib/Service/RegistrationService.php b/lib/Service/RegistrationService.php index 89041db..121597c 100644 --- a/lib/Service/RegistrationService.php +++ b/lib/Service/RegistrationService.php @@ -34,6 +34,7 @@ use OC\Authentication\Exceptions\InvalidTokenException; use OC\Authentication\Exceptions\PasswordlessTokenException; use OC\Authentication\Token\IProvider; use OC\Authentication\Token\IToken; +use OCA\Registration\AppInfo\Application; use OCA\Registration\Db\Registration; use OCA\Registration\Db\RegistrationMapper; use OCP\AppFramework\Db\DoesNotExistException; @@ -174,12 +175,41 @@ class RegistrationService { ); } - if (!$this->checkAllowedDomains($email)) { + if ($this->config->getAppValue($this->appName, 'allowed_domains', '') === '') { + return; + } + + $emailIsInDomainList = $this->checkAllowedDomains($email); + $blockDomains = $this->config->getAppValue(Application::APP_ID, 'domains_is_blocklist', 'no') === 'yes'; + $showDomains = $this->config->getAppValue(Application::APP_ID, 'show_domains', 'no') === 'yes'; + + if (!$blockDomains && !$emailIsInDomainList) { + if ($showDomains) { + throw new RegistrationException( + $this->l10n->t( + 'Registration is only allowed with the following domains:' + ) . ' ' . implode(', ', explode(';', + $this->config->getAppValue(Application::APP_ID, 'allowed_domains', '') + )) + ); + } throw new RegistrationException( - $this->l10n->t( - 'Registration is only allowed for the following domains: ' . - $this->config->getAppValue($this->appName, 'allowed_domains', '') - ) + $this->l10n->t('Registration with this email domain is not allowed.') + ); + } + + if ($blockDomains && $emailIsInDomainList) { + if ($showDomains) { + throw new RegistrationException( + $this->l10n->t( + 'Registration is not allowed with the following domains:' + ) . ' ' . implode(', ', explode(';', + $this->config->getAppValue(Application::APP_ID, 'allowed_domains', '') + )) + ); + } + throw new RegistrationException( + $this->l10n->t('Registration with this email domain is not allowed.') ); } } diff --git a/lib/Settings/RegistrationSettings.php b/lib/Settings/RegistrationSettings.php index bf2fd65..42a35df 100644 --- a/lib/Settings/RegistrationSettings.php +++ b/lib/Settings/RegistrationSettings.php @@ -59,11 +59,10 @@ class RegistrationSettings implements ISettings { // handle domains $allowedDomains = $this->config->getAppValue($this->appName, 'allowed_domains', ''); - // handle admin validation $adminApprovalRequired = $this->config->getAppValue($this->appName, 'admin_approval_required', 'no'); - - // handle admin validation $emailIsLogin = $this->config->getAppValue($this->appName, 'email_is_login', 'no'); + $domainsIsBlocklist = $this->config->getAppValue($this->appName, 'domains_is_blocklist', 'no'); + $showDomains = $this->config->getAppValue($this->appName, 'show_domains', 'no'); return new TemplateResponse('registration', 'admin', [ 'groups' => $groupIds, @@ -71,6 +70,8 @@ class RegistrationSettings implements ISettings { 'allowed' => $allowedDomains, 'approval_required' => $adminApprovalRequired, 'email_is_login' => $emailIsLogin, + 'domains_is_blocklist' => $domainsIsBlocklist, + 'show_domains' => $showDomains, ], ''); } diff --git a/templates/admin.php b/templates/admin.php index c3704b1..0bb6efe 100644 --- a/templates/admin.php +++ b/templates/admin.php @@ -28,7 +28,21 @@ foreach ($_['groups'] as $group) {

- t('Enter a semicolon-separated list of allowed domains, * for wildcard. Example: %s', ['nextcloud.com;*.example.com']));?> + t('Enter a semicolon-separated list of allowed email domains, * for wildcard. Example: %s', ['nextcloud.com;*.example.com']));?> + +

+ > + +

+ +

+ > + +

config->expects($this->once()) + public function testValidateEmail(string $email, string $allowedDomains, string $blocked) { + $this->config->expects($this->atLeastOnce()) ->method('getAppValue') - ->with('registration', 'allowed_domains', '') - ->willReturn($allowedDomains); + ->willReturnMap([ + ['registration', 'allowed_domains', '', $allowedDomains], + ['registration', 'domains_is_blocklist', 'no', $blocked], + ['registration', 'show_domains', 'no', 'no'], + ]); $this->service->validateEmail($email); } - public function testValidateNewEmailNotWithinAllowedDomain() { - $email2 = 'bbbb@gmail.com'; + public function dataValidateEmailThrows(): array { + return [ + ['aaaa@example.com', 'nextcloud.com;example.tld', 'no'], + ['aaaa@example.com', 'nextcloud.com', 'no'], - $this->config->expects($this->atLeastOnce()) - ->method('getAppValue') - ->with('registration', 'allowed_domains', '') - ->willReturn('example.com'); - - $this->expectException(RegistrationException::class); - $this->service->validateEmail($email2); - } - - public function testValidateNewEmailWithinMultipleAllowedDomain() { - $email = 'aaaa@example.com'; - $email2 = 'bbbb@gmail.com'; - - $this->config->expects($this->atLeastOnce()) - ->method('getAppValue') - ->with('registration', 'allowed_domains', '') - ->willReturn('example.com;gmail.com'); - - $this->service->validateEmail($email); - $this->service->validateEmail($email2); + ['aaaa@example.com', 'example.com', 'yes'], + ['aaaa@example.com', 'eXample.com', 'yes'], + ['aaaa@eXample.com', 'example.com', 'yes'], + ['aaaa@example.com', 'example.com;example.tld', 'yes'], + ['aaaa@example.com', 'example.tld;example.com', 'yes'], + ['aaaa@cloud.example.com', '*.example.com', 'yes'], + ['aaaa@cloud.example.com', 'cloud.example.*', 'yes'], + ]; } /** - * @depends testValidateNewEmailWithinMultipleAllowedDomain + * @dataProvider dataValidateEmailThrows + * @param string $email + * @param string $allowedDomains + * @param string $blocked + * @throws RegistrationException */ - public function testValidateNewEmailNotWithinMultipleAllowedDomain() { - $email2 = 'cccc@yahoo.com'; - + public function testValidateEmailThrows(string $email, string $allowedDomains, string $blocked) { $this->config->expects($this->atLeastOnce()) ->method('getAppValue') - ->with('registration', 'allowed_domains', '') - ->willReturn('example.com;gmail.com'); + ->willReturnMap([ + ['registration', 'allowed_domains', '', $allowedDomains], + ['registration', 'domains_is_blocklist', 'no', $blocked], + ['registration', 'show_domains', 'no', 'no'], + ]); $this->expectException(RegistrationException::class); - $this->service->validateEmail($email2); + $this->service->validateEmail($email); } public function testCreatePendingReg() {