Skip to content

Commit 01a6a06

Browse files
authored
Merge pull request #1685 from master3395/v2.5.5-dev
V2.5.5 dev
2 parents 05ae9fe + 99f51a8 commit 01a6a06

31 files changed

+1088
-1240
lines changed

baseTemplate/views.py

Lines changed: 74 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,27 @@
3333
BUILD = 'dev'
3434

3535

36+
def _version_compare(a, b):
37+
"""Return 1 if a > b, -1 if a < b, 0 if equal."""
38+
def parse(v):
39+
parts = []
40+
for p in str(v).split('.'):
41+
try:
42+
parts.append(int(p))
43+
except ValueError:
44+
parts.append(0)
45+
return parts
46+
pa, pb = parse(a), parse(b)
47+
for i in range(max(len(pa), len(pb))):
48+
va = pa[i] if i < len(pa) else 0
49+
vb = pb[i] if i < len(pb) else 0
50+
if va > vb:
51+
return 1
52+
if va < vb:
53+
return -1
54+
return 0
55+
56+
3657
@ensure_csrf_cookie
3758
def renderBase(request):
3859
template = 'baseTemplate/homePage.html'
@@ -45,27 +66,41 @@ def renderBase(request):
4566

4667
@ensure_csrf_cookie
4768
def versionManagement(request):
69+
currentVersion = VERSION
70+
currentBuild = str(BUILD)
71+
4872
getVersion = requests.get('https://cyberpanel.net/version.txt')
4973
latest = getVersion.json()
5074
latestVersion = latest['version']
5175
latestBuild = latest['build']
76+
branch_ref = 'v%s.%s' % (latestVersion, latestBuild)
5277

53-
currentVersion = VERSION
54-
currentBuild = str(BUILD)
55-
56-
u = "https://api.github.com/repos/usmannasir/cyberpanel/commits?sha=v%s.%s" % (latestVersion, latestBuild)
57-
logging.writeToFile(u)
58-
r = requests.get(u)
59-
latestcomit = r.json()[0]['sha']
60-
61-
command = "git -C /usr/local/CyberCP/ rev-parse HEAD"
62-
output = ProcessUtilities.outputExecutioner(command)
63-
64-
Currentcomt = output.rstrip("\n")
6578
notechk = True
79+
Currentcomt = ''
80+
latestcomit = ''
6681

67-
if Currentcomt == latestcomit:
82+
if _version_compare(currentVersion, latestVersion) > 0:
6883
notechk = False
84+
else:
85+
remote_cmd = 'git -C /usr/local/CyberCP remote get-url origin 2>/dev/null || true'
86+
remote_out = ProcessUtilities.outputExecutioner(remote_cmd)
87+
is_usmannasir = 'usmannasir/cyberpanel' in (remote_out or '')
88+
89+
if is_usmannasir:
90+
u = "https://api.github.com/repos/usmannasir/cyberpanel/commits?sha=%s" % branch_ref
91+
logging.CyberCPLogFileWriter.writeToFile(u)
92+
try:
93+
r = requests.get(u, timeout=10)
94+
r.raise_for_status()
95+
latestcomit = r.json()[0]['sha']
96+
except (requests.RequestException, IndexError, KeyError) as e:
97+
logging.CyberCPLogFileWriter.writeToFile('[versionManagement] GitHub API failed: %s' % str(e))
98+
head_cmd = 'git -C /usr/local/CyberCP rev-parse HEAD 2>/dev/null || true'
99+
Currentcomt = ProcessUtilities.outputExecutioner(head_cmd).rstrip('\n')
100+
if latestcomit and Currentcomt == latestcomit:
101+
notechk = False
102+
else:
103+
notechk = False
69104

