Andre Genrich 5 жил өмнө
parent
commit
6ce4fe47b5

+ 1 - 0
api/.gitignore

@@ -0,0 +1 @@
+config_*

+ 4 - 4
api/config.php

@@ -3,9 +3,9 @@
 // Config //
 ////////////
 
-$domain = "yourdomain.com";
-$zimbraserver = "zcs.".$domain;
-$zimbraadminemail = "admin@".$domain;
-$zimbraadminpassword = "admpassword";
+$domain = "thurdata.local";
+$zimbraServer = "192.168.16.225";
+$zimbraAdminEmail = "admin@".$domain;
+$zimbraAdminPassword = "Technics2312";
 
 ?>

+ 12 - 3
api/zm/Auth.php

@@ -72,6 +72,15 @@ class Zm_Auth
 	 */
 	function __construct($server, $username, $password, $authas="admin", $attempts=3)
 	{
+		$ssl_context = stream_context_create([
+			'ssl' => [
+			// set some SSL/TLS specific options
+			'verify_peer' => false,
+			'verify_peer_name' => false,
+			'allow_self_signed' => true
+			]
+		]);
+
 		if ($authas == "admin")
 		{
 			$location = "https://" . $server . ":7071/service/admin/soap/";
@@ -94,6 +103,7 @@ class Zm_Auth
 				'soap_version' => SOAP_1_2,
 				'style' => SOAP_RPC,
 				'use' => SOAP_LITERAL,
+				'stream_context' => $ssl_context,
 		    )
 		);
 
@@ -241,9 +251,8 @@ class Zm_Auth
 				$this->setSoapHeader();
 
 				$result = $this->client->__soapCall("AuthRequest", $this->params, null, $this->getSoapHeader());
-				//$result = $this->client->__getLastResponse();
-				//print_var($result);
-
+				// $result = $this->client->__getLastResponse();
+				// print_var($result);
 				// Save the soapHeader with token
 				$this->setSoapHeader($result['authToken']);
 				break;

+ 32 - 0
api/zmtest.php

@@ -0,0 +1,32 @@
+<?php
+ini_set('soap.wsdl_cache_enabled',0);
+ini_set('soap.wsdl_cache_ttl',0);
+
+
+require_once("config.php");
+
+require_once("Zm/Auth.php");
+require_once("Zm/Account.php");
+require_once("Zm/Domain.php");
+require_once("Zm/Server.php");
+
+$auth = new Zm_Auth($zimbraServer, $zimbraAdminEmail, $zimbraAdminPassword, "admin");
+
+$l = $auth->login();
+
+if(is_a($l, "Exception")) {
+
+    echo "Error : cannot login to $zimbraServer\n";
+
+    echo $l->getMessage()."\n";
+
+    exit();
+
+}
+
+$accountManager = new Zm_Account($auth);
+$r = $accountManager->accountExists("test3@thurdata.local");
+echo "$r\n";
+$r = $accountManager->accountExists("test5@thurdata.local");
+echo "$r\n";
+

+ 7 - 0
clientarea.tpl

@@ -0,0 +1,7 @@
+<table width="100%" cellspacing="0" cellpadding="0" class="frame">
+    <tr>
+      <td><table width="100%" border="0" cellpadding="10" cellspacing="0" class="table table-striped table-framed">
+          <tr><td align='left'>Webmail</td>
+            <td align="left"><a href="{$webmailURL}" target="_blank">{$webmailURL}</a></td>
+     </table>
+</td></tr></table>

+ 11 - 0
clientarea.tpl.bak

@@ -0,0 +1,11 @@
+<div class="page-header">
+    <div class="styled_title" align='left'><h3>{$LANG['orderlogininfo']}</h3> </div>
+</div>
+ <table width="100%" cellspacing="0" cellpadding="0" class="frame">
+    <tr>
+      <td><table width="100%" border="0" cellpadding="10" cellspacing="0" class="table table-striped table-framed">
+          <tr><td align='left'>Webmail</td>
+            <td align="left"><a href="{$serverhttpprefix}://{$serverhostname}" target="_blank">{$serverhttpprefix}://{$serverhostname}</a></td>
+          </tr>
+     </table>
+</td></tr></table>

+ 11 - 0
clienttest.tpl

@@ -0,0 +1,11 @@
+<div class="page-header">
+    <div class="styled_title" align='left'><h3>{$LANG['orderlogininfo']}</h3> </div>
+</div>
+ <table width="100%" cellspacing="0" cellpadding="0" class="frame">
+    <tr>
+      <td><table width="100%" border="0" cellpadding="10" cellspacing="0" class="table table-striped table-framed">
+          <tr><td align='left'>Webmail</td>
+            <td align="left"><a href="{$serverhttpprefix}://{$serverhostname}" target="_blank">{$serverhttpprefix}://{$serverhostname}</a></td>
+          </tr>
+     </table>
+</td></tr></table>

+ 6 - 0
decrypt.php

@@ -0,0 +1,6 @@
+<?php
+    $adminPassDecrypt = localAPI('DecryptPassword', array('password2' => 'dNPmi0wk0qsIXkXKwi2dZxP1xcNYvOp/rHidfc2b'));
+    if ($adminPassDecrypt['result'] == 'success') {
+       echo $adminPassDecrypt['password'];
+    }
+

+ 19 - 0
hooks.php.bak

@@ -0,0 +1,19 @@
+<?php
+if (!defined("WHMCS"))
+    die("This file cannot be accessed directly");
+require_once dirname(__FILE__) . '/zimbraSingle.inc';
+
+add_hook("ShoppingCartValidateProductUpdate", 1, "validate_emailaddress_zimbraSingle");
+
+function validate_emailaddress_zimbraSingle($vars)
+{
+    $keys = array('givenname', 'sn', 'mailname', 'domain', 'password');
+    $userdata = array_combine($keys, $vars["customfield"]);
+    $response = zimbraSingleDoesEMailExist($userdata['mailname'], $userdata['domain']);
+    if ($response == true) {
+        return 'Mailbox ' . $userdata['mailname'] . '@' . $userdata['domain'] . ' already exists, choose another. ';
+    } else {
+        return zimbraSingleCheckPassword($userdata['password']);
+    }
+}
+

