UserGroups.php 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379
  1. <?php
  2. /* vim: set expandtab sw=4 ts=4 sts=4: */
  3. /**
  4. * set of functions for user group handling
  5. *
  6. * @package PhpMyAdmin
  7. */
  8. namespace PhpMyAdmin\Server;
  9. use PhpMyAdmin\Relation;
  10. use PhpMyAdmin\Url;
  11. use PhpMyAdmin\Util;
  12. /**
  13. * PhpMyAdmin\Server\UserGroups class
  14. *
  15. * @package PhpMyAdmin
  16. */
  17. class UserGroups
  18. {
  19. /**
  20. * Return HTML to list the users belonging to a given user group
  21. *
  22. * @param string $userGroup user group name
  23. *
  24. * @return string HTML to list the users belonging to a given user group
  25. */
  26. public static function getHtmlForListingUsersofAGroup($userGroup)
  27. {
  28. $relation = new Relation();
  29. $html_output = '<h2>'
  30. . sprintf(__('Users of \'%s\' user group'), htmlspecialchars($userGroup))
  31. . '</h2>';
  32. $cfgRelation = $relation->getRelationsParam();
  33. $usersTable = Util::backquote($cfgRelation['db'])
  34. . "." . Util::backquote($cfgRelation['users']);
  35. $sql_query = "SELECT `username` FROM " . $usersTable
  36. . " WHERE `usergroup`='" . $GLOBALS['dbi']->escapeString($userGroup)
  37. . "'";
  38. $result = $relation->queryAsControlUser($sql_query, false);
  39. if ($result) {
  40. if ($GLOBALS['dbi']->numRows($result) == 0) {
  41. $html_output .= '<p>'
  42. . __('No users were found belonging to this user group.')
  43. . '</p>';
  44. } else {
  45. $html_output .= '<table>'
  46. . '<thead><tr><th>#</th><th>' . __('User') . '</th></tr></thead>'
  47. . '<tbody>';
  48. $i = 0;
  49. while ($row = $GLOBALS['dbi']->fetchRow($result)) {
  50. $i++;
  51. $html_output .= '<tr>'
  52. . '<td>' . $i . ' </td>'
  53. . '<td>' . htmlspecialchars($row[0]) . '</td>'
  54. . '</tr>';
  55. }
  56. $html_output .= '</tbody>'
  57. . '</table>';
  58. }
  59. }
  60. $GLOBALS['dbi']->freeResult($result);
  61. return $html_output;
  62. }
  63. /**
  64. * Returns HTML for the 'user groups' table
  65. *
  66. * @return string HTML for the 'user groups' table
  67. */
  68. public static function getHtmlForUserGroupsTable()
  69. {
  70. $relation = new Relation();
  71. $html_output = '<h2>' . __('User groups') . '</h2>';
  72. $cfgRelation = $relation->getRelationsParam();
  73. $groupTable = Util::backquote($cfgRelation['db'])
  74. . "." . Util::backquote($cfgRelation['usergroups']);
  75. $sql_query = "SELECT * FROM " . $groupTable . " ORDER BY `usergroup` ASC";
  76. $result = $relation->queryAsControlUser($sql_query, false);
  77. if ($result && $GLOBALS['dbi']->numRows($result)) {
  78. $html_output .= '<form name="userGroupsForm" id="userGroupsForm"'
  79. . ' action="server_privileges.php" method="post">';
  80. $html_output .= Url::getHiddenInputs();
  81. $html_output .= '<table id="userGroupsTable">';
  82. $html_output .= '<thead><tr>';
  83. $html_output .= '<th style="white-space: nowrap">'
  84. . __('User group') . '</th>';
  85. $html_output .= '<th>' . __('Server level tabs') . '</th>';
  86. $html_output .= '<th>' . __('Database level tabs') . '</th>';
  87. $html_output .= '<th>' . __('Table level tabs') . '</th>';
  88. $html_output .= '<th>' . __('Action') . '</th>';
  89. $html_output .= '</tr></thead>';
  90. $html_output .= '<tbody>';
  91. $userGroups = array();
  92. while ($row = $GLOBALS['dbi']->fetchAssoc($result)) {
  93. $groupName = $row['usergroup'];
  94. if (! isset($userGroups[$groupName])) {
  95. $userGroups[$groupName] = array();
  96. }
  97. $userGroups[$groupName][$row['tab']] = $row['allowed'];
  98. }
  99. foreach ($userGroups as $groupName => $tabs) {
  100. $html_output .= '<tr>';
  101. $html_output .= '<td>' . htmlspecialchars($groupName) . '</td>';
  102. $html_output .= '<td>' . self::getAllowedTabNames($tabs, 'server') . '</td>';
  103. $html_output .= '<td>' . self::getAllowedTabNames($tabs, 'db') . '</td>';
  104. $html_output .= '<td>' . self::getAllowedTabNames($tabs, 'table') . '</td>';
  105. $html_output .= '<td>';
  106. $html_output .= '<a class="" href="server_user_groups.php" data-post="'
  107. . Url::getCommon(
  108. array(
  109. 'viewUsers' => 1, 'userGroup' => $groupName
  110. ),
  111. '', false
  112. )
  113. . '">'
  114. . Util::getIcon('b_usrlist', __('View users'))
  115. . '</a>';
  116. $html_output .= '&nbsp;&nbsp;';
  117. $html_output .= '<a class="" href="server_user_groups.php" data-post="'
  118. . Url::getCommon(
  119. array(
  120. 'editUserGroup' => 1, 'userGroup' => $groupName
  121. ),
  122. '', false
  123. )
  124. . '">'
  125. . Util::getIcon('b_edit', __('Edit')) . '</a>';
  126. $html_output .= '&nbsp;&nbsp;';
  127. $html_output .= '<a class="deleteUserGroup ajax"'
  128. . ' href="server_user_groups.php" data-post="'
  129. . Url::getCommon(
  130. array(
  131. 'deleteUserGroup' => 1, 'userGroup' => $groupName
  132. ),
  133. '', false
  134. )
  135. . '">'
  136. . Util::getIcon('b_drop', __('Delete')) . '</a>';
  137. $html_output .= '</td>';
  138. $html_output .= '</tr>';
  139. }
  140. $html_output .= '</tbody>';
  141. $html_output .= '</table>';
  142. $html_output .= '</form>';
  143. }
  144. $GLOBALS['dbi']->freeResult($result);
  145. $html_output .= '<fieldset id="fieldset_add_user_group">';
  146. $html_output .= '<a href="server_user_groups.php'
  147. . Url::getCommon(array('addUserGroup' => 1)) . '">'
  148. . Util::getIcon('b_usradd')
  149. . __('Add user group') . '</a>';
  150. $html_output .= '</fieldset>';
  151. return $html_output;
  152. }
  153. /**
  154. * Returns the list of allowed menu tab names
  155. * based on a data row from usergroup table.
  156. *
  157. * @param array $row row of usergroup table
  158. * @param string $level 'server', 'db' or 'table'
  159. *
  160. * @return string comma separated list of allowed menu tab names
  161. */
  162. public static function getAllowedTabNames(array $row, $level)
  163. {
  164. $tabNames = array();
  165. $tabs = Util::getMenuTabList($level);
  166. foreach ($tabs as $tab => $tabName) {
  167. if (! isset($row[$level . '_' . $tab])
  168. || $row[$level . '_' . $tab] == 'Y'
  169. ) {
  170. $tabNames[] = $tabName;
  171. }
  172. }
  173. return implode(', ', $tabNames);
  174. }
  175. /**
  176. * Deletes a user group
  177. *
  178. * @param string $userGroup user group name
  179. *
  180. * @return void
  181. */
  182. public static function delete($userGroup)
  183. {
  184. $relation = new Relation();
  185. $cfgRelation = $relation->getRelationsParam();
  186. $userTable = Util::backquote($cfgRelation['db'])
  187. . "." . Util::backquote($cfgRelation['users']);
  188. $groupTable = Util::backquote($cfgRelation['db'])
  189. . "." . Util::backquote($cfgRelation['usergroups']);
  190. $sql_query = "DELETE FROM " . $userTable
  191. . " WHERE `usergroup`='" . $GLOBALS['dbi']->escapeString($userGroup)
  192. . "'";
  193. $relation->queryAsControlUser($sql_query, true);
  194. $sql_query = "DELETE FROM " . $groupTable
  195. . " WHERE `usergroup`='" . $GLOBALS['dbi']->escapeString($userGroup)
  196. . "'";
  197. $relation->queryAsControlUser($sql_query, true);
  198. }
  199. /**
  200. * Returns HTML for add/edit user group dialog
  201. *
  202. * @param string $userGroup name of the user group in case of editing
  203. *
  204. * @return string HTML for add/edit user group dialog
  205. */
  206. public static function getHtmlToEditUserGroup($userGroup = null)
  207. {
  208. $relation = new Relation();
  209. $html_output = '';
  210. if ($userGroup == null) {
  211. $html_output .= '<h2>' . __('Add user group') . '</h2>';
  212. } else {
  213. $html_output .= '<h2>'
  214. . sprintf(__('Edit user group: \'%s\''), htmlspecialchars($userGroup))
  215. . '</h2>';
  216. }
  217. $html_output .= '<form name="userGroupForm" id="userGroupForm"'
  218. . ' action="server_user_groups.php" method="post">';
  219. $urlParams = array();
  220. if ($userGroup != null) {
  221. $urlParams['userGroup'] = $userGroup;
  222. $urlParams['editUserGroupSubmit'] = '1';
  223. } else {
  224. $urlParams['addUserGroupSubmit'] = '1';
  225. }
  226. $html_output .= Url::getHiddenInputs($urlParams);
  227. $html_output .= '<fieldset id="fieldset_user_group_rights">';
  228. $html_output .= '<legend>' . __('User group menu assignments')
  229. . '&nbsp;&nbsp;&nbsp;'
  230. . '<input type="checkbox" id="addUsersForm_checkall" '
  231. . 'class="checkall_box" title="Check all">'
  232. . '<label for="addUsersForm_checkall">' . __('Check all') . '</label>'
  233. . '</legend>';
  234. if ($userGroup == null) {
  235. $html_output .= '<label for="userGroup">' . __('Group name:') . '</label>';
  236. $html_output .= '<input type="text" name="userGroup" maxlength="64" autocomplete="off" required="required" />';
  237. $html_output .= '<div class="clearfloat"></div>';
  238. }
  239. $allowedTabs = array(
  240. 'server' => array(),
  241. 'db' => array(),
  242. 'table' => array()
  243. );
  244. if ($userGroup != null) {
  245. $cfgRelation = $relation->getRelationsParam();
  246. $groupTable = Util::backquote($cfgRelation['db'])
  247. . "." . Util::backquote($cfgRelation['usergroups']);
  248. $sql_query = "SELECT * FROM " . $groupTable
  249. . " WHERE `usergroup`='" . $GLOBALS['dbi']->escapeString($userGroup)
  250. . "'";
  251. $result = $relation->queryAsControlUser($sql_query, false);
  252. if ($result) {
  253. while ($row = $GLOBALS['dbi']->fetchAssoc($result)) {
  254. $key = $row['tab'];
  255. $value = $row['allowed'];
  256. if (substr($key, 0, 7) == 'server_' && $value == 'Y') {
  257. $allowedTabs['server'][] = mb_substr($key, 7);
  258. } elseif (substr($key, 0, 3) == 'db_' && $value == 'Y') {
  259. $allowedTabs['db'][] = mb_substr($key, 3);
  260. } elseif (substr($key, 0, 6) == 'table_'
  261. && $value == 'Y'
  262. ) {
  263. $allowedTabs['table'][] = mb_substr($key, 6);
  264. }
  265. }
  266. }
  267. $GLOBALS['dbi']->freeResult($result);
  268. }
  269. $html_output .= self::getTabList(
  270. __('Server-level tabs'), 'server', $allowedTabs['server']
  271. );
  272. $html_output .= self::getTabList(
  273. __('Database-level tabs'), 'db', $allowedTabs['db']
  274. );
  275. $html_output .= self::getTabList(
  276. __('Table-level tabs'), 'table', $allowedTabs['table']
  277. );
  278. $html_output .= '</fieldset>';
  279. $html_output .= '<fieldset id="fieldset_user_group_rights_footer"'
  280. . ' class="tblFooters">';
  281. $html_output .= '<input type="submit" value="' . __('Go') . '">';
  282. $html_output .= '</fieldset>';
  283. return $html_output;
  284. }
  285. /**
  286. * Returns HTML for checkbox groups to choose
  287. * tabs of 'server', 'db' or 'table' levels.
  288. *
  289. * @param string $title title of the checkbox group
  290. * @param string $level 'server', 'db' or 'table'
  291. * @param array $selected array of selected allowed tabs
  292. *
  293. * @return string HTML for checkbox groups
  294. */
  295. public static function getTabList($title, $level, array $selected)
  296. {
  297. $tabs = Util::getMenuTabList($level);
  298. $html_output = '<fieldset>';
  299. $html_output .= '<legend>' . $title . '</legend>';
  300. foreach ($tabs as $tab => $tabName) {
  301. $html_output .= '<div class="item">';
  302. $html_output .= '<input type="checkbox" class="checkall"'
  303. . (in_array($tab, $selected) ? ' checked="checked"' : '')
  304. . ' name="' . $level . '_' . $tab . '" value="Y" />';
  305. $html_output .= '<label for="' . $level . '_' . $tab . '">'
  306. . '<code>' . $tabName . '</code>'
  307. . '</label>';
  308. $html_output .= '</div>';
  309. }
  310. $html_output .= '</fieldset>';
  311. return $html_output;
  312. }
  313. /**
  314. * Add/update a user group with allowed menu tabs.
  315. *
  316. * @param string $userGroup user group name
  317. * @param boolean $new whether this is a new user group
  318. *
  319. * @return void
  320. */
  321. public static function edit($userGroup, $new = false)
  322. {
  323. $relation = new Relation();
  324. $tabs = Util::getMenuTabList();
  325. $cfgRelation = $relation->getRelationsParam();
  326. $groupTable = Util::backquote($cfgRelation['db'])
  327. . "." . Util::backquote($cfgRelation['usergroups']);
  328. if (! $new) {
  329. $sql_query = "DELETE FROM " . $groupTable
  330. . " WHERE `usergroup`='" . $GLOBALS['dbi']->escapeString($userGroup)
  331. . "';";
  332. $relation->queryAsControlUser($sql_query, true);
  333. }
  334. $sql_query = "INSERT INTO " . $groupTable
  335. . "(`usergroup`, `tab`, `allowed`)"
  336. . " VALUES ";
  337. $first = true;
  338. foreach ($tabs as $tabGroupName => $tabGroup) {
  339. foreach ($tabGroup as $tab => $tabName) {
  340. if (! $first) {
  341. $sql_query .= ", ";
  342. }
  343. $tabName = $tabGroupName . '_' . $tab;
  344. $allowed = isset($_POST[$tabName]) && $_POST[$tabName] == 'Y';
  345. $sql_query .= "('" . $GLOBALS['dbi']->escapeString($userGroup) . "', '" . $tabName . "', '"
  346. . ($allowed ? "Y" : "N") . "')";
  347. $first = false;
  348. }
  349. }
  350. $sql_query .= ";";
  351. $relation->queryAsControlUser($sql_query, true);
  352. }
  353. }