70105
template = 'baseTemplate/versionManagment.html'
71106
finalData = {'build': currentBuild, 'currentVersion': currentVersion, 'latestVersion': latestVersion,
@@ -253,31 +288,41 @@ def getLoadAverage(request):
253288

254289
@ensure_csrf_cookie
255290
def versionManagment(request):
256-
## Get latest version
291+
currentVersion = VERSION
292+
currentBuild = str(BUILD)
257293

258294
getVersion = requests.get('https://cyberpanel.net/version.txt')
259295
latest = getVersion.json()
260296
latestVersion = latest['version']
261297
latestBuild = latest['build']
298+
branch_ref = 'v%s.%s' % (latestVersion, latestBuild)
262299

263-
## Get local version
264-
265-
currentVersion = VERSION
266-
currentBuild = str(BUILD)
267-
268-
u = "https://api.github.com/repos/usmannasir/cyberpanel/commits?sha=v%s.%s" % (latestVersion, latestBuild)
269-
logging.CyberCPLogFileWriter.writeToFile(u)
270-
r = requests.get(u)
271-
latestcomit = r.json()[0]['sha']
272-
273-
command = "git -C /usr/local/CyberCP/ rev-parse HEAD"
274-
output = ProcessUtilities.outputExecutioner(command)
275-
276-
Currentcomt = output.rstrip("\n")
277300
notechk = True
301+
Currentcomt = ''
302+
latestcomit = ''
278303

279-
if (Currentcomt == latestcomit):
304+
if _version_compare(currentVersion, latestVersion) > 0:
280305
notechk = False
306+
else:
307+
remote_cmd = 'git -C /usr/local/CyberCP remote get-url origin 2>/dev/null || true'
308+
remote_out = ProcessUtilities.outputExecutioner(remote_cmd)
309+
is_usmannasir = 'usmannasir/cyberpanel' in (remote_out or '')
310+
311+
if is_usmannasir:
312+
u = "https://api.github.com/repos/usmannasir/cyberpanel/commits?sha=%s" % branch_ref
313+
logging.CyberCPLogFileWriter.writeToFile(u)
314+
try:
315+
r = requests.get(u, timeout=10)
316+
r.raise_for_status()
317+
latestcomit = r.json()[0]['sha']
318+
except (requests.RequestException, IndexError, KeyError) as e:
319+
logging.CyberCPLogFileWriter.writeToFile('[versionManagment] GitHub API failed: %s' % str(e))
320+
head_cmd = 'git -C /usr/local/CyberCP rev-parse HEAD 2>/dev/null || true'
321+
Currentcomt = ProcessUtilities.outputExecutioner(head_cmd).rstrip('\n')
322+
if latestcomit and Currentcomt == latestcomit:
323+
notechk = False
324+
else:
325+
notechk = False
281326

282327
template = 'baseTemplate/versionManagment.html'
283328
finalData = {'build': currentBuild, 'currentVersion': currentVersion, 'latestVersion': latestVersion,

cyberpanel_upgrade.sh

Lines changed: 40 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -795,24 +795,36 @@ if [ "$Server_OS" = "Ubuntu" ]; then
795795
fi
796796
else
797797
rm -rf /usr/local/CyberPanel
798-
if [ -e /usr/bin/pip3 ]; then
799-
PIP3="/usr/bin/pip3"
798+
# AlmaLinux 9/10, Rocky 9: use python3 -m venv (no virtualenv pkg needed)
799+
if [[ "$Server_OS" = "AlmaLinux" ]] || [[ "$Server_OS" = "AlmaLinux9" ]] || [[ "$Server_OS" = "RockyLinux" ]]; then
800+
if [[ "$Server_OS_Version" = "9" ]] || [[ "$Server_OS_Version" = "10" ]]; then
801+
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] AlmaLinux/Rocky $Server_OS_Version: will use python3 -m venv, skipping virtualenv package" | tee -a /var/log/cyberpanel_upgrade_debug.log
802+
else
803+
if [ -e /usr/bin/pip3 ]; then PIP3="/usr/bin/pip3"; else PIP3="pip3.6"; fi
804+
$PIP3 install --default-timeout=3600 virtualenv
805+
Check_Return
806+
fi
800807
else
801-
PIP3="pip3.6"
808+
if [ -e /usr/bin/pip3 ]; then PIP3="/usr/bin/pip3"; else PIP3="pip3.6"; fi
809+
$PIP3 install --default-timeout=3600 virtualenv
810+
Check_Return
802811
fi
803-
$PIP3 install --default-timeout=3600 virtualenv
804-
Check_Return
805812
fi
806813

807814
if [[ -f /usr/local/CyberPanel/bin/python2 ]]; then
808815
echo -e "\nPython 2 dectected, doing re-setup...\n"
809816
rm -rf /usr/local/CyberPanel/bin
810817
if [[ "$Server_OS" = "Ubuntu" ]] && ([[ "$Server_OS_Version" = "22" ]] || [[ "$Server_OS_Version" = "24" ]]); then
811818
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Ubuntu $Server_OS_Version detected, using python3 -m venv..." | tee -a /var/log/cyberpanel_upgrade_debug.log
812-
python3 -m venv /usr/local/CyberPanel
813-
elif [[ "$Server_OS" = "CentOS" ]] && ([[ "$Server_OS_Version" = "9" ]] || [[ "$Server_OS_Version" = "10" ]]); then
814-
PYTHON_PATH=$(which python3 2>/dev/null || which python3.9 2>/dev/null || echo "/usr/bin/python3")
815-
virtualenv -p "$PYTHON_PATH" --system-site-packages /usr/local/CyberPanel
819+
python3 -m venv --system-site-packages /usr/local/CyberPanel
820+
elif [[ "$Server_OS" = "CentOS" ]] || [[ "$Server_OS" = "AlmaLinux" ]] || [[ "$Server_OS" = "AlmaLinux9" ]] || [[ "$Server_OS" = "RockyLinux" ]]; then
821+
if [[ "$Server_OS_Version" = "9" ]] || [[ "$Server_OS_Version" = "10" ]]; then
822+
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] AlmaLinux/Rocky $Server_OS_Version detected, using python3 -m venv..." | tee -a /var/log/cyberpanel_upgrade_debug.log
823+
python3 -m venv --system-site-packages /usr/local/CyberPanel
824+
else
825+
PYTHON_PATH=$(which python3 2>/dev/null || which python3.9 2>/dev/null || echo "/usr/bin/python3")
826+
virtualenv -p "$PYTHON_PATH" --system-site-packages /usr/local/CyberPanel
827+
fi
816828
else
817829
virtualenv -p /usr/bin/python3 --system-site-packages /usr/local/CyberPanel
818830
fi
@@ -828,14 +840,19 @@ echo -e "\nNothing found, need fresh setup...\n"
828840
if [[ "$Server_OS" = "Ubuntu" ]] && ([[ "$Server_OS_Version" = "22" ]] || [[ "$Server_OS_Version" = "24" ]]); then
829841
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Ubuntu $Server_OS_Version detected, using python3 -m venv..." | tee -a /var/log/cyberpanel_upgrade_debug.log
830842
python3 -m venv /usr/local/CyberPanel
831-
elif [[ "$Server_OS" = "CentOS" ]] && ([[ "$Server_OS_Version" = "9" ]] || [[ "$Server_OS_Version" = "10" ]]); then
832-
PYTHON_PATH=$(which python3 2>/dev/null || which python3.9 2>/dev/null || echo "/usr/bin/python3")
833-
virtualenv -p "$PYTHON_PATH" --system-site-packages /usr/local/CyberPanel
843+
elif [[ "$Server_OS" = "CentOS" ]] || [[ "$Server_OS" = "AlmaLinux" ]] || [[ "$Server_OS" = "AlmaLinux9" ]] || [[ "$Server_OS" = "RockyLinux" ]]; then
844+
if [[ "$Server_OS_Version" = "9" ]] || [[ "$Server_OS_Version" = "10" ]]; then
845+
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] AlmaLinux/Rocky $Server_OS_Version: using python3 -m venv (no virtualenv pkg needed)..." | tee -a /var/log/cyberpanel_upgrade_debug.log
846+
python3 -m venv --system-site-packages /usr/local/CyberPanel
847+
else
848+
PYTHON_PATH=$(which python3 2>/dev/null || which python3.9 2>/dev/null || echo "/usr/bin/python3")
849+
virtualenv -p "$PYTHON_PATH" --system-site-packages /usr/local/CyberPanel
850+
fi
834851
else
835852
virtualenv -p /usr/bin/python3 --system-site-packages /usr/local/CyberPanel
836853
fi
837854

