Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Skip to content
ecloud_account_creator.php 5.39 KiB
Newer Older
<?php
require 'vendor/autoload.php';
require_once('language.php');
require_once('account_creator.php');

use phpseclib3\Net\SSH2;

class ECloudAccountCreator implements AccountCreator
{
    private string $eCloudUrl;
    private string $eCloudUrlUsers;
    private string $eCloudCredentials;
    private int $quotaInMB = 1024;

    public function __construct(string $eCloudUrl, string $USERNAME_ADM, string $PASSWORD_ADM)
    {
        $this->eCloudUrl = endsWith($eCloudUrl, "/") ? $eCloudUrl : $eCloudUrl . "/";
        $this->eCloudUrlUsers = $this->eCloudUrl . "ocs/v2.php/cloud/users/";
        $this->eCloudCredentials = base64_encode($USERNAME_ADM . ":" . $PASSWORD_ADM);
    }
    public function validateData(object $userData): ValidatedData
    {
        $id = "e_cloud_account_data";
        try {
Akhil's avatar
Akhil committed
            if ($this->isUsernameTaken($userData->username))
                return new \ValidatedData($id, "error_account_taken");
Akhil's avatar
Akhil committed
        } catch (\Error $_) {
            return new \ValidatedData($id, "error_server_side");
        }
        return new \ValidatedData($id, null);
    }
    private function isUsernameTaken(string $username): bool
    {
        $curl = curl_init();
        curl_setopt_array($curl, array(
            CURLOPT_URL => $this->eCloudUrlUsers . $username,
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_ENCODING => "",
            CURLOPT_MAXREDIRS => 10,
            CURLOPT_TIMEOUT => 30,
            CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
            CURLOPT_HTTPHEADER => array(
                "cache-control: no-cache",
                "content-type: application/json",
                "OCS-APIRequest: true",
                "Accept: application/json",
                "Authorization: Basic " . $this->eCloudCredentials
            ),
        ));
        curl_exec($curl);
        $statusCode = curl_getinfo($curl, CURLINFO_RESPONSE_CODE);
        $err = curl_error($curl);
        curl_close($curl);
        if (!empty($err)) {
            throw new Error($err);
        }
        $userFound = $statusCode !== 404;
        return $userFound;
    }
Akhil's avatar
Akhil committed

    private function setAccountDataAtNextcloud(string $email, string $quota, string $recoveryEmail)
    {
Akhil's avatar
Akhil committed
        $token = getenv('ECLOUD_ACCOUNTS_SECRET');
        $domain = getenv('DOMAIN');

        $ch = curl_init();
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");

        $data = array(
            "uid" => $email,
Akhil's avatar
Akhil committed
            "token" => $token,
Akhil's avatar
Akhil committed
            "email" => $email,
            "quota" => $quota,
            "recoveryEmail" => $recoveryEmail
        );
        curl_setopt($ch, CURLOPT_URL, 'https://' . $domain . '/apps/ecloud-accounts/api/set_account_data');
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
        $output = curl_exec($ch);
        $output = json_decode($output);
        $statusCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);

        $answer = new \stdClass;
        $errorNotEmpty = !empty($output->error);
        $answer->success = true;

Akhil's avatar
Akhil committed
        if ($statusCode !== 200) {
Akhil's avatar
Akhil committed
            $isRecoveryEmailError = $errorNotEmpty && $output->error === 'error_setting_recovery';
            $answer->success = $isRecoveryEmailError ? true : false;
            $answer->type = $errorNotEmpty ? $output->error : 'error_creating_account';
Akhil's avatar
Akhil committed

            if ($isRecoveryEmailError) {
                $message = 'Setting recovery email of user ' . $email . ' failed with status code: ' . $statusCode . '(recovery email: ' . $recoveryEmail . ')' . PHP_EOL;
Akhil's avatar
Akhil committed
                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
Akhil's avatar
Akhil committed
        $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
Akhil's avatar
Akhil committed
            $answer = $this->setAccountDataAtNextcloud($resultmail, $quota . ' MB', $authmail);
Akhil's avatar
Akhil committed
            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]));
        }
    }
Akhil's avatar
Akhil committed
}