mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2026-05-06 10:26:23 +02:00
Fix catch-all bootstrap when e_catchall is missing.
Add runtime table self-healing for catch-all/plus/pattern email features and make upgrade SQL idempotent on existing latin1 installations by avoiding failing FK creation while preserving forwarding compatibility.
This commit is contained in:
@@ -12,6 +12,7 @@ sys.path.append('/usr/local/CyberCP')
|
||||
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "CyberCP.settings")
|
||||
django.setup()
|
||||
from django.http import HttpResponse
|
||||
from django.db import connection
|
||||
try:
|
||||
from .models import Domains,EUsers
|
||||
from loginSystem.views import loadLoginPage
|
||||
@@ -45,6 +46,57 @@ import threading as multi
|
||||
import argparse
|
||||
|
||||
|
||||
|
||||
|
||||
def _ensure_email_filter_tables():
|
||||
"""Create catch-all/plus/pattern email feature tables if missing."""
|
||||
create_statements = [
|
||||
"""CREATE TABLE IF NOT EXISTS `e_catchall` (
|
||||
`domain_id` varchar(50) NOT NULL,
|
||||
`destination` varchar(255) NOT NULL,
|
||||
`enabled` tinyint(1) NOT NULL DEFAULT 1,
|
||||
PRIMARY KEY (`domain_id`),
|
||||
KEY `idx_e_catchall_domain_id` (`domain_id`)
|
||||
) ENGINE=InnoDB""",
|
||||
"""CREATE TABLE IF NOT EXISTS `e_server_settings` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`plus_addressing_enabled` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`plus_addressing_delimiter` varchar(1) NOT NULL DEFAULT '+',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB""",
|
||||
"""CREATE TABLE IF NOT EXISTS `e_plus_override` (
|
||||
`domain_id` varchar(50) NOT NULL,
|
||||
`enabled` tinyint(1) NOT NULL DEFAULT 1,
|
||||
PRIMARY KEY (`domain_id`),
|
||||
KEY `idx_e_plus_override_domain_id` (`domain_id`)
|
||||
) ENGINE=InnoDB""",
|
||||
"""CREATE TABLE IF NOT EXISTS `e_pattern_forwarding` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`domain_id` varchar(50) NOT NULL,
|
||||
`pattern` varchar(255) NOT NULL,
|
||||
`destination` varchar(255) NOT NULL,
|
||||
`pattern_type` varchar(20) NOT NULL DEFAULT 'wildcard',
|
||||
`priority` int(11) NOT NULL DEFAULT 100,
|
||||
`enabled` tinyint(1) NOT NULL DEFAULT 1,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `idx_e_pattern_forwarding_domain_id` (`domain_id`)
|
||||
) ENGINE=InnoDB"""
|
||||
]
|
||||
|
||||
try:
|
||||
with connection.cursor() as cursor:
|
||||
for query in create_statements:
|
||||
cursor.execute(query)
|
||||
cursor.execute(
|
||||
"""INSERT INTO `e_server_settings` (`id`, `plus_addressing_enabled`, `plus_addressing_delimiter`)
|
||||
SELECT 1, 0, '+'
|
||||
WHERE NOT EXISTS (SELECT 1 FROM `e_server_settings` WHERE `id` = 1)"""
|
||||
)
|
||||
return True, ''
|
||||
except BaseException as msg:
|
||||
logging.CyberCPLogFileWriter.writeToFile(str(msg) + ' [_ensure_email_filter_tables]')
|
||||
return False, 'Email feature tables are missing and could not be created automatically. Please run CyberPanel upgrade or apply DB migration.'
|
||||
|
||||
def _get_email_limits_controller_js():
|
||||
"""Return EmailLimitsNew controller JS: from file or hardcoded fallback so it always works."""
|
||||
try:
|
||||
@@ -2084,6 +2136,12 @@ protocol sieve {
|
||||
if ACLManager.currentContextPermission(currentACL, 'emailForwarding') == 0:
|
||||
return ACLManager.loadErrorJson('fetchStatus', 0)
|
||||
|
||||
ok, schemaErr = _ensure_email_filter_tables()
|
||||
if not ok:
|
||||
data_ret = {'status': 0, 'fetchStatus': 0, 'error_message': schemaErr}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
data = json.loads(self.request.body)
|
||||
domain = data['domain']
|
||||
|
||||
@@ -2132,6 +2190,12 @@ protocol sieve {
|
||||
if ACLManager.currentContextPermission(currentACL, 'emailForwarding') == 0:
|
||||
return ACLManager.loadErrorJson('saveStatus', 0)
|
||||
|
||||
ok, schemaErr = _ensure_email_filter_tables()
|
||||
if not ok:
|
||||
data_ret = {'status': 0, 'saveStatus': 0, 'error_message': schemaErr}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
data = json.loads(self.request.body)
|
||||
domain = data['domain']
|
||||
destination = data['destination']
|
||||
@@ -2190,6 +2254,12 @@ protocol sieve {
|
||||
if ACLManager.currentContextPermission(currentACL, 'emailForwarding') == 0:
|
||||
return ACLManager.loadErrorJson('deleteStatus', 0)
|
||||
|
||||
ok, schemaErr = _ensure_email_filter_tables()
|
||||
if not ok:
|
||||
data_ret = {'status': 0, 'deleteStatus': 0, 'error_message': schemaErr}
|
||||
json_data = json.dumps(data_ret)
|
||||
return HttpResponse(json_data)
|
||||
|
||||
data = json.loads(self.request.body)
|
||||
domain = data['domain']
|
||||
|
||||
|
||||
@@ -2878,8 +2878,8 @@ CREATE TABLE `websiteFunctions_backupsv2` (`id` integer AUTO_INCREMENT NOT NULL
|
||||
`destination` varchar(255) NOT NULL,
|
||||
`enabled` tinyint(1) NOT NULL DEFAULT 1,
|
||||
PRIMARY KEY (`domain_id`),
|
||||
CONSTRAINT `fk_catchall_domain` FOREIGN KEY (`domain_id`) REFERENCES `e_domains` (`domain`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"""
|
||||
KEY `idx_e_catchall_domain_id` (`domain_id`)
|
||||
) ENGINE=InnoDB"""
|
||||
try:
|
||||
cursor.execute(query)
|
||||
except:
|
||||
@@ -2890,7 +2890,7 @@ CREATE TABLE `websiteFunctions_backupsv2` (`id` integer AUTO_INCREMENT NOT NULL
|
||||
`plus_addressing_enabled` tinyint(1) NOT NULL DEFAULT 0,
|
||||
`plus_addressing_delimiter` varchar(1) NOT NULL DEFAULT '+',
|
||||
PRIMARY KEY (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"""
|
||||
) ENGINE=InnoDB"""
|
||||
try:
|
||||
cursor.execute(query)
|
||||
except:
|
||||
@@ -2900,8 +2900,8 @@ CREATE TABLE `websiteFunctions_backupsv2` (`id` integer AUTO_INCREMENT NOT NULL
|
||||
`domain_id` varchar(50) NOT NULL,
|
||||
`enabled` tinyint(1) NOT NULL DEFAULT 1,
|
||||
PRIMARY KEY (`domain_id`),
|
||||
CONSTRAINT `fk_plus_override_domain` FOREIGN KEY (`domain_id`) REFERENCES `e_domains` (`domain`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"""
|
||||
KEY `idx_e_plus_override_domain_id` (`domain_id`)
|
||||
) ENGINE=InnoDB"""
|
||||
try:
|
||||
cursor.execute(query)
|
||||
except:
|
||||
@@ -2916,14 +2916,21 @@ CREATE TABLE `websiteFunctions_backupsv2` (`id` integer AUTO_INCREMENT NOT NULL
|
||||
`priority` int(11) NOT NULL DEFAULT 100,
|
||||
`enabled` tinyint(1) NOT NULL DEFAULT 1,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `fk_pattern_domain` (`domain_id`),
|
||||
CONSTRAINT `fk_pattern_domain` FOREIGN KEY (`domain_id`) REFERENCES `e_domains` (`domain`) ON DELETE CASCADE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4"""
|
||||
KEY `idx_e_pattern_forwarding_domain_id` (`domain_id`)
|
||||
) ENGINE=InnoDB"""
|
||||
try:
|
||||
cursor.execute(query)
|
||||
except:
|
||||
pass
|
||||
|
||||
# Seed singleton row for global email settings if missing.
|
||||
try:
|
||||
cursor.execute("""INSERT INTO `e_server_settings` (`id`, `plus_addressing_enabled`, `plus_addressing_delimiter`)
|
||||
SELECT 1, 0, '+'
|
||||
WHERE NOT EXISTS (SELECT 1 FROM `e_server_settings` WHERE `id` = 1)""")
|
||||
except:
|
||||
pass
|
||||
|
||||
try:
|
||||
connection.close()
|
||||
except:
|
||||
|
||||
Reference in New Issue
Block a user