# coding:utf-8 # --------------------------------------------------------------------------------- # MW-Linux面板 # --------------------------------------------------------------------------------- # copyright (c) 2018-∞(https://github.com/midoks/mdserver-web) All rights reserved. # --------------------------------------------------------------------------------- # Author: midoks # --------------------------------------------------------------------------------- import os import sys import json import time import uuid import logging from datetime import timedelta from flask import Flask from flask import request from flask import Response from flask import Flask, abort, current_app, session, url_for from flask import Blueprint, render_template from flask import render_template_string from flask_socketio import SocketIO, emit, send from flask_migrate import Migrate from flask_caching import Cache from werkzeug.local import LocalProxy from admin import setup from admin.common import isLogined import core.mw as mw import config import utils.config as utils_config import thisdb # 初始化db setup.init() # from threading import Lock # thread = None # thread_lock = Lock() app = Flask(__name__, template_folder='templates/default') # 缓存配置 cache = Cache(config={'CACHE_TYPE': 'simple'}) cache.init_app(app, config={'CACHE_TYPE': 'simple'}) # 静态文件配置 from whitenoise import WhiteNoise app.wsgi_app = WhiteNoise(app.wsgi_app, root="../web/static/", prefix="static/", max_age=604800) # session配置 # app.secret_key = uuid.UUID(int=uuid.getnode()).hex[-12:] app.config['SECRET_KEY'] = uuid.UUID(int=uuid.getnode()).hex[-12:] # 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) # db的配置 # app.config['SQLALCHEMY_DATABASE_URI'] = mw.getSqitePrefix()+config.SQLITE_PATH+"?timeout=20" # 使用 SQLite 数据库 app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True # BASIC AUTH app.config['BASIC_AUTH_OPEN'] = False try: basic_auth = thisdb.getOptionByJson('basic_auth', default={'open':False}) if basic_auth['open']: app.config['BASIC_AUTH_OPEN'] = True except Exception as e: pass # 加载模块 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) 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 @app.before_request def requestCheck(): config.APP_START_TIME=time.time() # 自定义basic auth认证 if app.config['BASIC_AUTH_OPEN']: basic_auth = thisdb.getOptionByJson('basic_auth', default={'open':False}) if not basic_auth['open']: return auth = request.authorization if request.path in ['/download', '/hook', '/down']: return if not auth: return sendAuthenticated() # print(auth.username.strip(),auth.password.strip()) 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() domain_check = mw.checkDomainPanel() if domain_check: return domain_check @app.after_request def requestAfter(response): response.headers['soft'] = config.APP_NAME response.headers['mw-version'] = config.APP_VERSION if mw.isDebugMode(): response.headers['mw-debug-cos'] = time.time() - config.APP_START_TIME return response @app.errorhandler(404) def page_unauthorized(error): return render_template_string('404 not found', error_info=error), 404 # 设置模板全局变量 @app.context_processor def inject_global_variables(): app_ver = config.APP_VERSION if mw.isDebugMode(): app_ver = app_ver + str(time.time()) data = utils_config.getGlobalVar() g_config = { 'version': app_ver, 'title' : 'MW面板', 'ip' : '127.0.0.1' } return dict(config=g_config, data=data) # webssh socketio = SocketIO() 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 # 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)) # 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)