api.ldap.php 17 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544
  1. <?php
  2. /**
  3. * LDAP database management class
  4. */
  5. class UbillingLDAPManager {
  6. /**
  7. * Contains available LDAP users as id=>userdata
  8. *
  9. * @var string
  10. */
  11. protected $allUsers = array();
  12. /**
  13. * Contains all of available user groups as id=>name
  14. *
  15. * @var array
  16. */
  17. protected $allGroups = array();
  18. /**
  19. * System message helper object placeholder
  20. *
  21. * @var object
  22. */
  23. protected $messages = '';
  24. const URL_ME = '?module=ldapmgr';
  25. /**
  26. * Even if you can forget, you can't erase the past. Kenzo Tenma.
  27. */
  28. public function __construct() {
  29. $this->initMessages();
  30. $this->loadUsers();
  31. $this->loadGroups();
  32. }
  33. /**
  34. * Inits system message helper as local instance
  35. *
  36. * @return void
  37. */
  38. protected function initMessages() {
  39. $this->messages = new UbillingMessageHelper();
  40. }
  41. /**
  42. * Loads existing users from database into protected property for further usage
  43. *
  44. * @return void
  45. */
  46. protected function loadUsers() {
  47. $query = "SELECT * from `ldap_users`";
  48. $all = simple_queryall($query);
  49. if (!empty($all)) {
  50. foreach ($all as $io => $each) {
  51. $this->allUsers[$each['id']] = $each;
  52. }
  53. }
  54. }
  55. /**
  56. * Sets available groups options
  57. *
  58. * @return
  59. */
  60. protected function loadGroups() {
  61. $query = "SELECT * from `ldap_groups`";
  62. $all = simple_queryall($query);
  63. if (!empty($all)) {
  64. foreach ($all as $io => $each) {
  65. $this->allGroups[$each['id']] = $each['name'];
  66. }
  67. }
  68. }
  69. /**
  70. * Create new group in database
  71. *
  72. * @param string $name
  73. *
  74. * @return void
  75. */
  76. public function createGroup($name) {
  77. $nameF = mysql_real_escape_string($name);
  78. $query = "INSERT INTO `ldap_groups` (`id`,`name`) VALUES ";
  79. $query.="(NULL,'" . $nameF . "');";
  80. nr_query($query);
  81. $newId = simple_get_lastid('ldap_groups');
  82. log_register('LDAPMGR GROUP CREATE `' . $name . '` [' . $newId . ']');
  83. }
  84. /**
  85. * Deletes existing group from database
  86. *
  87. * @param int $groupId
  88. *
  89. * @return void/string on error
  90. */
  91. public function deleteGroup($groupId) {
  92. $result = '';
  93. $groupId = vf($groupId, 3);
  94. if (isset($this->allGroups[$groupId])) {
  95. if (!$this->isGroupProtected($groupId)) {
  96. $query = "DELETE FROM `ldap_groups` WHERE `id`='" . $groupId . "';";
  97. nr_query($query);
  98. log_register('LDAPMGR GROUP DELETE [' . $groupId . ']');
  99. } else {
  100. $result.=__('Something went wrong') . ': EX_GROUPID_USED_BY_SOMEONE';
  101. }
  102. } else {
  103. $result.=__('Something went wrong') . ': EX_GROUPID_NOT_EXISTS';
  104. }
  105. return ($result);
  106. }
  107. /**
  108. * Renders group creation interface, Fuck yeah!
  109. *
  110. * @return string
  111. */
  112. public function renderGroupCreateFrom() {
  113. $result = '';
  114. $inputs = wf_TextInput('newldapgroupname', __('Name'), '', false, 20);
  115. $inputs.= wf_Submit(__('Create'));
  116. $result.=wf_Form(self::URL_ME . '&groups=true', 'POST', $inputs, 'glamour');
  117. return ($result);
  118. }
  119. /**
  120. * Renders existing groups list with some controls
  121. *
  122. * @return string
  123. */
  124. public function renderGroupsList() {
  125. $result = '';
  126. if (!empty($this->allGroups)) {
  127. $cells = wf_TableCell(__('ID'));
  128. $cells.= wf_TableCell(__('Name'));
  129. $cells.= wf_TableCell(__('Actions'));
  130. $rows = wf_TableRow($cells, 'row1');
  131. foreach ($this->allGroups as $io => $each) {
  132. $cells = wf_TableCell($io);
  133. $cells.= wf_TableCell($each);
  134. $actLinks = wf_JSAlert(self::URL_ME . '&groups=true&deletegroupid=' . $io, web_delete_icon(), $this->messages->getDeleteAlert());
  135. $cells.= wf_TableCell($actLinks);
  136. $rows.= wf_TableRow($cells, 'row5');
  137. }
  138. $result.=wf_TableBody($rows, '100%', 0, 'sortable');
  139. } else {
  140. $result.=$this->messages->getStyledMessage(__('Nothing to show'), 'info');
  141. }
  142. return ($result);
  143. }
  144. /**
  145. * Check is user login unique or not?
  146. *
  147. * @param string $login
  148. *
  149. * @return bool
  150. */
  151. protected function isUserUnique($login) {
  152. $login = trim($login);
  153. $result = true;
  154. if (!empty($this->allUsers)) {
  155. foreach ($this->allUsers as $io => $each) {
  156. if ($each['login'] == $login) {
  157. $result = false;
  158. }
  159. }
  160. }
  161. return ($result);
  162. }
  163. /**
  164. * Check is group protected from deletion?
  165. *
  166. * @param int $groupId
  167. *
  168. * @return bool
  169. */
  170. protected function isGroupProtected($groupId) {
  171. $result = false;
  172. $groupId = vf($groupId, 3);
  173. if (!empty($this->allUsers)) {
  174. foreach ($this->allUsers as $io => $eachUser) {
  175. $userGroups = json_decode($eachUser['groups'], true);
  176. if (isset($userGroups[$groupId])) {
  177. $result = true;
  178. }
  179. }
  180. }
  181. return ($result);
  182. }
  183. /**
  184. * Creates new user in database
  185. *
  186. * @param string $login
  187. * @param string $password
  188. * @param array $groups
  189. *
  190. * @return void
  191. */
  192. public function createUser($login, $password, $groups) {
  193. $loginF = mysql_real_escape_string($login);
  194. if ($this->isUserUnique($loginF)) {
  195. $passwordF = mysql_real_escape_string($password);
  196. $groupsList = json_encode($groups);
  197. $query = "INSERT INTO `ldap_users` (`id`,`login`,`password`,`groups`,`changed`) VALUES ";
  198. $query.="(NULL,'" . $loginF . "','" . $passwordF . "','" . $groupsList . "','1');";
  199. nr_query($query);
  200. $this->pushQueue('usercreate', $login);
  201. $passParam = array('login' => $login, 'password' => $password);
  202. $passParam = json_encode($passParam);
  203. $this->pushQueue('userpassword', $passParam);
  204. $taskGroups = array('login' => $login, 'groups' => $groups);
  205. $taskGroups = json_encode($taskGroups);
  206. $this->pushQueue('usergroups', $taskGroups);
  207. $newId = simple_get_lastid('ldap_users');
  208. log_register('LDAPMGR USER CREATE `' . $login . '` [' . $newId . ']');
  209. }
  210. }
  211. /**
  212. * Changes user groups
  213. *
  214. * @param int $userId
  215. * @param array $newGroups
  216. *
  217. * @return void
  218. */
  219. public function changeGroups($userId, $newGroups) {
  220. $userId = vf($userId, 3);
  221. $pushGroups = array();
  222. $removeGroups = array();
  223. if (isset($this->allUsers[$userId])) {
  224. $userData = $this->allUsers[$userId];
  225. $userLogin = $userData['login'];
  226. $oldGroups = json_decode($userData['groups'], true);
  227. if (!empty($newGroups)) {
  228. //checking for new groups
  229. foreach ($newGroups as $newGroupId => $newGroupName) {
  230. if (!isset($oldGroups[$newGroupId])) {
  231. $pushGroups[$newGroupId] = $newGroupName;
  232. }
  233. }
  234. }
  235. //checking for removed groups
  236. if (!empty($oldGroups)) {
  237. foreach ($oldGroups as $oldGroupId => $oldGroupName) {
  238. if (!isset($newGroups[$oldGroupId])) {
  239. $removeGroups[$oldGroupId] = $oldGroupName;
  240. }
  241. }
  242. }
  243. //is some changes available?
  244. if ((!empty($pushGroups)) OR ( !empty($removeGroups))) {
  245. //saving new groups into user profile
  246. simple_update_field('ldap_users', 'groups', json_encode($newGroups), "WHERE `id`='" . $userId . "'");
  247. log_register('LDAPMGR USER GROUPS CHANGED `' . $userLogin . '` [' . $userId . ']');
  248. //adding some new groups
  249. if (!empty($pushGroups)) {
  250. $taskGroups = array('login' => $userLogin, 'groups' => $pushGroups);
  251. $taskGroups = json_encode($taskGroups);
  252. $this->pushQueue('usergroups', $taskGroups);
  253. }
  254. //deleting removed groups
  255. if (!empty($removeGroups)) {
  256. $taskGroups = array('login' => $userLogin, 'groups' => $removeGroups);
  257. $taskGroups = json_encode($taskGroups);
  258. $this->pushQueue('usergroupsremove', $taskGroups);
  259. }
  260. /**
  261. * Jugemu jugemu gokou no surikire
  262. * Kaijari suigyo no suigyoumatsu
  263. * Unraimatsu fuuraimatsu
  264. * Kuuneru tokoro ni sumu tokoro
  265. */
  266. }
  267. }
  268. }
  269. /**
  270. * Deletes some existing user from database
  271. *
  272. * @param int $userId
  273. *
  274. * @return void/string on error
  275. */
  276. public function deleteUser($userId) {
  277. $result = '';
  278. $userId = vf($userId, 3);
  279. if (isset($this->allUsers[$userId])) {
  280. $userData = $this->allUsers[$userId];
  281. $query = "DELETE from `ldap_users` WHERE `id`='" . $userId . "';";
  282. nr_query($query);
  283. $this->pushQueue('userdelete', $userData['login']);
  284. log_register('LDAPMGR USER DELETE `' . $userData['login'] . '` [' . $userId . ']');
  285. } else {
  286. $result = __('Something went wrong') . ': EX_USERID_NOT_EXISTS';
  287. }
  288. return ($result);
  289. }
  290. /**
  291. * Renders password editing form
  292. *
  293. * @return string
  294. */
  295. protected function renderUserPasswordForm($userId) {
  296. $result = '';
  297. $userId = vf($userId, 3);
  298. if (isset($this->allUsers[$userId])) {
  299. $userData = $this->allUsers[$userId];
  300. $inputs = wf_HiddenInput('passchid', $userId);
  301. $inputs.= wf_PasswordInput('passchpass', __('Password'), $userData['password'], false, 15);
  302. $inputs.=wf_Submit(__('Save'));
  303. $result.=wf_Form(self::URL_ME, 'POST', $inputs, 'glamour');
  304. }
  305. return ($result);
  306. }
  307. /**
  308. * Renders user groups editing form
  309. *
  310. * @param int $userId
  311. *
  312. * @return string
  313. */
  314. protected function renderUserGroupsForm($userId) {
  315. $result = '';
  316. $userId = vf($userId, 3);
  317. if (isset($this->allUsers[$userId])) {
  318. $groupsInputs = '';
  319. $userData = $this->allUsers[$userId];
  320. $currentGroups = json_decode($userData['groups'], true);
  321. if (!empty($this->allGroups)) {
  322. foreach ($this->allGroups as $io => $each) {
  323. $checkFlag = (isset($currentGroups[$io])) ? true : false;
  324. $groupsInputs.=wf_CheckInput('ldapusergroup_' . $io, $each, true, $checkFlag);
  325. }
  326. }
  327. $inputs = wf_HiddenInput('chusergroupsuserid', $userId);
  328. $inputs.= $groupsInputs;
  329. $inputs.=wf_delimiter();
  330. $inputs.=wf_Submit(__('Save'));
  331. $result = wf_Form(self::URL_ME, 'POST', $inputs, 'glamour');
  332. }
  333. return ($result);
  334. }
  335. /**
  336. * Pushes some task for queue
  337. *
  338. * @param string $task
  339. * @param string $param
  340. *
  341. * @return void
  342. */
  343. protected function pushQueue($task, $param) {
  344. $task = mysql_real_escape_string($task);
  345. $param = mysql_real_escape_string($param);
  346. $query = "INSERT INTO `ldap_queue` (`id`,`task`,`param`) VALUES ";
  347. $query.="(NULL,'" . $task . "','" . $param . "');";
  348. nr_query($query);
  349. }
  350. /**
  351. * Changes user password and stores this into queue
  352. *
  353. * @param int $userId
  354. * @param string $newPassword
  355. *
  356. * @return void/string on error
  357. */
  358. public function changeUserPassword($userId, $newPassword) {
  359. $result = '';
  360. $userId = vf($userId, 3);
  361. if (isset($this->allUsers[$userId])) {
  362. $userData = $this->allUsers[$userId];
  363. $login = $userData['login'];
  364. if ($userData['password'] != $newPassword) {
  365. simple_update_field('ldap_users', 'password', $newPassword, "WHERE `id`='" . $userId . "'");
  366. $passParam = array('login' => $login, 'password' => $newPassword);
  367. $passParam = json_encode($passParam);
  368. $this->pushQueue('userpassword', $passParam);
  369. log_register('LDAPMGR USER PASSWORD CHANGED `' . $login . '` [' . $userId . ']');
  370. }
  371. } else {
  372. $result = __('Something went wrong') . ': EX_USERID_NOT_EXISTS';
  373. }
  374. return ($result);
  375. }
  376. /**
  377. * Renders user creation form
  378. *
  379. * @return string
  380. */
  381. protected function renderUserCreateForm() {
  382. $result = '';
  383. $groupsInputs = '';
  384. if (!empty($this->allGroups)) {
  385. foreach ($this->allGroups as $io => $each) {
  386. $groupsInputs.=wf_CheckInput('ldapusergroup_' . $io, $each, true, false);
  387. }
  388. $inputs = wf_TextInput('newldapuserlogin', __('Login'), '', true, 20);
  389. $inputs.= wf_TextInput('newldapuserpassword', __('Password'), '', true, 20);
  390. $inputs.=$groupsInputs;
  391. $inputs.=wf_tag('br');
  392. $inputs.= wf_Submit(__('Create'));
  393. $result.=wf_Form(self::URL_ME, 'POST', $inputs, 'glamour');
  394. } else {
  395. $result.=$this->messages->getStyledMessage(__('Oh no') . ': ' . __('No existing groups available'), 'warning');
  396. }
  397. return ($result);
  398. }
  399. /**
  400. * Catches and preprocess user groups
  401. *
  402. * @return array
  403. */
  404. public function catchNewUserGroups() {
  405. $result = array();
  406. if (!empty($_POST)) {
  407. foreach ($_POST as $io => $each) {
  408. if (ispos($io, 'ldapusergroup')) {
  409. $groupId = vf($io, 3);
  410. $result[$groupId] = $this->allGroups[$groupId];
  411. }
  412. }
  413. }
  414. return ($result);
  415. }
  416. /**
  417. * Flushes processed queue in database
  418. *
  419. * @return void
  420. */
  421. protected function flushQueue() {
  422. $query = "TRUNCATE TABLE `ldap_queue`;";
  423. nr_query($query);
  424. }
  425. /**
  426. * Returns current unprocessed tasks queue
  427. *
  428. * @return void
  429. */
  430. public function getQueue() {
  431. $query = "SELECT * from `ldap_queue` ORDER BY `id` ASC";
  432. $queue = simple_queryall($query);
  433. $queue = json_encode($queue);
  434. print($queue);
  435. $this->flushQueue();
  436. die();
  437. }
  438. /**
  439. * Renders main control panel
  440. *
  441. * @return string
  442. */
  443. public function panel() {
  444. $result = '';
  445. if (!wf_CheckGet(array('groups'))) {
  446. $result.=wf_modalAuto(wf_img('skins/add_icon.png') . ' ' . __('Users registration'), __('Users registration'), $this->renderUserCreateForm(), 'ubButton') . ' ';
  447. $result.= wf_Link(self::URL_ME . '&groups=true', web_icon_extended() . ' ' . __('Groups'), false, 'ubButton');
  448. } else {
  449. $result.=wf_BackLink(self::URL_ME) . ' ';
  450. $result.=wf_modalAuto(wf_img('skins/add_icon.png') . ' ' . __('Create'), __('Create'), $this->renderGroupCreateFrom(), 'ubButton');
  451. }
  452. return ($result);
  453. }
  454. /**
  455. * Unpacks and
  456. *
  457. * @param string $groupsData
  458. *
  459. * @return string
  460. */
  461. protected function previewGroups($groupsData) {
  462. $result = '';
  463. if (!empty($groupsData)) {
  464. $groupsData = json_decode($groupsData);
  465. if (!empty($groupsData)) {
  466. foreach ($groupsData as $groupId => $groupName) {
  467. $result.=$groupName . ' ';
  468. }
  469. }
  470. }
  471. return ($result);
  472. }
  473. /**
  474. * Renders existing users list and some controls
  475. *
  476. * @return string
  477. */
  478. public function renderUserList() {
  479. $result = '';
  480. if (!empty($this->allUsers)) {
  481. $cells = wf_TableCell(__('ID'));
  482. $cells.= wf_TableCell(__('Login'));
  483. $cells.= wf_TableCell(__('Password'));
  484. $cells.= wf_TableCell(__('Groups'));
  485. $cells.= wf_TableCell(__('Actions'));
  486. $rows = wf_TableRow($cells, 'row1');
  487. foreach ($this->allUsers as $io => $each) {
  488. $cells = wf_TableCell($each['id']);
  489. $cells.= wf_TableCell($each['login']);
  490. $userPass = __('Hidden');
  491. $cells.= wf_TableCell($userPass);
  492. $cells.= wf_TableCell($this->previewGroups($each['groups']));
  493. $actLinks = wf_JSAlert(self::URL_ME . '&deleteuserid=' . $each['id'], web_delete_icon(), $this->messages->getDeleteAlert()) . ' ';
  494. $actLinks.= wf_modalAuto(wf_img('skins/icon_key.gif', __('Password')), __('Password'), $this->renderUserPasswordForm($each['id'])) . ' ';
  495. $actLinks.=wf_modalAuto(web_icon_extended(__('Groups')), __('Groups'), $this->renderUserGroupsForm($each['id']));
  496. $cells.= wf_TableCell($actLinks);
  497. $rows.= wf_TableRow($cells, 'row5');
  498. }
  499. $result.=wf_TableBody($rows, '100%', 0, 'sortable');
  500. } else {
  501. $result.=$this->messages->getStyledMessage(__('Nothing to show'), 'info');
  502. }
  503. return ($result);
  504. }
  505. }
  506. ?>