diff --git a/appinfo/info.xml b/appinfo/info.xml index e6f7fd124363990e703b50dda59af8d319e09d81..b3a4c439615daa56d8f8bfb4153ce22d60bc88c0 100644 --- a/appinfo/info.xml +++ b/appinfo/info.xml @@ -25,6 +25,7 @@ OCA\EcloudAccounts\Settings\BetaSection + OCA\EcloudAccounts\Command\UpdateBlacklistedDomains OCA\EcloudAccounts\Command\Migrate2FASecrets OCA\EcloudAccounts\Command\MigrateWebmailAddressbooks OCA\EcloudAccounts\Command\MapActiveAttributetoLDAP diff --git a/lib/Command/UpdateBlacklistedDomains.php b/lib/Command/UpdateBlacklistedDomains.php new file mode 100644 index 0000000000000000000000000000000000000000..74bc1642c188e927c5fe1ac38f3adcd84fdee38c --- /dev/null +++ b/lib/Command/UpdateBlacklistedDomains.php @@ -0,0 +1,39 @@ +blackListService = $blackListService; + $this->logger = $logger; + } + + protected function configure() { + $this->setName(Application::APP_ID.':update-blacklisted-domains')->setDescription('Update blacklisted domains'); + } + + protected function execute(InputInterface $input, OutputInterface $output): int { + try { + $this->blackListService->updateBlacklistedDomains(); + $output->writeln('Updated blacklisted domains for creation.'); + } catch (\Throwable $th) { + $this->logger->error('Error while updating blacklisted domains. ' . $th->getMessage()); + $output->writeln('Error while updating blacklisted domains. '. $th->getMessage()); + } + return 1; + } +} diff --git a/lib/Service/BlackListService.php b/lib/Service/BlackListService.php new file mode 100644 index 0000000000000000000000000000000000000000..ba9d0a219f91970540371d6915e72c96fea728a7 --- /dev/null +++ b/lib/Service/BlackListService.php @@ -0,0 +1,118 @@ +appData = $appData; + $this->logger = $logger; + } + + /** + * Check if an email domain is blacklisted against a JSON list of disposable email domains. + * + * @param string $email The email address to check. + * @return bool True if the email domain is blacklisted, false otherwise. + */ + public function isBlacklistedEmail(string $email): bool { + if (!$this->ensureDocumentsFolder()) { + return false; + } + $blacklistedDomains = $this->getBlacklistedDomainData(); + if (empty($blacklistedDomains)) { + return false; + } + $emailParts = explode('@', $email); + $emailDomain = strtolower(end($emailParts)); + return in_array($emailDomain, $blacklistedDomains); + } + /** + * Update the blacklisted domains data by fetching it from a URL and saving it locally. + * + * @return void + */ + public function updateBlacklistedDomains(): void { + $blacklisted_domain_url = self::BLACKLISTED_DOMAINS_URL; + $json_data = file_get_contents($blacklisted_domain_url); + $this->setBlacklistedDomainsData($json_data); + } + /** + * Store blacklisted domain data in a file within AppData. + * + * @param string $data The data to be stored in the file. + * @return void + */ + private function setBlacklistedDomainsData(string $data): void { + $file = $this->getBlacklistedDomainsFile(); + $file->putContent($data); + } + /** + * Retrieve the blacklisted domain file path + * + * @return ISimpleFile + */ + private function getBlacklistedDomainsFile(): ISimpleFile { + try { + $currentFolder = $this->appData->getFolder('/'); + } catch (NotFoundException $e) { + $currentFolder = $this->appData->newFolder('/'); + } + $filename = self::BLACKLISTED_DOMAINS_FILE_NAME; + if ($currentFolder->fileExists($filename)) { + return $currentFolder->getFile($filename); + } + return $currentFolder->newFile($filename); + } + /** + * Retrieve the blacklisted domain data. + * + * @return array The array of blacklisted domains. + */ + public function getBlacklistedDomainData(): array { + $document = self::BLACKLISTED_DOMAINS_FILE_NAME; + $file = $this->getBlacklistedDomainsFile(); + try { + $blacklistedDomainsInJson = $file->getContent(); + if (empty($blacklistedDomainsInJson)) { + return []; + } + return json_decode($blacklistedDomainsInJson, true, 512, JSON_THROW_ON_ERROR); + } catch (NotFoundException $e) { + $this->logger->warning('Blacklisted domains file ' . $document . ' not found!'); + return []; + } catch (\Throwable $e) { + $this->logger->warning('Error decoding blacklisted domains file ' . $document . ': ' . $e->getMessage()); + return []; + } + } + + /** + * Ensure the specified folder exists within AppData. + * + * @return bool + */ + private function ensureDocumentsFolder(): bool { + try { + $this->appData->getFolder('/'); + } catch (NotFoundException $e) { + $this->logger->error(Application::APP_ID . ' AppData folder not found!'); + return false; + } catch (\RuntimeException $e) { + $this->logger->error(Application::APP_ID . ' AppData folder not found! Runtime Error: '.$e->getMessage()); + return false; + } + return true; + } +} diff --git a/lib/Service/UserService.php b/lib/Service/UserService.php index 1b8d5f46b4496ee64b75a58edc2f3de41f6f734c..8364edebed66c56a57b16daf8b1a66710eeda963 100644 --- a/lib/Service/UserService.php +++ b/lib/Service/UserService.php @@ -41,8 +41,8 @@ class UserService { private $apiConfig; /** @var LDAPConnectionService */ private $LDAPConnectionService; - - public function __construct($appName, IUserManager $userManager, IConfig $config, CurlService $curlService, ILogger $logger, Defaults $defaults, IFactory $l10nFactory, LDAPConnectionService $LDAPConnectionService) { + private BlackListService $blackListService; + public function __construct($appName, IUserManager $userManager, IConfig $config, CurlService $curlService, ILogger $logger, Defaults $defaults, IFactory $l10nFactory, LDAPConnectionService $LDAPConnectionService, BlackListService $blackListService) { $this->userManager = $userManager; $this->config = $config; $this->appConfig = $this->config->getSystemValue($appName); @@ -51,6 +51,7 @@ class UserService { $this->defaults = $defaults; $this->l10nFactory = $l10nFactory; $this->LDAPConnectionService = $LDAPConnectionService; + $this->blackListService = $blackListService; $commonServiceURL = $this->config->getSystemValue('common_services_url', ''); if (!empty($commonServiceURL)) { @@ -274,37 +275,10 @@ class UserService { if ($this->isRecoveryEmailDomainDisallowed($recoveryEmail)) { throw new Exception('You cannot set an email address with a Murena domain as recovery email address.'); } - if ($this->isBlacklistedEmail($recoveryEmail)) { + if ($this->blackListService->isBlacklistedEmail($recoveryEmail)) { throw new BlacklistedEmailException('The domain of this email address is blacklisted. Please provide another recovery address.'); } } - /** - * Check if an email domain is blacklisted against a JSON list of disposable email domains. - * - * @param string $email The email address to check. - * @return bool True if the email domain is blacklisted, false otherwise. - */ - public function isBlacklistedEmail(string $email): bool { - // Get the blacklisted domains from configuration - $blacklistedDomainsInJson = $this->config->getAppValue(Application::APP_ID, 'blacklisted_domains'); - if (empty($blacklistedDomainsInJson)) { - return false; - } - $blacklistedDomains = json_decode($blacklistedDomainsInJson, true); - - if (empty($blacklistedDomains)) { - return false; - } - - // Split the email address into parts using explode - $emailParts = explode('@', $email); - - // Extract the domain part - $emailDomain = strtolower(end($emailParts)); - - // Check if the email domain is in the blacklisted domains array - return in_array($emailDomain, $blacklistedDomains); - } /** * Add a new user to the LDAP directory. *