838-
# Check if the virtualenv command failed
855+
# Check if the virtualenv/venv command failed
839856
if [ $? -ne 0 ]; then
840857
echo "virtualenv command failed."
841858

@@ -861,11 +878,15 @@ if [ $? -ne 0 ]; then
861878
if [ $? -eq 0 ]; then
862879
echo "'packaging' module reinstalled and upgraded successfully."
863880
if [[ "$Server_OS" = "Ubuntu" ]] && ([[ "$Server_OS_Version" = "22" ]] || [[ "$Server_OS_Version" = "24" ]]); then
864-
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Ubuntu $Server_OS_Version detected, using python3 -m venv..." | tee -a /var/log/cyberpanel_upgrade_debug.log
865-
python3 -m venv /usr/local/CyberPanel
866-
elif [[ "$Server_OS" = "CentOS" ]] && ([[ "$Server_OS_Version" = "9" ]] || [[ "$Server_OS_Version" = "10" ]]); then
867-
PYTHON_PATH=$(which python3 2>/dev/null || which python3.9 2>/dev/null || echo "/usr/bin/python3")
868-
virtualenv -p "$PYTHON_PATH" --system-site-packages /usr/local/CyberPanel
881+
echo -e "[$(date +"%Y-%m-%d %H:%M:%S")] Ubuntu: using python3 -m venv..." | tee -a /var/log/cyberpanel_upgrade_debug.log
882+
python3 -m venv --system-site-packages /usr/local/CyberPanel
883+
elif [[ "$Server_OS" = "CentOS" ]] || [[ "$Server_OS" = "AlmaLinux" ]] || [[ "$Server_OS" = "AlmaLinux9" ]] || [[ "$Server_OS" = "RockyLinux" ]]; then
884+
if [[ "$Server_OS_Version" = "9" ]] || [[ "$Server_OS_Version" = "10" ]]; then
885+
python3 -m venv --system-site-packages /usr/local/CyberPanel
886+
else
887+
PYTHON_PATH=$(which python3 2>/dev/null || which python3.9 2>/dev/null || echo "/usr/bin/python3")
888+
virtualenv -p "$PYTHON_PATH" --system-site-packages /usr/local/CyberPanel
889+
fi
869890
else
870891
virtualenv -p /usr/bin/python3 --system-site-packages /usr/local/CyberPanel
871892
fi
@@ -888,7 +909,7 @@ fi
888909

