Просмотр исходного кода

[Feature] [#1460] PMA SSO Support (#1495)

* Add support for Single Sign on into PHPmyAdmin

* Undo commeting out error_reporting for debugging

* Limit time token is valid
Removed IP from pass trough

* - Delete temp user after log out

* - Delete temp user after logout 
- Improved comments

* - Check for valid return message

* Update /edit/server + Added support for proposed pma changes

* Fix typo in command

* Fix issue with sed target…

* Fix sed target

* Revert change to error_reporting

Co-authored-by: Raphael Schneeberger <rs@scit.ch>
Jaap Marcus 5 лет назад
Родитель
Сommit
56a4a09963

+ 1 - 1
CHANGELOG.md

@@ -3,7 +3,7 @@ All notable changes to this project will be documented in this file.
 
 ## [DEVELOPMENT]
 ### Features
-- No new features have been introduced in this release.
+- Introduced support for PHPmyAdmin Single Sign On
 
 ### Bugfixes
 - Fixed an issue where user name was duplicated when editing FTP users (#1411)

+ 82 - 0
bin/v-add-database-temp-user

@@ -0,0 +1,82 @@
+#!/bin/bash
+# info: add temp database user
+# options: USER DATABASE [TYPE] [HOST] [TTL]
+# labels: hestia database
+#
+# example: v-add-database-temp-user wordress wordpress_db mysql
+#
+# The function creates an temporary database user mysql_sso_db_XXXXXXXX and a random password 
+# The user has an limited validity and only granted access to the specific database 
+# Returns json to be read SSO Script
+
+#----------------------------------------------------------#
+#                    Variable&Function                     #
+#----------------------------------------------------------#
+
+# Argument definition
+user=$1
+database="$2"
+type=${3-mysql}
+host=$4
+ttl=$5
+
+if [ "$ttl" == '' ]; then
+    ttl=60
+fi
+
+# Includes
+source $HESTIA/func/main.sh
+source $HESTIA/func/db.sh
+source $HESTIA/conf/hestia.conf
+
+#----------------------------------------------------------#
+#                    Verifications                         #
+#----------------------------------------------------------#
+
+check_args '2' "$#" 'USER DATABASE [TYPE] [HOST]'
+is_format_valid 'user' 'database'
+is_system_enabled "$DB_SYSTEM" 'DB_SYSTEM'
+is_object_valid 'user' 'USER' "$user"
+is_object_unsuspended 'user' 'USER' "$user"
+is_object_valid 'db' 'DB' "$database"
+is_object_unsuspended 'db' 'DB' "$database"
+get_next_dbhost
+
+# Perform verification if read-only mode is enabled
+check_hestia_demo_mode
+
+#----------------------------------------------------------#
+#                       Action                             #
+#----------------------------------------------------------#
+
+# Get database values
+get_database_values
+
+#generate password and unique user 
+dbpass=$(generate_password);
+dbuser="hestia_sso_$(generate_password)";
+
+add_mysql_database_temp_user
+if [ $? -ne 0 ]; then
+    echo "Error: Unable to create temp user"
+    exit 2
+fi;
+
+if [[ "$ttl" -gt 0 ]]; then
+    echo "$BIN/v-delete-database-temp-user $user $database $dbuser mysql $host" | at "now +${ttl} minute" > /dev/null 2>&1
+fi
+echo '{
+    "login": {
+        "user": "'$dbuser'",
+        "password": "'$dbpass'"
+    }
+}'
+
+#----------------------------------------------------------#
+#                       Hestia                             #
+#----------------------------------------------------------#
+log_history "Granted $dbuser access to $database"
+
+# Logging
+log_event "$OK" "$ARGUMENTS"
+exit

+ 117 - 0
bin/v-add-sys-pma-sso

@@ -0,0 +1,117 @@
+#!/bin/bash
+# info: enables support for single sign on PHPmyAdmin 
+# options: [mode]
+# labels: 
+#
+# example: v-add-sys-pma-sso
+#
+# Enables support for SSO to PHPmyAdmin
+
+#----------------------------------------------------------#
+#                    Variable&Function                     #
+#----------------------------------------------------------#
+
+MODE=$1
+
+# Includes
+source $HESTIA/func/main.sh
+source $HESTIA/conf/hestia.conf
+
+PMA_INSTALL="/usr/share/phpmyadmin"
+PMA_CONFIG="/etc/phpmyadmin"
+
+#----------------------------------------------------------#
+#                    Verifications                         #
+#----------------------------------------------------------#
+
+# Perform verification if read-only mode is enabled
+check_hestia_demo_mode
+
+# Checking root permissions
+if [ "x$(id -u)" != 'x0' ]; then
+    echo "Error: Script can be run executed only by root"
+    exit 10
+fi
+
+if [ ! -z "$PHPMYADMIN_KEY" ] && [ "$PHPMYADMIN_KEY" != "" ] ; then
+    echo "Error: SSO has been installed before to reenable it please run v-delete-pma-sso first"
+    exit 1;
+fi
+
+# Ensure that $HESTIA (/usr/local/hestia/) and other variables are valid.
+if [ -z "$HESTIA" ]; then
+    HESTIA="/usr/local/hestia"
+fi
+
+if [ -z "$HOMEDIR" ] || [ -z "$HESTIA_INSTALL_DIR" ]; then
+    echo "Error: Hestia environment vars not present"
+    exit 2
+fi
+
+if [ -f "/usr/share/phpmyadmin/hestia-sso.php" ]; then 
+    echo "Error: hestia-sso.php is already installed"
+    exit 2
+fi
+
+if [ -f "/usr/local/hesta/web/api/index.php" ]; then 
+    echo "Error: API script not installed"
+    exit 2
+fi
+
+if [ "$API" != "yes" ]; then 
+    echo "Error: API is not enabled"
+    exit 2
+fi
+
+#----------------------------------------------------------#
+#                       Action                             #
+#----------------------------------------------------------#
+
+# Generate the keys to secure everything
+phpmyadminkey=$(generate_password);
+apikey=$($BIN/v-generate-api-key);
+
+# copy config dir to /usr/share/phpmyadmin/
+cp -f $HESTIA_INSTALL_DIR/phpmyadmin/hestia-sso.php $PMA_INSTALL/hestia-sso.php
+chmod 644 $PMA_INSTALL/hestia-sso.php 
+
+sed -i "s/%PHPMYADMIN_KEY%/$phpmyadminkey/g" $PMA_INSTALL/hestia-sso.php 
+sed -i "s/%API_KEY%/$apikey/g" $PMA_INSTALL/hestia-sso.php 
+sed -i "s/%API_HOST_NAME%/$(hostname)/g" $PMA_INSTALL/hestia-sso.php 
+sed -i "s/%API_HESTIA_PORT%/$BACKEND_PORT/g" $PMA_INSTALL/hestia-sso.php 
+
+
+# Check if config already contains the keys 
+
+touch $PMA_CONFIG/hestia-sso.inc.php
+chmod 644 $PMA_CONFIG/hestia-sso.inc.php
+echo "<?php
+if(isset(\$_GET['hestia_token']) || isset(\$_COOKIE['SignonSession'])){
+\$cfg['Servers'][\$i]['auth_type'] = 'signon';
+\$cfg['Servers'][\$i]['SignonSession'] = 'SignonSession';
+\$cfg['Servers'][\$i]['SignonURL'] = 'hestia-sso.php';
+\$cfg['Servers'][\$i]['LogoutURL'] = 'hestia-sso.php?logout=1';
+}
+?>" >> $PMA_CONFIG/hestia-sso.inc.php
+
+file=$(cat $PMA_CONFIG/config.inc.php)
+if ! [[  $file =~ "hestia-sso.inc.php" ]]; then 
+    if [[ $file =~ "//Add Hestia SSO code here" ]]; then 
+        sed -i "s|//Add Hestia SSO code here|//Add Hestia SSO code here\n     include ('$PMA_CONFIG/hestia-sso.inc.php');|g" $PMA_CONFIG/config.inc.php
+    else
+        echo "include ('$PMA_CONFIG/hestia-sso.inc.php');" >> $PMA_CONFIG/config.inc.php    
+    fi
+fi
+
+$BIN/v-change-sys-config-value 'PHPMYADMIN_KEY' "$phpmyadminkey"
+
+#----------------------------------------------------------#
+#                       Logging                            #
+#----------------------------------------------------------#
+
+if [ "$MODE" != "quiet" ]; then
+    echo "PMA Hestia-SSO plugin has been succesfully installed"
+fi
+
+log_history "PMA Hestia-SSO plugin has been succesfully installed" '' 'admin'
+log_event "$OK" "$ARGUMENTS"

+ 64 - 0
bin/v-delete-database-temp-user

@@ -0,0 +1,64 @@
+#!/bin/bash
+# info: deletes temp database user
+# options: USER DBUSER [TYPE] [HOST]
+# labels: hestia database
+#
+# example: v-add-database-temp-user wordress hestia_sso_user mysql
+#
+# Revokes "temp user" access to a database and removes the user
+# To be used in combination with v-add-database-temp-user 
+
+#----------------------------------------------------------#
+#                    Variable&Function                     #
+#----------------------------------------------------------#
+
+# Argument definition
+user=$1
+database=$2
+dbuser=$3
+type=${4-mysql}
+host=$5
+
+# Includes
+source $HESTIA/func/main.sh
+source $HESTIA/func/db.sh
+source $HESTIA/conf/hestia.conf
+
+#----------------------------------------------------------#
+#                    Verifications                         #
+#----------------------------------------------------------#
+
+check_args '3' "$#" 'USER DATABASE DBUSER [TYPE] [HOST]'
+is_format_valid 'user' 'dbuser'
+is_system_enabled "$DB_SYSTEM" 'DB_SYSTEM'
+is_object_valid 'user' 'USER' "$user"
+is_object_unsuspended 'user' 'USER' "$user"
+is_object_valid 'db' 'DB' "$database"
+is_object_unsuspended 'db' 'DB' "$database"
+get_next_dbhost
+
+if [[ $dbuser != *"hestia_sso"* ]]; then
+    echo "DBUSER is invalid SSO user"
+    exit $E_INVALID;
+fi
+
+# Perform verification if read-only mode is enabled
+check_hestia_demo_mode
+
+#----------------------------------------------------------#
+#                       Action                             #
+#----------------------------------------------------------#
+
+# Get database values
+get_database_values
+
+delete_mysql_database_temp_user
+
+#----------------------------------------------------------#
+#                       Hestia                             #
+#----------------------------------------------------------#
+log_history "Revoked $dbuser access to $database"
+
+# Logging
+log_event "$OK" "$ARGUMENTS"
+exit

+ 67 - 0
bin/v-delete-sys-pma-sso

@@ -0,0 +1,67 @@
+#!/bin/bash
+# info: disables support for single sign on PHPMYADMIN 
+# options: [mode]
+# labels: hestia
+#
+# example: v-delete-sys-pma-sso
+#
+# Disables support for SSO to PHPmyAdmin
+
+MODE=$1
+
+# Includes
+source $HESTIA/func/main.sh
+source $HESTIA/conf/hestia.conf
+
+PMA_INSTALL="/usr/share/phpmyadmin"
+PMA_CONFIG="/etc/phpmyadmin"
+
+#----------------------------------------------------------#
+#                    Verifications                         #
+#----------------------------------------------------------#
+
+# Perform verification if read-only mode is enabled
+check_hestia_demo_mode
+
+if [ "x$(id -u)" != 'x0' ]; then
+    echo "Error: Script can be run executed only by root"
+    exit 10
+fi
+
+if [ ! -e "$PMA_INSTALL/hestia-sso.php" ]; then
+     echo 'Error:  PMA Single Sign On already disabled'
+     exit 1;
+fi 
+
+#----------------------------------------------------------#
+#                       Action                             #
+#----------------------------------------------------------#
+
+apikey=$(grep -Po "'API_KEY', '(.*)'" /usr/share/phpmyadmin/hestia-sso.php |  cut "-d'" -f4 )
+
+$BIN/v-revoke-api-key $apikey
+
+#remove new files
+rm /usr/share/phpmyadmin/hestia-sso.php
+rm /etc/phpmyadmin/hestia-sso.inc.php
+
+#revert config
+sed -i "/hestia-sso.inc.php/d" $PMA_CONFIG/config.inc.php
+
+# disable key
+$BIN/v-change-sys-config-value 'PHPMYADMIN_KEY' ""
+
+#----------------------------------------------------------#
+#                       Hestia                             #
+#----------------------------------------------------------#
+
+if [ "$MODE" != "quiet" ]; then
+    echo "PMA Hestia-SSO plugin has been succesfully removed/disabled"
+fi
+
+
+log_history "Disabled support SSO" '' 'admin'
+
+# Logging
+log_event "$OK" "$ARGUMENTS"
+exit

+ 2 - 3
bin/v-list-sys-config

@@ -61,10 +61,9 @@ json_list() {
         "DB_PMA_ALIAS": "'$DB_PMA_ALIAS'",
         "DB_PGA_ALIAS": "'$DB_PGA_ALIAS'",
         "LOGIN_STYLE": "'$LOGIN_STYLE'",
-        "INACTIVE_SESSION_TIMEOUT": "'$INACTIVE_SESSION_TIMEOUT'",
-        "SOFTACULOUS": "'$SOFTACULOUS'"
+        "PHPMYADMIN_KEY": "'$PHPMYADMIN_KEY'"
     }
-}'
+    }'
 }
 
 # Shell list