BIN
logo.png


BIN
master.zip


+ 15 - 0
test.php

@@ -0,0 +1,15 @@
+<?php
+require_once("api/Zm/Auth.php");
+require_once("api/Zm/Account.php");
+
+$auth = new Zm_Auth('192.168.16.225', 'admin@thurdata.local', 'Technics2312');
+$l = $auth->login();
+$accountManager = new Zm_Account($auth);
+$r = $accountManager->getAccountOptions('test1@thurdata.local');
+
+	if(is_a($r, "Exception")) {
+		print_exception($r);
+	} else {
+		print_var($r, "Get Account Options");
+	}
+

BIN
test_old_api.tgz


+ 28 - 0
whmcs.json

@@ -0,0 +1,28 @@
+{
+  "schema": "1.0",
+  "type": "whmcs-provisioning",
+  "name": "zimbrasingle",
+  "license": "GPL",
+  "category": "provisioning",
+  "description": {
+    "name": "ZimbraSingle",
+    "tagline": "Zimbra Single Account Provisioning Module for WHMCS.",
+    "short": "Provides Zimbra Account Provisioning for single accounts. The customer can also reset his zimbra password.",
+    "long": "The module allows single-user provisioning of Zimbra accounts. It implements a simple seafile hosting for private customers with only one account each. The hosting of corporate environments was deliberately omitted, because its provided by the Modulesgarden Module."
+  },
+  "logo": {
+    "filename": "logo.png"
+  },
+  "support": {
+    "homepage": "https://www.thurdata.ch/whmcs",
+    "learn_more": "https://www.thurdata.ch/whmcs/#features",
+    "support_url": "https://www.thurdata.ch/support",
+    "docs_url": "https://www.thudata.ch/whmcs/docs"
+  },
+  "authors": [
+    {
+      "name": "Thurdata GmbH",
+      "homepage": "https://www.thurdata.ch/"
+    }
+  ]
+}

+ 39 - 29
zimbraSingle.inc

@@ -327,21 +327,46 @@ function zimbraSingleClientArea($userData)
             ""
         );
         return false;
+    } else {
+        $apiAccountManager = new Zm_Account($api);
+        $response = $apiAccountManager->getAccountInfo($account_name);
+        if(is_a($response, "Exception")) {
+            logModuleCall(
+                'zimbrasingle',
+                __FUNCTION__,
+                $params,
+                "Error : could not gather informations for  $account_name",
+                ""
+            );
+            return false;
+        } else {
+            $webMailURL = recursiveFindAll( $response, 'PUBLICMAILURL');
+            logModuleCall(
+                'zimbrasingle',
+                __FUNCTION__,
+                $params,
+                "debug",
+                $webMailURL
+            );
+            return $webMailURL;
+        }
     }
-    $apiAccountManager = new Zm_Account($api);
-    $response = $apiAccountManager->getAccountInfo($account_name);
-    if(is_a($response, "Exception")) {
-        logModuleCall(
-            'zimbrasingle',
-            __FUNCTION__,
-            $params,
-            "Error : could not gather informations for $account_name",
-            ""
-        );
-        return false;
+}
+
+function recursiveFindAll($haystack, $needle)
+{
+    $values = array();
+    $iterator  = new RecursiveArrayIterator($haystack);
+    $recursive = new RecursiveIteratorIterator(
+        $iterator,
+        RecursiveIteratorIterator::SELF_FIRST
+    );
+    foreach ($recursive as $key => $value) {
+        if ($key === $needle) {
+            array_push($values, $value);
+        }
     }
-    $webMailURL = recursiveFindAll( $response, 'PUBLICMAILURL');
-    return $webMailURL[0]['DATA'];
+    return $values;
 }
 
 function zimbraSingleCheckPassword($pwd)
@@ -369,23 +394,8 @@ function zimbraSingleCheckPassword($pwd)
     return $message;
 }
 
-function recursiveFindAll($haystack, $needle)
-{
-    $values = array();
-    $iterator  = new RecursiveArrayIterator($haystack);
-    $recursive = new RecursiveIteratorIterator(
-        $iterator,
-        RecursiveIteratorIterator::SELF_FIRST
-    );
-    foreach ($recursive as $key => $value) {
-        if ($key === $needle) {
-            array_push($values, $value);
-        }
-    }
-    return $values;
-}
-
 function zimbraSingleTestFunction()
 {
     return 'blubb';
 }
+

+ 259 - 0
zimbraSingle.inc.1

