ecloudUrl = endsWith($ecloudUrl, "/") ? $ecloudUrl : $ecloudUrl . "/"; $this->ecloudAccountsApiUrl = $this->ecloudUrl . 'apps/ecloud-accounts/api/'; $quota = getenv('CLOUD_QUOTA_IN_MB'); if ($quota !== false) { $this->quotaInMB = intval($quota); } } public function validateData(object $userData): ValidatedData { $id = "e_cloud_account_data"; try { // We use $userData->email as uid as it is set to username@domain if ($this->isUsernameTaken($userData->email)) { return new \ValidatedData($id, "error_account_taken"); } } catch (\Error $_) { return new \ValidatedData($id, "error_server_side"); } return new \ValidatedData($id, null); } private function isUsernameTaken(string $uid): bool { $token = getenv('ECLOUD_ACCOUNTS_SECRET'); $ch = curl_init(); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); $data = array( "uid" => $uid, "token" => $token, ); curl_setopt($ch, CURLOPT_URL, $this->ecloudAccountsApiUrl . 'user_exists'); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); $output = curl_exec($ch); $output = json_decode($output); $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); if ($statusCode !== 200) { $err = curl_error($ch); throw new Error($err); } return $output; } private function createHMEAlias(string $resultmail) : string { $token = getenv('COMMON_SERVICES_TOKEN'); $url = getenv('COMMON_SERVICES_URL'); $domain = getenv('DOMAIN'); $endpoint = '/aliases/hide-my-email/'; $url .= $endpoint . $resultmail; $data = array( "token" => $token, "domain" => $domain ); $result = curlPostJSON($url, $data); $output = $result->output; if ($result->statusCode != 200) { $err = $output->message; throw new Error($err); } $alias = isset($output->emailAlias) ? $output->emailAlias : ''; return $alias; } private function createNewDomainAlias(string $username, string $resultmail) { $token = getenv('COMMON_SERVICES_TOKEN'); $url = getenv('COMMON_SERVICES_URL'); $domain = getenv('ALIAS_DOMAIN'); $endpoint = '/aliases/'; $url .= $endpoint . $resultmail; $data = array( "token" => $token, "alias" => $username, "domain" => $domain ); $result = curlPostJSON($url, $data); $output = $result->output; if ($result->statusCode != 200) { $err = $output->message; throw new Error($err); } } private function setAccountDataAtNextcloud(string $email, string $quota, string $recoveryEmail, string $hmeAlias) { $token = getenv('ECLOUD_ACCOUNTS_SECRET'); $ch = curl_init(); curl_setopt($ch, CURLOPT_RETURNTRANSFER, true); curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST"); $data = array( "uid" => $email, "token" => $token, "email" => $email, "quota" => $quota, "recoveryEmail" => $recoveryEmail, "hmeAlias" => $hmeAlias ); curl_setopt($ch, CURLOPT_URL, $this->ecloudAccountsApiUrl . 'set_account_data'); curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data)); $output = curl_exec($ch); $output = json_decode($output, false); $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $answer = new \stdClass; $answer->success = true; $errorNotEmpty = !empty($output->error); $isRecoveryEmailError = $errorNotEmpty && $output->error === 'error_setting_recovery'; $isHmeError = $errorNotEmpty && $output->error === 'error_adding_hme_alias'; if ($isRecoveryEmailError) { $message = 'Setting recovery email of user ' . $email . ' failed with status code: ' . $statusCode . '(recovery email: ' . $recoveryEmail . ')' . PHP_EOL; error_log($message, 0); } if ($isHmeError) { $message = 'Setting HME alias of user ' . $email . ' failed with status code: ' . $statusCode . '(HME alias: ' . $hmeAlias . ')' . PHP_EOL; error_log($message, 0); } if ($statusCode !== 200) { // Don't fail if recovery email or hide-my-email alias not set correctly $answer->success = $isRecoveryEmailError || $isHmeError; $answer->type = $errorNotEmpty ? $output->error : 'error_creating_account'; } return $answer; } private function createMailAccount($resultmail, $username, $pw, $pw2, $name, $quota, $authmail, ?string $referrerCode = null) { global $strings; $PF_HOSTNAME = "postfixadmin"; $PF_USER = "pfexec"; $PF_PWD = getenv("POSTFIXADMIN_SSH_PASSWORD"); $ssh = new SSH2($PF_HOSTNAME); if (!$ssh->login($PF_USER, $PF_PWD)) { $error_string = $strings["error_server_side"]; sendAPIResponse(500, createAPIResponse("general", $error_string)); } // 1 - create the account $creationFeedBack = explode("\n", $ssh->exec('/postfixadmin/scripts/postfixadmin-cli mailbox add ' . escapeshellarg($resultmail) . ' --password ' . escapeshellarg($pw) . ' --password2 ' . escapeshellarg($pw2) . ' --name ' . escapeshellarg($name) . ' --email_other ' . escapeshellarg($authmail) . ' --quota ' . $quota . ' --active 1 --welcome-mail 0 2>&1')); $isCreated = preg_grep('/added/', $creationFeedBack); $answer = new \stdClass(); if (empty($isCreated)) { // There was an error during account creation on PFA side, return it $answer->success = false; $answer->type = "error_creating_account"; return $answer; } else { // 2 - the account was created, set some settings $hmeAlias = ''; try { $hmeAlias = $this->createHMEAlias($resultmail); $this->createNewDomainAlias($username, $resultmail); } catch (Error $e) { error_log('Error during alias creation for user: ' . $resultmail . ' : ' . $e->getMessage()); } $answer = $this->setAccountDataAtNextcloud($resultmail, $quota . ' MB', $authmail, $hmeAlias); return $answer; } } public function tryToCreate(object $userData) { global $strings; $pw = $userData->password; $answer = $this->createMailAccount($userData->email, $userData->username, $pw, $pw, $userData->name, $this->quotaInMB, $userData->authmail, $userData->referrerCode); if ($answer->success === false) { sendAPIResponse(400, createAPIResponse("general", $strings[$answer->type])); } } }