889910
# shellcheck disable=SC1091
890911
. /usr/local/CyberPanel/bin/activate
891-
pip install --upgrade setuptools packaging
912+
pip install --upgrade pip setuptools packaging
892913

893914
Download_Requirement
894915

fix-pureftpd-quota-once.sh

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
#!/bin/bash
2+
# One-time fix on the server: correct Pure-FTPd Quota line and start the service.
3+
# Run as root: sudo bash fix-pureftpd-quota-once.sh
4+
# Use when the panel has written invalid "Quota yes" and Pure-FTPd fails to start.
5+
6+
set -e
7+
CONF=/etc/pure-ftpd/pure-ftpd.conf
8+
SERVICE=pure-ftpd
9+
10+
if [ ! -f "$CONF" ]; then
11+
echo "Config not found: $CONF"
12+
exit 1
13+
fi
14+
15+
# Fix Quota line (Pure-FTPd requires Quota maxfiles:maxsize, not "yes")
16+
if grep -q '^Quota' "$CONF"; then
17+
sed -i 's/^Quota.*/Quota 100000:100000/' "$CONF"
18+
echo "Fixed Quota line in $CONF"
19+
else
20+
echo 'Quota 100000:100000' >> "$CONF"
21+
echo "Appended Quota line to $CONF"
22+
fi
23+
24+
# Optional: disable TLS if cert is missing (common cause of start failure)
25+
if grep -q '^TLS[[:space:]]*1' "$CONF" && [ ! -f /etc/ssl/private/pure-ftpd.pem ]; then
26+
sed -i 's/^TLS[[:space:]]*1/TLS 0/' "$CONF"
27+
echo "Set TLS 0 (certificate missing)"
28+
fi
29+
30+
# Start service
31+
systemctl start "$SERVICE"
32+
sleep 1
33+
if systemctl is-active --quiet "$SERVICE"; then
34+
echo "Pure-FTPd is running."
35+
exit 0
36+
else
37+
echo "Pure-FTPd failed to start. Run: systemctl status $SERVICE"
38+
exit 1
39+
fi

