zimbraSingle.inc 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556
  1. <?php
  2. use WHMCS\Database\Capsule;
  3. require_once("api/Zm/Auth.php");
  4. require_once("api/Zm/Account.php");
  5. require_once("api/Zm/Domain.php");
  6. require_once("api/Zm/Server.php");
  7. function zimbraSingle_MetaData()
  8. {
  9. return array(
  10. 'DisplayName' => 'Zimbra Single Mailbox Provisioning',
  11. 'APIVersion' => '1.2',
  12. 'DefaultNonSSLPort' => '7071',
  13. 'DefaultSSLPort' => '7071',
  14. 'RequiresServer' => true,
  15. 'ServiceSingleSignOnLabel' => 'Login to Zimbra',
  16. 'AdminSingleSignOnLabel' => 'Login to Zimbra Admin'
  17. );
  18. }
  19. /**
  20. */
  21. function zimbraSingleGetAccess()
  22. {
  23. global $packageid;
  24. $accessData = array('zimbraServer' => '', 'adminUser' => '', 'adminPass' => '');
  25. $whmcs = App::self();
  26. logModuleCall(
  27. 'zimbrasingle',
  28. __FUNCTION__,
  29. $params,
  30. "debug: whmcs",
  31. $packageid
  32. );
  33. $serverGroupID = $whmcs->get_req_var('servergroup');
  34. $serverID = Capsule::table('tblservergroupsrel')
  35. ->select('serverid')
  36. ->where('groupid', '=', $serverGroupID)
  37. ->get();
  38. $servers = Capsule::table('tblservers')
  39. ->select('ipaddress', 'username', 'password')
  40. ->where('id', '=', $serverID[0]->serverid)
  41. ->where('active', '=', 1)
  42. ->get();
  43. $accessData['zimbraServer'] = $servers[0]->ipaddress;
  44. $accessData['adminUser'] = $servers[0]->username;
  45. $adminPassCrypt = $servers[0]->password;
  46. $adminPassDecrypt = localAPI('DecryptPassword', array('password2' => $adminPassCrypt));
  47. if ($adminPassDecrypt['result'] == 'success') {
  48. $accessData['adminPass'] = $adminPassDecrypt['password'];
  49. }
  50. return $accessData;
  51. }
  52. /**
  53. * Checks if a given email address in the given domain already exists
  54. *
  55. * @param $emailNameOnly The name before the @-sign only
  56. * @param $domainName The domain to search for existance of the email account
  57. * @return true if such an account was found or false if not
  58. */
  59. function zimbraSingleDoesEMailExist($emailNameOnly, $domainName)
  60. {
  61. $account_name = $emailNameOnly . "@" . $domainName;
  62. $accessData = zimbraSingleGetAccess();
  63. $api = new Zm_Auth($accessData['zimbraServer'], $accessData['adminUser'], $accessData['adminPass'], "admin");
  64. $login = $api->login();
  65. if(is_a($login, "Exception")) {
  66. logModuleCall(
  67. 'zimbrasingle',
  68. __FUNCTION__,
  69. $params,
  70. "Error : cannot login to " . $accessData['zimbraServer'],
  71. "$login->getMessage()"
  72. );
  73. exit();
  74. } else {
  75. $apiAccountManager = new Zm_Account($api);
  76. if( $apiAccountManager->accountExists($account_name)) {
  77. return true;
  78. } else {
  79. return false;
  80. }
  81. }
  82. }
  83. /**
  84. */
  85. function zimbraSingleCreateAccount($userData)
  86. {
  87. $accessData = zimbraSingleGetAccess();
  88. $attrs = array();
  89. $attrs["gn"] = $userData["givenname"];
  90. $attrs["sn"] = $userData["sn"];
  91. $attrs["displayName"] = $attrs["gn"] . " " . $attrs["sn"];
  92. $passDecrypt = localAPI('DecryptPassword', array('password2' => $userData['password']));
  93. if ($passDecrypt['result'] == 'success') {
  94. $userData['password'] = $passDecrypt['password'];
  95. }
  96. $account_name = $userData['username'] . '@' . $userData['maildomain'];
  97. $api = new Zm_Auth($accessData['zimbraServer'], $accessData['adminUser'], $accessData['adminPass'], "admin");
  98. $login = $api->login();
  99. if(is_a($login, "Exception")) {
  100. logModuleCall(
  101. 'zimbrasingle',
  102. __FUNCTION__,
  103. $params,
  104. "Error : cannot login to " . $accessData['zimbraServer'],
  105. ""
  106. );
  107. return false;
  108. }
  109. $apiAccountManager = new Zm_Account($api);
  110. $cosName = $userData['cos'];
  111. $cosID = $apiAccountManager->getCosId($cosName);
  112. if(is_a($cosID, "Exception")) {
  113. logModuleCall(
  114. 'zimbrasingle',
  115. __FUNCTION__,
  116. $params,
  117. "Error : serviceclass $cosName not available",
  118. ""
  119. );
  120. return false;
  121. }
  122. $attrs['zimbraCOSId'] = $cosID;
  123. $id = $apiAccountManager->createAccount($account_name, $userData['password'], $attrs);
  124. if(is_a($id, "Exception")) {
  125. logModuleCall(
  126. 'zimbrasingle',
  127. __FUNCTION__,
  128. $params,
  129. "Error : account $account_name not created",
  130. ""
  131. );
  132. return false;
  133. }
  134. return $id;
  135. }
  136. function zimbraSingleSuspendAccount($userData)
  137. {
  138. $accessData = zimbraSingleGetAccess();
  139. $account_name = $userData['username'] . '@' . $userData['maildomain'];
  140. $api = new Zm_Auth($accessData['zimbraServer'], $accessData['adminUser'], $accessData['adminPass'], "admin");
  141. $login = $api->login();
  142. if(is_a($login, "Exception")) {
  143. logModuleCall(
  144. 'zimbrasingle',
  145. __FUNCTION__,
  146. $params,
  147. "Error : cannot login to " . $accessData['zimbraServer'],
  148. ""
  149. );
  150. return false;
  151. } else {
  152. $apiAccountManager = new Zm_Account($api);
  153. $response = $apiAccountManager->setAccountStatus($account_name, "locked");
  154. if(is_a($response, "Exception")) {
  155. logModuleCall(
  156. 'zimbrasingle',
  157. __FUNCTION__,
  158. $params,
  159. "Error : account $account_name could not locked",
  160. ""
  161. );
  162. return false;
  163. } else {
  164. return $response;
  165. }
  166. }
  167. }
  168. function zimbraSingleUnsuspendAccount($userData)
  169. {
  170. $accessData = zimbraSingleGetAccess();
  171. $account_name = $userData['username'] . '@' . $userData['maildomain'];
  172. $api = new Zm_Auth($accessData['zimbraServer'], $accessData['adminUser'], $accessData['adminPass'], "admin");
  173. $login = $api->login();
  174. if(is_a($login, "Exception")) {
  175. logModuleCall(
  176. 'zimbrasingle',
  177. __FUNCTION__,
  178. $params,
  179. "Error : cannot login to " . $accessData['zimbraServer'],
  180. ""
  181. );
  182. return false;
  183. } else {
  184. $apiAccountManager = new Zm_Account($api);
  185. $response = $apiAccountManager->setAccountStatus($account_name, "active");
  186. if(is_a($response, "Exception")) {
  187. logModuleCall(
  188. 'zimbrasingle',
  189. __FUNCTION__,
  190. $params,
  191. "Error : account $account_name could not unlocked",
  192. ""
  193. );
  194. return false;
  195. } else {
  196. return $response;
  197. }
  198. }
  199. }
  200. function zimbraSingleDeleteAccount($userData)
  201. {
  202. $accessData = zimbraSingleGetAccess();
  203. $account_name = $userData['username'] . '@' . $userData['maildomain'];
  204. $api = new Zm_Auth($accessData['zimbraServer'], $accessData['adminUser'], $accessData['adminPass'], "admin");
  205. $login = $api->login();
  206. if(is_a($login, "Exception")) {
  207. logModuleCall(
  208. 'zimbrasingle',
  209. __FUNCTION__,
  210. $params,
  211. "Error : cannot login to " . $accessData['zimbraServer'],
  212. ""
  213. );
  214. return false;
  215. } else {
  216. $apiAccountManager = new Zm_Account($api);
  217. $response = $apiAccountManager->getAccountStatus($account_name);
  218. if(is_a($response, "Exception")) {
  219. logModuleCall(
  220. 'zimbrasingle',
  221. __FUNCTION__,
  222. $params,
  223. "Error : account $account_name could not verified",
  224. ""
  225. );
  226. return false;
  227. }
  228. if ($response != 'locked') {
  229. return "Account $account_name active, suspend account first";
  230. }
  231. $response = $apiAccountManager->deleteAccount($account_name);
  232. if(is_a($response, "Exception")) {
  233. logModuleCall(
  234. 'zimbrasingle',
  235. __FUNCTION__,
  236. $params,
  237. "Error : account $account_name could not removed",
  238. ""
  239. );
  240. return false;
  241. }
  242. return 'success';
  243. }
  244. }
  245. function zimbraSingleChangePassword($userData) {
  246. $accessData = zimbraSingleGetAccess();
  247. $passDecrypt = localAPI('DecryptPassword', array('password2' => $userData['password']));
  248. if ($passDecrypt['result'] == 'success') {
  249. $userData['password'] = $passDecrypt['password'];
  250. }
  251. if ($checkPW = zimbraSingleCheckPassword($userData['password'])) {
  252. return $checkPW;
  253. }
  254. $account_name = $userData['username'] . '@' . $userData['maildomain'];
  255. $api = new Zm_Auth($accessData['zimbraServer'], $accessData['adminUser'], $accessData['adminPass'], "admin");
  256. $login = $api->login();
  257. if(is_a($login, "Exception")) {
  258. logModuleCall(
  259. 'zimbrasingle',
  260. __FUNCTION__,
  261. $params,
  262. "Error : cannot login to " . $accessData['zimbraServer'],
  263. ""
  264. );
  265. return false;
  266. } else {
  267. $apiAccountManager = new Zm_Account($api);
  268. $response = $apiAccountManager->setAccountPassword($account_name, $userData['password']);
  269. if(is_a($response, "Exception")) {
  270. logModuleCall(
  271. 'zimbrasingle',
  272. __FUNCTION__,
  273. $params,
  274. "Error : password for $account_name could not be set",
  275. ""
  276. );
  277. return false;
  278. } else {
  279. return $response;
  280. }
  281. }
  282. }
  283. function zimbraSingleChangePackage($userData) {
  284. $accessData = zimbraSingleGetAccess();
  285. $account_name = $userData['username'] . '@' . $userData['maildomain'];
  286. $api = new Zm_Auth($accessData['zimbraServer'], $accessData['adminUser'], $accessData['adminPass'], "admin");
  287. $login = $api->login();
  288. if(is_a($login, "Exception")) {
  289. logModuleCall(
  290. 'zimbrasingle',
  291. __FUNCTION__,
  292. $params,
  293. "Error : cannot login to " . $accessData['zimbraServer'],
  294. ""
  295. );
  296. return false;
  297. }
  298. $apiAccountManager = new Zm_Account($api);
  299. $response = $apiAccountManager->setAccountCos($account_name, $userData['cos']);
  300. if(is_a($response, "Exception")) {
  301. logModuleCall(
  302. 'zimbrasingle',
  303. __FUNCTION__,
  304. $params,
  305. "Error : class of service for $account_name could not be set",
  306. ""
  307. );
  308. return false;
  309. }
  310. return $response;
  311. }
  312. function zimbraSingleClientArea($userData)
  313. {
  314. $accessData = zimbraSingleGetAccess();
  315. $account_name = $userData['username'] . '@' . $userData['maildomain'];
  316. $api = new Zm_Auth($accessData['zimbraServer'], $accessData['adminUser'], $accessData['adminPass'], "admin");
  317. $login = $api->login();
  318. if(is_a($login, "Exception")) {
  319. logModuleCall(
  320. 'zimbrasingle',
  321. __FUNCTION__,
  322. $params,
  323. "Error : cannot login to " . $accessData['zimbraServer'],
  324. ""
  325. );
  326. return false;
  327. } else {
  328. $apiAccountManager = new Zm_Account($api);
  329. $response = $apiAccountManager->getAccountInfo($account_name);
  330. if(is_a($response, "Exception")) {
  331. logModuleCall(
  332. 'zimbrasingle',
  333. __FUNCTION__,
  334. $params,
  335. "Error : could not gather informations for $account_name",
  336. ""
  337. );
  338. return false;
  339. } else {
  340. $webMailURL = recursiveFindAll( $response, 'PUBLICMAILURL');
  341. logModuleCall(
  342. 'zimbrasingle',
  343. __FUNCTION__,
  344. $params,
  345. "debug",
  346. $webMailURL
  347. );
  348. return $webMailURL;
  349. }
  350. }
  351. }
  352. function zimbraSingleConfigOptions($params) {
  353. $accessData = zimbraSingleGetAccess();
  354. $api = new Zm_Auth($accessData['zimbraServer'], $accessData['adminUser'], $accessData['adminPass'], "admin");
  355. $login = $api->login();
  356. if(is_a($login, "Exception")) {
  357. logModuleCall(
  358. 'zimbrasingle',
  359. __FUNCTION__,
  360. $params,
  361. "Error : cannot login to " . $accessData['zimbraServer'],
  362. ""
  363. );
  364. return false;
  365. }
  366. $apiAccountManager = new Zm_Account($api);
  367. $response = $apiAccountManager->getAllCos();
  368. if(is_a($response, "Exception")) {
  369. logModuleCall(
  370. 'zimbrasingle',
  371. __FUNCTION__,
  372. $params,
  373. "Error : could not fetch classes of service",
  374. ""
  375. );
  376. return false;
  377. }
  378. $cosNames = recursiveFindAll($response, 'NAME');
  379. $configOptions = array();
  380. $configOptions['cos'] = array(
  381. "FriendlyName" => "Class of Service",
  382. "Type" => "dropdown",
  383. "Options" => implode(',', $cosNames),
  384. "Description" => "Select COS",
  385. );
  386. $apiDomainManager = new Zm_Domain($api);
  387. $response = $apiDomainManager->getAllDomains();
  388. if(is_a($response, "Exception")) {
  389. logModuleCall(
  390. 'zimbrasingle',
  391. __FUNCTION__,
  392. $params,
  393. "Error : could fetch available maildomains",
  394. ""
  395. );
  396. return false;
  397. }
  398. $domainNames = recursiveFindAll($response, 'NAME');
  399. $configOptions['maildomains'] = array(
  400. "FriendlyName" => "Mail Domain",
  401. "Type" => "dropdown",
  402. "Multiple" => true,
  403. "Options" => implode(',', $domainNames),
  404. "Description" => "select maildomains",
  405. );
  406. return $configOptions;
  407. }
  408. function zimbraSingleCreateCustomFields($packageconfigoption)
  409. {
  410. $whmcs = App::self();
  411. $productID = $whmcs->get_req_var('id');
  412. Capsule::table('tblcustomfields')
  413. ->where('relid', '=', $productID)
  414. ->delete();
  415. Capsule::table('tblcustomfields')
  416. ->insert(
  417. array(
  418. 'type' => 'product',
  419. 'relid' => $productID,
  420. 'fieldname' => 'givenname | Vorname',
  421. 'fieldtype' => 'text',
  422. 'required' => 'on',
  423. 'showorder' => 'on',
  424. 'sortorder' => '0'
  425. )
  426. );
  427. Capsule::table('tblcustomfields')
  428. ->insert(
  429. array(
  430. 'type' => 'product',
  431. 'relid' => $productID,
  432. 'fieldname' => 'sn | Nachname',
  433. 'fieldtype' => 'text',
  434. 'required' => 'on',
  435. 'showorder' => 'on',
  436. 'sortorder' => '1'
  437. )
  438. );
  439. Capsule::table('tblcustomfields')
  440. ->insert(
  441. array(
  442. 'type' => 'product',
  443. 'relid' => $productID,
  444. 'fieldname' => 'username | E-Mail Name',
  445. 'fieldtype' => 'text',
  446. 'required' => 'on',
  447. 'showorder' => 'on',
  448. 'sortorder' => '2'
  449. )
  450. );
  451. Capsule::table('tblcustomfields')
  452. ->insert(
  453. array(
  454. 'type' => 'product',
  455. 'relid' => $productID,
  456. 'fieldname' => 'maildomain | Mail Domaine',
  457. 'fieldtype' => 'dropdown',
  458. 'fieldoptions' => implode(',', $packageconfigoption[2]),
  459. 'required' => 'on',
  460. 'showorder' => 'on',
  461. 'sortorder' => '3'
  462. )
  463. );
  464. Capsule::table('tblcustomfields')
  465. ->insert(
  466. array(
  467. 'type' => 'product',
  468. 'relid' => $productID,
  469. 'fieldname' => 'password | Password',
  470. 'fieldtype' => 'password',
  471. 'required' => 'on',
  472. 'showorder' => 'on',
  473. 'sortorder' => '4'
  474. )
  475. );
  476. Capsule::table('tblcustomfields')
  477. ->insert(
  478. array(
  479. 'type' => 'product',
  480. 'relid' => $productID,
  481. 'fieldname' => 'cos | Class of Service',
  482. 'fieldtype' => 'dropdown',
  483. 'fieldoptions' => $packageconfigoption[1],
  484. 'adminonly' => 'on',
  485. 'required' => 'on',
  486. 'sortorder' => '5'
  487. )
  488. );
  489. }
  490. function recursiveFindAll($haystack, $needle)
  491. {
  492. $values = array();
  493. $iterator = new RecursiveArrayIterator($haystack);
  494. $recursive = new RecursiveIteratorIterator(
  495. $iterator,
  496. RecursiveIteratorIterator::SELF_FIRST
  497. );
  498. foreach ($recursive as $key => $value) {
  499. if ($key === $needle) {
  500. array_push($values, $value);
  501. }
  502. }
  503. return $values;
  504. }
  505. function zimbraSingleCheckPassword($pwd)
  506. {
  507. $message = '';
  508. if (strlen($pwd) < 9) {
  509. $message .= "Das das Passwort ist zu kurz. Es werden mind. 9 Zeichen benötigt<br>";
  510. }
  511. if (!preg_match("#[0-9]+#", $pwd)) {
  512. $message .= "Das Passwort muss mindestens eine Zahl enthalten<br>";
  513. }
  514. if (!preg_match("#[A-Z]+#", $pwd)) {
  515. $message .= "Das Passwort muss mindestens einen Grossbuchstaben (A-Z) enthalten<br>";
  516. }
  517. if (!preg_match("#[a-z]+#", $pwd)) {
  518. $message .= "Das Passwort muss mindestens einen Kleinbuchstaben (a-z) enthalten<br>";
  519. }
  520. if (!preg_match("#[^\w]+#", $pwd)) {
  521. $message .= "Das Passwort muss mindestens ein Sonderzeichen (.,-:=) enthalten<br>";
  522. }
  523. return $message;
  524. }
  525. function zimbraSingleTestFunction()
  526. {
  527. return 'blubb';
  528. }