@@ -0,0 +1,259 @@
+<?php
+
+use WHMCS\Database\Capsule;
+require_once("api/Zm/Auth.php");
+require_once("api/Zm/Account.php");
+require_once("api/Zm/Domain.php");
+require_once("api/Zm/Server.php");
+
+function zimbraSingle_MetaData()
+{
+    return array(
+        'DisplayName' => 'Zimbra Single Mailbox Provisioning',
+        'APIVersion' => '1.2',
+        'DefaultNonSSLPort' => '7071',
+        'DefaultSSLPort' => '7071',
+        'RequiresServer' => true,
+        'ServiceSingleSignOnLabel' => 'Login to Zimbra',
+        'AdminSingleSignOnLabel' => 'Login to Zimbra Admin'
+    );
+}
+/**
+ */
+function zimbraSingleGetAccess()
+{
+    $accessData = array('zimbraServer' => '', 'adminUser' => '', 'adminPass' => '');
+    $servers = Capsule::table('tblservers')
+        ->select('ipaddress', 'username', 'password')
+        ->where('id', '=', $_SESSION[CreatedServerId])
+        ->get();
+    $accessData['zimbraServer'] = $servers[0]->ipaddress;
+    $accessData['adminUser'] = $servers[0]->username;
+    $adminPassCrypt = $servers[0]->password;
+    $adminPassDecrypt = localAPI('DecryptPassword', array('password2' => $adminPassCrypt));
+    if ($adminPassDecrypt['result'] == 'success') {
+        $accessData['adminPass'] = $adminPassDecrypt['password'];
+    }
+    return $accessData;
+}
+
+/**
+ * Checks if a given email address in the given domain already exists
+ *
+ * @param  $emailNameOnly       The name before the @-sign only
+ * @param  $domainName          The domain to search for existance of the email account
+ * @return true if such an account was found or false if not
+ */
+function zimbraSingleDoesEMailExist($emailNameOnly, $domainName)
+{
+    $account_name = $emailNameOnly . "@" . $domainName;
+    $accessData = zimbraSingleGetAccess();
+
+    $api = new Zm_Auth($accessData['zimbraServer'], $accessData['adminUser'], $accessData['adminPass'], "admin");
+    $login = $api->login();
+    if(is_a($login, "Exception")) {
+        logModuleCall(
+            'zimbrasingle',
+            __FUNCTION__,
+            $params,
+            "Error : cannot login to " . $accessData['zimbraServer'],
+            "$login->getMessage()"
+        );
+        exit();
+    } else {
+        $apiAccountManager = new Zm_Account($api);
+	    if( $apiAccountManager->accountExists($account_name)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+}
+
+/**
+*/
+function zimbraSingleCreateAccount($userData)
+{
+    $accessData = zimbraSingleGetAccess();
+    $attrs = array();
+    $attrs["gn"] = $userData["givenname"];
+    $attrs["sn"] = $userData["sn"];
+    $attrs["displayName"] = $attrs["gn"] . " " . $attrs["sn"];
+    $passDecrypt = localAPI('DecryptPassword', array('password2' => $userData['password']));
+    if ($passDecrypt['result'] == 'success') {
+        $userData['password'] = $passDecrypt['password'];
+    }
+    $account_name = $userData['username'] . '@' . $userData['maildomain'];
+
+    $api = new Zm_Auth($accessData['zimbraServer'], $accessData['adminUser'], $accessData['adminPass'], "admin");
+    $login = $api->login();
+    if(is_a($login, "Exception")) {
+        logModuleCall(
+            'zimbrasingle',
+            __FUNCTION__,
+            $params,
+            "Error : cannot login to " . $accessData['zimbraServer'],
+            ""
+        );
+        return false;
+    } else {
+        $apiAccountManager = new Zm_Account($api);
+        $id = $apiAccountManager->createAccount($account_name, $userData['password'], $attrs);
+        if(is_a($id, "Exception")) {
+            logModuleCall(
+                'zimbrasingle',
+                __FUNCTION__,
+                $params,
+                "Error : account $account_name not created",
+                ""
+            );
+            return false;
+        } else {
+            return $id;
+        }
+    }
+}
+function zimbraSingleSuspendAccount($userData)
+{
+    $accessData = zimbraSingleGetAccess();
+    $account_name = $userData['username'] . '@' . $userData['maildomain'];
+
+    $api = new Zm_Auth($accessData['zimbraServer'], $accessData['adminUser'], $accessData['adminPass'], "admin");
+    $login = $api->login();
+    if(is_a($login, "Exception")) {
+        logModuleCall(
+            'zimbrasingle',
+            __FUNCTION__,
+            $params,
+            "Error : cannot login to " . $accessData['zimbraServer'],
+            ""
+        );
+        return false;
+    } else {
+        $apiAccountManager = new Zm_Account($api);
+        $response = $apiAccountManager->setAccountStatus($account_name, "locked");
+        if(is_a($response, "Exception")) {
+            logModuleCall(
+                'zimbrasingle',
+                __FUNCTION__,
+                $params,
+                "Error : account $account_name could not locked",
+                ""
+            );
+            return false;
+        } else {
+            return $response;
+        }
+    }
+}
+
+function zimbraSingleUnsuspendAccount($userData)
+{
+    $accessData = zimbraSingleGetAccess();
+    $account_name = $userData['username'] . '@' . $userData['maildomain'];
+
+    $api = new Zm_Auth($accessData['zimbraServer'], $accessData['adminUser'], $accessData['adminPass'], "admin");
+    $login = $api->login();
+    if(is_a($login, "Exception")) {
+        logModuleCall(
+            'zimbrasingle',
+            __FUNCTION__,
+            $params,
+            "Error : cannot login to " . $accessData['zimbraServer'],
+            ""
+        );
+        return false;
+    } else {
+        $apiAccountManager = new Zm_Account($api);
+        $response = $apiAccountManager->setAccountStatus($account_name, "active");
+        if(is_a($response, "Exception")) {
+            logModuleCall(
+                'zimbrasingle',
+                __FUNCTION__,
+                $params,
+                "Error : account $account_name could not unlocked",
+                ""
+            );
+            return false;
+        } else {
+            return $response;
+        }
+    }
+}
+
+function zimbraSingleDeleteAccount($userData)
+{
+    $accessData = zimbraSingleGetAccess();
+    $account_name = $userData['username'] . '@' . $userData['maildomain'];
+
+    $api = new Zm_Auth($accessData['zimbraServer'], $accessData['adminUser'], $accessData['adminPass'], "admin");
+    $login = $api->login();
+    if(is_a($login, "Exception")) {
+        logModuleCall(
+            'zimbrasingle',
+            __FUNCTION__,
+            $params,
+            "Error : cannot login to " . $accessData['zimbraServer'],
+            ""
+        );
+        return false;
+    } else {
+        $apiAccountManager = new Zm_Account($api);
+        $response = $apiAccountManager->getAccountStatus($account_name);
+        if(is_a($response, "Exception")) {
+            logModuleCall(
+                'zimbrasingle',
+                __FUNCTION__,
+                $params,
+                "Error : account $account_name could not verified",
+                ""
+            );
+            return false;
+        }
+        if ($response != 'locked') {
+            return "Account $account_name active, suspend account first";
+        }
+        $response = $apiAccountManager->deleteAccount($account_name);
+        if(is_a($response, "Exception")) {
+            logModuleCall(
+                'zimbrasingle',
+                __FUNCTION__,
+                $params,
+                "Error : account $account_name could not removed",
+                ""
+            );
+            return false;
+        }
+        return 'success';
+    }
+}
+
+function zimbraSingle_checkPassword($pwd)
+{
+    if (strlen($pwd) < 9) {
+        return "Das das Passwort ist zu kurz. Es werden mind. 9 Zeichen benötigt";
+    }
+
+    if (!preg_match("#[0-9]+#", $pwd)) {
+        return "Das Passwort muss mindestens eine Zahl enthalten";
+    }
+
+    if (!preg_match("#[A-Z]+#", $pwd)) {
+        return "Das Passwort muss mindestens einen Grossbuchstaben (A-Z) enthalten";
+    }
+
+    if (!preg_match("#[a-z]+#", $pwd)) {
+        return "Das Passwort muss mindestens einen Kleinbuchstaben (a-z) enthalten";
+    }
+
+    if (!preg_match("#[^\w]+#", $pwd)) {
+        return "Das Passwort muss mindestens ein Sonderzeichen (.,-:=) enthalten";
+    }
+    return null;
+}
+
+function zimbraSingleTestFunction()
+{
+    return 'blubb';
+}
+

+ 334 - 0
zimbraSingle.inc.2

@@ -0,0 +1,334 @@
+<?php
+
+use WHMCS\Database\Capsule;
+require_once("api/Zm/Auth.php");
+require_once("api/Zm/Account.php");
+require_once("api/Zm/Domain.php");
+require_once("api/Zm/Server.php");
+
+function zimbraSingle_MetaData()
+{
+    return array(
+        'DisplayName' => 'Zimbra Single Mailbox Provisioning',
+        'APIVersion' => '1.2',
+        'DefaultNonSSLPort' => '7071',
+        'DefaultSSLPort' => '7071',
+        'RequiresServer' => true,
+        'ServiceSingleSignOnLabel' => 'Login to Zimbra',
+        'AdminSingleSignOnLabel' => 'Login to Zimbra Admin'
+    );
+}
+/**
+ */
+function zimbraSingleGetAccess()
+{
+    $accessData = array('zimbraServer' => '', 'adminUser' => '', 'adminPass' => '');
+    $servers = Capsule::table('tblservers')
+        ->select('ipaddress', 'username', 'password')
+        ->where('id', '=', $_SESSION[CreatedServerId])
+        ->get();
+    $accessData['zimbraServer'] = $servers[0]->ipaddress;
+    $accessData['adminUser'] = $servers[0]->username;
+    $adminPassCrypt = $servers[0]->password;
+    $adminPassDecrypt = localAPI('DecryptPassword', array('password2' => $adminPassCrypt));
+    if ($adminPassDecrypt['result'] == 'success') {
+        $accessData['adminPass'] = $adminPassDecrypt['password'];
+    }
+    return $accessData;
+}
+
+/**
+ * Checks if a given email address in the given domain already exists
+ *
+ * @param  $emailNameOnly       The name before the @-sign only
+ * @param  $domainName          The domain to search for existance of the email account
+ * @return true if such an account was found or false if not
+ */
+function zimbraSingleDoesEMailExist($emailNameOnly, $domainName)
+{
+    $account_name = $emailNameOnly . "@" . $domainName;
+    $accessData = zimbraSingleGetAccess();
+
+    $api = new Zm_Auth($accessData['zimbraServer'], $accessData['adminUser'], $accessData['adminPass'], "admin");
+    $login = $api->login();
+    if(is_a($login, "Exception")) {
+        logModuleCall(
+            'zimbrasingle',
+            __FUNCTION__,
+            $params,
+            "Error : cannot login to " . $accessData['zimbraServer'],
+            "$login->getMessage()"
+        );
+        exit();
+    } else {
+        $apiAccountManager = new Zm_Account($api);
+	    if( $apiAccountManager->accountExists($account_name)) {
+            return true;
+        } else {
+            return false;
+        }
+    }
+}
+
+/**
+*/
+function zimbraSingleCreateAccount($userData)
+{
+    $accessData = zimbraSingleGetAccess();
+    $attrs = array();
+    $attrs["gn"] = $userData["givenname"];
+    $attrs["sn"] = $userData["sn"];
+    $attrs["displayName"] = $attrs["gn"] . " " . $attrs["sn"];
+    $passDecrypt = localAPI('DecryptPassword', array('password2' => $userData['password']));
+    if ($passDecrypt['result'] == 'success') {
+        $userData['password'] = $passDecrypt['password'];
+    }
+    $account_name = $userData['username'] . '@' . $userData['maildomain'];
+
+    $api = new Zm_Auth($accessData['zimbraServer'], $accessData['adminUser'], $accessData['adminPass'], "admin");
+    $login = $api->login();
+    if(is_a($login, "Exception")) {
+        logModuleCall(
+            'zimbrasingle',
+            __FUNCTION__,
+            $params,
+            "Error : cannot login to " . $accessData['zimbraServer'],
+            ""
+        );
+        return false;
+    } else {
+        $apiAccountManager = new Zm_Account($api);
+        $id = $apiAccountManager->createAccount($account_name, $userData['password'], $attrs);
+        if(is_a($id, "Exception")) {
+            logModuleCall(
+                'zimbrasingle',
+                __FUNCTION__,
+                $params,
+                "Error : account $account_name not created",
+                ""
+            );
+            return false;
+        } else {
+            return $id;
+        }
+    }
+}
+function zimbraSingleSuspendAccount($userData)
+{
+    $accessData = zimbraSingleGetAccess();
+    $account_name = $userData['username'] . '@' . $userData['maildomain'];
+
+    $api = new Zm_Auth($accessData['zimbraServer'], $accessData['adminUser'], $accessData['adminPass'], "admin");
+    $login = $api->login();
+    if(is_a($login, "Exception")) {
+        logModuleCall(
+            'zimbrasingle',
+            __FUNCTION__,
+            $params,
+            "Error : cannot login to " . $accessData['zimbraServer'],
+            ""
+        );
+        return false;
+    } else {
+        $apiAccountManager = new Zm_Account($api);
+        $response = $apiAccountManager->setAccountStatus($account_name, "locked");
+        if(is_a($response, "Exception")) {
+            logModuleCall(
+                'zimbrasingle',
+                __FUNCTION__,
+                $params,
+                "Error : account $account_name could not locked",
+                ""
+            );
+            return false;
+        } else {
+            return $response;
+        }
+    }
+}
+
+function zimbraSingleUnsuspendAccount($userData)
+{
+    $accessData = zimbraSingleGetAccess();
+    $account_name = $userData['username'] . '@' . $userData['maildomain'];
+
+    $api = new Zm_Auth($accessData['zimbraServer'], $accessData['adminUser'], $accessData['adminPass'], "admin");
+    $login = $api->login();
+    if(is_a($login, "Exception")) {
+        logModuleCall(
+            'zimbrasingle',
+            __FUNCTION__,
+            $params,
+            "Error : cannot login to " . $accessData['zimbraServer'],
+            ""
+        );
+        return false;
+    } else {
+        $apiAccountManager = new Zm_Account($api);
+        $response = $apiAccountManager->setAccountStatus($account_name, "active");
+        if(is_a($response, "Exception")) {
+            logModuleCall(
+                'zimbrasingle',
+                __FUNCTION__,
+                $params,
+                "Error : account $account_name could not unlocked",
+                ""
+            );
+            return false;
+        } else {
+            return $response;
+        }
+    }
+}
+
+function zimbraSingleDeleteAccount($userData)
+{
+    $accessData = zimbraSingleGetAccess();
+    $account_name = $userData['username'] . '@' . $userData['maildomain'];
+
+    $api = new Zm_Auth($accessData['zimbraServer'], $accessData['adminUser'], $accessData['adminPass'], "admin");
+    $login = $api->login();
+    if(is_a($login, "Exception")) {
+        logModuleCall(
+            'zimbrasingle',
+            __FUNCTION__,
+            $params,
+            "Error : cannot login to " . $accessData['zimbraServer'],
+            ""
+        );
+        return false;
+    } else {
+        $apiAccountManager = new Zm_Account($api);
+        $response = $apiAccountManager->getAccountStatus($account_name);
+        if(is_a($response, "Exception")) {
+            logModuleCall(
+                'zimbrasingle',
+                __FUNCTION__,
+                $params,
+                "Error : account $account_name could not verified",
+                ""
+            );
+            return false;
+        }
+        if ($response != 'locked') {
+            return "Account $account_name active, suspend account first";
+        }
+        $response = $apiAccountManager->deleteAccount($account_name);
+        if(is_a($response, "Exception")) {
+            logModuleCall(
+                'zimbrasingle',
+                __FUNCTION__,
+                $params,
+                "Error : account $account_name could not removed",
+                ""
+            );
+            return false;
+        }
+        return 'success';
+    }
+}
+
+function zimbraSingleChangePassword($userData) {
+    $accessData = zimbraSingleGetAccess();
+    $passDecrypt = localAPI('DecryptPassword', array('password2' => $userData['password']));
+    if ($passDecrypt['result'] == 'success') {
+        $userData['password'] = $passDecrypt['password'];
+    }
+    if ($checkPW = zimbraSingleCheckPassword($userData['password'])) {
+        return $checkPW;
+    }
+    $account_name = $userData['username'] . '@' . $userData['maildomain'];
+
+    $api = new Zm_Auth($accessData['zimbraServer'], $accessData['adminUser'], $accessData['adminPass'], "admin");
+    $login = $api->login();
+    if(is_a($login, "Exception")) {
+        logModuleCall(
+            'zimbrasingle',
+            __FUNCTION__,
+            $params,
+            "Error : cannot login to " . $accessData['zimbraServer'],
+            ""
+        );
+        return false;
+    } else {
+        $apiAccountManager = new Zm_Account($api);
+        $response = $apiAccountManager->setAccountPassword($account_name, $userData['password']);
+        if(is_a($response, "Exception")) {
+            logModuleCall(
+                'zimbrasingle',
+                __FUNCTION__,
+                $params,
+                "Error : password for $account_name could not be set",
+                ""
+            );
+            return false;
+        } else {
+            return $response;
+        }
+    }
+}
+
+function zimbraSingleClientArea($userData)
+{
+    $accessData = zimbraSingleGetAccess();
+    $account_name = $userData['username'] . '@' . $userData['maildomain'];
+
+    $api = new Zm_Auth($accessData['zimbraServer'], $accessData['adminUser'], $accessData['adminPass'], "admin");
+    $login = $api->login();
+    if(is_a($login, "Exception")) {
+        logModuleCall(
+            'zimbrasingle',
+            __FUNCTION__,
+            $params,
+            "Error : cannot login to " . $accessData['zimbraServer'],
+            ""
+        );
+        return false;
+    } else {
+        $apiAccountManager = new Zm_Account($api);
+        $response = $apiAccountManager->getAccountInfo($account_name);
+        if(is_a($response, "Exception")) {
+            logModuleCall(
+                'zimbrasingle',
+                __FUNCTION__,
+                $params,
+                "Error : account $account_name could not unlocked",
+                ""
+            );
+            return false;
+        } else {
+            return $response;
+        }
+    }
+}
+
+function zimbraSingleCheckPassword($pwd)
+{
+    $message = '';
+    if (strlen($pwd) < 9) {
+        $message .= "Das das Passwort ist zu kurz. Es werden mind. 9 Zeichen benötigt<br>";
+    }
+
+    if (!preg_match("#[0-9]+#", $pwd)) {
+        $message .= "Das Passwort muss mindestens eine Zahl enthalten<br>";
+    }
+
+    if (!preg_match("#[A-Z]+#", $pwd)) {
+        $message .= "Das Passwort muss mindestens einen Grossbuchstaben (A-Z) enthalten<br>";
+    }
+
+    if (!preg_match("#[a-z]+#", $pwd)) {
+        $message .= "Das Passwort muss mindestens einen Kleinbuchstaben (a-z) enthalten<br>";
+    }
+
+    if (!preg_match("#[^\w]+#", $pwd)) {
+        $message .= "Das Passwort muss mindestens ein Sonderzeichen (.,-:=) enthalten<br>";
+    }
+    return $message;
+}
+
+function zimbraSingleTestFunction()
+{
+    return 'blubb';
+}
+

+ 2 - 1
zimbraSingle.php

@@ -49,7 +49,7 @@ function zimbraSingle_ClientArea($params)
     return array(
         'templatefile' => 'clientarea',
         'vars' => array(
-            'webmailURL' => $response,
+            'webmailURL' => $response[0]['DATA'],
         ),
     );
 }
@@ -128,3 +128,4 @@ function zimbraSingle_genUsername($name)
 
     return $name; */
 }