+ 42 - 0
bin/v-revoke-api-key

@@ -0,0 +1,42 @@
+#!/bin/bash
+# info: revokes api key
+# options: [HASH]
+# labels: panel
+#
+# example: v-revoke-api-key mykey
+#
+# The function removes a key from in $HESTIA/data/keys/
+
+source $HESTIA/func/main.sh
+
+#----------------------------------------------------------#
+#                    Variable&Function                     #
+#----------------------------------------------------------#
+
+hash=$1
+KEYS="$HESTIA/data/keys/"
+
+# Perform verification if read-only mode is enabled
+check_hestia_demo_mode
+
+#----------------------------------------------------------#
+#                       Action                             #
+#----------------------------------------------------------#
+
+if [ ! -d ${KEYS} ]; then
+  mkdir -p ${KEYS}
+fi
+
+if [[ -e ${KEYS}${hash} ]] ; then
+   rm ${KEYS}${hash}
+fi
+
+#----------------------------------------------------------#
+#                       Hestia                             #
+#----------------------------------------------------------#
+
+log_history "Revoked API Key"
+
+# Logging
+log_event "$OK" "$ARGUMENTS"
+exit

+ 18 - 0
func/db.sh

@@ -280,6 +280,24 @@ add_pgsql_database() {
     md5=$(psql_query "$query" | grep md5 | cut -f 2 -d \ )
 }
 