panelAccess.zip

10.6 KB
Binary file not shown.

panelAccess/__init__.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# -*- coding: utf-8 -*-
2+
# Panel Access app: custom domain / reverse-proxy CSRF trusted origins

panelAccess/admin.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# -*- coding: utf-8 -*-
2+
# No admin models; settings are stored in a config file

panelAccess/apps.py

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
# -*- coding: utf-8 -*-
2+
"""
3+
Panel Access app: merges admin-configured custom panel domains into
4+
CSRF_TRUSTED_ORIGINS so POSTs work when the panel is behind a reverse proxy.
5+
"""
6+
import os
7+
from django.apps import AppConfig
8+
9+
10+
def get_panel_csrf_origins_file():
11+
"""Path to the file where custom panel origins are stored (one per line)."""
12+
return os.environ.get(
13+
'PANEL_CSRF_ORIGINS_FILE',
14+
'/home/cyberpanel/panel_csrf_origins.conf'
15+
)
16+
17+
18+
def read_panel_csrf_origins():
19+
"""Read trusted origins from the config file. Returns list of strings."""
20+
path = get_panel_csrf_origins_file()
21+
if not os.path.isfile(path):
22+
return []
23+
try:
24+
with open(path, 'r') as f:
25+
lines = f.readlines()
26+
except (OSError, IOError):
27+
return []
28+
origins = []
29+
for line in lines:
30+
line = line.strip()
31+
if not line or line.startswith('#'):
32+
continue
33+
origins.append(line)
34+
return origins
35+
36+
37+
class PanelaccessConfig(AppConfig):
38+
name = 'panelAccess'
39+
verbose_name = 'Panel Access (Custom Domain / CSRF)'
40+
41+
def ready(self):
42+
"""Merge admin-configured origins into CSRF_TRUSTED_ORIGINS at startup."""
43+
try:
44+
from django.conf import settings
45+
custom = read_panel_csrf_origins()
46+
if not custom:
47+
return
48+
base = list(getattr(settings, 'CSRF_TRUSTED_ORIGINS', []))
49+
for origin in custom:
50+
if origin and origin not in base:
51+
base.append(origin)
52+
settings.CSRF_TRUSTED_ORIGINS = base
53+
except Exception:
54+
pass

panelAccess/meta.xml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<cyberpanelPluginConfig>
3+
<name>Panel Access (Custom Domain)</name>
4+
<type>Utility</type>
5+
<description>Configure custom domain(s) for accessing CyberPanel behind a reverse proxy. Fixes 403 CSRF errors on POST (e.g. Ban IP) and optionally sets up OpenLiteSpeed proxy so the panel is reachable at your domain without manual OLS config. Detects panel port from bind.conf (2087/8090).</description>
6+
<version>1.0.1</version>
7+
<author>master3395</author>
8+
<url>/plugins/panelAccess/</url>
9+
<settings_url>/plugins/panelAccess/</settings_url>
10+
<paid>false</paid>
11+
</cyberpanelPluginConfig>

panelAccess/migrations/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# -*- coding: utf-8 -*-

panelAccess/models.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
# -*- coding: utf-8 -*-
2+
# No models; origins are stored in a config file (panel_csrf_origins.conf)

0 commit comments

Comments
 (0)