+

+ 338 - 0
zimbraSingle.php.1

@@ -0,0 +1,338 @@
+<?php
+
+/**
+ * WHMCS Zimbra Provisioning Module
+ *
+ * Provisioning for private user accounts on the Zimbra Server
+ *
+ * @see https://www.zimbra.com
+ * @copyright Copyright (c) Thurdata GmbH 2020
+ * @license GPL
+ */
+
+if (!defined("WHMCS")) {
+    die("This file cannot be accessed directly");
+}
+require_once dirname(__FILE__) . '/zimbraSingle.inc';
+
+function zimbraSingle_TestConnection($params)
+{
+    $auth = new Zm_Auth($params['serverip'], $params['serverusername'], $params['serverpassword'], "admin");
+    $login = $auth->login();
+    if(is_a($login, "Exception")) {
+        logModuleCall(
+            'zimbrasingle',
+            __FUNCTION__,
+            $params,
+            "Connection test to " . $params['serverip'] . " failed: Cannot login",
+            $login->getMessage()
+        );
+        return array(
+            'success' => false,
+            'error' => "Connection test to " . $params['serverip'] . " failed, the error was: " . $login->getMessage(),
+        );
+    } else {
+        return array(
+            'success' => true,
+            'error' => '',
+        );
+    }
+}
+
+function zimbraSingle_UsageUpdate($params)
+{
+}
+
+
+function zimbraSingle_ClientArea($params)
+{
+
+    // error_log(print_r($params,true));
+    #   error_log("CLIENT-AREA");
+    #   $zimbraSingleURL   = buildzimbraSingleURL($params);
+    #   $user = $params['username'];
+
+    #   $result0 = select_query("tblconfiguration","value" , array('setting' => 'Language'));
+    #   $data0 = mysql_fetch_array($result0);
+    #   $lla = ($_SESSION['Language']) ? trim($_SESSION['Language']) : strtolower($data0[0]);
+
+    #   $slang = array();
+    #   include_once dirname(__FILE__).'/lang/'.$lla.'.php';
+
+    #   return array(
+    #    'templatefile' => 'clientside',
+    #    'vars' => array_merge(array(
+    #      'url' => $seafileURL,
+    #      'user' => $user,
+    #      'mobile1' => $app,
+    #      'mobile2' => $google,
+    #      'drivewin' => $driveWin,
+    #      'winclient' => $winClient,
+    #      'macclient' => $macClient,
+    #      'drivemac' => $driveMac,
+    #      'linClient' => $linClient,
+    #    ), $slang, $params),
+    #  );
+}
+
+function zimbraSingle_ClientAreaCustomButtonArray()
+{
+    $buttonarray = array(
+        "Reset Password" => "ClientPassword",
+    );
+    return $buttonarray;
+}
+
+
+function zimbraSingle_ChangePassword($params)
+{
+    #       if (strcmp($params['status'],"Active") !== 0) {
+    #           return "Der Dienst ist gesperrt, das Passwort kann daher nicht geändert werden";
+    #       }
+    #       $loginPassword = $params["customfields"]["Passwort"];
+    #       $checkPassword = checkPassword($loginPassword);
+    #       if ($checkPassword != null) {
+    #           return $checkPassword;
+    #       }
+    #       $fieldID = getCustomFieldIDFor($params,"Passwort");
+    #
+    #       $seafileURL   = buildSeafileURL($params);
+    #       $apiuser      = getSeafileAdminUser($params);
+    #       $apipass      = getSeafileAdminPassword($params);
+    #
+    #       $seafileAPI = new SeafileAPI($seafileURL,$apiuser,$apipass);
+    #       if ($seafileAPI->login() != true) {
+    #           logModuleCall(
+    #               'seafile',
+    #               __FUNCTION__,
+    #               $params,
+    #               "Cannot login to " . $seafileURL,
+    #               ""
+    #           );
+    #           return "Login to " . $seafileURL . " fehlgeschlagen. Bitte den Administrator informieren.\n";
+    #       }
+    #
+    #       $userAccount = $seafileAPI->getAccountByEMail($params['username']);
+    #       if ($userAccount != null) {
+    #           $userAccount->password = $loginPassword;
+    #           try {
+    #               $result = $seafileAPI->updateAccount($userAccount);
+    #               if ($result != true) {
+    #                   logModuleCall(
+    #                       'seafile',
+    #                               __FUNCTION__,
+    #                       $params,
+    #                       "Cannot change password for " . $userAccount->email . ": Unknown error",
+    #                       ""
+    #                   );
+    #                   return "Das Passwort konnte nicht aktualisiert werden. Unbekannter Fehler.";
+    #               } else {
+    #                   update_query(   "tblcustomfieldsvalues",array(   "value" => $loginPassword,"updated_at"=> "now()", ),array("id" => $fieldID)   );
+    #                   logModuleCall(
+    #                       'seafile',
+    #                       __FUNCTION__,
+    #                       $params,
+    #                       "Changed password for " . $userAccount->email,
+    #                       ""
+    #                   );
+    #                   return 'success';
+    #               }
+    #           } catch (Exception $exe) {
+    #               logModuleCall(
+    #                       'seafile',
+    #                       __FUNCTION__,
+    #                       $params,
+    #                       "Cannot change password for " . $userAccount->email . ", the error was " . $exe->getMessage(),
+    #                       $exe->getTraceAsString()
+    #                   );
+    #               return "Fehler beim Update des Passworts, der Fehler war: " . $exe->getMessage();
+    #           }
+    #       } else {
+    #           logModuleCall(
+    #               'seafile',
+    #               __FUNCTION__,
+    #               $params,
+    #               "Changed password for " . $userAccount->email,
+    #               ""
+    #           );
+    #           return "Konnte den Account " . $params['username'] . " auf dem Server nicht finden";
+    #       }
+}
+
+
+
+function zimbraSingle_ClientPassword($params)
+{
+    /*      if (strcmp($params['status'],"Active") !== 0) {
+            return "Der Dienst ist gesperrt, das Passwort kann daher nicht geändert werden";
+        }
+        $password1 = $_POST['password1'];
+        $password2 = $_POST['password2'];
+
+        if (empty($password1) == true || empty($password2) == true) {
+            return "Bitte beide Passwörter zuerst ausfüllen";
+        }
+        if (strcmp($password1,$password2) !== 0) {
+            return "Die Passwörter stimmen nicht überein";
+        }
+
+        $checkPassword = checkPassword($password1);
+        if ($checkPassword != null) {
+            return $checkPassword;
+        }
+        $fieldID = getCustomFieldIDFor($params,"Passwort");
+
+        $seafileURL   = buildSeafileURL($params);
+        $apiuser      = getSeafileAdminUser($params);
+        $apipass      = getSeafileAdminPassword($params);
+
+        $seafileAPI = new SeafileAPI($seafileURL,$apiuser,$apipass);
+        if ($seafileAPI->login() != true) {
+            logModuleCall(
+                'seafile',
+                __FUNCTION__,
+                $params,
+                "Cannot login to " . $seafileURL,
+                ""
+            );
+            return "Login to " . $seafileURL . " fehlgeschlagen. Bitte den Administrator informieren.\n";
+        }
+
+        $userAccount = $seafileAPI->getAccountByEMail($params['username']);
+        if ($userAccount != null) {
+            $userAccount->password = $password1;
+            try {
+                $result = $seafileAPI->updateAccount($userAccount);
+                if ($result != true) {
+                    return "Das Passwort konnte nicht aktualisiert werden. Unbekannter Fehler.";
+                } else {
+                    update_query(   "tblcustomfieldsvalues",array(   "value" => $password1,"updated_at"=> "now()", ),array("id" => $fieldID)   );
+                    return 'success';
+                }
+            } catch (Exception $exe) {
+                    logModuleCall(
+                        'seafile',
+                        __FUNCTION__,
+                        $params,
+                        "Cannot change password for " . $userAccount->email . ", the error was " . $exe->getMessage(),
+                        $exe->getTraceAsString()
+                    );
+                return "Fehler beim Update des Passworts, der Fehler war: " . $exe->getMessage();
+            }
+        } else {
+            logModuleCall(
+                'seafile',
+                __FUNCTION__,
+                $params,
+                "Cannot find the Account " . $params['username'],
+                ""
+            );
+            return "Konnte den Account " . $params['username'] . " nicht finden";
+        } */
+}
+
+
+function zimbraSingle_CreateAccount($params)
+{
+    $response = zimbraSingleCreateAccount($params['customfields']);
+    if($response) {
+        return 'success';
+    }
+    return 'Error creating account';
+}
+
+function zimbraSingle_SuspendAccount($params)
+{
+    $response = zimbraSingleSuspendAccount($params['customfields']);
+    if($response) {
+        return 'success';
+    }
+    return 'Error suspending account';
+}
+
+function zimbraSingle_UnsuspendAccount($params)
+{
+    $response = zimbraSingleUnsuspendAccount($params['customfields']);
+    if($response) {
+        return 'success';
+    }
+    return 'Error unsuspending account';
+}
+
+function zimbraSingle_TerminateAccount($params)
+{
+    return zimbraSingleDeleteAccount($params['customfields']);
+}
+
+function zimbraSingle_genUsername($name)
+{
+    /*    $namelen = strlen($name);
+    $result = select_query("tblhosting","COUNT(*)",array("username" => $name));
+    $data = mysql_fetch_array($result);
+    $username_exists = $data[0];
+    $suffix=0;
+
+    while ($username_exists > 0) {
+        $suffix++;
+        $name = substr($name,0,$namelen).$suffix;
+
+        $result = select_query( "tblhosting", "COUNT(*)", array( "username" => $name ) );
+        $data = mysql_fetch_array($result);
+
+        $username_exists = $data[0];
+    }
+
+    return $name; */
+}
+
+function zimbraSingle_getCustomFieldIDFor($params, $fieldName)
+{
+    $Client = Client::find($params['userid']);
+    $clientFields = $Client->customFieldValues;
+
+    foreach ($Client->services as $service) {
+        //print "ServiceID: " . $service->id . " ?= " . $params['serviceid'] . " <br />";
+        // print nl2br(print_r($service,true));
+        if ($service->packageid == $params['packageid']) {
+            //print " => PackageID found <br />";
+            $serviceFields = $service->customFieldValues;
+            //print nl2br(print_r($serviceFields,true));
+            foreach ($serviceFields as $field) {
+                //print " ===> " . $field->customField->fieldName . " : " . $field->id . "</br />";
+                //print "    Field: " . $field->customField->fieldName . " ?= Search Field Name: " . $fieldName . " ? " . strcmp($field->customField->fieldName,$fieldName) . " : " . $field->id . " : " . $field->fieldid . "<br />";
+                if (strcmp($field->customField->fieldName, $fieldName) == 0) {
+                    return $field->id;
+                }
+            }
+        }
+    }
+    return -1;
+
+
+    /*
+        **** TESTING METHODS ****
+        Please do not remove this lines
+
+         // run through customfields
+        foreach($clientFields AS $field){
+              $HTML .= "Field ".$field->customField->fieldName.": ".$field->value."<br>";
+        }
+        return "";
+
+        $HTML .= "Service custom fields";
+        foreach($Client->services as $service) {
+            $HTML .= "----------------------------------------------------------<br />";
+            $HTML .= nl2br(print_r($service,true));
+            $HTML .= "----------------------------------------------------------<br />";
+            $ServiceFields = $service->customFieldValues;
+            foreach($ServiceFields as $field) {
+                //$HTML .= "Service field ".$field->customField->fieldName . ": ".$field->value."<br>";
+                //$HTML .= "----------------------------------------------------------<br />";
+                //$HTML .= nl2br(print_r($field,true));
+                //$HTML .= "Service field ".$field->customField->fieldName . "( FieldID: " . $field->fieldid . "/ ID: " . $field->id . "/ RelID:" . $field->relid . ") : " . $field->value . "<br>";
+                //$HTML .= "----------------------------------------------------------<br />";
+            }
+        }
+        */
+}
+

