mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2026-05-06 11:26:07 +02:00
fix: ensure phpMyAdmin signin bridge + auto plugin migrations + PMA tmp dir
- Add plogical/phpmyadmin_utils.ensure_phpmyadmin_signin_bridge: restore phpmyadminsignin.php and tmp/ if missing (fixes 404 on /phpmyadmin/phpmyadminsignin.php). - Call from databases phpMyAdmin page, fetchDetailsPHPMYAdmin, install, and upgrade PMA paths. - install/upgrade: use makedirs(..., exist_ok=True) for phpmyadmin/tmp instead of mkdir. - pluginInstaller: run migrate when migrations/ contains modules OR enable_migrations; use CyberCP venv python; --noinput for migrate; log non-zero exits.
This commit is contained in:
@@ -31,6 +31,11 @@ class DatabaseManager:
|
||||
return proc.render()
|
||||
|
||||
def phpMyAdmin(self, request = None, userID = None):
|
||||
try:
|
||||
from plogical.phpmyadmin_utils import ensure_phpmyadmin_signin_bridge
|
||||
ensure_phpmyadmin_signin_bridge()
|
||||
except BaseException:
|
||||
pass
|
||||
template = 'databases/phpMyAdmin.html'
|
||||
proc = httpProc(request, template, None, 'createDatabase')
|
||||
return proc.render()
|
||||
|
||||
@@ -257,6 +257,11 @@ def generateAccess(request):
|
||||
@csrf_exempt
|
||||
def fetchDetailsPHPMYAdmin(request):
|
||||
try:
|
||||
try:
|
||||
from plogical.phpmyadmin_utils import ensure_phpmyadmin_signin_bridge
|
||||
ensure_phpmyadmin_signin_bridge()
|
||||
except BaseException:
|
||||
pass
|
||||
|
||||
userID = request.session['userID']
|
||||
admin = Administrator.objects.get(id=userID)
|
||||
|
||||
@@ -3986,7 +3986,7 @@ $cfg['Servers'][$i]['LogoutURL'] = 'phpmyadminsignin.php?logout';
|
||||
|
||||
writeToFile.close()
|
||||
|
||||
os.mkdir('/usr/local/CyberCP/public/phpmyadmin/tmp')
|
||||
os.makedirs('/usr/local/CyberCP/public/phpmyadmin/tmp', exist_ok=True)
|
||||
|
||||
command = 'chown -R lscpd:lscpd /usr/local/CyberCP/public/phpmyadmin'
|
||||
preFlightsChecks.call(command, self.distro, '[chown -R lscpd:lscpd /usr/local/CyberCP/public/phpmyadmin]',
|
||||
|
||||
44
plogical/phpmyadmin_utils.py
Normal file
44
plogical/phpmyadmin_utils.py
Normal file
@@ -0,0 +1,44 @@
|
||||
# -*- coding: utf-8 -*-
|
||||
"""
|
||||
Ensure phpMyAdmin single-sign-on bridge files exist under public/phpmyadmin/.
|
||||
Fixes 404 on /phpmyadmin/phpmyadminsignin.php when the file was lost after a partial install or manual change.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import shutil
|
||||
|
||||
from plogical.CyberCPLogFileWriter import CyberCPLogFileWriter as logging
|
||||
|
||||
PMA_DIR = '/usr/local/CyberCP/public/phpmyadmin'
|
||||
SIGNIN_SRC = '/usr/local/CyberCP/plogical/phpmyadminsignin.php'
|
||||
SIGNIN_NAME = 'phpmyadminsignin.php'
|
||||
|
||||
|
||||
def ensure_phpmyadmin_signin_bridge() -> bool:
|
||||
"""
|
||||
Copy plogical/phpmyadminsignin.php into the public phpMyAdmin tree if missing,
|
||||
ensure tmp/ exists, and fix ownership for lscpd.
|
||||
Returns True if the sign-in file is present afterward.
|
||||
"""
|
||||
dst = os.path.join(PMA_DIR, SIGNIN_NAME)
|
||||
try:
|
||||
if not os.path.isdir(PMA_DIR):
|
||||
return False
|
||||
if not os.path.isfile(SIGNIN_SRC):
|
||||
logging.writeToFile('phpmyadmin_utils: source signin missing at ' + SIGNIN_SRC)
|
||||
return os.path.isfile(dst)
|
||||
need_copy = (not os.path.isfile(dst)) or os.path.getsize(dst) < 32
|
||||
if need_copy:
|
||||
shutil.copy2(SIGNIN_SRC, dst)
|
||||
tmp_dir = os.path.join(PMA_DIR, 'tmp')
|
||||
os.makedirs(tmp_dir, exist_ok=True)
|
||||
try:
|
||||
from plogical.processUtilities import ProcessUtilities
|
||||
ProcessUtilities.executioner('chown -R lscpd:lscpd ' + PMA_DIR)
|
||||
except Exception as ch_ex:
|
||||
logging.writeToFile('phpmyadmin_utils: chown skipped or failed (non-fatal): ' + str(ch_ex))
|
||||
return os.path.isfile(dst)
|
||||
except Exception as ex:
|
||||
logging.writeToFile('phpmyadmin_utils: ensure_phpmyadmin_signin_bridge failed: ' + str(ex))
|
||||
return os.path.isfile(dst)
|
||||
@@ -1388,7 +1388,7 @@ $cfg['Servers'][$i]['port'] = '3306';
|
||||
writeToFile.writelines("$cfg['TempDir'] = '/usr/local/CyberCP/public/phpmyadmin/tmp';\n")
|
||||
writeToFile.close()
|
||||
|
||||
os.mkdir('/usr/local/CyberCP/public/phpmyadmin/tmp')
|
||||
os.makedirs('/usr/local/CyberCP/public/phpmyadmin/tmp', exist_ok=True)
|
||||
|
||||
if saved_signon and os.path.isfile(tmp_signon):
|
||||
shutil.copy2(tmp_signon, os.path.join(pma_dir, 'phpmyadminsignin.php'))
|
||||
@@ -1417,6 +1417,12 @@ $cfg['Servers'][$i]['port'] = '3306';
|
||||
command = 'chown -R lscpd:lscpd /usr/local/CyberCP/public/phpmyadmin/tmp'
|
||||
Upgrade.executioner_silent(command, 'chown phpMyAdmin tmp')
|
||||
|
||||
try:
|
||||
from plogical.phpmyadmin_utils import ensure_phpmyadmin_signin_bridge
|
||||
ensure_phpmyadmin_signin_bridge()
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
os.chdir(cwd)
|
||||
|
||||
except Exception as e:
|
||||
|
||||
@@ -58,6 +58,35 @@ class pluginInstaller:
|
||||
pluginHome = '/usr/local/CyberCP/' + pluginName
|
||||
return os.path.exists(pluginHome + '/enable_migrations')
|
||||
|
||||
@staticmethod
|
||||
def shouldApplyPluginDatabaseMigrations(pluginName: str) -> bool:
|
||||
"""
|
||||
Run Django migrations when the plugin opts in (enable_migrations file)
|
||||
or when a migrations/ package with real migration modules is shipped.
|
||||
"""
|
||||
if pluginInstaller.migrationsEnabled(pluginName):
|
||||
return True
|
||||
mig_dir = '/usr/local/CyberCP/' + pluginName + '/migrations'
|
||||
if not os.path.isdir(mig_dir):
|
||||
return False
|
||||
try:
|
||||
for fn in os.listdir(mig_dir):
|
||||
if fn.endswith('.py') and fn != '__init__.py':
|
||||
return True
|
||||
except OSError:
|
||||
return False
|
||||
return False
|
||||
|
||||
@staticmethod
|
||||
def _manage_python_executable():
|
||||
for candidate in ('/usr/local/CyberCP/bin/python', '/usr/local/CyberCP/bin/python3'):
|
||||
try:
|
||||
if os.path.isfile(candidate) and os.access(candidate, os.X_OK):
|
||||
return candidate
|
||||
except OSError:
|
||||
continue
|
||||
return 'python3'
|
||||
|
||||
@staticmethod
|
||||
def _write_lines_to_protected_file(target_path, lines):
|
||||
"""
|
||||
@@ -338,12 +367,31 @@ class pluginInstaller:
|
||||
@staticmethod
|
||||
def installMigrations(pluginName):
|
||||
currentDir = os.getcwd()
|
||||
os.chdir('/usr/local/CyberCP')
|
||||
command = "python3 /usr/local/CyberCP/manage.py makemigrations %s" % pluginName
|
||||
subprocess.call(shlex.split(command))
|
||||
command = "python3 /usr/local/CyberCP/manage.py migrate %s" % pluginName
|
||||
subprocess.call(shlex.split(command))
|
||||
os.chdir(currentDir)
|
||||
manage_py = '/usr/local/CyberCP/manage.py'
|
||||
py = pluginInstaller._manage_python_executable()
|
||||
try:
|
||||
os.chdir('/usr/local/CyberCP')
|
||||
mk = subprocess.call(
|
||||
[py, manage_py, 'makemigrations', pluginName],
|
||||
stdin=subprocess.DEVNULL,
|
||||
)
|
||||
if mk != 0:
|
||||
pluginInstaller.stdOut(
|
||||
'makemigrations %s exited %s (ok if no model changes)' % (pluginName, mk)
|
||||
)
|
||||
mig = subprocess.call(
|
||||
[py, manage_py, 'migrate', pluginName, '--noinput'],
|
||||
stdin=subprocess.DEVNULL,
|
||||
)
|
||||
if mig != 0:
|
||||
pluginInstaller.stdOut(
|
||||
'migrate %s exited %s — check CyberPanel logs and DB permissions' % (pluginName, mig)
|
||||
)
|
||||
finally:
|
||||
try:
|
||||
os.chdir(currentDir)
|
||||
except OSError:
|
||||
pass
|
||||
|
||||
|
||||
@staticmethod
|
||||
@@ -427,12 +475,14 @@ class pluginInstaller:
|
||||
|
||||
##
|
||||
|
||||
if pluginInstaller.migrationsEnabled(pluginName):
|
||||
pluginInstaller.stdOut('Running Migrations..')
|
||||
if pluginInstaller.shouldApplyPluginDatabaseMigrations(pluginName):
|
||||
pluginInstaller.stdOut('Running database migrations for %s..' % pluginName)
|
||||
pluginInstaller.installMigrations(pluginName)
|
||||
pluginInstaller.stdOut('Migrations Completed..')
|
||||
pluginInstaller.stdOut('Database migrations step finished for %s.' % pluginName)
|
||||
else:
|
||||
pluginInstaller.stdOut('Migrations not enabled, add file \'enable_migrations\' to plugin to enable')
|
||||
pluginInstaller.stdOut(
|
||||
'No plugin migrations to apply (no migrations/ package and no enable_migrations marker).'
|
||||
)
|
||||
|
||||
##
|
||||
|
||||
@@ -625,8 +675,11 @@ class pluginInstaller:
|
||||
def removeMigrations(pluginName):
|
||||
currentDir = os.getcwd()
|
||||
os.chdir('/usr/local/CyberCP')
|
||||
command = "python3 /usr/local/CyberCP/manage.py migrate %s zero" % pluginName
|
||||
subprocess.call(shlex.split(command))
|
||||
py = pluginInstaller._manage_python_executable()
|
||||
subprocess.call(
|
||||
[py, '/usr/local/CyberCP/manage.py', 'migrate', pluginName, 'zero', '--noinput'],
|
||||
stdin=subprocess.DEVNULL,
|
||||
)
|
||||
os.chdir(currentDir)
|
||||
|
||||
@staticmethod
|
||||
@@ -640,12 +693,12 @@ class pluginInstaller:
|
||||
|
||||
##
|
||||
|
||||
if pluginInstaller.migrationsEnabled(pluginName):
|
||||
pluginInstaller.stdOut('Removing migrations..')
|
||||
if pluginInstaller.shouldApplyPluginDatabaseMigrations(pluginName):
|
||||
pluginInstaller.stdOut('Reverting database migrations for %s..' % pluginName)
|
||||
pluginInstaller.removeMigrations(pluginName)
|
||||
pluginInstaller.stdOut('Migrations removed..')
|
||||
pluginInstaller.stdOut('Database migrations reverted for %s.' % pluginName)
|
||||
else:
|
||||
pluginInstaller.stdOut('Migrations not enabled, add file \'enable_migrations\' to plugin to enable')
|
||||
pluginInstaller.stdOut('Skipping migrate zero (no migrations package / marker).')
|
||||
|
||||
##
|
||||
|
||||
|
||||
Reference in New Issue
Block a user