diff --git a/libraries/classes/Server/Privileges.php b/libraries/classes/Server/Privileges.php index f9d0642770..378c6e4a89 100644 --- a/libraries/classes/Server/Privileges.php +++ b/libraries/classes/Server/Privileges.php @@ -1425,34 +1425,91 @@ class Privileges */ public function getHtmlForSpecificTablePrivileges(string $db, string $table): string { - global $cfg, $pmaThemeImage, $text_dir, $is_createuser; + global $cfg, $pmaThemeImage, $text_dir, $is_createuser, $is_grantuser; $scriptName = Util::getScriptNameForOption( $cfg['DefaultTabTable'], 'table' ); - $tableBody = ''; + $privileges = []; if ($this->dbi->isSuperuser()) { - $privileges = $this->getDatabasePrivileges($db); + $databasePrivileges = $this->getDatabasePrivileges($db); $tablePrivileges = $this->getTablePrivileges($db, $table); foreach ($tablePrivileges as $user => $hosts) { - foreach ($hosts as $host => $privs) { - $privileges[$user] = $privileges[$user] ?? []; - $privileges[$user][$host] = array_merge($privileges[$user][$host] ?? [], $privs); + foreach ($hosts as $host => $specificPrivileges) { + $databasePrivileges[$user] = $databasePrivileges[$user] ?? []; + $databasePrivileges[$user][$host] = array_merge( + $databasePrivileges[$user][$host] ?? [], + $specificPrivileges + ); } } $routinePrivileges = $this->getRoutinesPrivileges($db); foreach ($routinePrivileges as $user => $hosts) { - foreach ($hosts as $host => $privs) { - $privileges[$user] = $privileges[$user] ?? []; - $privileges[$user][$host] = array_merge($privileges[$user][$host] ?? [], $privs); + foreach ($hosts as $host => $specificPrivileges) { + $databasePrivileges[$user] = $databasePrivileges[$user] ?? []; + $databasePrivileges[$user][$host] = array_merge( + $databasePrivileges[$user][$host] ?? [], + $specificPrivileges + ); } } - $tableBody = $this->getHtmlTableBodyForSpecificDbOrTablePrivs($privileges, $db); + foreach ($databasePrivileges as $user => $hosts) { + foreach ($hosts as $host => $specificPrivileges) { + $privileges[$user . '@' . $host] = [ + 'user' => $user, + 'host' => $host, + 'privileges' => [], + ]; + foreach ($specificPrivileges as $specificPrivilege) { + $privilege = [ + 'type' => $specificPrivilege['Type'], + 'database' => $specificPrivilege['Db'], + ]; + if ($specificPrivilege['Type'] === 'r') { + $privilege['routine'] = $specificPrivilege['Routine_name']; + $privilege['has_grant'] = strpos( + $specificPrivilege['Proc_priv'], + 'Grant' + ) !== false; + $privilege['privileges'] = explode(',', $specificPrivilege['Proc_priv']); + } elseif ($specificPrivilege['Type'] === 't') { + $privilege['table'] = $specificPrivilege['Table_name']; + $privilege['has_grant'] = strpos( + $specificPrivilege['Table_priv'], + 'Grant' + ) !== false; + $tablePrivs = explode(',', $specificPrivilege['Table_priv']); + $specificPrivileges = []; + $grantsArr = $this->getTableGrantsArray(); + foreach ($grantsArr as $grant) { + $specificPrivileges[$grant[0]] = 'N'; + foreach ($tablePrivs as $priv) { + if ($grant[0] == $priv) { + $specificPrivileges[$grant[0]] = 'Y'; + } + } + } + $privilege['privileges'] = $this->extractPrivInfo( + $specificPrivileges, + true, + true + ); + } else { + $privilege['has_grant'] = $specificPrivilege['Grant_priv'] === 'Y'; + $privilege['privileges'] = $this->extractPrivInfo( + $specificPrivilege, + true + ); + } + $privileges[$user . '@' . $host]['privileges'][$specificPrivilege['Type']] = $privilege; + } + } + } } return $this->template->render('server/privileges/table', [ @@ -1462,8 +1519,9 @@ class Privileges 'table_url' => $scriptName, 'pma_theme_image' => $pmaThemeImage, 'text_dir' => $text_dir, - 'table_body' => $tableBody, 'is_createuser' => $is_createuser, + 'is_grantuser' => $is_grantuser, + 'privileges' => $privileges, ]); } diff --git a/templates/server/privileges/table.twig b/templates/server/privileges/table.twig index 4c328cff3c..8b00fe2cc0 100644 --- a/templates/server/privileges/table.twig +++ b/templates/server/privileges/table.twig @@ -25,13 +25,95 @@ - {{ table_body|raw }} + + {% for privilege in privileges %} + {% set privileges_amount = privilege.privileges|length %} + + 1 %} rowspan="{{ privileges_amount }}"{% endif %}> + + + 1 %} rowspan="{{ privileges_amount }}"{% endif %}> + {% if privilege.user is empty %} + {% trans 'Any' %} + {% else %} + {{ privilege.user }} + {% endif %} + + 1 %} rowspan="{{ privileges_amount }}"{% endif %}> + {{ privilege.host }} + + {% for priv in privilege.privileges %} + + {% if priv.type == 'g' %} + {% trans 'global' %} + {% elseif priv.type == 'd' %} + {% if priv.database == db|replace({'_': '\\_', '%': '\\%'}) %} + {% trans 'database-specific' %} + {% else %} + {% trans 'wildcard' %}: {{ priv.database }} + {% endif %} + {% elseif priv.type == 't' %} + {% trans 'table-specific' %} + {% elseif priv.type == 'r' %} + {% trans 'routine' %} + {% endif %} + + + + {% if priv.type == 'r' %} + {{ priv.routine }} + ({{ priv.privileges|join(', ')|upper }}) + {% else %} + {{ priv.privileges|join(', ')|raw }} + {% endif %} + + + + {{ priv.has_grant ? 'Yes'|trans : 'No'|trans }} + + + {% if is_grantuser %} + + {{ get_icon('b_usredit', 'Edit privileges'|trans) }} + + {% endif %} + + + + {{ get_icon('b_tblexport', 'Export'|trans) }} + + + + {% if privileges_amount > 1 %} + + {% endif %} + {% endfor %} + {% else %} + + + {% trans 'No user found.' %} + + + {% endfor %} +

-            {%- trans 'With selected:' %} + {%- trans 'With selected:' %}" width="38" height="22"> {% trans 'With selected:' %}