+ 118 - 0
zimbraSingle.php.2

@@ -0,0 +1,118 @@
+<?php
+
+/**
+ * WHMCS Zimbra Provisioning Module
+ *
+ * Provisioning for private user accounts on the Zimbra Server
+ *
+ * @see https://www.zimbra.com
+ * @copyright Copyright (c) Thurdata GmbH 2020
+ * @license GPL
+ */
+
+if (!defined("WHMCS")) {
+    die("This file cannot be accessed directly");
+}
+require_once dirname(__FILE__) . '/zimbraSingle.inc';
+
+function zimbraSingle_TestConnection($params)
+{
+    $auth = new Zm_Auth($params['serverip'], $params['serverusername'], $params['serverpassword'], "admin");
+    $login = $auth->login();
+    if(is_a($login, "Exception")) {
+        logModuleCall(
+            'zimbrasingle',
+            __FUNCTION__,
+            $params,
+            "Connection test to " . $params['serverip'] . " failed: Cannot login",
+            $login->getMessage()
+        );
+        return array(
+            'success' => false,
+            'error' => "Connection test to " . $params['serverip'] . " failed, the error was: " . $login->getMessage(),
+        );
+    } else {
+        return array(
+            'success' => true,
+            'error' => '',
+        );
+    }
+}
+
+function zimbraSingle_UsageUpdate($params)
+{
+}
+
+
+function zimbraSingle_ClientArea($params)
+{
+    $response = zimbraSingleClientArea($params['customfields']);
+    if($response) {
+        return 'success';
+    }
+    return $response;
+}
+
+
+function zimbraSingle_ChangePassword($params)
+{
+    $response = zimbraSingleChangePassword($params['customfields']);
+    if($response) {
+        return 'success';
+    }
+    return $response;
+}
+
+function zimbraSingle_CreateAccount($params)
+{
+    $response = zimbraSingleCreateAccount($params['customfields']);
+    if($response) {
+        return 'success';
+    }
+    return 'Error creating account';
+}
+
+function zimbraSingle_SuspendAccount($params)
+{
+    $response = zimbraSingleSuspendAccount($params['customfields']);
+    if($response) {
+        return 'success';
+    }
+    return 'Error suspending account';
+}
+
+function zimbraSingle_UnsuspendAccount($params)
+{
+    $response = zimbraSingleUnsuspendAccount($params['customfields']);
+    if($response) {
+        return 'success';
+    }
+    return 'Error unsuspending account';
+}
+
+function zimbraSingle_TerminateAccount($params)
+{
+    return zimbraSingleDeleteAccount($params['customfields']);
+}
+
+function zimbraSingle_genUsername($name)
+{
+    /*    $namelen = strlen($name);
+    $result = select_query("tblhosting","COUNT(*)",array("username" => $name));
+    $data = mysql_fetch_array($result);
+    $username_exists = $data[0];
+    $suffix=0;
+
+    while ($username_exists > 0) {
+        $suffix++;
+        $name = substr($name,0,$namelen).$suffix;
+
+        $result = select_query( "tblhosting", "COUNT(*)", array( "username" => $name ) );
+        $data = mysql_fetch_array($result);
+
+        $username_exists = $data[0];
+    }
+
+    return $name; */
+}
+