mirror of
https://github.com/usmannasir/cyberpanel.git
synced 2026-02-16 19:46:48 +01:00
- pluginHolder/views: use dir+meta.xml for installed count; exclude core apps; repair pass to restore meta.xml from source or GitHub; ensure_plugin_meta_xml falls back to GitHub when source missing; cap active <= installed - pluginHolder/urls: include plugin routes for all on-disk plugins (not only INSTALLED_APPS) so /plugins/<name>/settings/ works after install - pluginHolder/plugins.html: Install button tries local then store (GitHub) - CyberCP/settings: sync INSTALLED_APPS with plugin dirs on disk (meta.xml+urls.py) Author: master3395
274 lines
9.2 KiB
Python
274 lines
9.2 KiB
Python
"""
|
||
Django settings for CyberCP project.
|
||
|
||
Generated by 'django-admin startproject' using Django 1.11.3.
|
||
|
||
For more information on this file, see
|
||
https://docs.djangoproject.com/en/1.11/topics/settings/
|
||
|
||
For the full list of settings and their values, see
|
||
https://docs.djangoproject.com/en/1.11/ref/settings/
|
||
"""
|
||
|
||
import os
|
||
from django.utils.translation import gettext_lazy as _
|
||
|
||
# Patreon OAuth (optional): for paid-plugin verification via Patreon membership.
|
||
# Set these only if you use Patreon-gated plugins; leave unset otherwise.
|
||
# Use environment variables; no defaults so the repo stays generic and safe to push to GitHub.
|
||
PATREON_CLIENT_ID = os.environ.get('PATREON_CLIENT_ID', '')
|
||
PATREON_CLIENT_SECRET = os.environ.get('PATREON_CLIENT_SECRET', '')
|
||
PATREON_CREATOR_ID = os.environ.get('PATREON_CREATOR_ID', '')
|
||
PATREON_MEMBERSHIP_TIER_ID = os.environ.get('PATREON_MEMBERSHIP_TIER_ID', '')
|
||
PATREON_CREATOR_ACCESS_TOKEN = os.environ.get('PATREON_CREATOR_ACCESS_TOKEN', '')
|
||
PATREON_CREATOR_REFRESH_TOKEN = os.environ.get('PATREON_CREATOR_REFRESH_TOKEN', '')
|
||
|
||
# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
|
||
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||
|
||
# Quick-start development settings - unsuitable for production
|
||
# See https://docs.djangoproject.com/en/1.11/howto/deployment/checklist/
|
||
|
||
# SECURITY WARNING: keep the secret key used in production secret!
|
||
SECRET_KEY = 'xr%j*p!*$0d%(-(e%@-*hyoz4$f%y77coq0u)6pwmjg4)q&19f'
|
||
|
||
# SECURITY WARNING: don't run with debug turned on in production!
|
||
DEBUG = False
|
||
|
||
ALLOWED_HOSTS = ['*']
|
||
|
||
# When the panel is behind a reverse proxy (e.g. https://panel.example.com -> http://backend:port),
|
||
# the browser sends Origin/Referer with the public domain while the proxy may send Host as the
|
||
# backend address. Django then fails CSRF (Referer vs Host mismatch) and POSTs get 403.
|
||
# Set CSRF_TRUSTED_ORIGINS to your public origin(s) so CSRF passes. Optional; leave unset if
|
||
# you access the panel by IP:port only.
|
||
# Example: export CSRF_TRUSTED_ORIGINS="https://panel.example.com,http://panel.example.com"
|
||
_csrf_origins_env = os.environ.get('CSRF_TRUSTED_ORIGINS', '')
|
||
_csrf_origins_list = [o.strip() for o in _csrf_origins_env.split(',') if o.strip()]
|
||
# Add default trusted origins for common CyberPanel domains
|
||
_default_origins = [
|
||
'https://cyberpanel.newstargeted.com',
|
||
'http://cyberpanel.newstargeted.com',
|
||
]
|
||
# Merge environment and default origins, avoiding duplicates
|
||
CSRF_TRUSTED_ORIGINS = list(dict.fromkeys(_csrf_origins_list + _default_origins))
|
||
|
||
# Application definition
|
||
|
||
INSTALLED_APPS = [
|
||
'django.contrib.admin',
|
||
'django.contrib.auth',
|
||
'django.contrib.contenttypes',
|
||
'django.contrib.sessions',
|
||
'django.contrib.messages',
|
||
'django.contrib.staticfiles',
|
||
|
||
# Core apps (no dependencies on other custom apps)
|
||
'loginSystem', # Base app - many apps depend on Administrator model
|
||
'packages', # websiteFunctions depends on this
|
||
|
||
# Apps with single dependency
|
||
'websiteFunctions', # Depends on packages and loginSystem
|
||
'baseTemplate', # Depends on loginSystem
|
||
'userManagment', # Depends on loginSystem
|
||
'dns', # Depends on loginSystem
|
||
|
||
# Apps depending on websiteFunctions
|
||
'databases', # Depends on websiteFunctions
|
||
'ftp', # Depends on websiteFunctions
|
||
'filemanager', # Depends on websiteFunctions
|
||
'mailServer', # Depends on websiteFunctions, ChildDomains
|
||
|
||
# Apps with multiple or complex dependencies
|
||
'emailPremium',
|
||
# Optional plugins (e.g. emailMarketing, discordWebhooks) - install via Plugin Store
|
||
# from https://github.com/master3395/cyberpanel-plugins - plugin installer adds them
|
||
'cloudAPI', # Depends on websiteFunctions
|
||
'containerization', # Depends on websiteFunctions
|
||
'IncBackups', # Depends on websiteFunctions and loginSystem
|
||
'CLManager', # Depends on packages
|
||
|
||
# Apps with dependencies on loginSystem only
|
||
's3Backups', # Depends on loginSystem
|
||
'dockerManager', # Depends on loginSystem
|
||
'aiScanner', # Depends on loginSystem
|
||
|
||
# Independent apps (no model dependencies found)
|
||
'firewall',
|
||
'tuning',
|
||
'serverStatus',
|
||
'serverLogs',
|
||
'backup',
|
||
'managePHP',
|
||
'manageSSL',
|
||
'api',
|
||
'manageServices',
|
||
'pluginHolder',
|
||
'highAvailability',
|
||
# 'WebTerminal'
|
||
]
|
||
|
||
# Add plugins that are installed (plugin installer handles adding/removing)
|
||
# Plugins are added by plugin installer when plugins are installed
|
||
|
||
MIDDLEWARE = [
|
||
'django.middleware.security.SecurityMiddleware',
|
||
'django.contrib.sessions.middleware.SessionMiddleware',
|
||
'django.middleware.locale.LocaleMiddleware',
|
||
'django.middleware.common.CommonMiddleware',
|
||
'django.middleware.csrf.CsrfViewMiddleware',
|
||
'django.contrib.auth.middleware.AuthenticationMiddleware',
|
||
'django.contrib.messages.middleware.MessageMiddleware',
|
||
'django.middleware.clickjacking.XFrameOptionsMiddleware',
|
||
'CyberCP.secMiddleware.secMiddleware'
|
||
]
|
||
|
||
ROOT_URLCONF = 'CyberCP.urls'
|
||
|
||
TEMPLATES = [
|
||
{
|
||
'BACKEND': 'django.template.backends.django.DjangoTemplates',
|
||
'DIRS': [os.path.join(BASE_DIR, 'templates')]
|
||
,
|
||
'APP_DIRS': True,
|
||
'OPTIONS': {
|
||
'context_processors': [
|
||
'django.template.context_processors.debug',
|
||
'django.template.context_processors.request',
|
||
'django.contrib.auth.context_processors.auth',
|
||
'django.contrib.messages.context_processors.messages',
|
||
'baseTemplate.context_processors.version_context',
|
||
'baseTemplate.context_processors.cosmetic_context',
|
||
'baseTemplate.context_processors.notification_preferences_context',
|
||
],
|
||
},
|
||
},
|
||
]
|
||
|
||
WSGI_APPLICATION = 'CyberCP.wsgi.application'
|
||
|
||
# Database
|
||
# https://docs.djangoproject.com/en/1.11/ref/settings/#databases
|
||
|
||
|
||
DATABASES = {
|
||
'default': {
|
||
'ENGINE': 'django.db.backends.mysql',
|
||
'NAME': 'cyberpanel',
|
||
'USER': 'cyberpanel',
|
||
'PASSWORD': '1XTy1XOV0BZPnM',
|
||
'HOST': 'localhost',
|
||
'PORT':''
|
||
},
|
||
'rootdb': {
|
||
'ENGINE': 'django.db.backends.mysql',
|
||
'NAME': 'mysql',
|
||
'USER': 'root',
|
||
'PASSWORD': '1XTy1XOV0BZPnM',
|
||
'HOST': 'localhost',
|
||
'PORT': '',
|
||
},
|
||
}
|
||
DATABASE_ROUTERS = ['backup.backupRouter.backupRouter']
|
||
|
||
# Password validation
|
||
# https://docs.djangoproject.com/en/1.11/ref/settings/#auth-password-validators
|
||
|
||
AUTH_PASSWORD_VALIDATORS = [
|
||
{
|
||
'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
|
||
},
|
||
{
|
||
'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
|
||
},
|
||
{
|
||
'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
|
||
},
|
||
{
|
||
'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
|
||
},
|
||
]
|
||
|
||
# Internationalization
|
||
# https://docs.djangoproject.com/en/1.11/topics/i18n/
|
||
|
||
LANGUAGE_CODE = 'en'
|
||
|
||
TIME_ZONE = 'UTC'
|
||
|
||
USE_I18N = True
|
||
|
||
USE_L10N = True
|
||
|
||
USE_TZ = True
|
||
|
||
# Static files (CSS, JavaScript, Images)
|
||
# https://docs.djangoproject.com/en/1.11/howto/static-files/
|
||
|
||
STATIC_ROOT = os.path.join(BASE_DIR, "static/")
|
||
|
||
STATIC_URL = '/static/'
|
||
|
||
# Panel public directory (SnappyMail, phpMyAdmin, etc.) – served so /snappymail/ and /phpmyadmin/ work when panel is behind Django
|
||
PUBLIC_ROOT = os.path.join(BASE_DIR, 'public')
|
||
|
||
LOCALE_PATHS = (
|
||
os.path.join(BASE_DIR, 'locale'),
|
||
)
|
||
|
||
LANGUAGES = (
|
||
('en', _('English')),
|
||
('cn', _('Chinese')),
|
||
('br', _('Bulgarian')),
|
||
('pt', _('Portuguese')),
|
||
('ja', _('Japanese')),
|
||
('bs', _('Bosnian')),
|
||
('gr', _('Greek')),
|
||
('ru', _('Russian')),
|
||
('tr', _('Turkish')),
|
||
('es', _('Spanish')),
|
||
('fr', _('French')),
|
||
('pl', _('Polish')),
|
||
('vi', _('Vietnamese')),
|
||
('it', _('Italian')),
|
||
('de', _('Deutsch')),
|
||
('id', _('Indonesian')),
|
||
('bn', _('Bangla')),
|
||
('nb', _('Norwegian Bokmål')),
|
||
)
|
||
|
||
MEDIA_URL = '/usr/local/CyberCP/tmp/'
|
||
MEDIA_ROOT = MEDIA_URL
|
||
DATA_UPLOAD_MAX_MEMORY_SIZE = 2147483648
|
||
|
||
# Security settings
|
||
X_FRAME_OPTIONS = 'SAMEORIGIN'
|
||
|
||
# Login URL - CyberPanel uses root path for login
|
||
LOGIN_URL = '/'
|
||
LOGIN_REDIRECT_URL = '/'
|
||
|
||
# Default primary key field type
|
||
# https://docs.djangoproject.com/en/3.2/ref/settings/#default-auto-field
|
||
DEFAULT_AUTO_FIELD = 'django.db.models.BigAutoField'
|
||
|
||
# Sync INSTALLED_APPS with plugins on disk so /plugins/<name>/ and /plugins/<name>/settings/ work.
|
||
# Plugins installed under /usr/local/CyberCP/ (or BASE_DIR) are added here if they have meta.xml + urls.py.
|
||
_cybercp_root = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
|
||
if os.path.isdir(_cybercp_root):
|
||
try:
|
||
_existing_apps = set(INSTALLED_APPS)
|
||
for _name in os.listdir(_cybercp_root):
|
||
if _name.startswith('.'):
|
||
continue
|
||
_plugin_dir = os.path.join(_cybercp_root, _name)
|
||
if not os.path.isdir(_plugin_dir):
|
||
continue
|
||
if _name in _existing_apps:
|
||
continue
|
||
if (os.path.exists(os.path.join(_plugin_dir, 'meta.xml')) and
|
||
os.path.exists(os.path.join(_plugin_dir, 'urls.py'))):
|
||
INSTALLED_APPS.append(_name)
|
||
_existing_apps.add(_name)
|
||
except (OSError, IOError):
|
||
pass |