From fcaf6e360acb23131f3548a16a1b17b7fe1c4361 Mon Sep 17 00:00:00 2001 From: Madhura Jayaratne Date: Wed, 16 Sep 2015 22:50:55 +1000 Subject: [PATCH] Fix #11479 Allow setting routine wise privileges Signed-off-by: Madhura Jayaratne --- libraries/server_privileges.lib.php | 642 ++++++++++-------- server_privileges.php | 55 +- .../privileges/add_privileges_database.phtml | 15 + .../privileges/add_privileges_routine.phtml | 14 + .../privileges/add_privileges_table.phtml | 14 + .../privileges/edit_routine_privileges.phtml | 26 + templates/privileges/privileges_summary.phtml | 67 ++ .../privileges/privileges_summary_row.phtml | 14 + test/libraries/PMA_server_privileges_test.php | 221 +----- 9 files changed, 564 insertions(+), 504 deletions(-) create mode 100644 templates/privileges/add_privileges_database.phtml create mode 100644 templates/privileges/add_privileges_routine.phtml create mode 100644 templates/privileges/add_privileges_table.phtml create mode 100644 templates/privileges/edit_routine_privileges.phtml create mode 100644 templates/privileges/privileges_summary.phtml create mode 100644 templates/privileges/privileges_summary_row.phtml diff --git a/libraries/server_privileges.lib.php b/libraries/server_privileges.lib.php index d7badbbe79..e083f1bf20 100644 --- a/libraries/server_privileges.lib.php +++ b/libraries/server_privileges.lib.php @@ -959,6 +959,97 @@ function PMA_getHtmlForResourceLimits($row) return $html_output; } +/** + * Get the HTML snippet for routine specific privileges + * + * @param string $username username for database connection + * @param string $hostname hostname for database connection + * @param string $db the database + * @param string $routine the routine + * @param string $url_dbname url encoded db name + * + * @return string $html_output + */ +function PMA_getHtmlForRoutineSpecificPrivilges( + $username, $hostname, $db, $routine, $url_dbname +) { + $header = PMA_getHtmlHeaderForUserProperties( + false, $url_dbname, $db, $username, $hostname, $routine + ); + + $sql = "SELECT `Proc_priv`" + . " FROM `mysql`.`procs_priv`" + . " WHERE `User` = '" . PMA_Util::sqlAddSlashes($username) . "'" + . " AND `Host` = '" . PMA_Util::sqlAddSlashes($hostname) . "'" + . " AND `Db` = '" + . PMA_Util::sqlAddSlashes(PMA_Util::unescapeMysqlWildcards($db)) . "'" + . " AND `Routine_name` LIKE '" . PMA_Util::sqlAddSlashes($routine) . "';"; + $res = $GLOBALS['dbi']->fetchValue($sql); + + $privs = array( + 'Alter_routine_priv' => 'N', + 'Execute_priv' => 'N', + 'Grant_priv' => 'N', + ); + foreach (explode(',', $res) as $priv) { + if ($priv == 'Alter Routine') { + $privs['Alter_routine_priv'] = 'Y'; + } else { + $privs[$priv . '_priv'] = 'Y'; + } + } + + $routineArray = array(PMA_getTriggerPrivilegeTable()); + $privTableNames = array(__('Routine')); + $privCheckboxes = PMA_getHtmlForGlobalPrivTableWithCheckboxes( + $routineArray, $privTableNames, $privs + ); + + $data = array( + 'username' => $username, + 'hostname' => $hostname, + 'database' => $db, + 'routine' => $routine, + 'grantCount' => count($privs), + 'privCheckboxes' => $privCheckboxes, + 'header' => $header, + ); + $html_output = PMA\Template::get('privileges/edit_routine_privileges') + ->render($data); + + return $html_output; +} + +/** + * Get routine privilege table as an array + * + * @return privilege type array + */ +function PMA_getTriggerPrivilegeTable() +{ + $routinePrivTable = array( + array( + 'Grant', + 'GRANT', + __( + 'Allows adding users and privileges ' + . 'without reloading the privilege tables.' + ) + ), + array( + 'Alter_routine', + 'ALTER ROUTINE', + __('Allows altering and dropping this routine.') + ), + array( + 'Execute', + 'EXECUTE', + __('Allows executing this routine.') + ) + ); + return $routinePrivTable; +} + /** * Get the HTML snippet for table specific privileges * @@ -1951,20 +2042,21 @@ function PMA_updatePassword($err_url, $username, $hostname) * @param string $tablename table name * @param string $username username * @param string $hostname host name + * @param string $itemType item type * * @return array ($message, $sql_query) */ function PMA_getMessageAndSqlQueryForPrivilegesRevoke($dbname, - $tablename, $username, $hostname + $tablename, $username, $hostname, $itemType ) { $db_and_table = PMA_wildcardEscapeForGrant($dbname, $tablename); - $sql_query0 = 'REVOKE ALL PRIVILEGES ON ' . $db_and_table + $sql_query0 = 'REVOKE ALL PRIVILEGES ON ' . $itemType . ' ' . $db_and_table . ' FROM \'' . PMA_Util::sqlAddSlashes($username) . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\';'; - $sql_query1 = 'REVOKE GRANT OPTION ON ' . $db_and_table + $sql_query1 = 'REVOKE GRANT OPTION ON ' . $itemType . ' ' . $db_and_table . ' FROM \'' . PMA_Util::sqlAddSlashes($username) . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\';'; @@ -2583,17 +2675,19 @@ function PMA_getHtmlListOfPrivs( /** * Returns edit, revoke or export link for a user. * - * @param string $linktype The link type (edit | revoke | export) - * @param string $username User name - * @param string $hostname Host name - * @param string $dbname Database name - * @param string $tablename Table name - * @param string $initial Initial value + * @param string $linktype The link type (edit | revoke | export) + * @param string $username User name + * @param string $hostname Host name + * @param string $dbname Database name + * @param string $tablename Table name + * @param string $routinename Routine name + * @param string $initial Initial value * * @return string HTML code with link */ function PMA_getUserLink( - $linktype, $username, $hostname, $dbname = '', $tablename = '', $initial = '' + $linktype, $username, $hostname, $dbname = '', + $tablename = '', $routinename = '', $initial = '' ) { $html = '' . "\n"; @@ -2937,29 +3034,40 @@ function PMA_getLinkToDbAndTable($url_dbname, $dbname, $tablename) * db name was given, so we want all user specific rights for this db * So this function returns user rights as an array * - * @param array $tables tables - * @param string $user_host_condition a where clause that contained user's host - * condition - * @param string $dbname database name + * @param string $username username + * @param string $hostname host name + * @param string $type database or table + * @param string $dbname database name * * @return array $db_rights database rights */ -function PMA_getUserSpecificRights($tables, $user_host_condition, $dbname) +function PMA_getUserSpecificRights($username, $hostname, $type, $dbname = '') { - if (!/*overload*/mb_strlen($dbname)) { + $user_host_condition = " WHERE `User`" + . " = '" . PMA_Util::sqlAddSlashes($username) . "'" + . " AND `Host`" + . " = '" . PMA_Util::sqlAddSlashes($hostname) . "'"; + + if ($type == 'database') { $tables_to_search_for_users = array( - 'tables_priv', 'columns_priv', + 'tables_priv', 'columns_priv', 'procs_priv' ); $dbOrTableName = 'Db'; - } else { - $user_host_condition .= - ' AND `Db`' - . ' LIKE \'' + } elseif ($type == 'table') { + $user_host_condition .= " AND `Db` LIKE '" . PMA_Util::sqlAddSlashes($dbname, true) . "'"; $tables_to_search_for_users = array('columns_priv',); $dbOrTableName = 'Table_name'; + } else { // routine + $user_host_condition .= " AND `Db` LIKE '" + . PMA_Util::sqlAddSlashes($dbname, true) . "'"; + $tables_to_search_for_users = array('procs_priv',); + $dbOrTableName = 'Routine_name'; } + // we also want privileges for this user not in table `db` but in other table + $tables = $GLOBALS['dbi']->fetchResult('SHOW TABLES FROM `mysql`;'); + $db_rights_sqls = array(); foreach ($tables_to_search_for_users as $table_search_in) { if (in_array($table_search_in, $tables)) { @@ -2987,7 +3095,7 @@ function PMA_getUserSpecificRights($tables, $user_host_condition, $dbname) while ($db_rights_row = $GLOBALS['dbi']->fetchAssoc($db_rights_result)) { $db_rights_row = array_merge($user_defaults, $db_rights_row); - if (!/*overload*/mb_strlen($dbname)) { + if ($type == 'database') { // only Db names in the table `mysql`.`db` uses wildcards // as we are in the db specific rights display we want // all db names escaped, also from other sources @@ -3000,10 +3108,10 @@ function PMA_getUserSpecificRights($tables, $user_host_condition, $dbname) $GLOBALS['dbi']->freeResult($db_rights_result); - if (!/*overload*/mb_strlen($dbname)) { + if ($type == 'database') { $sql_query = 'SELECT * FROM `mysql`.`db`' . $user_host_condition . ' ORDER BY `Db` ASC'; - } else { + } elseif ($type == 'table') { $sql_query = 'SELECT `Table_name`,' . ' `Table_priv`,' . ' IF(`Column_priv` = _latin1 \'\', 0, 1)' @@ -3011,6 +3119,12 @@ function PMA_getUserSpecificRights($tables, $user_host_condition, $dbname) . ' FROM `mysql`.`tables_priv`' . $user_host_condition . ' ORDER BY `Table_name` ASC;'; + } else { + $sql_query = "SELECT `Routine_name`, `Proc_priv`" + . " FROM `mysql`.`procs_priv`" + . $user_host_condition + . " ORDER BY `Routine_name`"; + } $result = $GLOBALS['dbi']->query($sql_query); @@ -3022,7 +3136,7 @@ function PMA_getUserSpecificRights($tables, $user_host_condition, $dbname) } else { $db_rights[$row[$dbOrTableName]] = $row; } - if (!/*overload*/mb_strlen($dbname)) { + if ($type == 'database') { // there are db specific rights for this user // so we can drop this db rights $db_rights[$row['Db']]['can_delete'] = true; @@ -3032,273 +3146,191 @@ function PMA_getUserSpecificRights($tables, $user_host_condition, $dbname) return $db_rights; } -/** - * Display user rights in table rows(Table specific or database specific privs) - * - * @param array $db_rights user's database rights array - * @param string $dbname database name - * @param string $hostname host name - * @param string $username username - * - * @return array $found_rows, $html_output - */ -function PMA_getHtmlForUserRights($db_rights, $dbname, - $hostname, $username -) { - $html_output = ''; - $found_rows = array(); - - // display rows - if (count($db_rights) < 1) { - $html_output .= '' . "\n" - . '
' . __('None') . '
' . "\n" - . '' . "\n"; - return array($found_rows, $html_output); - } - - $odd_row = true; - //while ($row = $GLOBALS['dbi']->fetchAssoc($res)) { - foreach ($db_rights as $row) { - $dbNameLength = /*overload*/mb_strlen($dbname); - $found_rows[] = (!$dbNameLength) - ? $row['Db'] - : $row['Table_name']; - - $html_output .= '' . "\n" - . '' - . htmlspecialchars( - (!$dbNameLength) - ? $row['Db'] - : $row['Table_name'] - ) - . '' . "\n" - . '' . "\n" - . ' ' - . join( - ',' . "\n" . ' ', - PMA_extractPrivInfo($row, true) - ) . "\n" - . '' . "\n" - . '' - . ((((!$dbNameLength) && $row['Grant_priv'] == 'Y') - || ($dbNameLength - && in_array('Grant', explode(',', $row['Table_priv'])))) - ? __('Yes') - : __('No')) - . '' . "\n" - . ''; - if (!empty($row['Table_privs']) || !empty($row['Column_priv'])) { - $html_output .= __('Yes'); - } else { - $html_output .= __('No'); - } - $html_output .= ''; - - $html_output .= ''; - if ($GLOBALS['is_grantuser']) { - $html_output .= PMA_getUserLink( - 'edit', - $username, - $hostname, - (!$dbNameLength) ? $row['Db'] : $dbname, - (!$dbNameLength) ? '' : $row['Table_name'] - ); - } - $html_output .= ''; - - $html_output .= ''; - if (! empty($row['can_delete']) - || isset($row['Table_name']) - && /*overload*/mb_strlen($row['Table_name']) - ) { - $html_output .= PMA_getUserLink( - 'revoke', - $username, - $hostname, - (!$dbNameLength) ? $row['Db'] : $dbname, - (!$dbNameLength) ? '' : $row['Table_name'] - ); - } - $html_output .= '' . "\n" - . '' . "\n"; - $odd_row = ! $odd_row; - } // end while - - return array($found_rows, $html_output); -} - /** * Get a HTML table for display user's tabel specific or database specific rights * * @param string $username username * @param string $hostname host name + * @param string $type database, table or routine * @param string $dbname database name * - * @return array $html_output, $found_rows + * @return array $html_output */ function PMA_getHtmlForAllTableSpecificRights( - $username, $hostname, $dbname + $username, $hostname, $type, $dbname = '' ) { - // table header - $html_output = PMA_URL_getHiddenInputs('', '') - . '' . "\n" - . '' . "\n" - . '
' . "\n" - . '' - . (!/*overload*/mb_strlen($dbname) - ? __('Database-specific privileges') - : __('Table-specific privileges') - ) - . '' . "\n" - . '' . "\n" - . '' . "\n" - . '' . "\n" - . '' . "\n" - . '' . "\n" - . '' . "\n" - . '' . "\n" - . '' . "\n" - . '' . "\n"; - - $user_host_condition = ' WHERE `User`' - . ' = \'' . PMA_Util::sqlAddSlashes($username) . "'" - . ' AND `Host`' - . ' = \'' . PMA_Util::sqlAddSlashes($hostname) . "'"; - - // table body - // get data - - // we also want privileges for this user not in table `db` but in other table - $tables = $GLOBALS['dbi']->fetchResult('SHOW TABLES FROM `mysql`;'); + $uiData = array( + 'database' => array( + 'formId' => 'database_specific_priv', + 'subMenuLabel' => __('Database'), + 'legend' => __('Database-specific privileges'), + 'typeLabel' => __('Database'), + ), + 'table' => array( + 'formId' => 'table_specific_priv', + 'subMenuLabel' => __('Table'), + 'legend' => __('Table-specific privileges'), + 'typeLabel' => __('Table'), + ), + 'routine' => array( + 'formId' => 'routine_specific_priv', + 'subMenuLabel' => __('Routine'), + 'legend' => __('Routine-specific privileges'), + 'typeLabel' => __('Routine'), + ), + ); /** * no db name given, so we want all privs for the given user * db name was given, so we want all user specific rights for this db */ - $db_rights = PMA_getUserSpecificRights($tables, $user_host_condition, $dbname); - + $db_rights = PMA_getUserSpecificRights($username, $hostname, $type, $dbname); ksort($db_rights); - $html_output .= '' . "\n"; - // display rows - list ($found_rows, $html_out) = PMA_getHtmlForUserRights( - $db_rights, $dbname, $hostname, $username - ); + $foundRows = array(); + $privileges = array(); + foreach ($db_rights as $row) { + $onePrivilege = array(); - $html_output .= $html_out; - $html_output .= '' . "\n"; - $html_output .='
' - . (!/*overload*/mb_strlen($dbname) ? __('Database') : __('Table')) - . '' . __('Privileges') . '' . __('Grant') . '' - . (!/*overload*/mb_strlen($dbname) - ? __('Table-specific privileges') - : __('Column-specific privileges') - ) - . '' . __('Action') . '
' . "\n"; + $paramDbName = ''; + $paramTableName = ''; + $paramRoutineName = ''; - return array($html_output, $found_rows); -} + if ($type == 'database') { + $name = $row['Db']; + $onePrivilege['grant'] = $row['Grant_priv'] == 'Y'; + $onePrivilege['tablePrivs'] = ! empty($row['Table_priv']) + || ! empty($row['Column_priv']); + $onePrivilege['privileges'] = join(',', PMA_extractPrivInfo($row, true)); -/** - * Get HTML for display select db - * - * @param array $found_rows isset($dbname)) ? $row['Db'] : $row['Table_name'] - * - * @return string HTML snippet - */ -function PMA_getHtmlForSelectDbInEditPrivs($found_rows) -{ - // we already have the list of databases from libraries/common.inc.php - // via $pma = new PMA; - $pred_db_array = $GLOBALS['pma']->databases; + $paramDbName = $row['Db']; - $databases_to_skip = array('information_schema', 'performance_schema'); + } elseif ($type == 'table') { + $name = $row['Table_name']; + $onePrivilege['grant'] = in_array('Grant', explode(',', $row['Table_priv'])); + $onePrivilege['columnPrivs'] = ! empty($row['Column_priv']); + $onePrivilege['privileges'] = join(',', PMA_extractPrivInfo($row, true)); - $html_output = '' . "\n"; - if (! empty($pred_db_array)) { - $html_output .= '' . "\n"; - } - $html_output .= '' - . "\n" - . PMA_Util::showHint( - __('Wildcards % and _ should be escaped with a \ to use them literally.') + $data['databases'] = $databases; + + } elseif ($type == 'table') { + $result = @$GLOBALS['dbi']->tryQuery( + "SHOW TABLES FROM " . PMA_Util::backquote($dbname), + null, + PMA_DatabaseInterface::QUERY_STORE ); - return $html_output; -} -/** - * Get HTML for display table in edit privilege - * - * @param string $dbname database naame - * @param array $found_rows isset($dbname)) ? $row['Db'] : $row['Table_name'] - * - * @return string HTML snippet - */ -function PMA_displayTablesInEditPrivs($dbname, $found_rows) -{ - $html_output = '' . "\n"; - $html_output .= '' . "\n"; + $tables = array(); + if ($result) { + while ($row = $GLOBALS['dbi']->fetchRow($result)) { + if (! in_array($row[0], $foundRows)) { + $tables[] = $row[0]; + } + } + $GLOBALS['dbi']->freeResult($result); + } + $data['tables'] = $tables; - $result = @$GLOBALS['dbi']->tryQuery( - 'SHOW TABLES FROM ' . PMA_Util::backquote( - PMA_Util::unescapeMysqlWildcards($dbname) - ) . ';', - null, - PMA_DatabaseInterface::QUERY_STORE - ); + } else { // routine + $routineData = $GLOBALS['dbi']->getRoutines($dbname); - if ($result) { - $pred_tbl_array = array(); - while ($row = $GLOBALS['dbi']->fetchRow($result)) { - if (! isset($found_rows) || ! in_array($row[0], $found_rows)) { - $pred_tbl_array[] = $row[0]; + $routines = array(); + foreach ($routineData as $routine) { + if (! in_array($routine['name'], $foundRows)) { + $routines[] = $routine['name']; } } - $GLOBALS['dbi']->freeResult($result); - - if (! empty($pred_tbl_array)) { - $html_output .= '' . "\n"; - } + $data['routines'] = $routines; } - $html_output .= '' - . "\n"; + + $html_output = PMA\Template::get('privileges/privileges_summary') + ->render($data); return $html_output; } @@ -3505,6 +3537,7 @@ function PMA_getHtmlTableBodyForUserRights($db_rights) $host['Host'], '', '', + '', isset($_GET['initial']) ? $_GET['initial'] : '' ) . ''; @@ -3726,19 +3759,20 @@ function PMA_deleteUser($queries) * @param string $hostname host name * @param string $tablename table name * @param string $dbname database name + * @param strubg $itemType item type * * @return PMA_message success message or error message for update */ -function PMA_updatePrivileges($username, $hostname, $tablename, $dbname) +function PMA_updatePrivileges($username, $hostname, $tablename, $dbname, $itemType) { $db_and_table = PMA_wildcardEscapeForGrant($dbname, $tablename); - $sql_query0 = 'REVOKE ALL PRIVILEGES ON ' . $db_and_table + $sql_query0 = 'REVOKE ALL PRIVILEGES ON ' . $itemType . ' ' . $db_and_table . ' FROM \'' . PMA_Util::sqlAddSlashes($username) . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\';'; if (! isset($_POST['Grant_priv']) || $_POST['Grant_priv'] != 'Y') { - $sql_query1 = 'REVOKE GRANT OPTION ON ' . $db_and_table + $sql_query1 = 'REVOKE GRANT OPTION ON ' . $itemType . ' ' . $db_and_table . ' FROM \'' . PMA_Util::sqlAddSlashes($username) . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\';'; } else { @@ -3751,7 +3785,7 @@ function PMA_updatePrivileges($username, $hostname, $tablename, $dbname) && 'USAGE' == implode('', PMA_extractPrivInfo())) ) { $sql_query2 = 'GRANT ' . join(', ', PMA_extractPrivInfo()) - . ' ON ' . $db_and_table + . ' ON ' . $itemType . ' ' . $db_and_table . ' TO \'' . PMA_Util::sqlAddSlashes($username) . '\'@\'' . PMA_Util::sqlAddSlashes($hostname) . '\''; @@ -4135,6 +4169,7 @@ function PMA_getDataForDBInfo() $hostname = null; $dbname = null; $tablename = null; + $routinename = null; $dbname_is_wildcard = null; if (isset($_REQUEST['username'])) { @@ -4154,6 +4189,14 @@ function PMA_getDataForDBInfo() unset($tablename); } + if (PMA_isValid($_REQUEST['pred_routinename'])) { + $routinename = $_REQUEST['pred_routinename']; + } elseif (PMA_isValid($_REQUEST['routinename'])) { + $routinename = $_REQUEST['routinename']; + } else { + unset($routinename); + } + if (isset($_REQUEST['pred_dbname'])) { $is_valid_pred_dbname = true; foreach ($_REQUEST['pred_dbname'] as $key => $db_name) { @@ -4232,6 +4275,7 @@ function PMA_getDataForDBInfo() $username, $hostname, isset($dbname)? $dbname : null, isset($tablename)? $tablename : null, + isset($routinename) ? $routinename : null, $db_and_table, $dbname_is_wildcard, ); @@ -4378,6 +4422,21 @@ function PMA_getHtmlHeaderForUserProperties( $html_output .= ' - ' . __('Table') . ' ' . htmlspecialchars($tablename) . ''; + } elseif (! empty($_REQUEST['routinename'])) { + $html_output .= ' ' . htmlspecialchars($dbname) + . ''; + + $html_output .= ' - ' . __('Routine') + . ' ' . htmlspecialchars($tablename) . ''; } else { if (! is_array($dbname)) { $dbname = array($dbname); @@ -4632,34 +4691,24 @@ function PMA_getHtmlForUserProperties($dbname_is_wildcard,$url_dbname, if (! is_array($dbname) && ! /*overload*/mb_strlen($tablename) && empty($dbname_is_wildcard) ) { - // no table name was given, display all table specific rights // but only if $dbname contains no wildcards - $html_output .= '
' . "\n"; + // unescape wildcards in dbname at table level + $unescaped_db = PMA_Util::unescapeMysqlWildcards($dbname); - $html_output .= '
' . "\n" - . ' ' - . '
' . "\n" - . '' . "\n"; + $html_output .= PMA_getHtmlForAllTableSpecificRights( + $username, $hostname, 'table', $unescaped_db + ); + $html_output .= PMA_getHtmlForAllTableSpecificRights( + $username, $hostname, 'routine', $unescaped_db + ); + } } // Provide a line with links to the relevant database and table @@ -5049,3 +5098,24 @@ function PMA_getSqlQueriesForDisplayAndAddUser($username, $hostname, $password) $password_set_show ); } + +/** + * Returns the type ('PROCEDURE' or 'FUNCTION') of the routine + * + * @param string $dbname database + * @param string $routineName routine + * + * @return string type + */ +function PMA_getRoutineType($dbname, $routineName) +{ + $routineData = $GLOBALS['dbi']->getRoutines($dbname); + + $routines = array(); + foreach ($routineData as $routine) { + if ($routine['name'] === $routineName) { + return $routine['type']; + } + } + return ''; +} diff --git a/server_privileges.php b/server_privileges.php index a08f159914..78790f2e1d 100644 --- a/server_privileges.php +++ b/server_privileges.php @@ -114,7 +114,7 @@ $_add_user_error = false; * tablename, db_and_table, dbname_is_wildcard */ list( - $username, $hostname, $dbname, $tablename, + $username, $hostname, $dbname, $tablename, $routinename, $db_and_table, $dbname_is_wildcard ) = PMA_getDataForDBInfo(); @@ -179,6 +179,11 @@ if (isset($_REQUEST['change_copy'])) { ); } +$itemType = ''; +if (! empty($routinename)) { + $itemType = PMA_getRoutineType($dbname, $routinename); +} + /** * Updates privileges */ @@ -188,8 +193,11 @@ if (! empty($_POST['update_privs'])) { list($sql_query[$key], $message) = PMA_updatePrivileges( (isset($username) ? $username : ''), (isset($hostname) ? $hostname : ''), - (isset($tablename) ? $tablename : ''), - (isset($db_name) ? $db_name : '') + (isset($tablename) + ? $tablename + : (isset($routinename) ? $routinename : '')), + (isset($db_name) ? $db_name : ''), + $itemType ); } @@ -198,8 +206,11 @@ if (! empty($_POST['update_privs'])) { list($sql_query, $message) = PMA_updatePrivileges( (isset($username) ? $username : ''), (isset($hostname) ? $hostname : ''), - (isset($tablename) ? $tablename : ''), - (isset($dbname) ? $dbname : '') + (isset($tablename) + ? $tablename + : (isset($routinename) ? $routinename : '')), + (isset($dbname) ? $dbname : ''), + $itemType ); } } @@ -220,8 +231,12 @@ if (! empty($_REQUEST['changeUserGroup']) && $cfgRelation['menuswork'] if (isset($_REQUEST['revokeall'])) { list ($message, $sql_query) = PMA_getMessageAndSqlQueryForPrivilegesRevoke( (isset($dbname) ? $dbname : ''), - (isset($tablename) ? $tablename : ''), - $username, $hostname + (isset($tablename) + ? $tablename + : (isset($routinename) ? $routinename : '')), + $username, + $hostname, + $itemType ); } @@ -382,25 +397,35 @@ if (isset($_REQUEST['adduser'])) { ); } } else { + if (isset($dbname) && ! is_array($dbname)) { + $url_dbname = urlencode( + str_replace( + array('\_', '\%'), + array('_', '%'), + $_REQUEST['dbname'] + ) + ); + } + if (! isset($username)) { // No username is given --> display the overview $response->addHTML( PMA_getHtmlForUserOverview($pmaThemeImage, $text_dir) ); + } else if (!empty($routinename)) { + $response->addHTML( + PMA_getHtmlForRoutineSpecificPrivilges( + $username, $hostname, $dbname, $routinename, + (isset($url_dbname) ? $url_dbname : '') + ) + ); } else { // A user was selected -> display the user's properties // In an Ajax request, prevent cached values from showing if ($GLOBALS['is_ajax_request'] == true) { header('Cache-Control: no-cache'); } - if (isset($dbname) && ! is_array($dbname)) { - $url_dbname = urlencode( - str_replace( - array('\_', '\%'), - array('_', '%'), $_REQUEST['dbname'] - ) - ); - } + $response->addHTML( PMA_getHtmlForUserProperties( (isset($dbname_is_wildcard) ? $dbname_is_wildcard : ''), diff --git a/templates/privileges/add_privileges_database.phtml b/templates/privileges/add_privileges_database.phtml new file mode 100644 index 0000000000..1ca23f5130 --- /dev/null +++ b/templates/privileges/add_privileges_database.phtml @@ -0,0 +1,15 @@ + + + + + + + + \ No newline at end of file diff --git a/templates/privileges/add_privileges_routine.phtml b/templates/privileges/add_privileges_routine.phtml new file mode 100644 index 0000000000..f613b8a248 --- /dev/null +++ b/templates/privileges/add_privileges_routine.phtml @@ -0,0 +1,14 @@ + + + + + + + + + \ No newline at end of file diff --git a/templates/privileges/add_privileges_table.phtml b/templates/privileges/add_privileges_table.phtml new file mode 100644 index 0000000000..ae1ba31149 --- /dev/null +++ b/templates/privileges/add_privileges_table.phtml @@ -0,0 +1,14 @@ + + + + + + + + + \ No newline at end of file diff --git a/templates/privileges/edit_routine_privileges.phtml b/templates/privileges/edit_routine_privileges.phtml new file mode 100644 index 0000000000..86bae18f94 --- /dev/null +++ b/templates/privileges/edit_routine_privileges.phtml @@ -0,0 +1,26 @@ +
+ + +
diff --git a/templates/privileges/privileges_summary.phtml b/templates/privileges/privileges_summary.phtml new file mode 100644 index 0000000000..7cbb871bc5 --- /dev/null +++ b/templates/privileges/privileges_summary.phtml @@ -0,0 +1,67 @@ + \ No newline at end of file diff --git a/templates/privileges/privileges_summary_row.phtml b/templates/privileges/privileges_summary_row.phtml new file mode 100644 index 0000000000..a8eee3e2a0 --- /dev/null +++ b/templates/privileges/privileges_summary_row.phtml @@ -0,0 +1,14 @@ + + + + + + + + + + + + + + \ No newline at end of file diff --git a/test/libraries/PMA_server_privileges_test.php b/test/libraries/PMA_server_privileges_test.php index b9adae6446..a0d5ef8700 100644 --- a/test/libraries/PMA_server_privileges_test.php +++ b/test/libraries/PMA_server_privileges_test.php @@ -150,7 +150,7 @@ class PMA_ServerPrivileges_Test extends PHPUnit_Framework_TestCase $_REQUEST['tablename'] = "PMA_tablename"; $_REQUEST['dbname'] = "PMA_dbname"; list( - $username, $hostname, $dbname, $tablename, + $username, $hostname, $dbname, $tablename, $routinename, $db_and_table, $dbname_is_wildcard ) = PMA_getDataForDBInfo(); $this->assertEquals( @@ -182,7 +182,7 @@ class PMA_ServerPrivileges_Test extends PHPUnit_Framework_TestCase $_REQUEST['pred_tablename'] = "PMA_pred__tablename"; $_REQUEST['pred_dbname'] = array("PMA_pred_dbname"); list( - ,, $dbname, $tablename, + ,, $dbname, $tablename, $routinename, $db_and_table, $dbname_is_wildcard ) = PMA_getDataForDBInfo(); $this->assertEquals( @@ -745,7 +745,7 @@ class PMA_ServerPrivileges_Test extends PHPUnit_Framework_TestCase $_POST['max_questions'] = 1000; list ($message, $sql_query) = PMA_getMessageAndSqlQueryForPrivilegesRevoke( - $dbname, $tablename, $username, $hostname + $dbname, $tablename, $username, $hostname, '' ); $this->assertEquals( @@ -753,9 +753,9 @@ class PMA_ServerPrivileges_Test extends PHPUnit_Framework_TestCase $message->getMessage() ); $this->assertEquals( - "REVOKE ALL PRIVILEGES ON `pma_dbname`.`pma_tablename` " + "REVOKE ALL PRIVILEGES ON `pma_dbname`.`pma_tablename` " . "FROM 'pma_username'@'pma_hostname'; " - . "REVOKE GRANT OPTION ON `pma_dbname`.`pma_tablename` " + . "REVOKE GRANT OPTION ON `pma_dbname`.`pma_tablename` " . "FROM 'pma_username'@'pma_hostname';", $sql_query ); @@ -779,7 +779,7 @@ class PMA_ServerPrivileges_Test extends PHPUnit_Framework_TestCase $_POST['Grant_priv'] = 'Y'; $_POST['max_questions'] = 1000; list($sql_query, $message) = PMA_updatePrivileges( - $username, $hostname, $tablename, $dbname + $username, $hostname, $tablename, $dbname, '' ); $this->assertEquals( @@ -787,7 +787,7 @@ class PMA_ServerPrivileges_Test extends PHPUnit_Framework_TestCase $message->getMessage() ); $this->assertEquals( - "REVOKE ALL PRIVILEGES ON `pma_dbname`.`pma_tablename` " + "REVOKE ALL PRIVILEGES ON `pma_dbname`.`pma_tablename` " . "FROM 'pma_username'@'pma_hostname'; ", $sql_query ); @@ -1475,7 +1475,7 @@ class PMA_ServerPrivileges_Test extends PHPUnit_Framework_TestCase $tablename = "pma_tablename"; $html = PMA_getUserLink( - 'edit', $username, $hostname, $dbname, $tablename + 'edit', $username, $hostname, $dbname, $tablename, '' ); $url_html = PMA_URL_getCommon( @@ -1484,6 +1484,7 @@ class PMA_ServerPrivileges_Test extends PHPUnit_Framework_TestCase 'hostname' => $hostname, 'dbname' => $dbname, 'tablename' => $tablename, + 'routinename' => '', ) ); $this->assertContains( @@ -1496,7 +1497,7 @@ class PMA_ServerPrivileges_Test extends PHPUnit_Framework_TestCase ); $html = PMA_getUserLink( - 'revoke', $username, $hostname, $dbname, $tablename + 'revoke', $username, $hostname, $dbname, $tablename, '' ); $url_html = PMA_URL_getCommon( @@ -1505,6 +1506,7 @@ class PMA_ServerPrivileges_Test extends PHPUnit_Framework_TestCase 'hostname' => $hostname, 'dbname' => $dbname, 'tablename' => $tablename, + 'routinename' => '', 'revokeall' => 1, ) ); @@ -2021,49 +2023,6 @@ class PMA_ServerPrivileges_Test extends PHPUnit_Framework_TestCase ); } - /** - * Tests for PMA_getUserSpecificRights - * - * @return void - */ - function testPMAGetUserSpecificRights() - { - // Setup for the test - $GLOBALS['dbi']->expects($this->any())->method('fetchAssoc') - ->will( - $this->onConsecutiveCalls( - array('Db' => 'y'), false, array('Db' => 'y'), false, - false, array('Table_name' => 't') - ) - ); - - // Test case 1 - $tables = array('columns_priv'); - $user_host_condition = ''; - $dbname = ''; - $expected = array( - 'y' => array( - 'privs' => array('USAGE'), - 'Db' => 'y', - 'Grant_priv' => 'N', - 'Column_priv' => true, - 'can_delete' => true - ) - ); - $actual = PMA_getUserSpecificRights($tables, $user_host_condition, $dbname); - $this->assertEquals($expected, $actual); - - // Test case 2 - $dbname = 'db'; - $expected = array( - 't' => array( - 'Table_name' => 't' - ) - ); - $actual = PMA_getUserSpecificRights($tables, $user_host_condition, $dbname); - $this->assertEquals($expected, $actual); - } - /** * Tests for PMA_getHtmlForUserProperties * @@ -2105,61 +2064,6 @@ class PMA_ServerPrivileges_Test extends PHPUnit_Framework_TestCase ); } - /** - * Tests for PMA_getHtmlForUserRights - * - * @return void - */ - function testPMAGetHtmlForUserRights() - { - // Test case 1 - $db_rights = array( - 'y' => array( - 'privs' => array('USAGE'), - 'Db' => 'y', - 'Grant_priv' => 'N', - 'Column_priv' => true, - 'can_delete' => true - ) - ); - $exp_found_rows = array('y'); - $actual = PMA_getHtmlForUserRights($db_rights, '', 'host', 'user'); - $this->assertArrayHasKey(0, $actual); - $this->assertArrayHasKey(1, $actual); - $this->assertEquals($exp_found_rows, $actual[0]); - $this->assertContains('Edit privileges', $actual[1]); - $this->assertContains('Revoke', $actual[1]); - $this->assertContains( - '', - $actual[1] - ); - $this->assertContains( - 'USAGE', - $actual[1] - ); - $this->assertContains( - '', - $actual[1] - ); - $this->assertContains( - 'Revoke', - $actual[1] - ); - - // Test case 2 - $actual = PMA_getHtmlForUserRights(array(), '', '', ''); - $this->assertArrayHasKey(0, $actual); - $this->assertArrayHasKey(1, $actual); - $this->assertEquals(array(), $actual[0]); - $this->assertEquals( - '' . "\n" - . '
None
' . "\n" - . '' . "\n", - $actual[1] - ); - } - /** * Tests for PMA_getHtmlForAllTableSpecificRights * @@ -2168,117 +2072,28 @@ class PMA_ServerPrivileges_Test extends PHPUnit_Framework_TestCase function testPMAGetHtmlForAllTableSpecificRights() { // Test case 1 - $actual = PMA_getHtmlForAllTableSpecificRights('pma', 'host', 'pmadb'); - $this->assertArrayHasKey(0, $actual); - $this->assertArrayHasKey(1, $actual); + $actual = PMA_getHtmlForAllTableSpecificRights('pma', 'host', 'table', 'pmadb'); $this->assertContains( '', - $actual[0] + $actual ); $this->assertContains( '', - $actual[0] + $actual ); $this->assertContains( '' . 'Table-specific privileges', - $actual[0] + $actual ); - $this->assertEquals(array(), $actual[1]); // Test case 2 - $actual = PMA_getHtmlForAllTableSpecificRights('pma2', 'host2', ''); - $this->assertArrayHasKey(0, $actual); - $this->assertArrayHasKey(1, $actual); + $GLOBALS['pma'] = new stdClass(); + $GLOBALS['pma']->databases = array('x', 'y', 'z'); + $actual = PMA_getHtmlForAllTableSpecificRights('pma2', 'host2', 'database', ''); $this->assertContains( '' . 'Database-specific privileges', - $actual[0] - ); - } - - /** - * Tests for PMA_getHtmlForSelectDbInEditPrivs - * - * @return void - */ - function testPMAGetHtmlForSelectDbInEditPrivs() - { - $GLOBALS['pma'] = new StdClass(); - $GLOBALS['pma']->databases = array( - 'pmadb', - 'testdb', - 'mysql' - ); - $actual = PMA_getHtmlForSelectDbInEditPrivs(array('pmadb')); - $this->assertContains( - '