Skip to content

Commit

Permalink
完善HOOK模块
Browse files Browse the repository at this point in the history
  • Loading branch information
showpy committed Jul 19, 2021
1 parent a394551 commit 008088d
Show file tree
Hide file tree
Showing 4 changed files with 235 additions and 6 deletions.
125 changes: 123 additions & 2 deletions BTPanel/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
import sys
import json
import os
import threading
import time
import re
import uuid

if not os.name in ['nt']:
os.chdir('/www/server/panel')
if not 'class/' in sys.path:
Expand All @@ -32,7 +34,10 @@
app = Flask(__name__, template_folder="templates/{}".format(public.GetConfigValue('template')))
Compress(app)
sockets = Sockets(app)

# 注册HOOK
hooks = {}
if not hooks:
public.check_hooks()
# import db
dns_client = None
app.config['DEBUG'] = os.path.exists('data/debug.pl')
Expand Down Expand Up @@ -134,7 +139,7 @@
def request_check():
g.request_time = time.time()
# 路由和URI长度过滤
if len(request.path) > 128: return abort(403)
if len(request.path) > 256: return abort(403)
if len(request.url) > 1024: return abort(403)

if request.path in ['/service_status']: return
Expand Down Expand Up @@ -669,6 +674,52 @@ def abnormal(pdata=None):
)
return publicObject(dataObject, defs, None, pdata)

@sockets.route('/sock_shell')
def sock_shell(ws):
'''
@name 执行指定命令,实时输出命令执行结果
@author hwliang<2021-07-19>
@return void
示例:
p = new WebSocket('ws://192.168.1.247:8888/sock_shell')
p.send('ping www.bt.cn -c 100')
'''
comReturn = comm.local()
if comReturn: return comReturn
import subprocess
cmdstring = ws.receive()
p = subprocess.Popen(cmdstring, close_fds=True, shell=True,bufsize=4096,stdout=subprocess.PIPE,stderr=subprocess.PIPE)
skey = public.md5(cmdstring)
cache.set(skey,p.pid,43200)
while p.poll() is None:
ws.send(p.stdout.read(1).decode())
ws.send(p.stdout.read().decode())
cache.delete(skey)


@app.route('/close_sock_shell',methods=method_all)
def close_sock_shell():
'''
@name 关闭指定命令
@author hwliang<2021-07-19>
@param cmdstring<string> 完整命令行
@return dict
示例:
$.post('/close_sock_shell',{cmdstring:'ping www.bt.cn -c 100'})
'''
comReturn = comm.local()
if comReturn: return comReturn
args = get_input()
cmdstring = args.cmdstring.strip()
skey = public.md5(cmdstring)
pid = cache.get(skey)
if not pid: return json.dumps(public.return_data(False,[],error_msg='指定sock已终止!')),json_header
os.kill(pid,9)
return json.dumps(public.return_data(True,'操作成功!')),json_header



@app.route('/project/<action>', methods=method_all)
def project(action):
comReturn = comm.local()
Expand Down Expand Up @@ -1939,3 +1990,73 @@ def workorder_client(ws):
toObject.client(ws, get)

# workorder end


# def ws_send(ws,action):
# while True:
# ws.send(action.receive())

# def ws_recv(ws,action):
# while True:
# action.send(ws.recv())

# @app.route('/vscode',methods=method_all)
# @app.route('/vscode/<path:action>',methods=method_all)
# def vscode(action = None):

# comReturn = comm.local()
# if comReturn: return comReturn
# uri = request.full_path[7:]
# action = request.environ.get("wsgi.websocket")
# public.writeFile('/tmp/11.log',"{} => {}\n".format(uri,str(action)),'a+')
# req_headers = {}
# for k in request.headers.keys():
# # if k == 'Cookie': continue
# if k == 'Host':
# req_headers[k] = '127.0.0.1:8080'
# else:
# req_headers[k] = request.headers[k]
# if action:
# from websocket import create_connection
# ws = create_connection("ws://127.0.0.1:8080/{}".format(uri),header=req_headers)
# p1 = threading.Thread(target=ws_send,args = (ws,action))
# p2 = threading.Thread(target=ws_send,args = (ws,action))
# p1.start()
# p2.start()

# p1.join()
# p2.join()
# return


# # return str(req_headers)
# import requests as p

# url = 'http://127.0.0.1:8080{}'.format(uri)
# # if url.find('workbench.js') != -1: return url
# if request.method == 'GET':
# res = p.get(url,headers=req_headers)
# else:
# res = p.post('http://127.0.0.1:8080{}'.format(uri),request.form.to_dict(),headers=req_headers)
# result = res.text
# if uri in ['/login']:
# result = res.text
# else:
# result = res.text.replace('/static/','/vscode/static/')

# res_headers = {}
# for k in res.headers.keys():
# if k in ['Content-Encoding','Transfer-Encoding']: continue
# res_headers[k] = res.headers[k]

