ecloudUrl = endsWith($ecloudUrl, "/") ? $ecloudUrl : $ecloudUrl . "/"; $this->ecloudAccountsApiUrl = $this->ecloudUrl . 'apps/ecloud-accounts/api/'; } 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 setAccountDataAtNextcloud(string $email, string $quota, string $recoveryEmail) { $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 ); 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; $errorNotEmpty = !empty($output->error); $answer->success = true; if ($statusCode !== 200) { $isRecoveryEmailError = $errorNotEmpty && $output->error === 'error_setting_recovery'; $answer->success = $isRecoveryEmailError ? true : false; $answer->type = $errorNotEmpty ? $output->error : 'error_creating_account'; if ($isRecoveryEmailError) { $message = 'Setting recovery email of user ' . $email . ' failed with status code: ' . $statusCode . '(recovery email: ' . $recoveryEmail . ')' . PHP_EOL; error_log($message, 0); } } return $answer; } private function createMailAccount($resultmail, $pw, $pw2, $name, $quota, $authmail) { 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 $answer = $this->setAccountDataAtNextcloud($resultmail, $quota . ' MB', $authmail); return $answer; } } public function tryToCreate(object $userData) { global $strings; $pw = $userData->password; $answer = $this->createMailAccount($userData->email, $pw, $pw, $userData->name, $this->quotaInMB, $userData->authmail); if ($answer->success === false) { sendAPIResponse(400, createAPIResponse("general", $strings[$answer->type])); } } }