+add_mysql_database_temp_user() {
+    mysql_connect $host;
+    query="GRANT ALL ON \`$database\`.* TO \`$dbuser\`@localhost
+    IDENTIFIED BY '$dbpass'"
+    mysql_query "$query" > /dev/null
+  }
+
+delete_mysql_database_temp_user(){
+    echo $database;
+    echo $dbuser;
+    echo $host;
+    mysql_connect $host;
+    query="REVOKE ALL ON \`$database\`.* FROM \`$dbuser\`@localhost"
+    mysql_query "$query" > /dev/null
+    query="DROP USER '$dbuser'@'localhost'"
+    mysql_query "$query" > /dev/null
+}
+
 # Check if database host do not exist in config 
 is_dbhost_new() {
     if [ -e "$HESTIA/conf/$type.conf" ]; then

+ 166 - 0
install/deb/phpmyadmin/hestia-sso.php

@@ -0,0 +1,166 @@
+<?php
+/* Hestia way to enable support for SSO to PHPmyAdmin */
+/* To install please run v-add-sys-pma-sso */
+
+/* Following keys will get replaced when calling v-add-sys-pma-sso */
+define('PHPMYADMIN_KEY','%PHPMYADMIN_KEY%');
+define('API_HOST_NAME','%API_HOST_NAME%');
+define('API_HESTIA_PORT','%API_HESTIA_PORT%');
+define('API_KEY', '%API_KEY%');
+
+
+class Hestia_API {
+    private $api_url;
+    function __construct(){
+        $this -> hostname = 'https://' . API_HOST_NAME . ':' . API_HESTIA_PORT .'/api/';
+        $this -> key = API_KEY;
+        $this -> pma_key = PHPMYADMIN_KEY;   
+    }
+    
+    /* Creates curl request */
+    function request($postvars){
+        $postdata = http_build_query($postvars);
+        $curl = curl_init();
+        curl_setopt($curl, CURLOPT_URL, $this -> hostname);
+        curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
+        curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
+        curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
+        curl_setopt($curl, CURLOPT_POST, true);
+        curl_setopt($curl, CURLOPT_POSTFIELDS, $postdata);
+        $answer = curl_exec($curl);
+        return $answer;
+    }
+    
+    /* Creates an new temp user in mysql */
+    function create_temp_user ($database, $user, $host){
+        $post_request = array(
+        'hash' => $this -> key,
+        'returncode' => 'no',
+        'cmd' => 'v-add-database-temp-user',
+        'arg1' => $user,
+        'arg2' => $database,
+        'arg3' => 'mysql',
+        'arg4' => $host
+        );
+        $request = $this -> request($post_request);
+        $json = json_decode($request);
+        if(json_last_error() == JSON_ERROR_NONE){
+            return $json;
+        }else{
+            return false;
+        }
+        
+    }
+    
+    /* Delete an new temp user in mysql */
+    function delete_temp_user ($database, $user, $dbuser, $host){
+        $post_request = array(
+        'hash' => $this -> key,
+        'returncode' => 'yes',
+        'cmd' => 'v-delete-database-temp-user',
+        'arg1' => $user,
+        'arg2' => $database,
+        'arg3' => $dbuser,
+        'arg4' => 'mysql',
+        'arg5' => $host
+        );
+        $request = $this -> request($post_request);
+        if(is_numeric($request) && $request == 0){
+            return true;
+        }else{
+            return false;
+        }
+    }
+
+    function get_user_ip(){
+        // Saving user IPs to the session for preventing session hijacking
+        $user_combined_ip = $_SERVER['REMOTE_ADDR'];
+        if(isset($_SERVER['HTTP_CLIENT_IP'])){
+            $user_combined_ip .=  '|'. $_SERVER['HTTP_CLIENT_IP'];
+        }
+        if(isset($_SERVER['HTTP_X_FORWARDED_FOR'])){
+            if($_SERVER['REMOTE_ADDR'] != $_SERVER['HTTP_X_FORWARDED_FOR']){
+                $user_combined_ip .=  '|'. $_SERVER['HTTP_X_FORWARDED_FOR'];
+            }
+        }
+        if(isset($_SERVER['HTTP_FORWARDED_FOR'])){
+            if($_SERVER['REMOTE_ADDR'] != $_SERVER['HTTP_FORWARDED_FOR']){
+                $user_combined_ip .=  '|'. $_SERVER['HTTP_FORWARDED_FOR'];
+            }
+        }
+        if(isset($_SERVER['HTTP_X_FORWARDED'])){
+            if($_SERVER['REMOTE_ADDR'] != $_SERVER['HTTP_X_FORWARDED']){
+                $user_combined_ip .=  '|'. $_SERVER['HTTP_X_FORWARDED'];
+            }
+        }        if(isset($_SERVER['HTTP_FORWARDED'])){
+            if($_SERVER['REMOTE_ADDR'] != $_SERVER['HTTP_FORWARDED']){
+                $user_combined_ip .=  '|'. $_SERVER['HTTP_FORWARDED'];
+            }
+        }
+        if(isset($_SERVER['HTTP_CF_CONNECTING_IP'])){
+            if(!empty($_SERVER['HTTP_CF_CONNECTING_IP'])){
+              $user_combined_ip = $_SERVER['HTTP_CF_CONNECTING_IP'];
+            }
+        }
+        return $user_combined_ip;
+    }
+}
+
+/* Need to have cookie visible from parent directory */
+session_set_cookie_params(0, '/', '', true, true);
+/* Create signon session */
+$session_name = 'SignonSession';
+session_name($session_name);
+@session_start();
+
+function session_invalid(){
+    global $session_name;
+    //delete all current sessions
+    session_destroy();
+    setcookie($session_name, null, -1, '/');
+    header('Location: /phpmyadmin/index.php');
+    die();
+}
+    $api = new Hestia_API();
+    if(!empty($_GET)){
+        if(isset($_GET['logout'])){
+            $api -> delete_temp_user($_SESSION['HESTIA_sso_database'], $_SESSION['HESTIA_sso_user'],  $_SESSION['PMA_single_signon_user'], $_SESSION['HESTIA_sso_host']);
+            //remove sessin
+            session_invalid();
+        }else{ 
+            if(isset($_GET['user']) && isset($_GET['hestia_token'])){
+                $database = $_GET['database'];
+                $user = $_GET['user'];
+                $host = 'localhost';
+                $token = $_GET['hestia_token'];
+                $time = $_GET['exp'];
+                if($time + 60 > time()){
+                    //note: Possible issues with cloudflare due to ip obfuscation
+                    $ip = $api -> get_user_ip();
+                    if(!password_verify($database.$user.$ip.$time.PHPMYADMIN_KEY,$token)){
+                        session_invalid();
+                    }else{
+                        $id = session_id();
+                        //create a new temp user 
+                        $data = $api -> create_temp_user($database,$user, $host);
+                        $_SESSION['PMA_single_signon_user'] = $data -> login -> user;
+                        $_SESSION['PMA_single_signon_password'] = $data -> login -> password ; 
+                        //save database / username to be used for sending logout notification. 
+                        $_SESSION['HESTIA_sso_user'] = $user;
+                        $_SESSION['HESTIA_sso_database'] = $database;
+                        $_SESSION['HESTIA_sso_host'] = $host;
+                        
+                        @session_write_close();
+                        setcookie($session_name, $id , 0, "/");
+                        header('Location: /phpmyadmin/index.php');
+                        die();
+                    }
+                }else{
+                    session_invalid();
+                }
+            }
+        }
+    }else{
+        session_invalid();
+    }
+?>

+ 16 - 0
web/edit/server/index.php

@@ -279,6 +279,22 @@ if (!empty($_POST['save'])) {
             }
         }
     }
