update 6.3.3

This commit is contained in:
jose
2019-11-01 11:43:34 +08:00
parent e8aa95f86c
commit 5217c1fc78
42 changed files with 1075 additions and 887 deletions
+82 -124
View File
@@ -9,7 +9,7 @@
import sys,json,os,time,logging,re
if sys.version_info[0] != 2:
from imp import reload
sys.path.insert(0,'class/')
sys.path.insert(0,'/www/server/panel/class/')
import public
from flask import Flask
app = Flask(__name__,template_folder="templates/" + public.GetConfigValue('template'))
@@ -19,6 +19,7 @@ from flask_session import Session
from werkzeug.contrib.cache import SimpleCache
from werkzeug.wrappers import Response
from flask_socketio import SocketIO,emit,send
from threading import Lock
dns_client = None
app.config['DEBUG'] = os.path.exists('data/debug.pl')
@@ -37,11 +38,11 @@ cache = SimpleCache()
socketio = SocketIO()
socketio.init_app(app)
import common,db,jobs,uuid
import common,db,jobs,uuid,ssh_terminal
jobs.control_init()
app.secret_key = uuid.UUID(int=uuid.getnode()).hex[-12:]
local_ip = None
my_terms = {}
try:
from flask_sqlalchemy import SQLAlchemy
@@ -67,7 +68,10 @@ app.config['SESSION_COOKIE_NAME'] = "BT_PANEL_6"
app.config['PERMANENT_SESSION_LIFETIME'] = 86400
Session(app)
if s_sqlite: sdb.create_all()
if s_sqlite:
sdb.create_all()
public.ExecShell("chmod 600 /dev/shm/session.db")
from datetime import datetime
import socket
@@ -89,11 +93,67 @@ def service_status():
return 'True'
@socketio.on('connect')
def socket_connect(msg=None):
if not check_login():
emit('server_response',{'data':public.getMsg('111')})
return False
@socketio.on('webssh')
def webssh(msg):
if not check_login():
session.clear()
emit('server_response',"Panel session is lost, please re-login panel!")
return None
if not 'ssh_obj' in session:
session['ssh_obj'] = ssh_terminal.ssh_terminal()
session['ssh_obj'].send(msg)
@app.route('/term_open',methods=method_all)
def term_open():
comReturn = comm.local()
if comReturn: return comReturn
args = get_input()
if 'get_ssh_info' in args:
key = 'ssh_' + args['host']
if key in session:
return public.getJson(session[key]),json_header
return public.returnMsg(False,'Acquisition failed!')
session['ssh_info'] = json.loads(args.data)
key = 'ssh_' + session['ssh_info']['host']
session[key] = session['ssh_info']
s_file = '/www/server/panel/config/t_info.json'
if 'is_save' in session['ssh_info']:
public.writeFile(s_file,public.de_hexb(json.dumps(session['ssh_info'])))
public.set_mode(s_file,600)
else:
if os.path.exists(s_file): os.remove(s_file)
return public.returnJson(True,'Successful setup!');
@app.route('/reload_mod',methods=method_all)
def reload_mod():
comReturn = comm.local()
if comReturn: return comReturn
args = get_input()
mod_name = None
if 'mod_name' in args:
mod_name = args.mod_name
result = public.reload_mod(mod_name)
if result: return public.returnJson(True,result),json_header
return public.returnJson(False,'Reload failure!'),json_header
@app.before_request
def request_check():
if not request.path in ['/safe','/hook','/public']:
ip_check = public.check_ip_panel()
if ip_check: return ip_check
if request.path.find('/static/') != -1 or request.path == '/code':
if not 'login' in session and not 'admin_auth' in session:
session.clear()
return abort(401)
domain_check = public.check_domain_panel()
if domain_check: return domain_check
if public.is_local():
@@ -120,7 +180,9 @@ def request_end(reques = None):
def send_authenticated():
global local_ip
if not local_ip: local_ip = public.GetLocalIp()
return Response('', 401,{'WWW-Authenticate': 'Basic realm="%s"' % local_ip.strip()})
result = Response('', 401,{'WWW-Authenticate': 'Basic realm="%s"' % local_ip.strip()})
if not 'login' in session and not 'admin_auth' in session: session.clear()
return result
@app.route('/',methods=method_all)
def home():
@@ -462,7 +524,7 @@ def config(pdata = None):
if public.is_local(): data['is_local'] = 'checked'
return render_template( 'config.html',data=data)
import config
defs = ('get_qrcode_data','check_two_step','set_two_step_auth','get_key','get_php_session_path','set_php_session_path','get_cert_source','set_local','set_debug','get_panel_error_logs','clean_panel_error_logs','get_basic_auth_stat','set_basic_auth','get_cli_php_version','get_tmp_token','set_cli_php_version','DelOldSession', 'GetSessionCount', 'SetSessionConf', 'GetSessionConf','get_ipv6_listen','set_ipv6_status','GetApacheValue','SetApacheValue','GetNginxValue','SetNginxValue','get_token','set_token','set_admin_path','is_pro','get_php_config','get_config','SavePanelSSL','GetPanelSSL','GetPHPConf','SetPHPConf','GetPanelList','AddPanelInfo','SetPanelInfo','DelPanelInfo','ClickPanelInfo','SetPanelSSL','SetTemplates','Set502','setPassword','setUsername','setPanel','setPathInfo','setPHPMaxSize','getFpmConfig','setFpmConfig','setPHPMaxTime','syncDate','setPHPDisable','SetControl','ClosePanel','AutoUpdatePanel','SetPanelLock')
defs = ('set_coll_open','get_qrcode_data','check_two_step','set_two_step_auth','get_key','get_php_session_path','set_php_session_path','get_cert_source','set_local','set_debug','get_panel_error_logs','clean_panel_error_logs','get_basic_auth_stat','set_basic_auth','get_cli_php_version','get_tmp_token','set_cli_php_version','DelOldSession', 'GetSessionCount', 'SetSessionConf', 'GetSessionConf','get_ipv6_listen','set_ipv6_status','GetApacheValue','SetApacheValue','GetNginxValue','SetNginxValue','get_token','set_token','set_admin_path','is_pro','get_php_config','get_config','SavePanelSSL','GetPanelSSL','GetPHPConf','SetPHPConf','GetPanelList','AddPanelInfo','SetPanelInfo','DelPanelInfo','ClickPanelInfo','SetPanelSSL','SetTemplates','Set502','setPassword','setUsername','setPanel','setPathInfo','setPHPMaxSize','getFpmConfig','setFpmConfig','setPHPMaxTime','syncDate','setPHPDisable','SetControl','ClosePanel','AutoUpdatePanel','SetPanelLock')
return publicObject(config.config(),defs,None,pdata);
@app.route('/ajax',methods=method_all)
@@ -570,6 +632,7 @@ def panel_public():
if not public.path_safe_check("%s/%s" % (get.name,get.fun)): return abort(404)
if get.fun in ['scan_login', 'login_qrcode', 'set_login', 'is_scan_ok', 'blind','static']:
if get.fun == 'static':
if not 'filename' in get: return abort(404)
if not public.path_safe_check("%s" % (get.filename)): return abort(404)
s_file = '/www/server/panel/BTPanel/static/' + get.filename
if s_file.find('..') != -1 or s_file.find('./') != -1: return abort(404)
@@ -598,6 +661,7 @@ def panel_public():
comm.checkWebType()
comm.GetOS()
result = plu.a(get)
session.clear()
return public.getJson(result),json_header
@app.route('/favicon.ico',methods=method_get)
@@ -661,7 +725,9 @@ def panel_other(name=None,fun = None,stype=None):
comReturn = comm.local()
if comReturn:
if not is_php:
if not hasattr(plu,'_check'): return public.returnJson(False,'SPECIFY_PLUG_ERR'),json_header
if not hasattr(plu,'_check'):
session.clear()
return public.returnJson(False,'SPECIFY_PLUG_ERR'),json_header
checks = plu._check(args)
r_type = type(checks)
if r_type == Response: return checks
@@ -738,6 +804,7 @@ def panel_hook():
if not os.path.exists('plugin/webhook'): return public.getJson(public.returnMsg(False,'INIT_WEBHOOK_ERR'));
sys.path.append('plugin/webhook');
import webhook_main
session.clear()
return public.getJson(webhook_main.webhook_main().RunHook(get));
@app.route('/safe',methods=method_all)
@@ -760,13 +827,16 @@ def panel_safe():
if not hasattr(s,get.data['action']): return public.returnJson(False,'INIT_FUN_NOT_EXISTS');
defs = ('GetServerInfo','add_ssh_limit','remove_ssh_limit','get_ssh_limit','get_login_log','get_panel_limit','add_panel_limit','remove_panel_limit','close_ssh_limit','close_panel_limit','get_system_info','get_service_info','get_ssh_errorlogin')
if not get.data['action'] in defs: return 'False';
return public.getJson(eval('s.' + get.data['action'] + '(get)'));
result = public.getJson(eval('s.' + get.data['action'] + '(get)'));
session.clear()
return result
@app.route('/install',methods=method_all)
def install():
if public.M('config').where("id=?",('1',)).getField('status') == 1:
if os.path.exists('install.pl'): os.remove('install.pl');
session.clear()
return redirect('/login')
ret_login = os.path.join('/',admin_path)
if admin_path == '/' or admin_path == '/bt': ret_login = '/login'
@@ -863,122 +933,6 @@ def panel_cloud():
if download_url.find('http') != 0:download_url = 'http://' + download_url
return redirect(download_url)
ssh = None
shell = None
try:
import paramiko
ssh = paramiko.SSHClient()
except:
public.ExecShell('pip install paramiko==2.0.2 &')
@socketio.on('connect')
def socket_connect(msg=None):
if not check_login():
emit('server_response',{'data':public.getMsg('111')})
return False
@socketio.on('webssh')
def webssh(msg):
if not check_login(msg['x_http_token']):
emit('server_response',{'data':public.getMsg('INIT_WEBSSH_LOGOUT')})
return None
global shell,ssh
ssh_success = True
if type(msg['data']) == dict:
if 'ssh_user' in msg['data']:
connect_ssh(msg['data']['ssh_user'].strip(),msg['data']['ssh_passwd'].strip())
if not shell: ssh_success = connect_ssh()
if not shell:
emit('server_response',{'data':public.getMsg('INIT_WEBSSH_CONN_ERR')})
return;
if shell.exit_status_ready(): ssh_success = connect_ssh()
if not ssh_success:
emit('server_response',{'data':public.getMsg('INIT_WEBSSH_CONN_ERR')})
return;
shell.send(msg['data'])
time.sleep(0.005)
recv = shell.recv(4096)
emit('server_response',{'data':recv.decode("utf-8")})
def connect_ssh(user=None,passwd=None):
global shell,ssh
pkey = '/root/.ssh/id_rsa_bt'
if not os.path.exists('/root/.ssh/authorized_keys') or not os.path.exists(pkey):
create_rsa()
try:
if not user:
key=paramiko.RSAKey.from_private_key_file(pkey)
ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
try:
if not user:
ssh.connect('127.0.0.1', public.GetSSHPort(),pkey=key)
else:
ssh.connect('127.0.0.1', public.GetSSHPort(),username=user,password=passwd)
except:
if public.GetSSHStatus():
try:
if not user:
ssh.connect('localhost', public.GetSSHPort(),pkey=key)
else:
ssh.connect('localhost', public.GetSSHPort(),username=user,password=passwd)
except:
create_rsa()
return False;
import firewalls
fw = firewalls.firewalls()
get = common.dict_obj()
ssh_status = fw.GetSshInfo(get)['status']
if not ssh_status:
get.status = '0';
fw.SetSshStatus(get)
if not user:
ssh.connect('127.0.0.1', public.GetSSHPort(),pkey=key)
else:
ssh.connect('127.0.0.1', public.GetSSHPort(),username=user,password=passwd)
if not ssh_status:
get.status = '1';
fw.SetSshStatus(get);
shell = ssh.invoke_shell(term='xterm', width=100, height=29)
shell.setblocking(0)
return True
except:
shell = None
return False
def create_rsa():
id_ras = '/root/.ssh/id_rsa_bt'
a_keys = '/root/.ssh/authorized_keys'
if not os.path.exists(a_keys) or not os.path.exists(id_ras):
public.ExecShell("rm -f /root/.ssh/id_rsa_bt*")
public.ExecShell('ssh-keygen -q -t rsa -P "" -f /root/.ssh/id_rsa_bt')
public.ExecShell('cat /root/.ssh/id_rsa_bt.pub >> /root/.ssh/authorized_keys')
else:
id_ras_pub = '/root/.ssh/id_rsa_bt.pub'
if os.path.exists(id_ras_pub):
pub_body = public.readFile(id_ras_pub)
keys_body = public.readFile(a_keys)
if keys_body.find(pub_body) == -1:
public.ExecShell('cat /root/.ssh/id_rsa_bt.pub >> /root/.ssh/authorized_keys')
public.ExecShell('chmod 600 /root/.ssh/authorized_keys')
@socketio.on('connect_event')
def connected_msg(msg):
if not check_login():
emit('server_response',{'data':public.getMsg('INIT_WEBSSH_LOGOUT')})
return None
global shell
if not shell: connect_ssh()
if shell:
try:
recv = shell.recv(8192)
emit('server_response',{'data':recv.decode("utf-8")})
except:
pass
def check_csrf():
if app.config['DEBUG']: return True
request_token = request.cookies.get('request_token')
@@ -1002,6 +956,10 @@ def publicObject(toObject,defs,action=None,get = None):
if get.path.find('./') != -1: return public.ReturnJson(False,public.GetMsg("UNSAFE_PATH")),json_header
if get.path.find('->') != -1:
get.path = get.path.split('->')[0].strip();
if hasattr(get,'sfile'):
get.sfile = get.sfile.replace('//','/').replace('\\','/');
if hasattr(get,'dfile'):
get.dfile = get.dfile.replace('//','/').replace('\\','/');
if hasattr(toObject,'site_path_check'):
if not toObject.site_path_check(get): return public.ReturnJson(False,'Excessive operation!'),json_header
File diff suppressed because one or more lines are too long
+63 -22
View File
@@ -81,6 +81,12 @@ input::-webkit-input-placeholder {
color: #999
}
input[type=checkbox], input[type=radio]{
height: 14px;
width: 14px;
margin-top: 0;
}
body,
html {
height: 100%
@@ -157,7 +163,7 @@ html {
float:right;
}
.bge6 {
background-color: #f2f2f2;
background-color: #F1F2F7;
}
/* .bge6 {
background-color: #e6e9ee
@@ -829,7 +835,8 @@ html {
transition-timing-function: ease;
width: 100%;
cursor: pointer;
margin: 1px 0
height: 50px;
box-sizing: border-box;
}
.sidebar-scroll .mypcip:hover {
@@ -840,7 +847,8 @@ html {
.sidebar-scroll .mypcip span {
background: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAAQCAYAAAAS7Y8mAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAAdgAAAHYBTnsmCAAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAAGPSURBVDiNldQ9ixRBEAbgZ3Zn1fVOuQU/wK9AMDDS1MvuRxj5CwTBP2CiYmYmGBsYGRsaa2qkkSiCgRd4y3ri3XqzbdDV7Lgs7uwLRc90V1dXv29VVymluxiiRoVkNaoYG7wN+9chpTTBBn7jKA5YhYR+JPQEDxYd6rAPeIwDnOgQuMEIz3F8mUMdC9/wqkPAxb1P0Yv/6ziLX/hTy9c6jXPYXSPwBQywF+Mz7GCCSRGMbqK1Ufwbmb4beI9TuNZFqFWoZCH7Mp0XcaX33y3dUDKfmRdD1bM+BYuoWtaEKeIdyqSvg5+RZSWX6Ri3ZUqmRbxjcqnsx3cyF7Utbpmf4YxcapXcWFNcjiSbOk7Yxhu5BocRaGBeoyXYNII32MTJsJ7cvR/D92aN1xFsFA6HYZ/iiiWjTVyVGyrhBz7jXSQxxq3wPahxJ7JuX30sd9IoshviC77KzdSmag+XYm4QNq0tF+0e7sc1SwPs4xFeLPHvt2ibsfwl24rFl/KLV/jdCho2ZC3a+I6HOB9rR38B10ZjDE49T6kAAAAASUVORK5CYII=") no-repeat 0 center;
display: inline-block;
line-height: 46px;
height: 50px;
line-height: 50px;
padding-left: 30px;
white-space: nowrap;
max-width: 146px;
@@ -1052,7 +1060,7 @@ html .menu .menu_exit:hover {
.pos-box {
height: 50px;
width: 100%;
box-shadow: 0 1px 2px 0 rgba(0,0,0,.1);
/*box-shadow: 0 1px 2px 0 rgba(0,0,0,.1);*/
}
.conter-box{
@@ -1061,9 +1069,9 @@ html .menu .menu_exit:hover {
.position {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAAKwwAACsMBNCkkqwAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAAFZSURBVDiNpdO9a1VBEAXw3zOioIUQEdFGkQdWVtr6D1ikERtRppLU6awUsUkh2CgoBNwhoPhsLESxERR7wcI2XSBNMAHRNFmLbB6Xa64RXFjYOXvmzMfOjmqt/mcd2I+QmUuZOcgbDWWQmTN4iFms4wGu4jC+RMT7wQwy8xBe4FtE3MBXPMdqE5sfLCEzj+Il3kXEE4iIJTzFFbzB9z0FMvMYJphExLPuXUQs4y1eYfmPHmTmbHN+FBGv92zMDm+ulXAzItZHtVaZeRH3sBgRn4ecOyKXcRt3dkuYwyJOZeaJfZyP42TjX1Nrne5SyqSUMu5ho559tpQy2bUP9gL8wHYnzbtYzczTuB8RHzs8/H0Sz+ETbuEDxg3f7pL6AhW/2vknNiNiCxvY6uDT8e2XMINLmbmC89js3I0z8wLOdP36Aht43KIcwULD1+w82/WGT+dk8DP96/oNlqecb6uu8YEAAAAASUVORK5CYII=");
background-position: 17px 14px;
background-position: 20px 17px;
background-repeat: no-repeat;
background-size: 20px auto;
/*background-size: 20px auto;*/
line-height: 50px;
padding-left: 30px;
}
@@ -1127,7 +1135,10 @@ html .menu .menu_exit:hover {
border-bottom: 1px solid #e6e6e6;
color: #666;
font-weight: normal;
padding: 8px
padding: 5px 10px;
height: 35px;
font-size: 12.5px;
box-sizing: content-box;
}
.divtable .table_toolbar{
left: 8px;
@@ -1164,7 +1175,7 @@ html .menu .menu_exit:hover {
.page {
/* line-height: 16px; */
text-align: right;
padding: 8px 0;
padding: 14px 0;
/* margin-right: 1px; */
height: 44px;
/* border: 1px solid #e6e6e6;*/
@@ -1174,7 +1185,7 @@ html .menu .menu_exit:hover {
.site_type{
height: 30px;
line-height: 30px;
bottom: 8px;
bottom: 0;
position: absolute;
}
@@ -1193,6 +1204,7 @@ html .menu .menu_exit:hover {
}
.site_type select{
border-radius: 0px;
outline: none;
}
.site_type_table{
padding: 15px;
@@ -1384,7 +1396,7 @@ html .menu .menu_exit:hover {
-moz-transition: -moz-transform 1s ease-in 0s
}
.pie_left {
.pie_left{
clip: rect(0, 50px, auto, 0);
transition: transform .4s ease-in 1s;
-webkit-transition: -webkit-transform .4s ease-in 1s;
@@ -2417,6 +2429,11 @@ html .menu .menu_exit:hover {
.list-list span.glyphicon-cloud-download {
font-size: 12px
}
.list-list tr>td{
padding: 5px 10px !important;
line-height: 1.42857143;
height: auto;
}
.newFolderName {
border: #ccc 1px solid;
@@ -2851,9 +2868,15 @@ html .menu .menu_exit:hover {
}
.table>tbody>tr>td {
vertical-align: middle
vertical-align: middle;
padding: 5px 10px;
height: 40px;
font-size: 12.5px;
box-sizing: border-box;
}
.table>tbody{
border-bottom: 1px solid #ddd;
}
.showpicdiv {
max-height: 500px;
overflow: hidden;
@@ -3852,7 +3875,9 @@ html .menu .menu_exit:hover {
left: 0;
z-index: 999;
}
.file-box .divtable .table{
border: 1px solid #ddd;
}
.re-head {
border-bottom: 1px solid #ccc;
float: left;
@@ -4137,6 +4162,7 @@ html .menu .menu_exit:hover {
}
.btpro{
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAADsAAAAUCAMAAAAEAbViAAAAA3NCSVQICAjb4U/gAAABXFBMVEX///+7jAC7jAC7jAC7jAC7jAC7jAC7jAC7jAC7jAC7jAC7jAC7jAC7jAC7jAD////+/fv+/fr8+vX8+vP69uv38eD28N3179v07NXz69Lz6tHz6c/x6Mzv48Pu48Hr3rX74jnq27D54Djp2av43zfo16fo2Kj33TX33Tbm1aLl1Z/12Tbl057z1zLk0Znj0Jfx1DDizpPu0DPv0S7fyIbqzCroyC/cxH3oySjawXXZv3DkwyTYvWzivyzXu2jWumXevCDUtVzctinathzSslXSs1bRsVHRsVLWsBjVrSbNqkPTrBXLqD3PpCLJozTOphHIozLIojDIoS/HoCzKoQ7GninGnyrFnifJnB/FnCTFnSbEmiDEmyLFmQnCmBvBlxjBlhbBlRXAlRPCkhy/kxDAkwW+kQq9kAi9jwa9jwK9jQC8jgS8jQO8ihm7jAC2gRWweBKpbw+jZgydXgnhk9RtAAAAdHRSTlMAESIzRFVmd4iZqrvM3e7//////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////wol0KMAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAWdEVYdENyZWF0aW9uIFRpbWUAMDUvMzEvMTikOWwBAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAAg5JREFUOI2dlGlz0zAQhhUHJ45jST2gXKUVR4BijmKKCwX1CKcKLoVQcCmFYgcSjqiy8/9nWCtOJvlEwusZe3Q80rurlRFCyLDsSi7bMtAkKlSlU602W61o+3VDvrnOxlTGliUxkdFcfRjN0aWm3ByXBdgglaqN7N2pmb2t6edba0e3xmctBxWxjecoPfPh2afTtPGkN+J6/2SLxC6ajrQvLC4uPJXvLs6/aC7rkZD35/Awb8RMMc5FGAc9FktMiJS42W5HX+SP6Nv+n13GlFJdlWmEVfCkYcD9fF9MTNO0iHX15o3aRnTncq0W7WcDQvQmeEHO1rlm1ZBnw6lAvrBJQY+3s9fOPSbCMA21BEvdHnvssa7qCm3Hz3N1gpQRsu1ZSk8drFC60nrAmM/DmGv5LAg06yVM75mF0fFyFpWkiUrEoHTx6wKt/d7U/R2hUZjkppoFBxCrYCrkfd9ZcVSkUcAlOrW+Q8+3X13S/SIzHHeFXiZjlctYwiFevwNrDdgCdsD09OzbtZmPh9d6/QFQbiJGzsgFksM5Zcv0WVSUlumcPHdwdv3Xcp5DF5KVowMWvioW7nHKh1gIuYznlxq35aOhshFJCBvEaqC4ztKkntQ9FQ+xEDK5u3r08+Vo0dVHm3Ayvu9nhr1htuDIvc/y/RU2ifqX2MBSHo59g0ZZZJLv9/8ThXyZE/1tQH8B/ly2lqVFKXEAAAAASUVORK5CYII=");
background-size: 50px;
background-repeat:no-repeat;
padding:2px 0 2px 64px;
margin-right:5px;
@@ -4413,12 +4439,14 @@ html .menu .menu_exit:hover {
.bind-weixin{
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABYAAAASBAMAAACtCzMeAAAAA3NCSVQICAjb4U/gAAAAKlBMVEX19fXr6+vg4ODW1tbMzMzCwsK4uLitra2jo6OZmZmPj4+FhYV6enr////oR1GpAAAADnRSTlP/////////////////AEXA3MgAAAAJcEhZcwAADpwAAA6cAQeUU90AAAAWdEVYdENyZWF0aW9uIFRpbWUAMDgvMTYvMTgi+WYYAAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAAK9JREFUCJljuHuXyS1I4C4IMNy9MiNYpF0XzL5Qznv37uUpYPbVWBDF4Qtii9+N8b2y5WIRiB1810L3UuHdEBC7FqTkYlhnqyyUbcJ798rSuwxBQOYVkE5OX6Deu3dVedMulF1oYLgCNDPpbujd1LtJDEDqbhDYCc4Md9WUBIrB7ESGu15pLiUg5oUAhrvKd+9etQWy2WUZwEJAPUCbwey7zCHu04ug7LsMDExL7gIAh3d+c1Jd4JYAAAAASUVORK5CYII=");
background-repeat: no-repeat;
background-size: 16px;
padding-left:26px;
margin-right:30px;
}
.bind-user{
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABIAAAASBAMAAACk4JNkAAAAA3NCSVQICAjb4U/gAAAAMFBMVEX19fXr6+vg4ODW1tbMzMzCwsK4uLitra2jo6OZmZmPj4+FhYV6enpwcHBmZmb///+wFcT2AAAAEHRSTlP///////////////////8A4CNdGQAAAAlwSFlzAAAOnAAADpwBB5RT3QAAABZ0RVh0Q3JlYXRpb24gVGltZQAwOC8xNi8xOCL5ZhgAAAAcdEVYdFNvZnR3YXJlAEFkb2JlIEZpcmV3b3JrcyBDUzbovLKMAAAAh0lEQVQImWP4//+/2KxiIMnw//+X2+1rCsCsuP7/n26CWB+PA6X04oGsbweBrJ/rgawf64GsbxtQWBDZ+TAdNv5gUxL+s74EmfJpz6mOtWdAYnYTNFZP/vb0P8OHU///f/j/P0+f4duF/yDwaz4Ddz2Y9ekQg448mPV/G4M3hPG/g8ESygoHALeIhpF8DGw6AAAAAElFTkSuQmCC");
background-repeat: no-repeat;
background-size: 14px;
padding-left:24px;
margin-right:16px;
}
@@ -4428,35 +4456,48 @@ html .menu .menu_exit:hover {
padding-left:13px;
margin-right:20px;
}
.bt-724 {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAACEAAAAQCAMAAACvHOZVAAAAA3NCSVQICAjb4U/gAAAAOVBMVEXeQRTxrJnkZUD76OLqiWzzuKfgTSP53NT////30MXvoIriWTHmcU/99PHslHvofV71xLbjXznpgGGbp65eAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAFnRFWHRDcmVhdGlvbiBUaW1lADA3LzEwLzE5ht15uwAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAACrSURBVCiRrZBLAsMgCETJRxwUTdP7H7b4SUnW7SxU4gMnQ/QP5TSlrVqDyGufV4usbVNMJSv2cVw6UIHexdoUUdjOBVHXAPBs1e9TB9AGctqybf3G6OKEVcmd7R2PCOJEwuaAFoi5RGQnbMRln3iB3dmcksmJ2m0OINpPMeWCTcR8y/hsTzpQ9B4BRmbAQWd6dzbyPYKqVzJEZ1vqo9N9VAk9BPMnU4/Uf9cHAxAHhkB15V0AAAAASUVORK5CYII=");
background-repeat: no-repeat;
padding-left: 35px;
margin-right: 20px;
}
/*系统图标*/
.ico-linux{
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABEAAAATBAMAAACEi/vCAAAAA3NCSVQICAjb4U/gAAAAMFBMVEX///9mZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmambAcKAAAAEHRSTlMAESIzRFVmd4iZqrvM3e7/dpUBFQAAAAlwSFlzAAAOwwAADsMBx2+oZAAAABZ0RVh0Q3JlYXRpb24gVGltZQAwOC8xNi8xOCL5ZhgAAAAcdEVYdFNvZnR3YXJlAEFkb2JlIEZpcmV3b3JrcyBDUzbovLKMAAAAmUlEQVQImWNgYGCQ/GvAAAHz/1+CMBjPvvoOYTFVLXkNZZ2u+isAZjE/4vyvAGaxlgbnJ4BZHAoM3A/BLA8GBpafYNYiIL4PMpt1A5DYPwFIcDWArDkAJPgWAInzF4BE9jMGBvb/QM2SBfEGDFy7UhkY3Bk4CxisGdgCGMwYGI97vGKwSmAQC1G8e+aN2WagDuP0IEGbawIMAPDJKG706GgtAAAAAElFTkSuQmCC");
background-size: 12px;
background-repeat:no-repeat;
padding-left: 20px;
}
.ico-windows{
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQBAMAAADt3eJSAAAAA3NCSVQICAjb4U/gAAAALVBMVEX///+ZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZny8jBSAAAAD3RSTlMAESIzRFVmd4iZqrvM7v/Y8bBbAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAFnRFWHRDcmVhdGlvbiBUaW1lADA4LzE2LzE4IvlmGAAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAABGSURBVAiZY2AAAkbTqrMMDEJuHvfevXvHcPbdu+53IMY7Ihi7d+9O7QACBiB2BTOAol0wNbgY59696wQzGFQqw8GWwpwBAGURWs03JAEWAAAAAElFTkSuQmCC");
background-repeat:no-repeat;
background-size: 12px;
background-position: 0 2px;
padding-left: 20px;
}
.ico-centos{
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAPCAMAAADjyg5GAAAAA3NCSVQICAjb4U/gAAAASFBMVEX///9mZmZmZmZiYmJaWlpYWFhmZmZiYmJgYGBmZmZgYGBmZmZiYmJmZmZiYmJmZmZiYmJmZmZmZmZmZmZmZmZmZmZmZmZmZmbwNFvuAAAAGHRSTlMAESIiIiIzMzNERFVVZmZ3d4iZqrvM3f93YyfbAAAACXBIWXMAAA7DAAAOwwHHb6hkAAAAFnRFWHRDcmVhdGlvbiBUaW1lADA4LzE3LzE4mkUBfQAAABx0RVh0U29mdHdhcmUAQWRvYmUgRmlyZXdvcmtzIENTNui8sowAAAB6SURBVAiZVY5ZEsIwDEMdUpYQghIv9f1vWpNCp/hH1oz1LKI5if5G5ezuzLff7ibO7KK+H2LaBp1WDMLcYDNf3A31CXMvRCy995rSK0SExhjAkh/XEK5E2YOCN5r75RNGUJgtZJLXoMQjw/ot2LR3baJHSbN8Ll3LrhtQxAfrvVHLpQAAAABJRU5ErkJggg==");
background-size: 12px;
background-repeat:no-repeat;
padding-left: 20px;
}
.ico-ubuntu{
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAAAA3NCSVQICAjb4U/gAAAAOVBMVEX///9mZmZhYWFmZmZiYmJmZmZiYmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZVQ1Z+AAAAE3RSTlMAEREiIjMzRFVmd4iZqrvM3e7/67N/KAAAAAlwSFlzAAAOwwAADsMBx2+oZAAAABZ0RVh0Q3JlYXRpb24gVGltZQAwOC8xNy8xOJpFAX0AAAAcdEVYdFNvZnR3YXJlAEFkb2JlIEZpcmV3b3JrcyBDUzbovLKMAAAAbElEQVQImU2OWQ6AMAhEcW3Z2jL3P6xWjHE+CMPwCESfDOXtFmutAp6OtwC0jUwZVlWHaaaBniyYVq6B/Rn3G3aEjDxRuPwtN6NFzkB97IAlE3ddHTimPUKkd3TlhLb5huvLzAWWE2j0k0elCynoBUe/zXGJAAAAAElFTkSuQmCC");
background-size: 12px;
background-repeat:no-repeat;
padding-left: 20px;
}
.ico-debian{
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAQCAMAAAARSr4IAAAAA3NCSVQICAjb4U/gAAAAPFBMVEX///9paWlmZmZgYGBdXV1mZmZgYGBmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYdQ+x6AAAAFHRSTlMAERERESIiM0RVZneImaq7zN3u/ynguF0AAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAWdEVYdENyZWF0aW9uIFRpbWUAMDgvMTcvMTiaRQF9AAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAAHJJREFUCJlVjlESwjAIRLFFIRhCaO5/VyHijN2vt+zCABBq87IhT/hK1+zdfOl2Y71r2rPp1UKfAOdFgaTtAWIRWgacMUUquSi7TR6U2LflFuW0nOVjYB7JQBqwHklOe49f9dOAf+HvjRIZ3L3ePTIWfQAgiAODqr7Z+QAAAABJRU5ErkJggg==");
background-size: 12px;
background-repeat:no-repeat;
padding-left: 20px;
}
.ico-fedora{
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAMAAAAolt3jAAAAA3NCSVQICAjb4U/gAAAAPFBMVEX///9VVVVLS0tmZmZaWlpmZmZiYmJmZmZiYmJmZmZiYmJiYmJmZmZmZmZmZmZmZmZmZmZmZmZmZmZmZmYd2jWRAAAAFHRSTlMAEREiIjMzRERVVWaImaq7zN3u/2KENScAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAAWdEVYdENyZWF0aW9uIFRpbWUAMDgvMTcvMTiaRQF9AAAAHHRFWHRTb2Z0d2FyZQBBZG9iZSBGaXJld29ya3MgQ1M26LyyjAAAAGJJREFUCJlFj1kSwCAIQ9N9Lxjuf9faUKf5IPNQiAJAZ4yg9ZCWkMj5pxWwGCqK5skLg8AphMv2dIJC0106nNmu5VLA1bBmfqclF7fZO9HTYqzO4tMuOt5XGLA1enMzQ194ADH/CrSqGfFbAAAAAElFTkSuQmCC");
background-size: 12px;
background-repeat:no-repeat;
padding-left: 20px;
}
@@ -4916,11 +4957,11 @@ select[disabled]{
.search_box{
position: absolute;
right: 65px;
top: 12px;
top: 16px;
height: 16px;
}
.search_box input{
position: relative;
top: 2.5px;
vertical-align: sub;
}
.search_box label{
color: #666;
@@ -5070,10 +5111,11 @@ select[disabled]{
background: -webkit-linear-gradient(top,rgba(255, 255, 255, 0),rgba(220, 220, 220, .8));
}
.newTableShadow{
width: 100%;
height: 8px;
position: relative;
background: -webkit-linear-gradient(top,rgba(220, 220, 220, .8),rgba(255, 255, 255, 0));
/*display: none;*/
/*width: 100%;*/
/* height: 8px;*/
/* position: relative;*/
/* background: -webkit-linear-gradient(top,rgba(220, 220, 220, .8),rgba(255, 255, 255, 0));*/
}
.disable {
@@ -5422,10 +5464,9 @@ select[disabled]{
text-overflow: ellipsis;
line-height: 40px;
height: 40px;
margin: 0 10px 0 0;
margin: 0 15px 0 0;
}
.ace_conter_menu .item .icon_file {
color: #ff9800;
font-weight: 500;
margin-left: 10px;
}
+42 -22
View File
@@ -164,20 +164,18 @@ $('.open_two_verify_view').click(function(){
$('#panel_verification').prop('checked',res.status);
});
})()
function get_qrcode_data(callback){
$.post('/config?action=get_qrcode_data',function(res){
if(callback) callback(res);
});
}
function check_two_step(callback){
$.post('/config?action=check_two_step',function(res){
if(callback) callback(res);
});
}
function get_qrcode_data(callback){
$.post('/config?action=get_qrcode_data',function(res){
if(callback) callback(res);
});
}
function get_two_verify(callback){
$.post('/config?action=get_key',function(res){
if(callback) callback(res);
@@ -764,31 +762,53 @@ function GetPanelApi() {
})
});
}
function showPawApi(){
layer.msg('The panel API key only supports one-time display, please keep it safe. <br>To display the panel API key, click the reset button to regain the new API key.<br><span style="color:red;">Note: After the key is reset, the associated key product will be invalid. Please re-add the new key to the product.</span>',{icon:0,time:0,shadeClose:true,shade:0.1});
}
function SetPanelApi(t_type) {
function SetPanelApi(t_type,index) {
var pdata = {}
pdata['t_type'] = t_type
if (t_type == 3) {
pdata['limit_addr'] = $("textarea[name='api_limit_addr']").val()
}
var loadT = layer.msg(lan.config.is_submitting, { icon: 16, time: 0, shade: [0.3, '#000'] });
$.post('/config?action=set_token', pdata, function (rdata) {
if (t_type == 1) {
if (rdata.status) {
$("input[name='panel_token_value']").val(rdata.msg);
layer.msg(lan.config.create_int_key_success, { icon: 1, time: 0, shade: 0.3, shadeClose:true });
return;
}
}
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
if(t_type == 1){
var bdinding = layer.confirm('Are you sure you want to reset your current key?<br><span style="color:red;">After the key is reset, the associated key product will be invalid. Please re-add the new key to the product.</span>',{
btn:['Confirm','Cancel'],
icon:3,
closeBtn: 2,
title:'Reset key'
},function(){
var loadT = layer.msg(lan.config.is_submitting, { icon: 16, time: 0, shade: [0.3, '#000'] });
set_token_req(pdata,function(rdata){
if (rdata.status) {
$("input[name='panel_token_value']").val(rdata.msg);
layer.msg(lan.config.create_int_key_success, { icon: 1, time: 0, shade: 0.3, shadeClose:true,closeBtn:2});
}else{
layer.msg(rdata.msg, { icon: 2});
}
return false;
});
});
return false
}
set_token_req(pdata,function(rdata){
layer.msg(rdata.msg, { icon: rdata.status ? 1 : 2 });
if (rdata.msg == lan.config.open_successfully) {
GetPanelApi();
if(t_type == 2 && index != '0') GetPanelApi();
}
})
});
}
function set_token_req(pdata,callback){
$.post('/config?action=set_token', pdata, function (rdata) {
if(callback) callback(rdata);
});
}
function SetIPv6() {
var loadT = layer.msg(lan.config.setting_up, { icon: 16, time: 0, shade: [0.3, '#000'] });
$.post('/config?action=set_ipv6_status', {}, function (rdata) {
+1 -1
View File
@@ -819,7 +819,7 @@ function toBackup(type){
<span><input type="number" name="save" id="save" value="3" maxlength="4" max="100" min="1"></span>\
<span class="name">'+lan.crontab.save_num+'</span>\
</div>';
if (sType == 'sites') {
if (sType == 'sites' && sMsg !== lan.crontab.backup_log) {
sBody += '<p class="clearfix plan">\
<div class="textname pull-left mr20" style="margin-left: 63px; font-size: 14px;">'+lan.crontab.exclusion_rule+'</div>\
<div class="dropdown planBackupTo pull-left mr20">\
+4 -3
View File
@@ -2,6 +2,7 @@
var database = {
get_list: function (page, search) {
if (page == undefined) page = 1;
if (!search) search = $("#SearchValue").val();
bt.database.get_list(page, search, function (rdata) {
$('#databasePage').html(rdata.page);
var _tab = bt.render({
@@ -369,7 +370,7 @@ var database = {
},
input_database: function (name) {
var path = bt.get_cookie('backup_path') + "/database";
bt.files.get_files(path, '', function (rdata) {
bt.send('get_files', 'files/GetDir', 'reverse=True&sort=mtime&tojs=GetFiles&p=1&showRow=100&path=' + path, function (rdata) {
var data = [];
for (var i = 0; i < rdata.FILES.length; i++) {
if (rdata.FILES[i] == null) continue;
@@ -410,8 +411,8 @@ var database = {
}
},
{
field: 'opt', title: lan.database.operation, align: 'right', templet: function (item) {
return '<a class="btlink" herf="javascrpit:;" onclick="bt.database.input_sql(\'' + bt.rtrim(rdata.PATH, '/') + "/" + item.name + '\',\'' + name + '\')">'+lan.database.input+'</a> ';;
field: 'opt', title: 'Operating', align: 'right', templet: function (item) {
return '<a class="btlink" herf="javascrpit:;" onclick="bt.database.input_sql(\'' + bt.rtrim(rdata.PATH, '/') + "/" + item.name + '\',\'' + name + '\')">'+lan.database.input+'</a> | <a class="btlink" onclick="database.remove_input_file(\'' + bt.rtrim(rdata.PATH, '/') + "/" + item.name + '\',\'' + name + '\')">Del</a>';
}
},
],
+79 -77
View File
@@ -534,15 +534,15 @@ function GetFiles(Path,sort) {
</thead>\
<tbody id="filesBody" class="list-list">'+Body+'</tbody>\
</table></div><div class="oldTableShadow"></div>';
$("#fileCon").removeClass("fileList").html(tablehtml);
$("#tipTools").width($("#fileCon").width());
}
else{
$("#fileCon").addClass("fileList").html(Body);
$("#tipTools").width($("#fileCon").width());
}
$("#DirPathPlace input").val(rdata.PATH);
var BarTools = '<div class="btn-group">\
$("#fileCon").removeClass("fileList").html(tablehtml);
$("#tipTools").width($("#fileCon")[0].clientWidth - 20);
}
else {
$("#fileCon").addClass("fileList").html(Body);
$("#tipTools").width($("#fileCon")[0].clientWidth - 20);
}
$("#DirPathPlace input").val(rdata.PATH);
var BarTools = '<div class="btn-group">\
<button class="btn btn-default btn-sm dropdown-toggle" type="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">\
'+lan.files.new+' <span class="caret"></span>\
</button>\
@@ -600,9 +600,9 @@ function GetFiles(Path,sort) {
}
$("#Batch").html(BatchTools);
$("#setBox").prop("checked", false);
$("#BarTools").html(BarTools);
$("input[name=id]").click(function(){
if($(this).prop("checked")) {
$(this).prop("checked", true);
@@ -631,7 +631,7 @@ function GetFiles(Path,sort) {
if ($(this).prop("checked")) {
$("input[name=id]").prop("checked", true);
$("#filesBody > tr").addClass("ui-selected");
} else {
$("input[name=id]").prop("checked", false);
$("#filesBody > tr").removeClass("ui-selected");
@@ -690,13 +690,13 @@ function auto_table_width(){
});
if(oldTable_heigth > oldTable){
$('.oldTableShadow,.newTableShadow').show();
$('.oldTable').css('marginTop','-8px')
$('.oldTable').css('marginTop','0')
}else{
$('.oldTableShadow,.newTableShadow').hide();
$('.oldTable').css('marginTop','0')
}
$('.oldTable').height(oldTable);
$('.oldTable table').css({'marginTop':'-39px'})
$('.oldTable table').css({ 'marginTop': '-36px' })
}
@@ -757,22 +757,22 @@ function showSeclect(){
$("#Batch").html(BatchTools);
}
}
$("#tipTools").width($(".file-box").width());
$("#PathPlaceBtn").width($(".file-box").width()-700);
$("#DirPathPlace input").width($(".file-box").width()-700);
if($(window).width()<1160){
$("#PathPlaceBtn").width(290);
$("#tipTools").width($(".file-box")[0].clientWidth);
$("#PathPlaceBtn").width($(".file-box").width() - 700);
$("#DirPathPlace input").width($(".file-box").width() - 700);
if ($(window).width() < 1160) {
$("#PathPlaceBtn").width(290);
}
window.onresize = function(){
$("#tipTools").width($(".file-box").width()-30);
$("#PathPlaceBtn").width($(".file-box").width()-700);
$("#DirPathPlace input").width($(".file-box").width()-700);
if($(window).width()<1160){
$("#PathPlaceBtn,#DirPathPlace input").width(290);
}
PathLeft();
IsDiskWidth()
auto_table_width();
window.onresize = function () {
$("#tipTools").width($(".file-box")[0].clientWidth);
$("#PathPlaceBtn").width($(".file-box").width() - 700);
$("#DirPathPlace input").width($(".file-box").width() - 700);
if ($(window).width() < 1160) {
$("#PathPlaceBtn,#DirPathPlace input").width(290);
}
PathLeft();
IsDiskWidth()
auto_table_width();
}
function Batch(type,access){
var path = $("#DirPathPlace input").val();
@@ -781,9 +781,9 @@ function Batch(type,access){
var data='path='+path+'&type='+type;
var name = 'data';
var datas = []
var oldType = getCookie('BatchPaste');
for(var i=0;i<len;i++){
if (el[i].checked == true && el[i].value != 'on') {
datas.push(el[i].value)
@@ -791,27 +791,28 @@ function Batch(type,access){
}
data += "&data=" + encodeURIComponent(JSON.stringify(datas))
if(type == 3 && access == undefined){
SetChmod(0,lan.files.all);
return;
}
if(type < 3) setCookie('BatchSelected', '1');
setCookie('BatchPaste',type);
if(access == 1){
var access = $("#access").val();
var chown = $("#chown").val();
data += '&access='+access+'&user='+chown;
layer.closeAll();
}
if(type == 4){
AllDeleteFileSub(data,path);
setCookie('BatchPaste',oldType);
return;
}
if (access == 1) {
var access = $("#access").val();
var chown = $("#chown").val();
var all = $("#accept_all").prop("checked") ? 'True' : 'False';
data += '&access=' + access + '&user=' + chown + "&all=" + all;
layer.closeAll();
}
if (type == 4) {
AllDeleteFileSub(data, path);
setCookie('BatchPaste', oldType);
return;
}
if(type == 5){
var names = '';
for(var i=0;i<len;i++){
@@ -822,7 +823,7 @@ function Batch(type,access){
Zip(names);
return;
}
myloadT = layer.msg("<div class='myspeed'>"+lan.public.the+"</div>",{icon:16,time:0,shade: [0.3, '#000']});
setTimeout(function(){getSpeed('.myspeed');},1000);
$.post('/files?action=SetBatchData',data,function(rdata){
@@ -835,14 +836,14 @@ function BatchPaste(){
var path = $("#DirPathPlace input").val();
var type = getCookie('BatchPaste');
var data = 'type='+type+'&path='+path;
$.post('/files?action=CheckExistsFiles',{dfile:path},function(result){
if(result.length > 0){
var tbody = '';
for(var i=0;i<result.length;i++){
tbody += '<tr><td>'+result[i].filename+'</td><td>'+ToSize(result[i].size)+'</td><td>'+getLocalTime(result[i].mtime)+'</td></tr>';
}
var mbody = '<div class="divtable" style="height: 395px;overflow: auto;border: #ddd 1px solid;position: relative;"><table class="table table-hover" width="100%" border="0" cellpadding="0" cellspacing="0"><thead><th>'+lan.files.file_name+'</th><th>'+lan.files.file_size+'</th><th>'+lan.files.last_edit_time+'</th></thead>\
var mbody = '<div class="divtable" style="height: 395px;overflow: auto;margin-top: -8px;border: #ddd 1px solid;position: relative;"><table class="table table-hover" width="100%" border="0" cellpadding="0" cellspacing="0"><thead><th>'+lan.files.file_name+'</th><th>'+lan.files.file_size+'</th><th>'+lan.files.last_edit_time+'</th></thead>\
<tbody>'+tbody+'</tbody>\
</table></div>';
SafeMessage(lan.files.will_cover_this_file,mbody,function(){
@@ -854,7 +855,7 @@ function BatchPaste(){
}
});
}
function BatchPasteTo(data,path){
myloadT = layer.msg("<div class='myspeed'>"+lan.public.the+"</div>",{icon:16,time:0,shade: [0.3, '#000']});
setTimeout(function(){getSpeed('.myspeed');},1000);
@@ -866,7 +867,7 @@ function BatchPasteTo(data,path){
});
}
function GetExtName(fileName){
var extArr = fileName.split(".");
var extArr = fileName.split(".");
var exts = ['folder','folder-unempty','sql','c','cpp','cs','flv','css','js','htm','html','java','log','mht','php','url','xml','ai','bmp','cdr','gif','ico','jpeg','jpg','JPG','png','psd','webp','ape','avi','flv','mkv','mov','mp3','mp4','mpeg','mpg','rm','rmvb','swf','wav','webm','wma','wmv','rtf','docx','fdf','potm','pptx','txt','xlsb','xlsx','7z','cab','iso','bz2','rar','zip','gz','bt','file','apk','bookfolder','folder','folder-empty','folder-unempty','fromchromefolder','documentfolder','fromphonefolder','mix','musicfolder','picturefolder','videofolder','sefolder','access','mdb','accdb','sql','c','cpp','cs','js','fla','flv','htm','html','java','log','mht','php','url','xml','ai','bmp','cdr','gif','ico','jpeg','jpg','JPG','png','psd','webp','ape','avi','flv','mkv','mov','mp3','mp4','mpeg','mpg','rm','rmvb','swf','wav','webm','wma','wmv','doc','docm','dotx','dotm','dot','rtf','docx','pdf','fdf','ppt','pptm','pot','potm','pptx','txt','xls','csv','xlsm','xlsb','xlsx','7z','gz','cab','iso','rar','zip','bt','file','apk','css'];
var extLastName = extArr[extArr.length - 1];
for(var i=0; i<exts.length; i++){
@@ -940,7 +941,7 @@ function CreateFile(type, path) {
type: 1,
shift: 5,
closeBtn: 2,
area: '320px',
area: '320px',
title: lan.files.new_empty_file,
content: '<div class="bt-form pd20 pb70">\
<div class="line">\
@@ -1114,7 +1115,7 @@ function ExecShell(action){
else{
layer.msg(rdata.msg,{icon:rdata.status?1:2});
}
});
return;
}
@@ -1122,7 +1123,7 @@ function ExecShell(action){
type: 1,
shift: 5,
closeBtn: 2,
area: ['70%','600px'],
area: ['70%','600px'],
title: lan.files.shell_title,
content: '<div class="bt-form pd15">\
<div class="shellcode"><pre id="Result"></pre></div>\
@@ -1134,7 +1135,7 @@ function ExecShell(action){
setTimeout(function(){
outTimeGet();
},1000);
}
var outTime = null;
@@ -1171,7 +1172,7 @@ function ReName(type, fileName) {
type: 1,
shift: 5,
closeBtn: 2,
area: '320px',
area: '320px',
title: lan.files.file_menu_rename,
content: '<div class="bt-form pd20 pb70">\
<div class="line">\
@@ -1250,7 +1251,7 @@ function PasteTo(path,copyName,cutName,fileName){
setCookie('cutFileName', null);
return;
}
if (cutName != 'null' && cutName != undefined) {
layer.msg(lan.files.mv_the, {
icon: 16,
@@ -1298,13 +1299,13 @@ function Zip(dirName,submits) {
});
return
}
param = dirName;
if(dirName.indexOf(',') != -1){
tmp = path.split('/')
dirName = path + '/' + tmp[tmp.length-1]
}
var layers = layer.open({
type: 1,
shift: 5,
@@ -1336,7 +1337,7 @@ function Zip(dirName,submits) {
$("#dfile").val(dirName + '.' + z_type);
});
},100);
}
function UnZip(fileName,type) {
var path = $("#DirPathPlace input").val();
@@ -1354,7 +1355,7 @@ function UnZip(fileName,type) {
});
return
}
type = (type == 1) ? 'tar':'zip'
var umpass = '';
if(type == 'zip'){
@@ -1459,7 +1460,7 @@ function UploadFiles() {
type:1,
closeBtn: 2,
title:lan.files.up_title,
area: ['500px','500px'],
area: ['500px','500px'],
shadeClose:false,
content:'<div class="fileUploadDiv"><input type="hidden" id="input-val" value="'+path+'" />\
<input type="file" id="file_input" multiple="true" autocomplete="off" />\
@@ -1497,9 +1498,9 @@ function SetChmod(action,fileName){
});
return;
}
var toExec = fileName == lan.files.all?'Batch(3,1)':'SetChmod(1,\''+fileName+'\')';
$.post('/files?action=GetFileAccess','filename='+encodeURIComponent(fileName),function(rdata){
var layers = layer.open({
type:1,
@@ -1552,7 +1553,7 @@ function SetChmod(action,fileName){
$("#access").keyup(function(){
onAccess();
});
$("input[type=checkbox]").change(function(){
var idName = ['owner','group','public'];
var onacc = '';
@@ -1564,15 +1565,15 @@ function SetChmod(action,fileName){
onacc += access;
}
$("#access").val(onacc);
});
})
}
function onAccess(){
var access = $("#access").val();
var idName = ['owner','group','public'];
var idName = ['owner','group','public'];
for(var n=0;n<idName.length;n++){
$("#"+idName[n]+"_x").prop('checked',false);
$("#"+idName[n]+"_w").prop('checked',false);
@@ -1612,15 +1613,16 @@ function onAccess(){
}
}
}
function RClick(type, path, name, file_store){
var displayZip = isZip(type);
var options = {items:[
{text: lan.files.file_menu_copy, onclick: function() {CopyFile(path)}},
{text: lan.files.file_menu_mv, onclick: function() {CutFile(path)}},
{text: lan.files.file_menu_rename, onclick: function() {ReName(0,name)}},
{text: lan.files.file_menu_auth, onclick: function() {SetChmod(0,path)}},
{text: lan.files.file_menu_zip, onclick: function() {Zip(path)}}
function RClick(type, path, name, file_store) {
var displayZip = isZip(type);
var options = {
items: [
{ text: lan.files.file_menu_copy, onclick: function () { CopyFile(path) } },
{ text: lan.files.file_menu_mv, onclick: function () { CutFile(path) } },
{ text: lan.files.file_menu_rename, onclick: function () { ReName(0, name) } },
{ text: lan.files.file_menu_auth, onclick: function () { SetChmod(0, path) } },
{ text: lan.files.file_menu_zip, onclick: function () { Zip(path) } }
]
};
+14 -2
View File
@@ -145,7 +145,7 @@ var index = {
crs += 'CPU-' + i + ": " + d[2][i] + '%' + (n1 % 2 == 0?'</br>':' | ');
}
layer.tips(d[3] +"</br>"+ crs, _this.find('.cicle'), { time: 0, tips: [1, '#999'] });
layer.tips(d[3] + "</br>" + d[5] + " CPU, " + d[4] + " Core, " + d[4]+" Thread</br>"+ crs, _this.find('.cicle'), { time: 0, tips: [1, '#999'] });
}, function () {
layer.closeAll('tips');
});
@@ -230,7 +230,7 @@ var index = {
var load_arr = [{ title: lan.index.run_block, val: 100, color: '#dd2f00' }, { title: lan.index.run_slow, val: 90, color: '#ff9900' }, { title: lan.index.run_normal, val: 70, color: '#20a53a' }, { title: lan.index.run_fluent, val: 30, color: '#20a53a' }];
var _cpubox = $('.cpubox'), _membox = $('.membox'), _loadbox = $('.loadbox')
index.set_val(_cpubox, { usage: net.cpu[0], title: net.cpu[1] + ' ' + lan.index.cpu_core, items: pub_arr })
index.set_val(_cpubox, { usage: net.cpu[0], title: net.cpu[1]+' '+lan.index.cpu_core, items: pub_arr })
index.set_val(_membox, { usage: (net.mem.memRealUsed * 100 / net.mem.memTotal).toFixed(1), items: pub_arr, title: net.mem.memRealUsed + '/' + net.mem.memTotal + '(MB)' })
bt.set_cookie('memSize', net.mem.memTotal)
@@ -262,6 +262,11 @@ var index = {
$("#messageError").show();
$("#messageError").append('<p><span class="glyphicon glyphicon-alert" style="color: #ff4040; margin-right: 10px;"></span>' + lan.index.user_warning + '<span class="c7 mr5" title="'+lan.index.safe_problem_cant_ignore+'" style="cursor:no-drop"> ['+lan.index.cant_ignore+']</span><a class="btlink" href="javascript:setUserName();"> ['+lan.index.edit_now+']</a></p>')
}
if (info.isport === true) {
$("#messageError").show();
$("#messageError").append('<p><span class="glyphicon glyphicon-alert" style="color: #ff4040; margin-right: 10px;"></span>'+lan.index.panel_port_tips+'<span class="c7 mr5" title="'+lan.index.panel_port_tip1+'" style="cursor:no-drop"> ['+lan.index.panel_port_tip2+']</span><a class="btlink" href="/config"> ['+lan.index.panel_port_tip3+']</a></p>')
}
var _system = info.system;
$("#info").html(_system);
$("#running").html(info.time);
@@ -302,6 +307,11 @@ var index = {
arr.push({ title: lan.index.already_use, value: item.inodes[1] })
arr.push({ title: lan.index.available, value: item.inodes[2] })
arr.push({ title: lan.index.inode_percent, value: item.inodes[3] })
arr.push({ title: '<b>Capacity information</b>', value: '' })
arr.push({ title: 'Capacity', value: item.size[0] })
arr.push({ title: 'Used', value: item.size[1] })
arr.push({ title: 'Available', value: item.size[2] })
arr.push({ title: 'Usage rate', value: item.size[3] })
obj.masks = arr;
data.items.push(obj)
}
@@ -446,7 +456,9 @@ var index = {
})
},
check_update: function () {
var _load = bt.load('Getting updates, please wait...');
bt.system.check_update(function (rdata) {
_load.close();
if (rdata.status === false) {
if (!rdata.msg.beta) {
bt.msg(rdata);
+172 -222
View File
@@ -339,11 +339,11 @@ var aceEditor = {
break;
// 搜索
case 'searchs':
editor_item.ace.execCommand('find');
break;
// 替换
case 'replaces':
editor_item.ace.execCommand('replace');
break;
// 字体
case 'fontSize':
@@ -2574,254 +2574,204 @@ function scroll_handle(e){
var scrollTop = this.scrollTop;
$(this).find("thead").css({"transform":"translateY("+scrollTop+"px)","position":"relative","z-index":"1"});
}
var clipboard, interval, socket, gterm, ssh_login,term_box;
var clipboard, interval, socket, term, ssh_login,term_box;
var pdata_socket = {
x_http_token: document.getElementById("request_token_head").getAttribute('token')
}
function ssh_login_def() {
pdata_socket['data'] = {};
pdata_socket['data']['ssh_user'] = $("input[name='ssh_user']").val();
pdata_socket['data']['ssh_passwd'] = $("input[name='ssh_passwd']").val();
if (!pdata_socket.data.ssh_user || !pdata_socket.data.ssh_passwd) {
layer.msg('The SSH username and password cannot be empty!');
return;
}
layer.close(ssh_login);
socket.emit('webssh', pdata_socket);
gterm.focus();
}
function web_shell() {
var termCols = 100;
var termRows = 29;
var sendTotal = 0;
if(!socket)socket = io.connect();
var term = new Terminal({ cols: termCols, rows: termRows, screenKeys: true, useStyle: true});
term.open();
gterm = term
var termRows = 34;
if (!socket) connect_io()
term = new Terminal({ cols: termCols, rows: termRows, screenKeys: true, useStyle: true });
term.setOption('cursorBlink', true);
socket.on('server_response', function (data) {
if (data.data == "Failed to connect to SSH service!\r\n") {
if ($("input[name='ssh_user']").attr('autocomplete')) return;
var s_body = '<div class="bt-form bt-form pd20 pb70"><div class="line " style="display:none;">\
<span class="tname">id</span><div class="info-r "><input name="id" class="bt-input-text mr5" type="text" style="width:330px" value=""></div></div>\
<div class="line "><span class="tname">Username</span><div class="info-r "><input name="ssh_user" class="bt-input-text mr5" type="text" style="width:330px" value="" readonly="readonly" autocomplete="off"></div></div>\
<div class="line "><span class="tname">Password</span><div class="info-r "><input name="ssh_passwd" class="bt-input-text mr5" type="password" style="width:330px" value="" readonly="readonly" autocomplete="off"></div></div>\
<div class="bt-form-submit-btn"><button type="button" class="btn btn-sm btn-danger" onclick="layer.closeAll()">Close</button><button type="button" class="btn btn-sm btn-success ssh-login" onclick="ssh_login_def()">Login SSH</button></div></div>';
ssh_login = layer.open({
type: 1,
title: 'Please enter the SSH login account and password',
area: "500px",
closeBtn: 0,
shadeClose: false,
content: s_body
});
term_box = layer.open({
type: 1,
title: 'aaPanel terminal',
area: ['920px', '630px'],
closeBtn: 2,
shadeClose: false,
content: '<a class="btlink" onclick="show_ssh_login(1)" style="position: fixed;margin-left: 140px;margin-top: -30px;">[Set]</a><div class="term-box" style="background-color:#000"><div id="term"></div></div>',
cancel: function () {
term.destroy();
},
success: function () {
term.open(document.getElementById('term'));
}
});
setTimeout(function removeReadonly() {
$("input[name='ssh_user']").removeAttr('readonly');
$("input[name='ssh_passwd']").removeAttr('readonly');
$("input[name='ssh_user']").focus();
term.on('data', function (data) {
socket.emit('webssh', data);
});
$("input[name='ssh_passwd']").keydown(function (e) {
if (e.keyCode == 13) {
$('.ssh-login').click();
}
});
$(".shell_btn_close").click(function(){
layer.close(term_box);
term.destroy();
})
}, 500);
setTimeout(function () {
socket.emit('webssh', "\u0015");
socket.emit('webssh', "new_bt_terminal");
//socket.emit('webssh', "new_bt_terminal");
term.focus();
}, 100)
}
function connect_io() {
socket = io.connect();
socket.on('ssh_data', function (data) {
if (data === "\rServer connection failed!\r" || data === "\rWrong user name or password!\r") {
show_ssh_login(0);
return;
}
term.write(data.data);
term.write(data);
if (data.data == '\r\n'+lan.public.logout+'\r\n' || data.data == lan.public.logout+'\r\n' || data.data == '\r\nlogout\r\n' || data.data == 'logout\r\n') {
if (data == '\r\n登出\r\n' || data == '登出\r\n' || data == '\r\nlogout\r\n' || data == 'logout\r\n') {
setTimeout(function () {
layer.close(term_box);
}, 500);
}
});
}
if (socket) {
socket.emit('connect_event', '');
interval = setInterval(function () {
socket.emit('connect_event', '');
}, 1000);
}
term.on('data', function (data) {
pdata_socket['data'] = data;
socket.emit('webssh', pdata_socket);
});
term_box = layer.open({
function show_ssh_login(is_config) {
if ($("input[name='ssh_user']").attr('autocomplete')) return;
var s_body = '<div class="bt-form bt-form pd20 pb70">\
<style>.ssh_check_s1{ display: inline-block;\
height: 38px;\
background-color: #fff;\
color: #050505;\
white-space: nowrap;\
text-align: center;\
cursor: pointer;\
border-radius: 0;\
margin-left: 0px !important;\
position: relative;\
top: 2px;\
line-height: 34px;\
font-size: 13px;\
border-color: #e6e6e6;\
padding: 0 14px;\
border: 1px solid #e0dfdf;}\
.ssh_check_s2{margin-left: 0 !important;\
position: relative;\
top: 2px;\
border-color: #e6e6e6;\
display: inline - block;\
height: 38px;\
line-height: 38px;\
padding: 0 18px;\
background-color: #20a53a;\
color: #fff;\
white-space: nowrap;\
text-align: center;\
font-size: 14px;\
border: none;\
border-radius: 2px;\
cursor: pointer;} </style >\
<div class="line " style="margin-left: -40px;"><span class="tname">IP</span><div class="info-r "><input name="ssh_host" class="bt-input-text mr5" type="text" style="width:330px" value="127.0.0.1" autocomplete="off"></div></div>\
<div class="line " style="margin-left: -40px;"><span class="tname">Port</span><div class="info-r "><input name="ssh_port" class="bt-input-text mr5" type="text" style="width:330px" value="22" autocomplete="off"></div></div>\
<div class="line " style="margin-left: -40px;"><span class="tname">Username</span><div class="info-r "><input name="ssh_user" class="bt-input-text mr5" type="text" style="width:330px" value="root" readonly="readonly" autocomplete="off"></div></div>\
<div class="line " style="margin-left: -40px;"><span class="tname">Method</span><div class="info-r "><button class="ssh_check_s2" id="pass_check" onclick="pass_check()">Password</button><button id="rsa_check" class="ssh_check_s1" onclick="rsa_check()">Key</button></div></div>\
<div class="line ssh_passwd" style="margin-left: -40px;"><span class="tname">Password</span><div class="info-r "><input name="ssh_passwd" readonly="readonly" class="bt-input-text mr5" type="password" style="width:330px" value="" autocomplete="off"></div></div>\
<div class="line ssh_pkey" style="display:none;"><span class="tname">Key</span><div class="info-r "><textarea name="ssh_pkey" class="bt-input-text mr5" style="width:330px;height:80px;" ></textarea></div></div>\
<div class="line " style="margin-left: -40px;"><span class="tname"></span><div class="info-r "><input style="margin-top: 1px;width: 16px;" name="ssh_is_save" id="ssh_is_save" class="bt-input-text mr5" type="checkbox" ><label style="position: absolute;margin-left: 5px;" for="ssh_is_save">Remember password, the next time you use the aaPanel terminal will automatically log in</label></div></div>\
<p style="color: red;margin-top: 10px;text-align: center;margin-left: -62px;">Only support login to this server</p>\
<div class="bt-form-submit-btn"><button type="button" class="btn btn-sm btn-danger" onclick="'+ (is_config ? 'layer.close(ssh_login)' :'layer.closeAll()')+'">Close</button><button type="button" class="btn btn-sm btn-success ssh-login" onclick="send_ssh_info('+is_config+')">'+(is_config?'Confirm':'Login SSH')+'</button></div></div>';
ssh_login = layer.open({
type: 1,
title: lan.public.bt_terminal,
area: ['920px','640px'],
closeBtn: 2,
title: is_config?'Please fill in the SSH connection configuration':'Please enter the SSH login account and password',
area: "500px",
closeBtn: 0,
shadeClose: false,
content: '<div class="term-box"><div id="term"></div></div>\
<div class="shell-text-input">\
<textarea type="text" class="bt-input-text-shell" placeholder="'+lan.public.paste_comm_this+'" value="" name="ssh_copy" />\
<div class="shell-btn-group">\
<button class="shellbutton btn btn-success btn-sm pull-right shell_btn_1">'+lan.public.send+'(Ctrl+Enter)</button>\
<button class="shellbutton btn btn-default btn-sm pull-right shell_btn_close">'+lan.public.turnoff+'</button>\
</div>\
</div>',
cancel: function () {
term.destroy();
clearInterval(interval)
}
content: s_body
});
$(".shell_btn_close").click(function(){
layer.close(term_box);
term.destroy();
clearInterval(interval)
})
setTimeout(function () {
$('.terminal').detach().appendTo('#term');
$("#term").show();
pdata_socket['data'] = "\u0015"
socket.emit('webssh', pdata_socket);
pdata_socket['data'] = "\n"
socket.emit('webssh', pdata_socket);
setTimeout(function removeReadonly() {
$("input[name='ssh_user']").removeAttr('readonly');
$("input[name='ssh_passwd']").removeAttr('readonly');
$("input[name='ssh_passwd']").focus();
$("input[name='ssh_passwd']").keydown(function (e) {
if (e.keyCode == 13) {
$('.ssh-login').click();
}
});
}, 500);
}
function pass_check() {
$("#pass_check").attr("class", "ssh_check_s2");
$("#rsa_check").attr("class", "ssh_check_s1");
$(".ssh_pkey").hide();
$(".ssh_passwd").show();
}
function rsa_check() {
$("#pass_check").attr("class", "ssh_check_s1");
$("#rsa_check").attr("class", "ssh_check_s2");
$(".ssh_pkey").show();
$(".ssh_passwd").hide();
}
function send_ssh_info() {
pdata = {
host: $("input[name='ssh_host']").val(),
port: Number($("input[name='ssh_port']").val()),
password: $("input[name='ssh_passwd']").val(),
username: $("input[name='ssh_user']").val(),
pkey: $("textarea[name='ssh_pkey']").val()
}
if (pdata['host'] !== '127.0.0.1' && pdata['host'] !== 'localhost') {
layer.msg("Connection address can only be [ 127.0.0.1 or localhost ]");
$("input[name='ssh_host']").focus();
return;
}
if (pdata['port'] < 1 || pdata['port'] > 65535) {
layer.msg("Port range is incorrect [1-65535]");
$("input[name='ssh_port']").focus();
return;
}
if (!pdata['username']) {
layer.msg("Username can not be empty!");
$("input[name='ssh_user']").focus();
return;
}
if ($("#rsa_check").attr("class") === "ssh_check_s2") {
pdata['c_type'] = 'True'
if (!pdata['pkey']) {
layer.msg("Private key cannot be empty!");
$("input[name='ssh_pkey']").focus();
return;
}
} else {
if (!pdata['password']) {
layer.msg("Password can not be blank!");
$("input[name='ssh_passwd']").focus();
return;
}
}
if ($("#ssh_is_save").prop("checked")) {
pdata['is_save'] = '1';
}
var loadT = layer.msg('Trying to log in to SSH...', { icon: 16, time: 0, shade: 0.3 });
$.post("/term_open", { data: JSON.stringify(pdata) }, function () {
layer.close(loadT)
socket.emit('webssh', pdata);
layer.close(ssh_login)
term.focus();
// 鼠标右键事件
var can = $("#term");
can.contextmenu(function (e) {
var winWidth = can.width();
var winHeight = can.height();
var mouseX = e.pageX;
var mouseY = e.pageY;
var menuWidth = $(".contextmenu").width();
var menuHeight = $(".contextmenu").height();
var minEdgeMargin = 10;
if (mouseX + menuWidth + minEdgeMargin >= winWidth &&
mouseY + menuHeight + minEdgeMargin >= winHeight) {
menuLeft = mouseX - menuWidth - minEdgeMargin + "px";
menuTop = mouseY - menuHeight - minEdgeMargin + "px";
}
else if (mouseX + menuWidth + minEdgeMargin >= winWidth) {
menuLeft = mouseX - menuWidth - minEdgeMargin + "px";
menuTop = mouseY + minEdgeMargin + "px";
}
else if (mouseY + menuHeight + minEdgeMargin >= winHeight) {
menuLeft = mouseX + minEdgeMargin + "px";
menuTop = mouseY - menuHeight - minEdgeMargin + "px";
}
else {
menuLeft = mouseX + minEdgeMargin + "px";
menuTop = mouseY + minEdgeMargin + "px";
};
var selectText = term.getSelection()
var style_str = '';
var paste_str = '';
if (!selectText) {
if (!getCookie('shell_copy_body')) {
paste_str = 'style="color: #bbb;" disable';
}
style_str = 'style="color: #bbb;" disable';
} else {
setCookie('ssh_selection', selectText);
}
})
var menudiv = '<ul class="contextmenu">\
<li>\
<a class="shell_copy_btn menu_ssh" data-clipboard-text="'+ selectText + '" ' + style_str + '>'+lan.public.cp_to_shear_plate+'</a>\
</li>\
<li>\
<a onclick="shell_paste_text()" '+ paste_str+'>'+lan.public.paste_choose+'</a>\
</li>\
<li>\
<a onclick="shell_translate_text()" ' + style_str + '>'+lan.public.translate+'</a>\
</li>\
<li>\
<a onclick="shell_to_baidu()" ' + style_str + '>'+lan.public.search+'</a>\
</li>\
</ul>';
$("body").append(menudiv);
$(".contextmenu").css({
"left": menuLeft,
"top": menuTop
});
return false;
});
can.click(function () {
remove_ssh_menu();
});
clipboard = new ClipboardJS('.shell_copy_btn');
clipboard.on('success', function (e) {
layer.msg(lan.public.cp_success);
setCookie('shell_copy_body', e.text)
remove_ssh_menu();
term.focus();
});
clipboard.on('error', function (e) {
layer.msg(lan.public.cp_fail);
setCookie('shell_copy_body', e.text)
remove_ssh_menu();
term.focus();
});
$(".shellbutton").click(function () {
var tobj = $("textarea[name='ssh_copy']");
var ptext = tobj.val();
tobj.val('');
if ($(this).text().indexOf('Alt') != -1) {
ptext +="\n";
}
pdata_socket['data'] = ptext;
socket.emit('webssh', pdata_socket);
term.focus();
})
$("textarea[name='ssh_copy']").keydown(function (e) {
if (e.ctrlKey && e.keyCode == 13) {
$(".shell_btn_1").click();
} else if (e.altKey && e.keyCode == 13) {
$(".shell_btn_1").click();
}
});
}, 100)
}
function shell_translate_text() {
remove_ssh_menu();
var selectText = getCookie('ssh_selection');
var loadT = layer.msg(lan.public.translate_now, { icon: 16, time: 1000 * 60, });
$.get('https://www.bt.cn/api/index/fanyi', { query: selectText }, function (rdata) {
layer.close(loadT);
layer.msg(lan.public.original + rdata.src + '<br>'+ lan.public.translation + rdata.dst, { time: 1000 * 10, shadeClose: true, shade: 0.01 });
}, 'JSONP');
gterm.focus();
}
function shell_to_baidu() {
var selectText = getCookie('ssh_selection');
remove_ssh_menu();
window.open('https://www.baidu.com/s?wd=' + selectText)
gterm.focus();
}
function shell_paste_text() {
pdata_socket['data'] = getCookie('ssh_selection')
socket.emit('webssh', pdata_socket);
remove_ssh_menu();
gterm.focus();
}
function remove_ssh_menu() {
$(".contextmenu").remove();
}
+6 -3
View File
@@ -463,13 +463,15 @@ var bt =
//会话失效时自动跳转到登录页面
if (typeof (rdata) == 'string') {
if (rdata.indexOf('/static/favicon.ico') != -1 && rdata.indexOf('/static/img/qrCode.png') != -1) {
if ((rdata.indexOf('/static/favicon.ico') != -1 && rdata.indexOf('/static/img/qrCode.png') != -1) || rdata.indexOf('<!DOCTYPE html>') === 0) {
window.location.href = "/login"
return
}
}
if(callback) callback(rdata);
}).error(function () {
}).error(function (e, f) {
// console.log(e,f)
if(callback) callback('error');
});
}
@@ -3975,10 +3977,11 @@ bt.soft = {
</div>'
});
},
update_soft: function (name,title, version, min_version) {
update_soft: function (name,title, version, min_version,update_msg) {
var _this = this;
var msg = "<li>"+lan.public_backup.update_tips+"</li>";
if(name == 'mysql') msg = "<ul style='color:red;'><li>"+lan.public_backup.db_update_tips+"</li><li>"+lan.public_backup.update_tips1+"</li><li>"+lan.public_backup.update_tips+"</li></ul>";
if (update_msg) msg += '<div style=" margin-top: 10px;"><span style="font-size: 14px;font-weight: 900;">Update description: </span><hr style="margin-top: 5px; margin-bottom: 5px;" /><pre>' + update_msg.replace(/(_bt_)/g, "\n") +'</pre><hr style="margin-top: -5px; margin-bottom: -5px;" /></div>';
bt.show_confirm(lan.public_backup.update+'[' + title + ']', lan.public_backup.update_tips2.replace('{1}',title).replace('{2}',version).replace('{3}',min_version),function(){
var loadT = bt.load(lan.public_backup.update_tips3.replace('{1}',title).replace('{2}',version).replace('{3}',min_version));
bt.send('install_plugin', 'plugin/install_plugin', { sName: name, version: version, upgrade: version }, function (rdata) {
+12
View File
@@ -6,6 +6,7 @@ var site = {
if (type == '-1' || type == undefined) {
type = $('.site_type select').val();
}
if (!search) search = $("#SearchValue").val();
bt.site.get_list(page, search, type, function (rdata) {
$('.dataTables_paginate').html(rdata.page);
var data = rdata.data;
@@ -1581,6 +1582,12 @@ var site = {
var area_size = '500px';
var err_info = "";
if (!new_data.msg[1].challenges[1]) {
if (new_data.msg[1].challenges[0]) {
new_data.msg[1].challenges[1] = new_data.msg[1].challenges[0]
}
}
if (ldata.msg[1].status === 'invalid') {
area_size = '600px';
var trs = $("#dns_txt_jx tbody tr");
@@ -1617,6 +1624,11 @@ var site = {
site.reload();
bt.msg(ret);
} else {
if (!ret.msg[1].challenges[1]) {
if (ret.msg[1].challenges[0]) {
ret.msg[1].challenges[1] = ret.msg[1].challenges[0]
}
}
var area_size = '500px';
var err_info = "";
+9 -6
View File
@@ -1,9 +1,10 @@
var soft = {
is_install: false,
get_list: function (page, type, search) {
if (page == undefined) page = 0;
if (type == undefined) type = 0;
if (page == undefined || page == 'null' || page == 'undefined') page = 0;
if (type == undefined || type == 'null' || type == 'undefined') type = 0;
if (!search) search = $("#SearchValue").val();
if (search == undefined || search == 'null' || search == 'undefined' || search == '') search = undefined;
var _this = this;
var istype = getCookie('softType');
if (istype == 'undefined' || istype == 'null' || !istype) {
@@ -235,7 +236,8 @@ var soft = {
var min_version = item.versions[i]
var ret = bt.check_version(item.version, min_version.m_version + '.' + min_version.version);
if (ret > 0) {
if (ret == 2) option += '<a class="btlink" onclick="bt.soft.update_soft(\'' + item.name + '\',\'' + item.title + '\',\'' + min_version.m_version + '\',\'' + min_version.version + '\')" >' + lan.soft.update + '</a> | ';
if (!min_version.update_msg) min_version.update_msg = '';
if (ret == 2) option += '<a class="btlink" onclick="bt.soft.update_soft(\'' + item.name + '\',\'' + item.title + '\',\'' + min_version.m_version + '\',\'' + min_version.version + '\',\'' + min_version.update_msg.replace(/\n/g,"_bt_") + '\')" >' + lan.soft.update + '</a> | ';
break;
}
}
@@ -243,7 +245,8 @@ var soft = {
else {
var min_version = item.versions[0];
var cloud_version = min_version.m_version + '.' + min_version.version;
if (item.version != cloud_version) option += '<a class="btlink" onclick="bt.soft.update_soft(\'' + item.name + '\',\'' + item.title + '\',\'' + min_version.m_version + '\',\'' + min_version.version + '\')" >' + lan.soft.update + '</a> | ';
if (!min_version.update_msg) min_version.update_msg = '';
if (item.version != cloud_version) option += '<a class="btlink" onclick="bt.soft.update_soft(\'' + item.name + '\',\'' + item.title + '\',\'' + min_version.m_version + '\',\'' + min_version.version + '\',\'' + min_version.update_msg.replace(/\n/g, "_bt_") + '\')" >' + lan.soft.update + '</a> | ';
}
if (item.admin) {
option += '<a class="btlink" onclick="bt.soft.set_lib_config(\'' + item.name + '\',\'' + item.title + '\')">' + lan.soft.setup + '</a> | ';
@@ -288,7 +291,7 @@ var soft = {
bt.set_cookie('load_search', search)
if (soft.is_install) {
setTimeout(function () {
soft.get_list(page + 'not_load', type, search);
soft.get_list(bt.get_cookie('load_page') + 'not_load', bt.get_cookie('load_type'), bt.get_cookie('load_search'));
}, 3000);
}
})
@@ -170,7 +170,9 @@
"BASICAUTH":"BasicAuth",
"BASICAUTH_TIPS1":"Used for BasicAuth authentication configuration",
"CONFIG":"Set",
"BASICAUTH_TIPS2":"Add a BasicAuth-based authentication service to the panel to prevent the panel from being swept"
"BASICAUTH_TIPS2":"Add a BasicAuth-based authentication service to the panel to prevent the panel from being swept",
"S_PORT_TIPS":"Note: For servers with security groups, please release the new port in the security group in advance."
},
"close":{
+2 -2
View File
@@ -53,7 +53,7 @@
</div>
</div>
<div class="ss-text pull-left mr50">
<em title="基于Google Authenticator对用户进行登录认证"><a href="javascript:;" class="btlink open_two_verify_view">Google authentication</a></em>
<em title="User login authentication based on Google Authenticator"><a href="javascript:;" class="btlink open_two_verify_view">Google authentication</a></em>
<div class='ssh-item'>
<input class='btswitch btswitch-ios' id='panel_verification' type='checkbox'/>
<label class='btswitch-btn' for='panel_verification'></label>
@@ -79,7 +79,7 @@
<div class="mtb15">
<span class="set-tit text-right" title="{{data['lan']['CT2']}}">{{data['lan']['CT2']}}</span>
<input id="banport" name="port" class="inputtxt bt-input-text" type="number" value="{{data['panel']['port']}}" maxlength="5">
<span class="set-info c7">{{data['lan']['CY2']}}</span>
<span class="set-info c7">{{data['lan']['CY2']}}, <a style="color:red;">{{data['lan']['S_PORT_TIPS']}}</a></span>
</div>
<div class="mtb15">
<span class="set-tit text-right" title="{{data['lan']['panel_performance']}}">{{data['lan']['concurrent_thread']}}</span>
+1 -1
View File
@@ -56,7 +56,7 @@
{% if not data['isSetup'] %}
layer.msg('{{data["lan"]["JS1"]}}<a href="/soft#i" style="color:#20a53a;float: right;">{{data["lan"]["JS2"]}}</a>',{icon:7,shade: [0.3, '#000'],time:0});
$(".layui-layer-shade").css("margin-left", "200px");
$(".layui-layer-shade").css("margin-left", "180px");
{% else %}
database.get_list();
{% endif %}
+2 -2
View File
@@ -64,8 +64,8 @@
<span class="saveFile"><i class="glyphicon glyphicon-floppy-disk" aria-hidden="true"></i>Save</span>
<span class="saveFileAll"><i class="glyphicon glyphicon-duplicate" aria-hidden="true"></i>Save All</span>
<span class="refreshs"><i class="glyphicon glyphicon-refresh" aria-hidden="true"></i>Refresh</span>
<!-- <span class="searchs"><i class="fa fa-search" aria-hidden="true"></i>搜索</span>
<span class="replaces"><i class="fa fa-random" aria-hidden="true"></i>替换</span> -->
<span class="searchs"><i class="fa fa-search" aria-hidden="true"></i>Search</span>
<span class="replaces"><i class="fa fa-random" aria-hidden="true"></i>Replace</span>
<span class="fontSize"><i class="glyphicon glyphicon-text-width" aria-hidden="true"></i>Font</span>
<span class="themes"><i class="glyphicon glyphicon-magnet" aria-hidden="true"></i>Theme</span>
<span class="helps"><i class="glyphicon glyphicon-question-sign" aria-hidden="true"></i>Help</span>
+2 -1
View File
@@ -229,7 +229,8 @@
})
},
get_list:function(page,search){
if(page==undefined) page=1;
if (page == undefined) page = 1;
if (!search) search = $("#SearchValue").val();
bt.firewall.get_list(page, search, function (rdata) {
$('.firewallBody').html(rdata.page);
var ports_ps = {"80": lan.firewall.site_default_port, "3306": lan.firewall.mysql_default_port, "888": lan.firewall.phpmmyadmin_default_port, "22": lan.firewall.ssh_default_port, "20": lan.firewall.ftp1_default_port, "21": lan.firewall.ftp_default_port, "39000-40000": lan.firewall.ftp2_default_port, "30000-40000": lan.firewall.ftp2_default_port,"11211":lan.firewall.mem_default_port,"873":lan.firewall.rsync_default_port,"8888":lan.firewall.bt_default_port}
+3 -2
View File
@@ -42,7 +42,8 @@
var ftp = {
get_list:function(page,search){
if(page==undefined) page=1;
if (page == undefined) page = 1;
if (!search) search = $("#SearchValue").val();
bt.ftp.get_list(page,search,function(rdata){
$('.dataTables_paginate').html(rdata.page);
var _tab = bt.render({
@@ -165,7 +166,7 @@
bt.set_cookie('sites_path',"{{session['config']['sites_path']}}");
{% if not data['isSetup'] %}
layer.msg('{{data["lan"]["JS1"]}}<a href="/soft" style="color:#20a53a; float: right;">{{data["lan"]["JS2"]}}</a>',{icon:7,time:0,shade: [0.3, '#000']});
$(".layui-layer-shade").css("margin-left", "200px");
$(".layui-layer-shade").css("margin-left", "180px");
{% else %}
ftp.get_list();
{% endif %}
+4 -4
View File
@@ -22,7 +22,7 @@
<span style="margin-right:10px"><a class="btlink" href="javascript:index.re_server();">{{data['lan']['RESTART']}}</a></span>
</span>
</div>
<div class="container-fluid" style="padding-bottom: 66px;">
<div class="container-fluid" style="padding-bottom: 66px;padding-left: 0px;">
<div class="danger-tips">
<div class="important-title" id="messageError" style="display: none; margin-top:15px"></div>
</div>
@@ -76,7 +76,7 @@
</ul>
</div>
</div>
<div class="conter-box system-info bgw clearfix mtb15">
<div class="system-info bgw clearfix mtb15">
<div class="title c6 f16 plr15">
{{data['lan']['Overview']}}
</div>
@@ -99,7 +99,7 @@
</div>
<div class="col-xs-12 col-sm-12 col-md-6 pull-left pd0">
<div class="pr8">
<div class="bgw conter-box">
<div class="bgw">
<div class="title c6 f16 plr15">{{data['lan']['P4']}}</div>
<div class="setting-con" style="padding:0; height:442px; margin-right: -4px; overflow: hidden;">
<div class="container-fluid soft-man">
@@ -112,7 +112,7 @@
</div>
<div class="col-xs-12 col-sm-12 col-md-6 pull-left pd0">
<div class="pl7">
<div class="bgw conter-box" style="height:491px">
<div class="bgw" style="height:491px">
<div class="title c6 f16 plr15">{{data['lan']['FLOW']}}</div>
<div class="bw-info">
<div class="col-sm-6 col-md-3"><p class="c9"><span class="ico-up"></span>{{data['lan']['UPLOAD']}}</p><a id="upSpeed">{{data['lan']['S2']}}</a></div>
+16 -27
View File
@@ -8,7 +8,7 @@
<title>{{g.title}}</title>
<link rel="shortcut icon" href="/static/favicon.ico" type="image/x-icon" />
<link href="/static/bootstrap-3.3.5/css/bootstrap.min.css" rel="stylesheet">
<link href="/static/css/site.css?date={{g['version']}}" rel="stylesheet">
<link href="/static/css/site.css?f={{g['version']}}" rel="stylesheet">
<link href="/static/codemirror/lib/codemirror.css" rel="stylesheet">
<!--[if lte IE 9]>
<script src="/static/js/requestAnimationFrame.js"></script>
@@ -35,29 +35,18 @@
<div class="bt-warp bge6">
<div class="top-tips">{{session['top_tips']}}</div>
<a style="display:none;" id="request_token_head" token="{{session['request_token_head']}}"></a>
<div id="container" class="container-fluid {% if 'tmp_login' in session %}group-control{% endif %}">
<div class="sidebar-scroll{% if 'tmp_login' in session %}-panel{% endif %}">
<div id="container" class="container-fluid">
<div class="sidebar-scroll">
<div class="sidebar-auto">
<div id="task" class="task cw" onclick="messagebox()"></div>
<h3 class="mypcip"><span class="f14 cw">{{session['address']}}</span></h3>
<ul class="menu">
{% for menu in session['menus'] %}
{% if menu['class'] == 'menu_exit' %}
{% if not 'tmp_login' in session %}
{% if menu['href'] == g.uri %}
<li id="{{menu['id']}}" class="current"> <a class="{{menu['class']}}" href="{{menu['href']}}">{{menu['title']}}</a></li>
{% else %}
<li id="{{menu['id']}}"> <a class="{{menu['class']}}" href="{{menu['href']}}">{{menu['title']}}</a></li>
{% endif %}
{% endif %}
{% else %}
{% if menu['href'] == g.uri %}
<li id="{{menu['id']}}" class="current"> <a class="{{menu['class']}}" href="{{menu['href']}}">{{menu['title']}}</a></li>
{% else %}
<li id="{{menu['id']}}"> <a class="{{menu['class']}}" href="{{menu['href']}}">{{menu['title']}}</a></li>
{% endif %}
{% endif %}
{% if menu['href'] == g.uri %}
<li id="{{menu['id']}}" class="current"> <a class="{{menu['class']}}" href="{{menu['href']}}">{{menu['title']}}</a></li>
{% else %}
<li id="{{menu['id']}}"> <a class="{{menu['class']}}" href="{{menu['href']}}">{{menu['title']}}</a></li>
{% endif %}
{% endfor %}
</ul>
<div id="newbtpc"></div>
@@ -80,16 +69,16 @@
<script src="/static/codemirror/addon/scroll/annotatescrollbar.js"></script>
<script src="/static/js/jquery.qrcode.min.js"></script>
<script src="/static/js/socket.io.min.js"></script>
<link rel="stylesheet" href="/static/build/xterm.css" />
<link rel="stylesheet" href="/static/build/addons/fullscreen/fullscreen.css" />
<script src="/static/build/xterm.js"></script>
<script src="/static/build/addons/attach/attach.js"></script>
<script src="/static/build/addons/fit/fit.js"></script>
<script src="/static/build/addons/fullscreen/fullscreen.js"></script>
<script src="/static/build/addons/search/search.js"></script>
<link rel="stylesheet" href="/static/build/xterm.min.css" />
<link rel="stylesheet" href="/static/build/addons/fullscreen/fullscreen.min.css" />
<script src="/static/build/xterm.min.js"></script>
<script src="/static/build/addons/attach/attach.min.js"></script>
<script src="/static/build/addons/fit/fit.min.js"></script>
<script src="/static/build/addons/fullscreen/fullscreen.min.js"></script>
<script src="/static/build/addons/search/search.min.js"></script>
<script src="/static/build/addons/winptyCompat/winptyCompat.js"></script>
<script type="text/javascript" src="/static/js/clipboard.min.js"></script>
<script src="/static/js/public.js?version={{g['version']}}"></script>
<script src="/static/js/public.js?v3={{g['version']}}"></script>
<script src="/static/js/public_backup.js?version={{g['version']}}"></script>
<script src="/static/js/bt_upload.js?version={{g['version']}}"></script>
{% block content %}{% endblock %}
+2 -2
View File
@@ -15,7 +15,7 @@
<iframe name='hid' id="hid" style="display:none"></iframe>
</div>
</div>
<div class="conter-box bgw mtb15 pd15">
<div class="bgw mtb15 pd15">
<div class="info-title-tips">
<p><span class="glyphicon glyphicon-alert" style="color: #f39c12; margin-right: 10px;"></span> {{data['lan']['PS']}}</p>
</div>
@@ -48,7 +48,7 @@
{% block scripts %}
<script type="text/javascript" src="/static/laydate/laydate.js?date=20180301"></script>
<script type="text/javascript" src="/static/js/bootstrap-select.min.js"></script>
<script type="text/javascript" src="/static/js/site.js?version={{g['version']}}"></script>
<script type="text/javascript" src="/static/js/site.js?version_new={{g['version']}}"></script>
<script type="text/javascript">
bt.set_cookie('sites_path', "{{session['config']['sites_path']}}");
bt.set_cookie('serverType', "{{session['webserver']}}");
+1 -2
View File
@@ -33,8 +33,7 @@ class ajax:
time.sleep(0.5)
#取Nginx负载状态
self.CheckStatusConf()
result = public.HttpGet('http://127.0.0.1/nginx_status')
return result
result = public.ExecShell('/usr/local/curl/bin/curl -Ss http://127.0.0.1/nginx_status')[0]
tmp = result.split()
data = {}
if "request_time" in tmp:
+10 -3
View File
@@ -27,7 +27,7 @@ class panelSetup:
if ua:
ua = ua.lower();
if ua.find('spider') != -1 or ua.find('bot') != -1: return redirect('https://www.baidu.com');
g.version = '6.2.6'
g.version = '6.3.3'
g.title = public.GetConfigValue('title')
g.uri = request.path
session['version'] = g.version;
@@ -102,9 +102,13 @@ class panelAdmin(panelSetup):
api_check = True
if not 'login' in session:
api_check = self.get_sk()
if api_check: return api_check
if api_check:
session.clear()
return api_check
else:
if session['login'] == False: return redirect('/login')
if session['login'] == False:
session.clear()
return redirect('/login')
if api_check:
try:
sess_out_path = 'data/session_timeout.pl'
@@ -117,6 +121,7 @@ class panelAdmin(panelSetup):
os.remove(sess_input_path)
session['login'] = False;
cache.set('dologin',True)
session.clear()
return redirect('/login')
public.writeFile(sess_input_path,str(int(time.time())))
except:pass
@@ -126,8 +131,10 @@ class panelAdmin(panelSetup):
token = public.readFile(filename).strip()
if 'login_token' in session:
if session['login_token'] != token:
session.clear()
return redirect('/login?dologin=True')
except:
session.clear()
return redirect('/login')
#获取sk
+28 -7
View File
@@ -7,11 +7,15 @@
# | Author: 黄文良 <287962566@qq.com>
# +-------------------------------------------------------------------
import public,re,sys,os,nginx,apache,json,time,pyotp
import public,re,sys,os,nginx,apache,json,time
try:
import pyotp
except:
os.system("pip install pyotp &")
from BTPanel import session,admin_path_checks
from flask import request
class config:
_setup_path = "/www/server/panel"
_key_file = _setup_path+"/data/two_step_auth.txt"
_bk_key_file = _setup_path + "/data/bk_two_step_auth.txt"
@@ -423,7 +427,8 @@ class config:
#设置面板SSL
def SetPanelSSL(self,get):
if hasattr(get,"email"):
rep_mail = "^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$"
# rep_mail = "^[a-zA-Z0-9_-\.]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$"
rep_mail = "[\w!#$%&'*+/=?^_`{|}~-]+(?:\.[\w!#$%&'*+/=?^_`{|}~-]+)*@(?:[\w](?:[\w-]*[\w])?\.)+[\w](?:[\w-]*[\w])?"
if not re.search(rep_mail,get.email):
return public.returnMsg(False,'The E-Mail format is illegal')
import setPanelLets
@@ -433,7 +438,8 @@ class config:
else:
sslConf = '/www/server/panel/data/ssl.pl';
if os.path.exists(sslConf):
os.system('rm -f ' + sslConf);
# os.system('rm -f ' + sslConf);
os.remove(sslConf)
return public.returnMsg(True,'PANEL_SSL_CLOSE');
else:
os.system('pip install cffi');
@@ -742,7 +748,7 @@ class config:
# s = "find /tmp -mtime +1 |grep 'sess_'|wc -l"
# old_file_conf = int(public.ExecShell(s)[0].split("\n")[0])
old_file_conf = self.GetSessionCount(get)
old_file_conf = self.GetSessionCount(get)["oldfile"]
if old_file_conf == 0:
return public.returnMsg(True, 'DEL_SUCCESS')
else:
@@ -796,7 +802,11 @@ class config:
public.WriteFile(save_path,json.dumps(data))
public.ExecShell("chmod 600 " + save_path)
data = json.loads(public.ReadFile(save_path))
data['token'] = "***********************************"
if 'token_crypt' in data:
data['token'] = public.de_crypt(data['token'],data['token_crypt'])
else:
data['token'] = "***********************************"
data['limit_addr'] = '\n'.join(data['limit_addr'])
return data
@@ -807,6 +817,7 @@ class config:
if get.t_type == '1':
token = public.GetRandomString(32)
data['token'] = public.md5(token)
data['token_crypt'] = public.en_crypt(data['token'],token).decode('utf-8')
public.WriteLog('SET_API', 'REGENERATE_API_TOKEN')
elif get.t_type == '2':
data['open'] = not data['open']
@@ -819,6 +830,7 @@ class config:
token = public.GetMsg("SAVE_SUCCESS")
public.WriteFile(save_path, json.dumps(data))
os.chmod(save_path,0o600)
return public.returnMsg(True, token)
@@ -1119,4 +1131,13 @@ class config:
data = public.readFile(self._core_fle_path + '/qrcode.txt')
if data:
return data
return public.returnMsg(True, "No QR code data, please re-open")
return public.returnMsg(True, "No QR code data, please re-open")
# 设置是否云控打开
def set_coll_open(self,get):
if not 'coll_show' in get: return public.returnMsg(False,'Parameter error!')
if get.coll_show == 'True':
session['tmp_login'] = True
else:
session['tmp_login'] = False
return public.returnMsg(True,'Successful setup!')
+22 -10
View File
@@ -316,10 +316,7 @@ class crontab:
#从crond删除
def remove_for_crond(self,echo):
u_file = '/var/spool/cron/crontabs/root'
if not os.path.exists(u_file):
file='/var/spool/cron/root'
else:
file=u_file
file = self.get_cron_file()
conf=public.readFile(file)
rep = ".+" + str(echo) + ".+\n"
conf = re.sub(rep, "", conf)
@@ -405,11 +402,7 @@ echo "--------------------------------------------------------------------------
#将Shell脚本写到文件
def WriteShell(self,config):
u_file = '/var/spool/cron/crontabs/root'
if not os.path.exists(u_file):
file='/var/spool/cron/root'
else:
file=u_file
file = self.get_cron_file()
if not os.path.exists(file): public.writeFile(file,'')
conf = public.readFile(file)
if type(conf)==bool:return public.returnMsg(False,'Failed to read file!')
@@ -429,6 +422,25 @@ echo "--------------------------------------------------------------------------
os.system('chmod +x ' + execstr)
os.system('nohup ' + execstr + ' >> ' + execstr + '.log 2>&1 &');
return public.returnMsg(True,'CRONTAB_TASK_EXEC')
#获取计划任务文件位置
def get_cron_file(self):
u_path = '/var/spool/cron/crontabs'
u_file = u_path + '/root'
c_file = '/var/spool/cron/root'
cron_path = c_file
if not os.path.exists(u_path):
cron_path=c_file
if os.path.exists('/usr/bin/yum'):
cron_path = c_file
elif os.path.exists("/usr/bin/apt-get"):
cron_path = u_file
if cron_path == u_file:
if not os.path.exists(u_path):
os.makedirs(u_path,472)
public.ExecShell("chown root:crontab {}".format(u_path))
return cron_path
+1 -1
View File
@@ -149,7 +149,7 @@ class data:
where += " and type='" + get.type+"'";
if get.table == 'sites' and get.search:
pid = SQL.table('domain').where('name=?',(get.search,)).getField('pid');
pid = SQL.table('domain').where("name LIKE '%"+get.search+"%'",()).getField('pid');
if pid: where = "id=" + str(pid);
if get.table == 'sites' and hasattr(get,'type'):
+5 -4
View File
@@ -20,7 +20,7 @@ class database(datatool.datatools):
try:
data_name = get['name'].strip()
if self.CheckRecycleBin(data_name): return public.returnMsg(False,'DATABASE_DEL_RECYCLE_BIN',(data_name,))
if len(data_name) > 16: return public.returnMsg(False, 'DATABASE_NAME_LEN')
if len(data_name) > 64: return public.returnMsg(False, 'DATABASE_NAME_LEN')
reg = "^[\w\.-]+$"
if not re.match(reg, data_name): return public.returnMsg(False,'DATABASE_NAME_ERR_T')
if not hasattr(get,'db_user'): get.db_user = data_name;
@@ -30,7 +30,7 @@ class database(datatool.datatools):
if data_name in checks or len(data_name) < 1: return public.returnMsg(False,'DATABASE_NAME_ERR');
data_pwd = get['password']
if len(data_pwd)<1:
data_pwd = public.md5(time.time())[0:8]
data_pwd = public.md5(str(time.time()))[0:8]
sql = public.M('databases')
if sql.where("name=? or username=?",(data_name,username)).count(): return public.returnMsg(False,'DATABASE_NAME_EXISTS')
@@ -690,7 +690,8 @@ SetLink
os.system('/etc/init.d/mysqld restart');
else:
path = self.GetMySQLInfo(get)['datadir'];
if hasattr(get,'status'):
if not os.path.exists(path): return public.returnMsg(False,'数据库目录不存在!')
if hasattr(get,'status'):
dsize = 0;
for n in os.listdir(path):
if len(n) < 9: continue;
@@ -698,7 +699,7 @@ SetLink
dsize += os.path.getsize(path + '/' + n);
return public.returnMsg(True,dsize);
if os.path.exists(masterslaveconf):
return public.returnMsg(False, "MYSQL_TURNOFF_BIN_CHECK")
return public.returnMsg(False, "Database directory does not exist")
mycnf = mycnf.replace('log-bin=mysql-bin','#log-bin=mysql-bin')
mycnf = mycnf.replace('binlog_format=mixed','#binlog_format=mixed')
os.system('sync')
+32 -15
View File
@@ -7,7 +7,7 @@
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# +-------------------------------------------------------------------
import sys,os,public,time,json,pwd,cgi,shutil
import sys,os,public,time,json,pwd,cgi,shutil,re
from BTPanel import session,request
class files:
run_path = None
@@ -204,7 +204,8 @@ session.save_handler = files'''.format(path,sess_path,sess_path)
p_stat = os.stat(s_path)
os.chown(path,p_stat.st_uid,p_stat.st_gid)
if os.path.isfile(path):
os.chmod(path,0644)
public.writeFile("/tmp/2",str(sys.version_info[0]))
os.chmod(path, 0o644)
else:
os.chmod(path,p_stat.st_mode)
@@ -609,19 +610,27 @@ session.save_handler = files'''.format(path,sess_path,sess_path)
rPath = '/www/Recycle_bin/'
if sys.version_info[0] == 2: get.path = get.path.encode('utf-8');
dFile = get.path.split('_t_')[0];
filename = rPath + get.path
tfile = get.path.replace('_bt_','/').split('_t_')[0];
if not os.path.exists(filename): return public. returnMsg(True,'FILE_DEL_RECYCLE_BIN',(tfile,))
if dFile.find('BTDB_') != -1:
import database;
return database.database().DeleteTo(rPath+get.path);
if not self.CheckDir(rPath + get.path):
return database.database().DeleteTo(filename);
if not self.CheckDir(filename):
return public.returnMsg(False,'FILE_DANGER');
os.system('chattr -R -i ' + rPath + get.path)
if os.path.isdir(rPath + get.path):
os.system('chattr -R -i ' + filename)
if os.path.isdir(filename):
import shutil
shutil.rmtree(rPath + get.path);
try:
shutil.rmtree(filename);
except:
os.system("rm -rf " + filename)
else:
os.remove(rPath + get.path);
tfile = get.path.replace('_bt_','/').split('_t_')[0];
try:
os.remove(filename);
except:
os.system("rm -f " + filename)
public.WriteLog('TYPE_FILE','FILE_DEL_RECYCLE_BIN',(tfile,));
return public.returnMsg(True,'FILE_DEL_RECYCLE_BIN',(tfile,));
@@ -726,8 +735,8 @@ session.save_handler = files'''.format(path,sess_path,sess_path)
if not os.path.exists(get.sfile):
return public.returnMsg(False,'FILE_NOT_EXISTS')
#if os.path.exists(get.dfile):
# return public.returnMsg(False,'FILE_EXISTS')
if get.dfile == get.sfile:
return public.returnMsg(False,'Meaningless operation');
if not self.CheckDir(get.sfile):
return public.returnMsg(False,'FILE_DANGER');
@@ -775,7 +784,7 @@ session.save_handler = files'''.format(path,sess_path,sess_path)
return public.returnMsg(False,'FILE_NOT_EXISTS',(get.path,))
public.writeFile(get.path,'');
if os.path.getsize(get.path) > 2097152: return public.returnMsg(False,'CANT_EDIT_ONLINE_FILE');
if os.path.getsize(get.path) > 3145928: return public.returnMsg(False,'CANT_EDIT_ONLINE_FILE');
if not os.path.isfile(get.path): return public.returnMsg(False,'This is not a file!')
fp = open(get.path,'rb')
data = {}
@@ -1011,8 +1020,11 @@ session.save_handler = files'''.format(path,sess_path,sess_path)
if sys.version_info[0] == 2: key = key.encode('utf-8')
filename = get.path+'/'+key
if not self.CheckDir(filename): return public.returnMsg(False,'FILE_DANGER');
os.system('chmod -R '+get.access+" '"+filename+"'")
os.system('chown -R '+get.user+':'+get.user+" '"+filename+"'")
ret = ' -R '
if 'all' in get:
if get.all == 'False': ret = ''
os.system('chmod '+ret+get.access+" '"+filename+"'")
os.system('chown '+ret+get.user+':'+get.user+" '"+filename+"'")
except:
continue;
public.WriteLog('TYPE_FILE','FILE_ALL_ACCESS')
@@ -1109,6 +1121,9 @@ session.save_handler = files'''.format(path,sess_path,sess_path)
#移动和重命名
def move(self,sfile,dfile):
sfile = sfile.replace('//','/')
dfile = dfile.replace('//','/')
if sfile == dfile: return False
if not os.path.exists(sfile): return False
is_dir = os.path.isdir(sfile)
if not os.path.exists(dfile) or not is_dir:
@@ -1125,6 +1140,7 @@ session.save_handler = files'''.format(path,sess_path,sess_path)
#复制目录
def copytree(self,sfile,dfile):
if sfile == dfile: return False
if not os.path.exists(dfile): os.makedirs(dfile)
for f_name in os.listdir(sfile):
src_filename = (sfile + '/' + f_name).replace('//','/')
@@ -1238,6 +1254,7 @@ done
freshFile = '/tmp/panelFresh'
import db
find = db.Sql().table('tasks').where('status=? OR status=?',('-1','0')).field('id,type,name,execstr').find()
if(type(find) == str): return public.returnMsg(False,"Query error, "+find)
if not len(find): return public.returnMsg(False,'NO_TASK_AT_LINEUP',("-2",))
isTask = '/tmp/panelTask.pl'
public.writeFile(isTask,'True');
+24 -233
View File
@@ -6,18 +6,15 @@
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# +-------------------------------------------------------------------
import system,psutil,time,public,db,os,sys,json,py_compile,re
import time,public,db,os,sys,json,re
os.chdir('/www/server/panel')
sm = system.system();
taskConfig = json.loads(public.ReadFile('config/task.json'))
oldEdate = None
exec_tips = None
from BTPanel import cache
def control_init():
sql = db.Sql().dbfile('system')
csql = '''CREATE TABLE IF NOT EXISTS `load_average` (
if not sql.table('sqlite_master').where('type=? AND name=?', ('table', 'load_average')).count():
csql = '''CREATE TABLE IF NOT EXISTS `load_average` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`pro` REAL,
`one` REAL,
@@ -25,17 +22,21 @@ def control_init():
`fifteen` REAL,
`addtime` INTEGER
)'''
sql.execute(csql,())
public.M('sites').execute("alter TABLE sites add edate integer DEFAULT '0000-00-00'",());
public.M('sites').execute("alter TABLE sites add type_id integer DEFAULT 0",());
sql.execute(csql,())
if not public.M('sqlite_master').where('type=? AND name=? AND sql LIKE ?', ('table', 'sites','%type_id%')).count():
public.M('sites').execute("alter TABLE sites add edate integer DEFAULT '0000-00-00'",());
public.M('sites').execute("alter TABLE sites add type_id integer DEFAULT 0",());
sql = db.Sql()
csql = '''CREATE TABLE IF NOT EXISTS `site_types` (
if not sql.table('sqlite_master').where('type=? AND name=?', ('table', 'site_types')).count():
csql = '''CREATE TABLE IF NOT EXISTS `site_types` (
`id` INTEGER PRIMARY KEY AUTOINCREMENT,
`name` REAL,
`ps` REAL
)'''
sql.execute(csql,())
sql.execute(csql,())
filename = '/www/server/nginx/off'
if os.path.exists(filename): os.remove(filename)
c = public.to_string([99, 104, 97, 116, 116, 114, 32, 45, 105, 32, 47, 119, 119, 119, 47,
@@ -56,15 +57,9 @@ def control_init():
except:pass
public.writeFile('/var/bt_setupPath.conf','/www')
public.ExecShell(c)
p_file = 'class/plugin2.so'
if os.path.exists(p_file): public.ExecShell("rm -f class/*.so")
public.ExecShell("chmod -R 600 /www/server/panel/data")
public.ExecShell("chmod -R 600 /www/server/panel/config")
public.ExecShell("chmod -R 700 /www/server/cron")
public.ExecShell("chmod -R 600 /www/server/cron/*.log")
public.ExecShell("chown -R root:root /www/server/panel/data")
public.ExecShell("chown -R root:root /www/server/panel/config")
public.ExecShell("chmod -R 600 /www/server/panel/data;chmod -R 600 /www/server/panel/config;chmod -R 700 /www/server/cron;chmod -R 600 /www/server/cron/*.log;chown -R root:root /www/server/panel/data;chown -R root:root /www/server/panel/config")
#disable_putenv('putenv')
clean_session()
#set_crond()
@@ -80,6 +75,16 @@ def clean_hook_log():
if name[-4:] != ".log": continue;
clean_max_log(path+'/' + name,524288)
#清理PHP日志
def clean_php_log():
path = '/www/server/panel/php'
if not os.path.exists(path): return False
for name in os.listdir(path):
filename = path + '/var/log/php-fpm.log'
if os.path.exists(filename): clean_max_log(filename)
filename = path + '/var/log/slow.log'
if os.path.exists(filename): clean_max_log(filename)
#清理大日志
def clean_max_log(log_file,max_size = 104857600,old_line = 100):
if not os.path.exists(log_file): return False
@@ -173,217 +178,3 @@ def clean_session():
except:return False
#监控任务
def control_task():
global sm,taskConfig
if not taskConfig['control']['open']: return False
day = taskConfig['control']['day'];
if day < 1:
return False
sql = db.Sql().dbfile('system')
#取当前CPU Io
cpuUsed = sm.get_cpu_percent()
memUsed = get_mem_used()
#取当前网络Io
networkInfo = sm.GetNetWork(False)
#取磁盘Io
if os.path.exists('/proc/diskstats'):
diskInfo = sm.get_io_info()
addtime = int(time.time())
deltime = addtime - (day * 86400)
data = (cpuUsed,memUsed,addtime)
sql.table('cpuio').add('pro,mem,addtime',data)
sql.table('cpuio').where("addtime<?",(deltime,)).delete();
data = (networkInfo['up'],networkInfo['down'],networkInfo['upTotal'],networkInfo['downTotal'],networkInfo['downPackets'],networkInfo['upPackets'],addtime)
sql.table('network').add('up,down,total_up,total_down,down_packets,up_packets,addtime',data)
sql.table('network').where("addtime<?",(deltime,)).delete();
if os.path.exists('/proc/diskstats'):
data = (1,1,diskInfo['read'],diskInfo['write'],1,1,addtime)
#public.writeFile('/tmp/1.txt',str((time.time(),data)) + "\n",'a+')
sql.table('diskio').add('read_count,write_count,read_bytes,write_bytes,read_time,write_time,addtime',data)
sql.table('diskio').where("addtime<?",(deltime,)).delete();
#LoadAverage
load_average = sm.GetLoadAverage(None)
lpro = round((load_average['one'] / load_average['max']) * 100,2)
if lpro > 100: lpro = 100;
sql.table('load_average').add('pro,one,five,fifteen,addtime',(lpro,load_average['one'],load_average['five'],load_average['fifteen'],addtime))
#取内存使用率
def get_mem_used():
mem = psutil.virtual_memory()
memInfo = {'memTotal':mem.total/1024/1024,'memFree':mem.free/1024/1024,'memBuffers':mem.buffers/1024/1024,'memCached':mem.cached/1024/1024}
tmp = memInfo['memTotal'] - memInfo['memFree'] - memInfo['memBuffers'] - memInfo['memCached']
tmp1 = memInfo['memTotal'] / 100
return int(tmp / tmp1)
#软件安装任务
def install_task():
if cache.get('install_task'): return True
if cache.get('install_exists'): return True
sql = db.Sql()
sql.table('tasks').where("status=?",('-1',)).setField('status','0')
taskArr = sql.table('tasks').where("status=?",('0',)).field('id,type,execstr').order("id asc").select();
cache.set('install_exists',True)
cache.delete('install_task')
logPath = '/tmp/panelExec.log'
for value in taskArr:
start = int(time.time());
if not sql.table('tasks').where("id=?",(value['id'],)).count(): continue;
sql.table('tasks').where("id=?",(value['id'],)).save('status,start',('-1',start))
if value['type'] == 'download':
import downloadFile
argv = value['execstr'].split('|bt|')
downloadFile.downloadFile().DownloadFile(argv[0],argv[1])
elif value['type'] == 'execshell':
os.system(value['execstr'] + " > " + logPath + " 2>&1")
end = int(time.time())
sql.table('tasks').where("id=?",(value['id'],)).save('status,end',('1',end))
cache.delete('install_exists')
#网站到期处理
def site_end_task():
global oldEdate
if not oldEdate: oldEdate = public.readFile('data/edate.pl')
if not oldEdate: oldEdate = '0000-00-00'
mEdate = time.strftime('%Y-%m-%d',time.localtime())
if oldEdate == mEdate: return False
edateSites = public.M('sites').where('edate>? AND edate<? AND (status=? OR status=?)',('0000-00-00',mEdate,1,public.GetMsg("ALREADY_RUN"))).field('id,name').select()
import panelSite,common
siteObject = panelSite.panelSite()
for site in edateSites:
get = common.dict_obj()
get.id = site['id']
get.name = site['name']
siteObject.SiteStop(get)
oldEdate = mEdate
public.writeFile('data/edate.pl',mEdate)
#PHP守护
def php_safe_task():
if not os.path.exists('/www/server/panel/plugin/phpguard'): return True
phpversions = ['53','54','55','56','70','71','72','73','74']
for version in phpversions:
if not os.path.exists('/etc/init.d/php-fpm-'+version): continue;
if check_php_version(version): continue;
if start_php_version(version):
public.WriteLog('PHPDAEMON','PHP_CHECK_ERR_FIX_SUCCESS',(version,))
#处理指定PHP版本
def start_php_version(version):
fpm = '/etc/init.d/php-fpm-'+version
if not os.path.exists(fpm): return False;
#尝试重载服务
os.system(fpm + ' reload');
if check_php_version(version): return True;
#尝试重启服务
cgi = '/tmp/php-cgi-'+version
pid = '/www/server/php'+version+'/php-fpm.pid';
os.system('pkill -9 php-fpm-'+version)
time.sleep(0.5);
if not os.path.exists(cgi): os.remove(cgi)
if not os.path.exists(pid): os.remove(pid)
os.system(fpm + ' start');
if check_php_version(version): return True;
#检查是否正确启动
if os.path.exists(cgi): return True;
#检查指定PHP版本
def check_php_version(version):
url = 'http://127.0.0.1/phpfpm_'+version+'_status';
result = public.httpGet(url);
#检查nginx
if result.find('Bad Gateway') != -1: return False;
#检查Apache
if result.find('Service Unavailable') != -1: return False;
if result.find('Not Found') != -1: check_phpinfo();
#检查Web服务是否启动
if result.find('Connection refused') != -1:
global isTask
if os.path.exists(isTask):
isStatus = public.readFile(isTask);
if isStatus == 'True': return True;
filename = '/etc/init.d/nginx';
if os.path.exists(filename): os.system(filename + ' start');
filename = '/etc/init.d/httpd';
if os.path.exists(filename): os.system(filename + ' start');
return True;
#检测PHPINFO配置
def check_phpinfo():
php_versions = ['53','54','55','56','70','71','72','73','74'];
setupPath = '/www/server';
path = setupPath +'/panel/vhost/nginx/phpinfo.conf';
if not os.path.exists(path):
opt = "";
for version in php_versions:
opt += "\n\tlocation /"+version+" {\n\t\tinclude enable-php-"+version+".conf;\n\t}";
phpinfoBody = '''server
{
listen 80;
server_name 127.0.0.2;
allow 127.0.0.1;
index phpinfo.php index.html index.php;
root /www/server/phpinfo;
%s
}''' % (opt,);
public.writeFile(path,phpinfoBody);
path = setupPath + '/panel/vhost/apache/phpinfo.conf';
if not os.path.exists(path):
opt = "";
for version in php_versions:
opt += """\n<Location /%s>
SetHandler "proxy:unix:/tmp/php-cgi-%s.sock|fcgi://localhost"
</Location>""" % (version,version);
phpinfoBody = '''
<VirtualHost *:80>
DocumentRoot "/www/server/phpinfo"
ServerAdmin phpinfo
ServerName 127.0.0.2
%s
<Directory "/www/server/phpinfo">
SetOutputFilter DEFLATE
Options FollowSymLinks
AllowOverride All
Order allow,deny
Allow from all
DirectoryIndex index.php index.html index.htm default.php default.html default.htm
</Directory>
</VirtualHost>
''' % (opt,);
public.writeFile(path,phpinfoBody);
class JobsConfig:
JOBS = []
SCHEDULER_API_ENABLED = True
def __init__(self):
global taskConfig
self.JOBS = taskConfig['JOBS']
+1 -1
View File
@@ -27,7 +27,7 @@ class panelAuth:
if len(tmp) < 2: tmp = '{}'
data = json.loads(tmp);
if not data: return public.returnMsg(False,'LOGIN_FIRST');
if not hasattr(data,'serverid'):
if not 'serverid' in data:
s1 = self.get_mac_address() + self.get_hostname()
s2 = self.get_cpuname();
serverid = public.md5(s1) + public.md5(s2);
+6 -7
View File
@@ -51,28 +51,27 @@ import public
def extract_zone(domain_name):
domain_name = domain_name.lstrip("*.")
#处理地区域名
top_domain_list = ['.ac.cn', '.ah.cn', '.bj.cn', '.com.cn', '.cq.cn', '.fj.cn', '.gd.cn',
'.gov.cn', '.gs.cn', '.gx.cn', '.gz.cn', '.ha.cn', '.hb.cn', '.he.cn',
'.hi.cn', '.hk.cn', '.hl.cn', '.hn.cn', '.jl.cn', '.js.cn', '.jx.cn',
'.ln.cn', '.mo.cn', '.net.cn', '.nm.cn', '.nx.cn', '.org.cn']
old_domain_name = domain_name
m_count = domain_name.count(".")
top_domain = "."+".".join(domain_name.rsplit('.')[-2:])
new_top_domain = "." + top_domain.replace(".","")
is_tow_top = False
if top_domain in top_domain_list:
is_tow_top = True
domain_name = domain_name[:-len(top_domain)] + new_top_domain #地区域名后缀去点处理
domain_name = domain_name[:-len(top_domain)] + new_top_domain
if domain_name.count(".") > 1:
zone, middle, last = domain_name.rsplit(".", 2)
acme_txt = "_acme-challenge.%s" % zone
if is_tow_top: last = top_domain[1:] #还原地区域名后缀
if is_tow_top: last = top_domain[1:]
root = ".".join([middle, last])
else:
zone = ""
root = domain_name
root = old_domain_name
acme_txt = "_acme-challenge"
return root, zone, acme_txt
@@ -281,7 +280,7 @@ class Dns_com(object):
return dns_main.dns_main()
def create_dns_record(self, domain_name, domain_dns_value):
root, _, acme_txt = self.extract_zone(domain_name)
root, _, acme_txt = extract_zone(domain_name)
print("[DNS]Create a TXT record,", acme_txt, domain_dns_value)
result = self.get_dns_obj().add_txt(acme_txt + '.' + root,domain_dns_value)
if result == "False":
@@ -291,7 +290,7 @@ class Dns_com(object):
time.sleep(10)
def delete_dns_record(self, domain_name, domain_dns_value):
root, _, acme_txt = self.extract_zone(domain_name)
root, _, acme_txt = extract_zone(domain_name)
print("[DNS] ready to delete TXT records: ", acme_txt, domain_dns_value)
result = self.get_dns_obj().remove_txt(acme_txt + '.' + root)
print("[DNS] TXT record deleted successfully")
+12 -7
View File
@@ -59,31 +59,29 @@ class panelLets:
ret = p12.set_friendlyname(friendly_name.encode())
return p12
#域名处理
def extract_zone(self,domain_name):
domain_name = domain_name.lstrip("*.")
#处理地区域名
top_domain_list = ['.ac.cn', '.ah.cn', '.bj.cn', '.com.cn', '.cq.cn', '.fj.cn', '.gd.cn',
'.gov.cn', '.gs.cn', '.gx.cn', '.gz.cn', '.ha.cn', '.hb.cn', '.he.cn',
'.hi.cn', '.hk.cn', '.hl.cn', '.hn.cn', '.jl.cn', '.js.cn', '.jx.cn',
'.ln.cn', '.mo.cn', '.net.cn', '.nm.cn', '.nx.cn', '.org.cn']
old_domain_name = domain_name
m_count = domain_name.count(".")
top_domain = "."+".".join(domain_name.rsplit('.')[-2:])
new_top_domain = "." + top_domain.replace(".","")
is_tow_top = False
if top_domain in top_domain_list:
is_tow_top = True
domain_name = domain_name[:-len(top_domain)] + new_top_domain #地区域名后缀去点处理
domain_name = domain_name[:-len(top_domain)] + new_top_domain
if domain_name.count(".") > 1:
zone, middle, last = domain_name.rsplit(".", 2)
acme_txt = "_acme-challenge.%s" % zone
if is_tow_top: last = top_domain[1:] #还原地区域名
if is_tow_top: last = top_domain[1:]
root = ".".join([middle, last])
else:
zone = ""
root = domain_name
root = old_domain_name
acme_txt = "_acme-challenge"
return root, zone, acme_txt
@@ -137,6 +135,10 @@ class panelLets:
return "Connection timed out, CA server could not access your website!"
elif error.find("DNS problem: SERVFAIL looking up CAA for") != -1:
return "The domain name %s is currently required to verify the CAA record. Please manually resolve the CAA record, or try again after 1 hour.!" % re.findall("looking up CAA for (.+)", error)
elif error.find("Read timed out.") != -1:
return "Verification timeout, please check whether the domain name is correctly resolved. If dns is resolved, the connection between the server and Let'sEncrypt may be abnormal. Please try again later!"
elif error.find("Error creating new order") != -1:
return "Order creation failed, please try again later!"
else:
return error;
@@ -272,7 +274,10 @@ class panelLets:
cpath = self.setupPath + '/panel/vhost/cert/crontab.json'
config = {}
if os.path.exists(cpath):
config = json.loads(public.readFile(cpath))
try:
config = json.loads(public.readFile(cpath))
except:pass
config[data['siteName']] = data
public.writeFile(cpath,json.dumps(config))
public.set_mode(cpath,600)
+37 -23
View File
@@ -158,6 +158,7 @@ class panelPlugin:
if 'download' in pluginInfo['versions'][0]:
tmp_path = '/www/server/panel/temp'
if not os.path.exists(tmp_path): os.makedirs(tmp_path,mode=384);
public.ExecShell("rm -rf " + tmp_path + '/*')
toFile = tmp_path + '/' + pluginInfo['name'] + '.zip'
public.downloadFile('http://www.bt.cn/api/Pluginother/get_file?fname=' + pluginInfo['versions'][0]['download'],toFile)
if public.FileMd5(toFile) != pluginInfo['versions'][0]['md5']: return public.returnMsg(False,'CHECK_FILE_HASH')
@@ -276,14 +277,21 @@ class panelPlugin:
public.writeFile("/tmp/" + cache.get('p_token'),str(softList['pro']))
except:pass
sType = 0
if hasattr(get,'type'): sType = int(get['type'])
try:
if hasattr(get,'type'): sType = int(get['type'])
if hasattr(get,'query'):
if get.query: sType = 0
except:pass
softList['list'] = self.get_local_plugin(softList['list'])
softList['list'] = self.get_types(softList['list'],sType)
if hasattr(get,'query'):
if get.query:
tmpList = []
for softInfo in softList['list']:
if softInfo['name'].find(get.query) != -1 or softInfo['title'].find(get.query) != -1: tmpList.append(softInfo)
if softInfo['name'].lower().find(get.query) != -1 or \
softInfo['title'].lower().find(get.query) != -1 or \
softInfo['ps'].lower().find(get.query) != -1:
tmpList.append(softInfo)
softList['list'] = tmpList
return softList
@@ -356,7 +364,7 @@ class panelPlugin:
m_version = info['versions'].split(".")
if len(m_version) < 2: return None
if len(m_version) > 2:
tmp = m_version.copy()
tmp = m_version[:]
del(tmp[0])
m_version[1] = '.'.join(tmp)
@@ -686,10 +694,11 @@ class panelPlugin:
if sInfo['name'] == 'mysql':
vFile3 = sInfo['uninsatll_checks'] + '/version.pl'
if os.path.exists(vFile3):
version_str = None
if os.path.exists(vFile3):
version_str = public.readFile(vFile3)
if version_str.find('AliSQL') != -1: version = 'AliSQL'
if version == 'Linux':
if version == 'Linux' and version_str:
version = version_str
public.writeFile(vFile1,version)
@@ -729,25 +738,27 @@ class panelPlugin:
def process_exists(self,pname,exe = None):
if not self.pids: self.pids = psutil.pids() #self.get_pids() #
for pid in self.pids:
l = '/proc/%s/exe' % pid
f = '/proc/%s/comm' % pid
p_exe = ''
p_name = ''
if os.path.exists(l):
p_exe = os.readlink(l)
if not p_name: p_name = p_exe.split('/')[-1]
try:
l = '/proc/%s/exe' % pid
f = '/proc/%s/comm' % pid
p_exe = ''
p_name = ''
if os.path.exists(l):
p_exe = os.readlink(l)
if not p_name: p_name = p_exe.split('/')[-1]
if not p_name and os.path.exists(f):
fp = open(f,'r')
p_name = fp.read().strip()
fp.close()
if not p_name and os.path.exists(f):
fp = open(f,'r')
p_name = fp.read().strip()
fp.close()
if not p_name: continue
if p_name == pname:
if not exe:
return True;
else:
if p_exe == exe: return True
if not p_name: continue
if p_name == pname:
if not exe:
return True;
else:
if p_exe == exe: return True
except: continue
return False
#取分页
@@ -761,7 +772,10 @@ class panelPlugin:
info['row'] = self.ROWS;
info['p'] = 1
if hasattr(get,'p'):
info['p'] = int(get['p'])
try:
info['p'] = int(get['p'])
except:
info['p'] = 1
info['uri'] = {}
info['return_js'] = ''
if hasattr(get,'tojs'):
+37 -26
View File
@@ -367,7 +367,7 @@ class panelSite(panelRedirect):
data['databaseStatus'] = False
if get.sql == 'true' or get.sql == 'MySQL':
import database
if len(get.datauser) > 16: get.datauser = get.datauser[:16]
if len(get.datauser) > 64: get.datauser = get.datauser[:64]
get.name = get.datauser
get.db_user = get.datauser
get.password = get.datapassword
@@ -916,7 +916,12 @@ class panelSite(panelRedirect):
return public.returnMsg(False, 'Please go to the software store to install [Cloud Resolution] and complete the domain name NS binding.');
self.check_ssl_pack()
import panelLets
try:
import panelLets
except Exception as ex:
if str(ex).find('No module named requests') != -1:
os.system("pip install requests &")
return public.returnMsg(False,'Missing requests component, please try to repair the panel!')
public.mod_reload(panelLets)
lets = panelLets.panelLets()
result = lets.apple_lest_cert(get)
@@ -1606,6 +1611,7 @@ class panelSite(panelRedirect):
#nginx
filename = self.setupPath + '/panel/vhost/nginx/' + siteName + '.conf';
mconf = public.readFile(filename);
if mconf == False: return public.returnMsg(False,'The specified configuration file does not exist!')
if mconf:
if(srcDomain == 'all'):
conf301 = "\t#301-START\n\t\treturn 301 "+toDomain+"$request_uri;\n\t#301-END";
@@ -1623,7 +1629,8 @@ class panelSite(panelRedirect):
#apache
filename = self.setupPath + '/panel/vhost/apache/' + siteName + '.conf';
mconf = public.readFile(filename);
if type == '1':
if mconf == False: return public.returnMsg(False,'The specified configuration file does not exist!')
if type == '1':
if(srcDomain == 'all'):
conf301 = "\n\t#301-START\n\t<IfModule mod_rewrite.c>\n\t\tRewriteEngine on\n\t\tRewriteRule ^(.*)$ "+toDomain+"$1 [L,R=301]\n\t</IfModule>\n\t#301-END\n";
else:
@@ -1890,6 +1897,7 @@ server
Name = public.M('sites').where("id=?",(id,)).getField('name');
file = self.setupPath + '/panel/vhost/'+public.get_webserver()+'/' + Name + '.conf';
conf = public.readFile(file)
if conf == False: return public.returnMsg(False,'The specified website profile does not exist!')
if public.get_webserver() == 'nginx':
rep = "\s+index\s+(.+);";
else:
@@ -2025,28 +2033,30 @@ server
def SetPHPVersion(self,get):
siteName = get.siteName
version = get.version
#nginx
file = self.setupPath + '/panel/vhost/nginx/'+siteName+'.conf';
conf = public.readFile(file);
if conf:
rep = "enable-php-([0-9]{2,3})\.conf";
tmp = re.search(rep,conf).group()
conf = conf.replace(tmp,'enable-php-'+version+'.conf');
public.writeFile(file,conf)
#apache
file = self.setupPath + '/panel/vhost/apache/'+siteName+'.conf';
conf = public.readFile(file);
if conf:
rep = "php-cgi-([0-9]{2,3})\.sock";
tmp = re.search(rep,conf).group()
conf = conf.replace(tmp,'php-cgi-'+version+'.sock');
public.writeFile(file,conf)
public.serviceReload();
public.WriteLog("TYPE_SITE", "SITE_PHPVERSION_SUCCESS",(siteName,version));
return public.returnMsg(True,'SITE_PHPVERSION_SUCCESS',(siteName,version));
try:
#nginx
file = self.setupPath + '/panel/vhost/nginx/'+siteName+'.conf';
conf = public.readFile(file);
if conf:
rep = "enable-php-([0-9]{2,3})\.conf";
tmp = re.search(rep,conf).group()
conf = conf.replace(tmp,'enable-php-'+version+'.conf');
public.writeFile(file,conf)
#apache
file = self.setupPath + '/panel/vhost/apache/'+siteName+'.conf';
conf = public.readFile(file);
if conf:
rep = "php-cgi-([0-9]{2,3})\.sock";
tmp = re.search(rep,conf).group()
conf = conf.replace(tmp,'php-cgi-'+version+'.sock');
public.writeFile(file,conf)
public.serviceReload();
public.WriteLog("TYPE_SITE", "SITE_PHPVERSION_SUCCESS",(siteName,version));
return public.returnMsg(True,'SITE_PHPVERSION_SUCCESS',(siteName,version));
except:
return public.returnMsg(False, 'The setup failed, no enable-php-xx related configuration items were found in the website configuration file!')
#是否开启目录防御
@@ -2521,7 +2531,7 @@ server
proxyUrl[i]["type"] = int(get.type)
self.__write_config(self.__proxyfile, proxyUrl)
public.serviceReload()
return public.returnMsg(True, '修改成功')
return public.returnMsg(True, 'Successfully modified')
else:
if os.path.exists(ap_conf_file+"_bak"):
os.system("mv %s_bak %s" % (ap_conf_file, ap_conf_file))
@@ -3416,6 +3426,7 @@ location %s
file = '/www/server/panel/vhost/nginx/' + get.name + '.conf';
conf = public.readFile(file);
data = {}
if type(conf)==bool:return public.returnMsg(False,'Failed to read configuration file!')
if conf.find('SECURITY-START') != -1:
rep = "#SECURITY-START(\n|.){1,500}#SECURITY-END";
tmp = re.search(rep,conf).group()
+1 -1
View File
@@ -287,7 +287,7 @@ class plugin_deployment:
self.WriteLogs(json.dumps({'name':'Install the necessary PHP extensions','total':0,'used':0,'pre':0,'speed':0}));
import files
mfile = files.files();
if type(pinfo['php_ext']) == str : pinfo['php_ext'] = pinfo['php_ext'].strip().split(',')
if type(pinfo['php_ext']) != list : pinfo['php_ext'] = pinfo['php_ext'].strip().split(',')
for ext in pinfo['php_ext']:
if ext == 'pathinfo':
import config
+82 -6
View File
@@ -11,7 +11,7 @@
# 宝塔公共库
# --------------------------------
import json, os, sys, time, re, socket
import json,os,sys,time,re,socket,importlib,binascii,base64
if sys.version_info[0] == 2:
reload(sys)
@@ -902,7 +902,7 @@ def CheckMyCnf():
confFile = '/etc/my.cnf'
if os.path.exists(confFile):
conf = readFile(confFile)
if len(conf) > 100: return True;
if conf.find('[mysqld]') != -1: return True;
versionFile = '/www/server/mysql/version.pl';
if not os.path.exists(versionFile): return False;
@@ -921,7 +921,7 @@ export PATH
CN='125.88.182.172'
HK='download.bt.cn'
HK2='103.224.251.67'
US='174.139.221.74'
US='128.1.164.196'
sleep 0.5;
CN_PING=`ping -c 1 -w 1 $CN|grep time=|awk '{print $7}'|sed "s/time=//"`
HK_PING=`ping -c 1 -w 1 $HK|grep time=|awk '{print $7}'|sed "s/time=//"`
@@ -1336,7 +1336,7 @@ def mod_reload(mode):
reload(mode)
else:
import imp
imp.reload(module)
imp.reload(mode)
return True
except:
return False
@@ -1444,13 +1444,13 @@ def en_crypt(key,strings):
#解密字符串
def de_crypt(key,strings):
try:
if type(strings) != bytes: strings = strings.encode('utf-8')
if type(strings) != bytes: strings = strings.decode('utf-8')
from cryptography.fernet import Fernet
f = Fernet(key)
result = f.decrypt(strings).decode('utf-8')
return result
except:
print(get_error_info())
#print(get_error_info())
return strings
@@ -1529,6 +1529,82 @@ def check_port_stat(port):
if temp['local']: result +=2;
return result;
#同步时间
def sync_date():
tip_file = "/dev/shm/last_sync_time.pl"
s_time = int(time.time())
try:
if os.path.exists(tip_file):
if s_time - int(readFile(tip_file)) < 60: return False
os.remove(tip_file)
time_str = HttpGet('http://www.bt.cn/api/index/get_time')
new_time = int(time_str)
time_arr = time.localtime(new_time)
date_str = time.strftime("%Y-%m-%d %H:%M:%S", time_arr)
os.system('date -s "%s"' % date_str)
writeFile(tip_file,str(s_time))
return True
except:
if os.path.exists(tip_file): os.remove(tip_file)
return False
#重载模块
def reload_mod(mod_name = None):
#是否重载指定模块
modules = []
if mod_name:
if type(mod_name) == str:
mod_names = mod_name.split(',')
for mod_name in mod_names:
if mod_name in sys.modules:
print(mod_name)
try:
if sys.version_info[0] == 2:
reload(sys.modules[mod_name])
else:
importlib.reload(sys.modules[mod_name])
modules.append([mod_name,True])
except:
modules.append([mod_name,False])
else:
modules.append([mod_name,False])
return modules
#重载所有模块
for mod_name in sys.modules.keys():
if mod_name in ['BTPanel']: continue
f = getattr(sys.modules[mod_name],'__file__',None)
if f:
try:
if f.find('panel/') == -1: continue
if sys.version_info[0] == 2:
reload(sys.modules[mod_name])
else:
importlib.reload(sys.modules[mod_name])
modules.append([mod_name,True])
except:
modules.append([mod_name,False])
return modules
def de_hexb(data):
if sys.version_info[0] != 2:
if type(data) == str: data = data.encode('utf-8')
pdata = base64.b64encode(data);
if sys.version_info[0] != 2:
if type(pdata) == str: pdata = pdata.encode('utf-8')
return binascii.hexlify(pdata);
def en_hexb(data):
if sys.version_info[0] != 2:
if type(data) == str: data = data.encode('utf-8')
result = base64.b64decode(binascii.unhexlify(data));
if type(result) != str: result = result.decode('utf-8')
return result;
#取通用对象
class dict_obj:
def __contains__(self, key):
+22 -1
View File
@@ -116,6 +116,22 @@ class SiteDirAuth:
if name in i.values() or site_dir == i["site_dir"]:
return True
# 获取当前站点php版本
def get_site_php_version(self,siteName):
try:
conf = public.readFile(self.setup_path + '/panel/vhost/'+public.get_webserver()+'/'+siteName+'.conf');
if public.get_webserver() == 'nginx':
rep = "enable-php-([0-9]{2,3})\.conf"
else:
rep = "php-cgi-([0-9]{2,3})\.sock"
tmp = re.search(rep,conf).groups()
if tmp:
return tmp[0]
else:
return ""
except:
return public.returnMsg(False, 'SITE_PHPVERSION_ERR_A22')
# 获取站点名
def get_site_info(self,id):
site_info = public.M('sites').where('id=?', (id,)).field('name,path').find()
@@ -123,6 +139,10 @@ class SiteDirAuth:
# 设置独立认证文件
def set_dir_auth_file(self,site_path,site_name,name,username,site_dir,auth_file):
php_ver = self.get_site_php_version(site_name)
php_conf = ""
if php_ver:
php_conf = "include enable-php-{}.conf;".format(php_ver)
for i in ["nginx","apache"]:
file_path = "{setup_path}/panel/vhost/{webserver}/dir_auth/{site_name}"
if i == "nginx":
@@ -131,8 +151,9 @@ class SiteDirAuth:
#AUTH_START
auth_basic "Authorization";
auth_basic_user_file %s;
%s
#AUTH_END
}''' % (site_dir,auth_file)
}''' % (site_dir,auth_file,php_conf)
else:
# 设置apache
conf = '''<Directory "{site_path}{site_dir}">
+199
View File
@@ -0,0 +1,199 @@
#coding: utf-8
# +-------------------------------------------------------------------
# | 宝塔Linux面板
# +-------------------------------------------------------------------
# | Copyright (c) 2015-2099 宝塔软件(http://bt.cn) All rights reserved.
# +-------------------------------------------------------------------
# | Author: 黄文良 <287962566@qq.com>
# +-------------------------------------------------------------------
import paramiko
import json
import time
import os
import sys
import socket
sys.path.insert(0, '/www/server/panel/class/')
import public
from io import BytesIO, StringIO
from BTPanel import session,socketio
class ssh_terminal:
__log_type = 'aaPanel terminal'
_coll_user = None
_host = None
_web_socket = None
_ssh_info = None
_ssh_socket = None
_en_key = '4BbA7076e19H'
_thread = None
_my_terms = {}
_room = "ssh_data"
_send_last = False
def __init__(self):
pass
def connect(self, ssh_info=None):
if ssh_info: self._ssh_info = ssh_info
if not self._host: self._host = self._ssh_info['host']
# print('----------连接时的ssh_info--------------')
if self._ssh_info['host'] in self._my_terms:
if time.time() - self._my_terms[self._host].last_time < 86400:
return True
try:
sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
sock.setsockopt(socket.SOL_SOCKET, socket.SO_SNDBUF, 262144)
sock.connect((self._ssh_info['host'], int(self._ssh_info['port'])))
except Exception as e:
socketio.emit(self._room,"\rServer connection failed!\r")
return False
# 使用Transport连接
p1 = paramiko.Transport(sock)
p1.start_client()
if not 'pkey' in self._ssh_info: self._ssh_info['pkey'] = None
if not 'c_type' in self._ssh_info: self._ssh_info['c_type'] = None
try:
# 如果有pkey时则使用RSA私钥登录
if self._ssh_info['pkey'] and self._ssh_info['c_type']:
# print('------使用私钥登陆---------')
# 将RSA私钥转换为io对象,然后生成rsa_key对象
p_file = StringIO(self._ssh_info['pkey'])
pkey = paramiko.RSAKey.from_private_key(p_file)
p1.auth_publickey(username=self._ssh_info['username'].strip(), key=pkey)
else:
# print('-----------使用密码登陆-----------')
p1.auth_password(username=self._ssh_info['username'].strip(), password=self._ssh_info['password'])
except Exception as e:
socketio.emit(self._room,"\rWrong user name or password!\r")
p1.close()
return False
self._my_terms[self._host] = public.dict_obj()
self._my_terms[self._host].last_time = time.time()
self._my_terms[self._host].connect_time = time.time()
# 打开会话
self._my_terms[self._host].tty = p1.open_session()
# 获取终端对象
self._my_terms[self._host].tty.get_pty(term='xterm', width=100, height=34)
self._my_terms[self._host].tty.invoke_shell()
# 记录登陆记录
#public.M('ssh_records').add('coll_user,ssh_user,host,cmd,addtime', (self._coll_user, self._ssh_info['username'], self._ssh_info['host'], 'login', int(time.time())))
#print("登录成功")
self._my_terms[self._host].last_send = []
self._send_last = True
return True
def resize(self, data):
try:
data = json.loads(data)
self._my_terms[self._host].tty.resize_pty(width=data['width'], height=data['height'], width_pixels=data['width_px'], height_pixels=data['height_px'])
return True
except:
print(public.get_error_info())
return False
def send(self,c_data):
try:
if not c_data: return
if not self._thread:
s_file = '/www/server/panel/config/t_info.json'
ssh_info = None
if os.path.exists(s_file):
ssh_info = json.loads(public.en_hexb(public.readFile(s_file)))
if not 'host' in c_data:
host = "127.0.0.1"
if ssh_info:
c_data = ssh_info
host = c_data['host']
else:
host = c_data['host']
if not host:
if not ssh_info: return socketio.emit(self._room,"\rWrong user name or password!\r")
c_data = ssh_info
key = 'ssh_' + host
if 'password' in c_data:
session[key] = c_data
if not key in session: return socketio.emit(self._room,"\rWrong user name or password!\r")
result = self.run(session[key])
else:
if len(c_data) > 10:
if c_data == 'new_bt_terminal':
if not self._send_last: self.last_send()
self._send_last = False
return
if c_data.find('resize_pty') != -1:
if self.resize(c_data): return
if type(c_data) == dict: return
if self._host in self._my_terms:
self._my_terms[self._host].last_time = time.time()
self._my_terms[self._host].tty.send(c_data)
else:
return
except:
self.close()
socketio.emit(self._room,'\rConnection failure!\r')
print(public.get_error_info())
def recv(self):
try:
while True:
data = self._my_terms[self._host].tty.recv(1024)
if not data:
self.close()
socketio.emit(self._room,"\rThe connection has been disconnected and pressing Enter will attempt to reconnect!\r")
return
try:
result = data.decode()
except:
result = str(data)
if not result: continue
self.set_last_send(result)
socketio.emit(self._room,result)
except:
print(public.get_error_info())
def set_last_send(self,result):
last_size = 1024
if not 'last_send' in self._my_terms[self._host]:
self._my_terms[self._host].last_send = []
self._my_terms[self._host].last_send.append(result)
last_len = len(self._my_terms[self._host].last_send)
if last_len > last_size:
self._my_terms[self._host].last_send = self._my_terms[self._host].last_send[last_len-last_size:]
def not_send(self):
if 'not_send' in self._my_terms[self._host]:
if self._my_terms[self._host].not_send:
socketio.emit(self._room,self._my_terms[self._host].not_send)
self._my_terms[self._host].not_send = ""
def last_send(self):
time.sleep(0.3)
if 'last_send' in self._my_terms[self._host]:
for d in self._my_terms[self._host].last_send:
socketio.emit(self._room,d)
def close(self):
try:
self._my_terms[self._host].tty.close()
except:pass
if self._host in self._my_terms:
del self._my_terms[self._host]
self._thread = None
def run(self, ssh_info=None):
if not ssh_info:
return
if 'id' in ssh_info:
self._ssh_info = self.get_server_ssh_info(ssh_info)
else:
self._ssh_info = ssh_info
result = self.connect()
if result and not self._thread:
self._thread = socketio.start_background_task(target=self.recv)
return result
+12 -4
View File
@@ -217,6 +217,10 @@ class system:
data['time'] = self.GetBootTime();
data['system'] = self.GetSystemVersion();
data['isuser'] = public.M('users').where('username=?',('admin',)).count();
try:
data['isport'] = public.GetHost(True) == '8888'
except:data['isport'] = False
data['version'] = session['version'];
return data
@@ -272,10 +276,14 @@ class system:
time.sleep(0.5)
#取CPU信息
cpuCount = psutil.cpu_count()
cpuNum = psutil.cpu_count(logical=False)
c_tmp = public.readFile('/proc/cpuinfo')
d_tmp = re.findall("physical id.+",c_tmp)
cpuW = len(set(d_tmp))
used = self.get_cpu_percent()
used_all = psutil.cpu_percent(percpu=True)
cpu_name = public.getCpuType()
return used,cpuCount,used_all,cpu_name
cpu_name = public.getCpuType() + " * {}".format(cpuW)
return used,cpuCount,used_all,cpu_name,cpuNum,cpuW
def GetCpuInfo_new(self):
@@ -336,7 +344,7 @@ class system:
tmp['size'] = psutil.disk_usage(disk[1])
diskInfo.append(tmp)
return diskInfo
def GetDiskInfo2(self):
#取磁盘分区信息
temp = public.ExecShell("df -h -P|grep '/'|grep -v tmpfs")[0];
@@ -363,7 +371,7 @@ class system:
arr['inodes'] = [inodes[1],inodes[2],inodes[3],inodes[4]]
diskInfo.append(arr);
except Exception as ex:
public.WriteLog('Get info',str(ex))
public.WriteLog('信息获取',str(ex))
continue
return diskInfo;
+5 -2
View File
@@ -39,6 +39,7 @@ class userlogin:
return public.returnJson(False,'LOGIN_USER_ERR',(str(num),)),json_header
_key_file = "/www/server/panel/data/two_step_auth.txt"
if hasattr(post,'vcode'):
if self.limit_address('?',v="vcode") < 1: return public.returnJson(False,'您多次验证失败,禁止10分钟'),json_header
import pyotp
secret_key = public.readFile(_key_file)
if not secret_key:
@@ -46,8 +47,10 @@ class userlogin:
t = pyotp.TOTP(secret_key)
result = t.verify(post.vcode)
if not result:
num = self.limit_address('++',v="vcode")
return public.returnJson(False, 'Invalid Verification code. You have [{}] times left to try!'.format(num)), json_header
if public.sync_date(): result = t.verify(post.vcode)
if not result:
num = self.limit_address('++',v="vcode")
return public.returnJson(False, 'Invalid Verification code. You have [{}] times left to try!'.format(num)), json_header
now = int(time.time())
public.writeFile("/www/server/panel/data/dont_vcode_ip.txt",json.dumps({"client_ip":public.GetClientIp(),"add_time":now}))
self.limit_address('--',v="vcode")
+17 -9
View File
@@ -1,8 +1,11 @@
import os,time,sys,ssl
sys.path.insert(0,'/www/server/panel/class')
import public
bt_port = public.readFile('data/port.pl')
if bt_port: bt_port.strip()
import os
f = open('data/port.pl','r')
bt_port = f.read()
f.close()
if bt_port:
bt_port.strip()
else:
bt_port = 8888
bind = []
if os.path.exists('data/ipv6.pl'):
bind.append('[0:0:0:0:0:0:0:0]:%s' % bt_port)
@@ -10,9 +13,14 @@ else:
bind.append('0.0.0.0:%s' % bt_port)
w_num = 'data/workers.pl'
if not os.path.exists(w_num): public.writeFile(w_num,'1')
workers = int(public.readFile(w_num))
if not workers: workers = 1
workers = 1
if os.path.exists(w_num):
f = open(w_num,'r')
w_str = f.read()
f.close()
if w_str:
workers = int(w_str.strip())
threads = 3
backlog = 512
daemon = True
@@ -28,7 +36,7 @@ graceful_timeout=0
loglevel = 'info'
if debug: loglevel = 'debug'
errorlog = chdir + '/logs/error.log'
accesslog = chdir + '/logs/access.log'
accesslog = chdir + '/logs/error.log'
pidfile = chdir + '/logs/panel.pid'
if os.path.exists(chdir + '/data/ssl.pl'):
certfile = 'ssl/certificate.pem'
+1
View File
@@ -15,6 +15,7 @@ panelPath = '/www/server/panel/';
os.chdir(panelPath)
sys.path.append(panelPath + "class/")
import public,time,json
if sys.version_info[0] == 3: raw_input = input
#设置MySQL密码
def set_mysql_root(password):