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

Commit 3b7b4830 authored by Akhil's avatar Akhil 🙂 Committed by Arnau Vàzquez
Browse files

LDAP account creator

parent 9349d408
Loading
Loading
Loading
Loading
+4 −1
Original line number Diff line number Diff line
@@ -35,7 +35,10 @@ RUN apt-get update && apt-get install -y libyaml-dev nano libpng-dev libfreetype
RUN docker-php-ext-configure gd --with-freetype --with-jpeg 
RUN docker-php-ext-install -j$(nproc) gd 
RUN docker-php-ext-install mysqli
RUN COMPOSER_ALLOW_SUPERUSER=1 composer require --no-plugins --no-scripts pear/mail pear/net_smtp pear/auth_sasl pear/mail_mime phpseclib/phpseclib:~3.0 curl/curl sendgrid/sendgrid
RUN apt-get install libldap2-dev -y && \
    docker-php-ext-configure ldap --with-libdir=lib/x86_64-linux-gnu/ && \
    docker-php-ext-install ldap
RUN COMPOSER_ALLOW_SUPERUSER=1 composer require --no-plugins --no-scripts directorytree/ldaprecord pear/mail pear/net_smtp pear/auth_sasl pear/mail_mime phpseclib/phpseclib:~3.0 curl/curl sendgrid/sendgrid
RUN apt-get remove -y git unzip 
RUN rm -rf /var/lib/apt/lists/* && rm /usr/bin/composer
RUN chown -R www-data:www-data /var/www/html/vendor/ /var/www/html/composer.lock /var/www/html/composer.json
+4 −0
Original line number Diff line number Diff line
@@ -71,6 +71,10 @@ flowchart TD
    B --> |4. Create entry for user's email, code and ecloud username| E[(auth.file.done)]
    B --> |5. Send user welcome email| A
```
# To use with LDAP backend

- Add the following environment variables to use welcome with LDAP backend
    - `LDAP_HOSTS`, `LDAP_PORT`, `LDAP_ADMIN_DN`, `LDAP_ADMIN_PASSWORD`, `LDAP_USERS_BASE_DN`, `LDAP_BACKEND_ENABLED`

# SendGrid integration
To be able to use [SendGrid](https://sendgrid.com/) as the email sender, you need to set the following ENV variables:
+69 −85
Original line number Diff line number Diff line
<?php
require 'vendor/autoload.php';
require_once('language.php');
require_once('account_creator.php');
require_once('helpers.php');

use phpseclib3\Net\SSH2;

class ECloudAccountCreator implements AccountCreator
class BaseEcloudAccountCreator implements AccountCreator
{
    private string $ecloudUrl;
    private string $ecloudAccountsApiUrl;
    private int $quotaInMB = 1024;
    protected int $quota = 1024;
    protected bool $usernameIsEmail = true;

    public function __construct(string $ecloudUrl)
    {
@@ -18,7 +16,17 @@ class ECloudAccountCreator implements AccountCreator
        $this->ecloudAccountsApiUrl = $this->ecloudUrl . 'apps/ecloud-accounts/api/';
        $quota = getenv('CLOUD_QUOTA_IN_MB');
        if ($quota !== false) {
            $this->quotaInMB = intval($quota);
            $this->quota = intval($quota);
        }
    }

    public function tryToCreate(object $userData)
    {
        global $strings;
        $pw = $userData->password;
        $answer = $this->createAccount($userData->email, $userData->username, $pw, $pw, $userData->name, $this->quota, $userData->authmail, $userData->referrerCode);
        if ($answer->success === false) {
            sendAPIResponse(400, createAPIResponse("general", $strings[$answer->type]));
        }
    }

@@ -26,8 +34,8 @@ class ECloudAccountCreator implements AccountCreator
    {
        $id = "e_cloud_account_data";
        try {
            // We use $userData->email as uid as it is set to username@domain
            if ($this->isUsernameTaken($userData->email)) {
            // We check if account with uid set to email or username exists
            if ($this->isUsernameTaken($userData->email) || $this->isUsernameTaken($userData->username)) {
                return new \ValidatedData($id, "error_account_taken");
            }
        } catch (\Error $_) {
@@ -36,41 +44,34 @@ class ECloudAccountCreator implements AccountCreator
        return new \ValidatedData($id, null);
    }

    private function isUsernameTaken(string $uid): bool
    protected function postCreationActions(string $email, string $username, string $authmail, string $quota, string $commonApiVersion = '')
    {
        $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);
        try {
            $hmeAlias = '';
            $commonApiUrl = getenv('COMMON_SERVICES_URL');
            $commonApiUrl = endsWith($commonApiUrl, '/') ? $commonApiUrl : $commonApiUrl . '/';
            
            $aliasDomain =  getenv('ALIAS_DOMAIN');
            // Create HME Alias
            $hmeAlias = $this->createHMEAlias($email, $commonApiUrl, $commonApiVersion, $aliasDomain);
            // Create Alias to new domain
            $this->createNewDomainAlias($username, $email, $commonApiUrl, $commonApiVersion, $aliasDomain);

            // Create alias with same name as email pointing to email to block this alias
            $domain = getMailDomain();
            $this->createNewDomainAlias($username, $email, $commonApiUrl, $commonApiVersion, $domain);
        } catch (Error $e) {
            error_log('Error during alias creation for user: ' . $username . ' with email: ' . $email . ' : ' . $e->getMessage());
        }

        return $output;
        $answer = $this->setAccountDataAtNextcloud($username, $email, $quota . ' MB', $authmail, $hmeAlias);
        return $answer;
    }

    private function createHMEAlias(string $resultmail) : string
    private function createHMEAlias(string $resultmail, string $commonApiUrl, string $commonApiVersion, string $domain) : string
    {
        $token = getenv('COMMON_SERVICES_TOKEN');
        $url = getenv('COMMON_SERVICES_URL');
        $domain = getenv('ALIAS_DOMAIN');
        
        $endpoint = '/aliases/hide-my-email/';
        $url .= $endpoint . $resultmail;
        $endpoint = $commonApiVersion . '/aliases/hide-my-email/';
        $url = $commonApiUrl . $endpoint . $resultmail;
        $data = array(
            "token" => $token,
            "domain" => $domain
@@ -86,18 +87,16 @@ class ECloudAccountCreator implements AccountCreator
        return $alias;
    }

    private function createNewDomainAlias(string $username, string $resultmail)
    private function createNewDomainAlias(string $alias, string $resultmail, string $commonApiUrl, string $commonApiVersion, string $domain)
    {
        $token = getenv('COMMON_SERVICES_TOKEN');
        $url = getenv('COMMON_SERVICES_URL');
        $domain = getenv('ALIAS_DOMAIN');

        $endpoint = '/aliases/';
        $url .= $endpoint . $resultmail;
        $endpoint = $commonApiVersion . '/aliases/';
        $url = $commonApiUrl . $endpoint . $resultmail;

        $data = array(
            "token" => $token,
            "alias" => $username,
            "alias" => $alias,
            "domain" => $domain
        );
        $result = curlPostJSON($url, $data);
@@ -108,7 +107,7 @@ class ECloudAccountCreator implements AccountCreator
        }
    }

    private function setAccountDataAtNextcloud(string $email, string $quota, string $recoveryEmail, string $hmeAlias)
    private function setAccountDataAtNextcloud(string $username, string $email, string $quota, string $recoveryEmail, string $hmeAlias)
    {
        $token = getenv('ECLOUD_ACCOUNTS_SECRET');

@@ -116,14 +115,15 @@ class ECloudAccountCreator implements AccountCreator
        curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
        curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");

        $data = array(
            "uid" => $email,
        $data = [
            "token" => $token,
            "email" => $email,
            "quota" => $quota,
            "recoveryEmail" => $recoveryEmail,
            "hmeAlias" => $hmeAlias
        );
        ];
        $data['uid'] = $this->usernameIsEmail ? $email : $username;
        
        curl_setopt($ch, CURLOPT_URL, $this->ecloudAccountsApiUrl . 'set_account_data');
        curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($data));
        $output = curl_exec($ch);
@@ -155,50 +155,34 @@ class ECloudAccountCreator implements AccountCreator
        return $answer;
    }

    private function createMailAccount($resultmail, $username, $pw, $pw2, $name, $quota, $authmail, ?string $referrerCode = null)
    private function isUsernameTaken(string $uid): bool
    {
        global $strings;
        $PF_HOSTNAME = "postfixadmin";
        $PF_USER = "pfexec";
        $PF_PWD = getenv("POSTFIXADMIN_SSH_PASSWORD");
        $token = getenv('ECLOUD_ACCOUNTS_SECRET');

        $ssh = new SSH2($PF_HOSTNAME);
        if (!$ssh->login($PF_USER, $PF_PWD)) {
            $error_string = $strings["error_server_side"];
            sendAPIResponse(500, createAPIResponse("general", $error_string));
        }
        $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));

        // 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;
        $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;
    }

    public function tryToCreate(object $userData)
    protected function createAccount(string $resultmail, string $username, string $pw, string $pw2, string $name, int $quota, string $authmail, ?string $referrerCode = null)
    {
        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]));
        }
    }
}
+47 −0
Original line number Diff line number Diff line
<?php
require 'vendor/autoload.php';
require_once('language.php');
require_once('helpers.php');
require_once('accounts/account_creator.php');
require_once('accounts/base_ecloud_account_creator.php');


use phpseclib3\Net\SSH2;

class ECloudAccountCreator extends BaseEcloudAccountCreator
{
    public function __construct(string $ecloudUrl)
    {
        parent::__construct($ecloudUrl);
    }

    protected function createAccount(string $resultmail, string $username, string $pw, string $pw2, string $name, int $quota, string $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 {
            $answer = $this->postCreationActions($resultmail, $username, $authmail, $quota);
            return $answer;
        }
    }

}
Loading