+    // Set File Manager support
+    if (empty($_SESSION['error_msg'])) {
+        if (!empty($_POST['v_phpmyadmin_key'])) {
+            if ($_POST['v_phpmyadmin_key'] == 'yes' && $_SESSION['PHPMYADMIN_KEY'] == '') {
+                exec (HESTIA_CMD."v-add-sys-pma-sso quiet", $output, $return_var);
+                check_return_code($return_var,$output);
+                unset($output);
+                if (empty($_SESSION['error_msg'])) $_SESSION['PHPMYADMIN_KEY'] != "";
+            } else if($_POST['v_phpmyadmin_key'] == 'no' && $_SESSION['PHPMYADMIN_KEY'] != ''){
+                exec (HESTIA_CMD."v-delete-sys-pma-sso  quiet", $output, $return_var);
+                check_return_code($return_var,$output);
+                unset($output);
+                if (empty($_SESSION['error_msg'])) $_SESSION['PHPMYADMIN_KEY'] = '';
+            }
+        }
+    }
 
     // Set disk_quota support
     if (empty($_SESSION['error_msg'])) {

+ 15 - 0
web/templates/admin/edit_server.html

@@ -464,6 +464,21 @@
                                                 <br><br>
                                             </td>
                                         </tr>
+                                        <tr>
+                                            <td class="vst-text">
+                                                <?php print _('phpMyAdmin Single Sign On') ?>
+                                            </td>
+                                        </tr>
+                                        <tr>
+                                            <td>
+                                                <select class="vst-list" name="v_phpmyadmin_key">
+                                                    <option value='no'><?php print _('Disabled'); ?></option>
+                                                    <option value='yes' <?php if($_POST['v_phpmyadmin_key'] == "yes" || $_SESSION['PHPMYADMIN_KEY'] != ''){ echo 'selected="selected"'; }; ?>><?php print _('Enabled'); ?></option>
+                                                </select>
+                                                <br />
+                                                <br />
+                                            </td>
+                                        </tr>
                                         <?php } ?>
                                         <?php if ($v_mysql == 'yes') {
                                                   $i = 0;

+ 9 - 3
web/templates/admin/list_db.html

@@ -79,7 +79,7 @@
                       <input id="toggle-all" type="checkbox" name="toggle-all" value="toggle-all" onChange="checkedAll('objects');">
                   </div>
                   <div class="clearfix l-unit__stat-col--left wide-3"><b><?php print _('Database');?></b></div>
-                  <div class="clearfix l-unit__stat-col--left text-right compact-2"><b>&nbsp;</b></div>
+                  <div class="clearfix l-unit__stat-col--left text-right compact-3"><b>&nbsp;</b></div>
                   <div class="clearfix l-unit__stat-col--left text-center compact"><b><?php print _('Type');?></b></div>
                   <div class="clearfix l-unit__stat-col--left text-center wide"><b><?php print _('Username');?></b></div>
                   <div class="clearfix l-unit__stat-col--left text-center"><b><?php print _('Hostname');?></b></div>
@@ -123,7 +123,7 @@ sort-user="<?=$data[$key]['DBUSER']?>" sort-server="<?=$data[$key]['HOST']?>" so
                 </div>
                 <div class="clearfix l-unit__stat-col--left wide-3 truncate"><b><a href="/edit/db/?database=<?=$key?>&token=<?=$_SESSION['token']?>" title="<?=_('Editing Database')?>"><?=$key?></a></b></div>
                 <!-- START QUICK ACTION TOOLBAR AREA -->
-                <div class="clearfix l-unit__stat-col--left text-right compact-2">
+                <div class="clearfix l-unit__stat-col--left text-right compact-3">
                       <div class="l-unit-toolbar__col l-unit-toolbar__col--right noselect">
                           <div class="actions-panel clearfix">
                             <div class="actions-panel__col actions-panel__logs shortcut-enter" key-action="href"><a href="/edit/db/?database=<?=$key?>&token=<?=$_SESSION['token']?>" title="<?=_('Editing Database')?>"><i class="fas fa-pencil-alt status-icon orange status-icon dim"></i></a></div>
@@ -145,7 +145,13 @@ sort-user="<?=$data[$key]['DBUSER']?>" sort-server="<?=$data[$key]['HOST']?>" so
                                 </div>
                               </a>
                             </div>
-
+                            <?php if ($data[$key]['TYPE'] == 'mysql' && isset($_SESSION['PHPMYADMIN_KEY']) && $_SESSION['PHPMYADMIN_KEY'] != '') {
+                            $time = time();
+                            ?>
+                                <div class="actions-panel__col actions-panel__logs shortcut-enter" key-action="href"><a href="<?=$db_myadmin_link;?>/hestia-sso.php?database=<?=$key;?>&user=<?=$user;?>&exp=<?=$time;?>&hestia_token=<?=password_hash($key.$user.$_SESSION['user_combined_ip'].$time.$_SESSION['PHPMYADMIN_KEY'], PASSWORD_DEFAULT)?>" title="<?=_('Editing Database')?>"><i class="fas fa-sign-in-alt status-icon orange status-icon dim"></i></a></div>
+                            <?php
+                            }
+                            ?>
                           </div>
                         </div>
                   </div>