pull/632/head
Mr Chen 6 months ago
parent 82ee20b1a9
commit bcfdd22161
  1. 6
      new_cli.sh
  2. 7
      panel_tools.py
  3. 44
      web/admin/dashboard/login.py
  4. 44
      web/admin/setting/secondary_verifiy.py
  5. 3
      web/admin/setup/option.py
  6. 45
      web/admin/site/__init__.py
  7. 2
      web/core/db.py
  8. 13
      web/core/mw.py
  9. 4
      web/static/app/config.js
  10. 2
      web/templates/default/login.html
  11. 6
      web/templates/default/setting.html
  12. 15
      web/thisdb/user.py
  13. 4
      web/utils/config.py
  14. 89
      web/utils/site.py
  15. 9
      web/utils/system/main.py

@ -64,7 +64,11 @@ mw_start_debug(){
}
mw_start_panel(){
cd ${DIR}/web && gunicorn -b :7200 -w 1 app:app
port=7200
if [ -f ${DIR}/data/port.pl ];then
port=$(cat ${DIR}/data/port.pl)
fi
cd ${DIR}/web && gunicorn -b :${port} -w 1 app:app
}
mw_start_bgtask(){

@ -158,9 +158,10 @@ def mwcli(mw_input=0):
open_ssh_port()
print("|-已开启!")
elif mw_input == 26:
auth_secret = 'data/auth_secret.pl'
if os.path.exists(auth_secret):
os.remove(auth_secret)
two_step_verification = thisdb.getOptionByJson('two_step_verification', default={'open':False})
if two_step_verification['open']:
two_step_verification['open'] = False
thisdb.setOption('two_step_verification', json.dumps(two_step_verification))
print("|-关闭二次验证成功!")
else:
print("|-二次验证已关闭!")

@ -20,8 +20,6 @@ from flask import request,g
from admin.common import isLogined
from admin.user_login_check import panel_login_required
from admin import cache,session
from admin import model
from admin.model import db,TempLogin,Users
import core.mw as mw
import thisdb
@ -63,7 +61,7 @@ def login_temp_user(token):
stime = int(time.time())
tmp_data = model.getTempLoginByToken(token)
tmp_data = thisdb.getTempLoginByToken(token)
if not tmp_data:
setErrorNum(skey)
return '验证失败!'
@ -73,12 +71,10 @@ def login_temp_user(token):
return "过期"
user_data = thisdb.getUserById(1)
login_addr = mw.getClientIp() + ":" + str(request.environ.get('REMOTE_PORT'))
mw.writeLog('用户临时登录', "登录成功,帐号:{1},登录IP:{2}",(user_data['name'], login_addr))
TempLogin.query.filter(TempLogin.id==tmp_data['id']).update({"login_time": stime, 'state': 1, 'login_addr': login_addr})
db.session.commit()
mw.M('temp_login').where('id=?',(tmp_data['id'],)).update({"login_time": stime, 'state': 1, 'login_addr': login_addr})
session['login'] = True
session['username'] = user_data['name']
@ -105,11 +101,11 @@ def login():
session['login'] = False
session['overdue'] = 0
db_path = model.getOption('admin_path')
db_path = thisdb.getOption('admin_path')
if db_path == '':
return render_template('default/login.html')
else:
unauthorized_status = model.getOption('unauthorized_status')
unauthorized_status = thisdb.getOption('unauthorized_status')
if unauthorized_status == '0':
return render_template('default/path.html')
return Response(status=int(unauthorized_status))
@ -134,6 +130,32 @@ def check_login():
return mw.returnData(True,'已登录')
return mw.returnData(False,'未登录')
@blueprint.route("/verify_login", methods=['POST'])
def verifyLogin():
import pyotp
username = request.form.get('username', '').strip()
password = request.form.get('password', '').strip()
password = mw.md5(password)
info = thisdb.getUserByRoot()
if info['name'] != username or info['password'] != password:
return mw.returnJson(-1, "密码错误?")
auth = request.form.get('auth', '').strip()
two_step_verification = thisdb.getOptionByJson('two_step_verification', default={'open':False})
if two_step_verification['open']:
sec = mw.deDoubleCrypt('mdserver-web', two_step_verification['secret'])
totp = pyotp.TOTP(sec)
if totp.verify(auth):
session['login'] = True
session['username'] = info['name']
session['overdue'] = int(time.time()) + 7 * 24 * 60 * 60
thisdb.updateUserLoginTime()
return mw.returnData(1, '二次验证成功!')
return mw.returnData(-1, '二次验证失败!')
# 执行登录操作
@blueprint.route('/do_login', endpoint='do_login', methods=['POST'])
def do_login():
@ -181,9 +203,15 @@ def do_login():
mw.writeLog('用户登录', mw.getInfo(msg))
return mw.returnData(-1, mw.getInfo("用户名或密码错误,您还可以尝试[{1}]次!", (str(login_cache_count - login_cache_limit))))
cache.delete('login_cache_limit')
# 二步验证密钥
two_step_verification = thisdb.getOptionByJson('two_step_verification', default={'open':False})
if two_step_verification['open']:
return mw.returnData(2, '需要两步验证!')
session['login'] = True
session['username'] = info['name']
session['overdue'] = int(time.time()) + 7 * 24 * 60 * 60
thisdb.updateUserLoginTime()
return mw.returnJson(1, '登录成功,正在跳转...')

@ -25,30 +25,48 @@ import core.mw as mw
import utils.config as utils_config
from .setting import blueprint
import thisdb
# 获取二次验证信息
@blueprint.route('/get_auth_secret', endpoint='get_auth_secret', methods=['POST'])
@panel_login_required
def get_auth_secret():
reset = request.form.get('reset', '')
__file = mw.getCommonFile()
import pyotp
auth = __file['auth_secret']
reset = request.form.get('reset', '')
tag = 'mdserver-web'
if os.path.exists(auth) and reset != '1':
content = mw.readFile(auth)
sec = mw.deDoubleCrypt(tag,content)
two_step_verification = thisdb.getOptionByJson('two_step_verification', default={'open':False})
if 'secret' in two_step_verification and reset != '1':
secret = mw.deDoubleCrypt(tag, two_step_verification['secret'])
else:
sec = pyotp.random_base32()
crypt_data = mw.enDoubleCrypt(tag, sec)
mw.writeFile(auth, crypt_data)
secret = pyotp.random_base32()
crypt_data = mw.enDoubleCrypt(tag, secret)
two_step_verification['secret'] = crypt_data
thisdb.setOption('two_step_verification', json.dumps(two_step_verification))
ip = mw.getHostAddr()
url = pyotp.totp.TOTP(sec).provisioning_uri(name=ip, issuer_name=tag)
url = pyotp.totp.TOTP(secret).provisioning_uri(name=ip, issuer_name=tag)
rdata = {}
rdata['secret'] = sec
rdata['secret'] = secret
rdata['url'] = url
return mw.returnData(True, '设置成功!', rdata)
# 设置二次验证,加强安全登录
@blueprint.route('/set_auth_secret', endpoint='set_auth_secret', methods=['POST'])
@panel_login_required
def set_auth_secret():
two_step_verification = thisdb.getOptionByJson('two_step_verification', default={'open':False})
if two_step_verification['open']:
two_step_verification['open'] = False
thisdb.setOption('two_step_verification', json.dumps(two_step_verification))
return mw.returnData(True, '关闭成功!', 0)
else:
two_step_verification['open'] = True
thisdb.setOption('two_step_verification', json.dumps(two_step_verification))
return mw.returnData(True, '开启成功!', 1)

@ -32,6 +32,9 @@ def init_option():
# basic auth 配置
thisdb.setOption('basic_auth', json.dumps({'open':False}))
# 二步验证|默认关闭
thisdb.setOption('two_step_verification', json.dumps({'open':False}))
# 开启后台任务
# model.setOption('run_bg_task', 'close')

@ -26,7 +26,7 @@ blueprint = Blueprint('site', __name__, url_prefix='/site', template_folder='../
def index():
return render_template('site.html')
# 插件列表
# 站点列表
@blueprint.route('/list', endpoint='list', methods=['GET','POST'])
@panel_login_required
def list():
@ -42,11 +42,54 @@ def list():
data['page'] = mw.getPage({'count':info['count'],'tojs':'getWeb','p':p, 'row':limit})
return data
#添加站点
@blueprint.route('/add', endpoint='add',methods=['POST'])
@panel_login_required
def add():
webname = request.form.get('webinfo', '')
ps = request.form.get('ps', '')
path = request.form.get('path', '')
version = request.form.get('version', '')
port = request.form.get('port', '')
return []
# 获取站点类型
@blueprint.route('/get_site_types', endpoint='get_site_types',methods=['POST'])
@panel_login_required
def get_site_types():
return []
# 获取站点根目录
@blueprint.route('/get_root_dir', endpoint='get_root_dir',methods=['POST'])
@panel_login_required
def get_root_dir():
data = {}
data['dir'] = mw.getWwwDir()
return data
# 检查OpenResty安装/启动状态
@blueprint.route('/check_web_status', endpoint='check_web_status',methods=['POST'])
@panel_login_required
def check_web_status():
'''
创建站点检查web服务
'''
if not mw.isInstalledWeb():
return mw.returnJson(False, '请安装并启动OpenResty服务!')
# 这个快点
pid = mw.getServerDir() + '/openresty/nginx/logs/nginx.pid'
if not os.path.exists(pid):
return mw.returnData(False, '请启动OpenResty服务!')
return mw.returnData(True, 'OK')
# 获取PHP版本
@blueprint.route('/get_php_version', endpoint='get_php_version',methods=['POST'])
@panel_login_required
def get_php_version():
return site.getPhpVersion()
@blueprint.route('/get_cli_php_version', endpoint='get_cli_php_version',methods=['POST'])
@panel_login_required
def get_cli_php_version():

@ -39,6 +39,8 @@ class Sql():
__OPT_FIELD = "*" # field条件
__OPT_PARAM = () # where值
__debug = False
def __init__(self):
self.__DB_FILE = getPanelDir()+'/data/panel.db'

@ -909,6 +909,19 @@ def panelCmd(method):
# ------------------------------ panel end -----------------------------
# ------------------------------ openresty start -----------------------------
def checkWebConfig():
op_dir = getServerDir() + '/openresty/nginx'
# "ulimit -n 10240 && " +
cmd = op_dir + "/sbin/nginx -t -c " + op_dir + "/conf/nginx.conf"
result = execShell(cmd)
searchStr = 'test is successful'
if result[1].find(searchStr) == -1:
msg = getInfo('配置文件错误: {1}', (result[1],))
writeLog("软件管理", msg)
return result[1]
return True
def restartWeb():
return opWeb("reload")

@ -1236,13 +1236,13 @@ function setTempAccess(){
});
}
//二验证
//二验证
function setAuthBind(){
$.post('/setting/get_auth_secret', {}, function(rdata){
console.log(rdata);
var tip = layer.open({
area: ['500px', '355px'],
title: '二验证设置',
title: '二验证设置',
closeBtn:1,
shift: 0,
type: 1,

@ -231,7 +231,7 @@ $('#login-button').click(function(){
layer.prompt({
formType: 3,
value: '',
title: '二验证',
title: '二验证',
}, function(value, index, elem){
$.post('/verify_login',{'auth':value,'username':username,'password':password},function(vdata){
if (vdata.status < 0){

@ -149,11 +149,11 @@
</p>
<p class="mtb15">
<span class="set-tit text-right" title="二验证" style="float: left;">验证</span>
<input class="btswitch btswitch-ios" id="cfg_panel_auth" type="checkbox" {{data['auth_secret']}}/>
<span class="set-tit text-right" title="二验证" style="float: left;">验证</span>
<input class="btswitch btswitch-ios" id="cfg_panel_auth" type="checkbox" {% if data['two_step_verification']['open'] %}checked{% endif %}/>
<label class="btswitch-btn ml5" for="cfg_panel_auth" style="float: left;margin-top:4px;" onclick="setAuthSecretApi()"></label>
<button type="button" class="btn btn-default btn-xs panel_api_btn" style="vertical-align: middle; margin-left: 10px" onclick="setAuthBind();">绑定设置</button>
<span class="set-info c7">验证,加强安全登录</span>
<span class="set-info c7">验证,加强安全登录</span>
</p>
</div>

@ -10,9 +10,11 @@
import core.mw as mw
__field = 'id,name,password,login_ip,login_time,phone,email,add_time,update_time'
# 初始化用户信息
def initAdminUser():
data = mw.M('users').field('id').where('id=?', (1,)).find()
data = mw.M('users').field(__field).where('id=?', (1,)).find()
if data is None:
name = mw.getRandomString(8).lower()
password = mw.getRandomString(8).lower()
@ -39,8 +41,7 @@ def getUserByName(name,
'''
获取用户信息通过用户名
'''
users_field = 'id,name,password,login_ip,login_time,phone,email,add_time,update_time'
data = mw.M('users').field(users_field).where('name=?', (name,)).find()
data = mw.M('users').field(__field).where('name=?', (name,)).find()
if data is None:
return None
row = {}
@ -60,8 +61,7 @@ def getUserById(id,
'''
获取用户信息通过用户名
'''
users_field = 'id,name,password,login_ip,login_time,phone,email,add_time,update_time'
data = mw.M('users').field(users_field).where('id=?', (1,)).find()
data = mw.M('users').field(__field).where('id=?', (1,)).find()
if data is None:
return None
row = {}
@ -83,6 +83,11 @@ def getUserByRoot() -> None:
'''
return getUserById(1)
def updateUserLoginTime():
now_time = mw.formatDate()
mw.M('users').field(__field).where('id=?', (1,)).update({'login_time',now_time})
return True
def setUserByRoot(
name: str | None = None,
password: str | None = None,

@ -62,10 +62,14 @@ def getGlobalVar():
else:
data['ipv6'] = ''
# 获取ROOT用户名
data['username'] = mw.M('users').where("id=?", (1,)).getField('name')
# 获取未认证状态信息
unauthorized_status = thisdb.getOption('unauthorized_status', default='0')
data['unauthorized_status'] = getUnauthStatus(code=unauthorized_status)
data['basic_auth'] = thisdb.getOptionByJson('basic_auth', default={'open':False})
data['two_step_verification'] = thisdb.getOptionByJson('two_step_verification', default={'open':False})
# 服务器时间
sformat = 'date +"%Y-%m-%d %H:%M:%S %Z %z"'

@ -18,43 +18,56 @@ from admin import model
import core.mw as mw
def getPhpVersion():
phpVersions = ('00', '52', '53', '54', '55',
'56', '70', '71', '72', '73',
'74', '80', '81', '82', '83',
'84')
data = []
for val in phpVersions:
tmp = {}
if val == '00':
tmp['version'] = '00'
tmp['name'] = '纯静态'
data.append(tmp)
# 标准判断
checkPath = mw.getServerDir() + '/php/' + val + '/bin/php'
if os.path.exists(checkPath):
tmp['version'] = val
tmp['name'] = 'PHP-' + val
data.append(tmp)
class sites(object):
# lock
_instance_lock = threading.Lock()
@classmethod
def instance(cls, *args, **kwargs):
if not hasattr(sites, "_instance"):
with sites._instance_lock:
if not hasattr(sites, "_instance"):
sites._instance = sites(*args, **kwargs)
return sites._instance
def getPhpVersion(self):
phpVersions = ('00', '52', '53', '54', '55',
'56', '70', '71', '72', '73',
'74', '80', '81', '82', '83',
'84')
data = []
for val in phpVersions:
tmp = {}
if val == '00':
tmp['version'] = '00'
tmp['name'] = '纯静态'
data.append(tmp)
# 其他PHP安装类型
conf_dir = mw.getServerDir() + "/web_conf/php/conf"
conf_list = os.listdir(conf_dir)
l = len(conf_list)
rep = r"enable-php-(.*?)\.conf"
for name in conf_list:
tmp = {}
try:
matchVer = re.search(rep, name).groups()[0]
except Exception as e:
continue
if matchVer in phpVersions:
continue
tmp['version'] = matchVer
tmp['name'] = 'PHP-' + matchVer
data.append(tmp)
return data
# 标准判断
checkPath = mw.getServerDir() + '/php/' + val + '/bin/php'
if os.path.exists(checkPath):
tmp['version'] = val
tmp['name'] = 'PHP-' + val
data.append(tmp)
# 其他PHP安装类型
conf_dir = mw.getServerDir() + "/web_conf/php/conf"
conf_list = os.listdir(conf_dir)
l = len(conf_list)
rep = r"enable-php-(.*?)\.conf"
for name in conf_list:
tmp = {}
try:
matchVer = re.search(rep, name).groups()[0]
except Exception as e:
continue
if matchVer in phpVersions:
continue
tmp['version'] = matchVer
tmp['name'] = 'PHP-' + matchVer
data.append(tmp)
return data

@ -105,12 +105,13 @@ def getSystemVersion():
def getBootTime():
# 取系统启动时间
uptime = mw.readFile('/proc/uptime')
if uptime == False:
if os.path.exists('/proc/uptime'):
uptime = mw.readFile('/proc/uptime')
run_time = uptime.split()[0]
else:
start_time = psutil.boot_time()
run_time = time.time() - start_time
else:
run_time = uptime.split()[0]
tStr = float(run_time)
min = tStr / 60
hours = min / 60

Loading…
Cancel
Save