mdserver-web/web/admin/__init__.py

224 lines
6.9 KiB
Python
Raw Permalink Normal View History

2024-10-08 11:35:42 -04:00
# coding:utf-8
# ---------------------------------------------------------------------------------
# MW-Linux面板
# ---------------------------------------------------------------------------------
# copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved.
# ---------------------------------------------------------------------------------
# Author: midoks <midoks@163.com>
# ---------------------------------------------------------------------------------
2024-10-24 14:24:38 -04:00
import os
2024-10-08 11:35:42 -04:00
import sys
2024-10-30 16:57:02 -04:00
import json
2024-10-25 16:04:00 -04:00
import time
2024-10-24 14:24:38 -04:00
import uuid
import logging
2024-11-11 12:42:53 -05:00
2024-10-24 14:24:38 -04:00
from datetime import timedelta
2024-10-08 11:35:42 -04:00
from flask import Flask
2024-11-11 12:00:06 -05:00
from flask import request
2024-12-10 09:13:20 -05:00
from flask import redirect
2024-11-11 12:00:06 -05:00
from flask import Response
2024-10-30 16:57:02 -04:00
from flask import Flask, abort, current_app, session, url_for
2024-10-13 10:15:58 -04:00
from flask import Blueprint, render_template
2024-10-19 10:17:16 -04:00
from flask import render_template_string
2026-04-04 09:04:47 -04:00
from flask_compress import Compress
2024-10-21 13:36:09 -04:00
2024-11-11 12:42:53 -05:00
from flask_socketio import SocketIO, emit, send
2024-10-30 16:57:02 -04:00
2024-10-29 12:55:34 -04:00
from flask_caching import Cache
2024-10-21 13:36:09 -04:00
from werkzeug.local import LocalProxy
2024-11-26 16:48:44 -05:00
2024-11-11 12:42:53 -05:00
from admin.common import isLogined
2024-10-29 12:55:34 -04:00
2024-10-20 15:19:08 -04:00
import core.mw as mw
2024-10-27 15:13:10 -04:00
import config
2024-10-26 14:23:12 -04:00
import utils.config as utils_config
2024-11-11 12:00:06 -05:00
import thisdb
2024-11-26 16:48:44 -05:00
2024-11-28 07:43:17 -05:00
# 初始化db
from admin import setup
setup.init()
2024-10-13 10:15:58 -04:00
app = Flask(__name__, template_folder='templates/default')
2024-10-08 11:35:42 -04:00
2026-04-04 10:13:22 -04:00
2026-04-07 11:27:43 -04:00
# curl --compressed -I "http://127.0.0.1:44010/" -H "Accept-Encoding: br" --write-out "%{json}"
app.config["COMPRESS_ALGORITHM"] = ["br", "zstd", "gzip", "deflate"]
2026-04-05 03:12:45 -04:00
app.config["COMPRESS_LEVEL"] = 9 # 最高压缩级别
app.config["COMPRESS_MIN_SIZE"] = 500 # 最小压缩大小
2026-04-04 09:04:47 -04:00
Compress(app)
2024-10-30 16:57:02 -04:00
# 缓存配置
cache = Cache(config={'CACHE_TYPE': 'simple'})
cache.init_app(app, config={'CACHE_TYPE': 'simple'})
2024-10-21 13:36:09 -04:00
# 静态文件配置
app.static_folder = "../static"
app.static_url_path = "/static"
2024-11-28 07:16:02 -05:00
app.jinja_env.trim_blocks = True
2024-10-08 11:35:42 -04:00
# from whitenoise import WhiteNoise
# app.wsgi_app = WhiteNoise(app.wsgi_app, root="../web/static/", prefix="static/", max_age=604800)
2024-10-24 14:24:38 -04:00
# session配置
2024-11-23 14:49:53 -05:00
# app.secret_key = uuid.UUID(int=uuid.getnode()).hex[-12:]
app.config['SECRET_KEY'] = uuid.UUID(int=uuid.getnode()).hex[-12:]
2024-10-24 14:24:38 -04:00
# app.config['sessions'] = dict()
app.config['SESSION_PERMANENT'] = True
app.config['SESSION_USE_SIGNER'] = True
app.config['SESSION_KEY_PREFIX'] = 'MW_:'
app.config['SESSION_COOKIE_NAME'] = "MW_VER_1"
app.config['PERMANENT_SESSION_LIFETIME'] = timedelta(days=31)
2025-07-17 05:37:57 -04:00
app.config['SEND_FILE_MAX_AGE_DEFAULT'] = 604800
2024-10-24 14:24:38 -04:00
2024-10-21 13:36:09 -04:00
# db的配置
2024-11-04 06:08:39 -05:00
# app.config['SQLALCHEMY_DATABASE_URI'] = mw.getSqitePrefix()+config.SQLITE_PATH+"?timeout=20" # 使用 SQLite 数据库
2024-10-21 13:36:09 -04:00
app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True
2024-10-20 15:19:08 -04:00
2024-11-11 12:42:02 -05:00
# BASIC AUTH
2024-10-30 16:57:02 -04:00
app.config['BASIC_AUTH_OPEN'] = False
2024-11-04 11:16:19 -05:00
try:
2024-11-26 13:07:08 -05:00
basic_auth = thisdb.getOptionByJson('basic_auth', default={'open':False})
2024-11-04 11:16:19 -05:00
if basic_auth['open']:
app.config['BASIC_AUTH_OPEN'] = True
except Exception as e:
pass
2024-10-20 15:19:08 -04:00
2024-10-13 10:15:58 -04:00
# 加载模块
from .submodules import get_submodules
for module in get_submodules():
app.logger.info('Registering blueprint module: %s' % module)
if app.blueprints.get(module.name) is None:
app.register_blueprint(module)
2024-10-08 11:35:42 -04:00
2024-10-30 16:57:02 -04:00
def sendAuthenticated():
# 发送http认证信息
request_host = mw.getHostAddr()
result = Response('', 401, {'WWW-Authenticate': 'Basic realm="%s"' % request_host.strip()})
if not 'login' in session and not 'admin_auth' in session:
session.clear()
return result
2024-10-29 12:55:34 -04:00
2024-10-24 14:24:38 -04:00
@app.before_request
def requestCheck():
2025-07-17 05:37:57 -04:00
request.start_time = time.time()
2024-12-10 09:13:20 -05:00
admin_close = thisdb.getOption('admin_close')
if admin_close == 'yes':
if not request.path.startswith('/close'):
return redirect('/close')
2024-10-30 16:57:02 -04:00
# 自定义basic auth认证
if app.config['BASIC_AUTH_OPEN']:
2024-11-26 13:07:08 -05:00
basic_auth = thisdb.getOptionByJson('basic_auth', default={'open':False})
2024-10-30 16:57:02 -04:00
if not basic_auth['open']:
return
auth = request.authorization
if request.path in ['/download', '/hook', '/down']:
return
if not auth:
return sendAuthenticated()
salt = basic_auth['salt']
basic_user = mw.md5(auth.username.strip() + salt)
basic_pwd = mw.md5(auth.password.strip() + salt)
if basic_user != basic_auth['basic_user'] or basic_pwd != basic_auth['basic_pwd']:
return sendAuthenticated()
2024-11-26 10:50:17 -05:00
2025-11-03 05:17:37 -05:00
# domain_check = mw.checkDomainPanel()
# if domain_check:
# return domain_check
2024-10-30 16:57:02 -04:00
2024-10-08 11:35:42 -04:00
2024-10-19 10:17:16 -04:00
@app.after_request
def requestAfter(response):
2024-10-27 15:13:10 -04:00
response.headers['soft'] = config.APP_NAME
response.headers['mw-version'] = config.APP_VERSION
2025-07-17 05:37:57 -04:00
response.headers['X-Response-Time'] = round(time.time() - request.start_time, 4)
2024-10-19 10:17:16 -04:00
return response
@app.errorhandler(404)
def page_unauthorized(error):
2024-12-01 07:24:57 -05:00
from flask import redirect
2024-12-01 07:22:19 -05:00
return redirect('/', code=302)
# return render_template_string('404 not found', error_info=error), 404
2024-10-19 10:17:16 -04:00
2024-10-20 15:19:08 -04:00
# 设置模板全局变量
@app.context_processor
def inject_global_variables():
2024-11-04 11:16:19 -05:00
app_ver = config.APP_VERSION
2024-10-25 16:04:00 -04:00
if mw.isDebugMode():
2024-11-04 11:16:19 -05:00
app_ver = app_ver + str(time.time())
2024-10-25 16:04:00 -04:00
2024-10-26 14:23:12 -04:00
data = utils_config.getGlobalVar()
2024-10-27 15:13:10 -04:00
g_config = {
2024-11-04 11:16:19 -05:00
'version': app_ver,
2024-10-29 10:28:38 -04:00
'title' : 'MW面板',
2024-10-25 07:04:14 -04:00
'ip' : '127.0.0.1'
2024-10-20 15:19:08 -04:00
}
2024-10-27 15:13:10 -04:00
return dict(config=g_config, data=data)
2024-10-20 15:19:08 -04:00
2024-11-12 09:56:40 -05:00
# webssh
2024-11-27 11:52:16 -05:00
# socketio = SocketIO(manage_session=False, async_mode='threading',
# logger=False, engineio_logger=False, debug=False,
# ping_interval=25, ping_timeout=120)
2024-11-27 12:28:45 -05:00
socketio = SocketIO(logger=False,
engineio_logger=False,
2026-04-05 21:48:31 -04:00
cors_allowed_origins="*",
async_mode='threading')
2024-11-12 09:56:40 -05:00
socketio.init_app(app)
@socketio.on('webssh_websocketio')
def webssh_websocketio(data):
if not isLogined():
emit('server_response', {'data': '会话丢失,请重新登陆面板!\r\n'})
return
import utils.ssh.ssh_terminal as ssh_terminal
shell_client = ssh_terminal.ssh_terminal.instance()
shell_client.run(request.sid, data)
return
@socketio.on('webssh')
def webssh(data):
if not isLogined():
emit('server_response', {'data': '会话丢失,请重新登陆面板!\r\n'})
return None
import utils.ssh.ssh_local as ssh_local
shell = ssh_local.ssh_local.instance()
shell.run(data)
return
2024-11-11 12:00:06 -05:00
2024-11-26 16:48:44 -05:00
2024-11-13 06:28:56 -05:00
# File logging
logger = logging.getLogger('werkzeug')
logger.setLevel(config.CONSOLE_LOG_LEVEL)
from utils.enhanced_log_rotation import EnhancedRotatingFileHandler
fh = EnhancedRotatingFileHandler(config.LOG_FILE,
config.LOG_ROTATION_SIZE,
config.LOG_ROTATION_AGE,
config.LOG_ROTATION_MAX_LOG_FILES)
fh.setLevel(config.FILE_LOG_LEVEL)
app.logger.addHandler(fh)
logger.addHandler(fh)
# Console logging
ch = logging.StreamHandler()
ch.setLevel(config.CONSOLE_LOG_LEVEL)
ch.setFormatter(logging.Formatter(config.CONSOLE_LOG_FORMAT))
2024-11-11 12:00:06 -05:00
# Log the startup
app.logger.info('########################################################')
app.logger.info('Starting %s v%s...', config.APP_NAME, config.APP_VERSION)
app.logger.info('########################################################')
app.logger.debug("Python syspath: %s", sys.path)