# # return res.cookies.get_dict()
# # return str(res.headers.items())

# return Resp(result,status=res.status_code,headers=res_headers)



# def vscode_sock(ws):
# comReturn = comm.local()
# if comReturn: return comReturn
# ws.send('OK')
5 changes: 4 additions & 1 deletion class/flask_session/sessions.py
Original file line number Diff line number Diff line change
Expand Up @@ -285,9 +285,12 @@ def save_session(self, app, session, response):
session_id = self._get_signer(app).sign(want_bytes(session.sid))
else:
session_id = session.sid
response.set_cookie(app.session_cookie_name, session_id,
from BTPanel import request
if not request.cookies.get(app.session_cookie_name):
response.set_cookie(app.session_cookie_name, session_id,
expires=expires, httponly=httponly,
domain=domain, path=path, secure=secure)



class FileSystemSessionInterface(SessionInterface):
Expand Down
29 changes: 27 additions & 2 deletions class/panelProjectController.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,12 +12,13 @@
#------------------------------
import os,sys,public,json,re

from numpy import isin

class ProjectController:


def __init__(self):
pass



def get_parser_list(self,args):
Expand Down Expand Up @@ -137,4 +138,28 @@ def model(self,args):
# 方法是否存在
if not def_object:
return public.return_status_code(1004,def_name)
return def_object(pdata)

# 前置HOOK
hook_index = '{}_{}_LAST'.format(mod_name.upper(),def_name.upper())
hook_result = public.exec_hook(hook_index,pdata)
if isinstance(hook_result,public.dict_obj):
pdata = hook_result # 桥接
elif isinstance(hook_result,dict):
return hook_result # 响应具体错误信息
elif isinstance(hook_result,bool):
if not hook_result: # 直接中断操作
return public.return_data(False,{},error_msg='前置HOOK中断操作')

# 调用处理方法
result = def_object(pdata)

# 后置HOOK
hook_index = '{}_{}_END'.format(mod_name.upper(),def_name.upper())
hook_data = public.to_dict_obj({
'args': pdata,
'result': result
})
hook_result = hook_result = public.exec_hook(hook_index,hook_data)
if isinstance(hook_result,dict):
result = hook_result['result']
return result
82 changes: 81 additions & 1 deletion class/public.py
Original file line number Diff line number Diff line change
Expand Up @@ -3469,4 +3469,84 @@ def to_dict_obj(data):
pdata = dict_obj()
for key in data.keys():
pdata[key] = data[key]
return pdata
return pdata

def get_sctipt_object(filename):
'''
@name 从脚本文件获取对像
@author hwliang<2021-07-19>
@param filename<string> 文件名
@return object
'''
from types import ModuleType
_obj = sys.modules.setdefault(filename, ModuleType(filename))
_code = readFile(filename)
_code_object = compile(_code,filename, 'exec')
_obj.__file__ = filename
_obj.__package__ = ''
exec(_code_object, _obj.__dict__)
return _obj

def check_hooks():
'''
@name 自动注册HOOK
@author hwliang<2021-07-19>
@return void
'''
hooks_path = '{}/hooks'.format(get_panel_path())
if not os.path.exists(hooks_path):
return
for hook_name in os.listdir(hooks_path):
if hook_name[-3:] != '.py': continue
filename = os.path.join(hooks_path,hook_name)
_obj = get_sctipt_object(filename)
_main = getattr(_obj,'main',None)
if not _main: continue
_main()

def register_hook(hook_index,hook_def):
'''
@name 注册HOOK
@author hwliang<2021-07-15>
@param hook_index<string> HOOK位置
@param hook_def<def> HOOK函数对像
@return void
'''
from BTPanel import hooks
hook_keys = hooks.keys()
if not hook_index in hook_keys:
hooks[hook_index] = []
if not hook_def in hooks[hook_index]:
hooks[hook_index].append(hook_def)

def exec_hook(hook_index,data):
'''
@name 执行HOOk
@author hwliang<2021-07-15>
@param hook_index<string> HOOK索引位置,格式限制:^\w+$
@param data<mixed> 运行数据
@return mixed
'''

from BTPanel import hooks
hook_keys = hooks.keys()
if not hook_index in hook_keys:
return data

for hook_def in hook_keys[hook_index]:
data = hook_def(data)
return data

def get_hook_index(mod_name,def_name):
'''
@name 获取HOOK位置
@author hwliang<2021-07-19>
@param mod_name<string> 模块名称
@param def_name<string> 方法名称
@return tuple
'''
mod_name = mod_name.upper()
def_name = def_name.upper()
last_index = '{}_{}_LAST'.format(mod_name,def_name)
end_index = '{}_{}_END'.format(mod_name,def_name)
return last_index,end_index

0 comments on commit 008088d

Please sign in to comment.