提供面板API接口访问的支持

还有功能要上,肯能会影响使用,,测试使用即可。
pull/278/head
midoks 2 years ago
parent 93785a2472
commit 7e014dfa94
  1. 12
      class/core/config_api.py
  2. 1
      plugins/php/install.sh
  3. 51
      route/__init__.py
  4. 94
      version/api/mw_api.php
  5. 122
      version/api/mw_api.py

@ -490,6 +490,18 @@ class config_api:
'id,type,uid,log,addtime').select() 'id,type,uid,log,addtime').select()
return mw.returnJson(False, 'ok', data) return mw.returnJson(False, 'ok', data)
def checkPanelToken(self):
api_file = self.__api_addr
if not os.path.exists(api_file):
return False, ''
tmp = mw.readFile(api_file)
data = json.loads(tmp)
if data['open']:
return True, data
else:
return False, ''
def getPanelTokenApi(self): def getPanelTokenApi(self):
api_file = self.__api_addr api_file = self.__api_addr

@ -63,6 +63,7 @@ if [ "${action}" == "install" ] && [ -d ${serverPath}/php/${type} ];then
cd ${rootPath}/plugins/php/versions/common && bash intl.sh install ${type} cd ${rootPath}/plugins/php/versions/common && bash intl.sh install ${type}
cd ${rootPath}/plugins/php/versions/common && bash mcrypt.sh install ${type} cd ${rootPath}/plugins/php/versions/common && bash mcrypt.sh install ${type}
cd ${rootPath}/plugins/php/versions/common && bash openssl.sh install ${type} cd ${rootPath}/plugins/php/versions/common && bash openssl.sh install ${type}
cd ${rootPath}/plugins/php/versions/common && bash bcmath.sh install ${type}
cd ${rootPath}/plugins/php/versions/common && bash gettext.sh install ${type} cd ${rootPath}/plugins/php/versions/common && bash gettext.sh install ${type}
cd ${rootPath}/plugins/php/versions/common && bash redis.sh install ${type} cd ${rootPath}/plugins/php/versions/common && bash redis.sh install ${type}
cd ${rootPath}/plugins/php/versions/common && bash memcached.sh install ${type} cd ${rootPath}/plugins/php/versions/common && bash memcached.sh install ${type}

@ -133,8 +133,6 @@ def funConvert(fun):
func += suf func += suf
return func return func
# Flask请求勾子
def sendAuthenticated(): def sendAuthenticated():
# 发送http认证信息 # 发送http认证信息
@ -148,6 +146,7 @@ def sendAuthenticated():
@app.before_request @app.before_request
def requestCheck(): def requestCheck():
# Flask请求勾子
if app.config['BASIC_AUTH_OPEN']: if app.config['BASIC_AUTH_OPEN']:
auth = request.authorization auth = request.authorization
if request.path in ['/download', '/hook', '/down']: if request.path in ['/download', '/hook', '/down']:
@ -407,9 +406,49 @@ def login_temp_user(token):
return redirect('/') return redirect('/')
@app.route('/api', methods=['POST', 'GET']) @app.route('/api/<reqClass>/<reqAction>', methods=['POST', 'GET'])
def api(reqClass=None, reqAction=None, reqData=None): def api(reqClass=None, reqAction=None, reqData=None):
pass
comReturn = common.local()
if comReturn:
return comReturn
import config_api
isOk, data = config_api.config_api().checkPanelToken()
if not isOk:
return mw.returnJson(False, '未开启API')
request_time = request.form.get('request_time', '')
request_token = request.form.get('request_token', '')
request_ip = request.remote_addr
token_md5 = mw.md5(str(request_time) + mw.md5(data['token_crypt']))
if not (token_md5 == request_token):
return mw.returnJson(False, '密钥错误')
if not mw.inArray(data['limit_addr'], request_ip):
return mw.returnJson(False, '非法请求')
if reqClass == None:
return mw.returnJson(False, '请指定请求方法类')
if reqAction == None:
return mw.returnJson(False, '请指定请求方法')
classFile = ('config_api', 'crontab_api', 'files_api', 'firewall_api',
'plugins_api', 'system_api', 'site_api', 'task_api')
className = reqClass + '_api'
if not className in classFile:
return "external api request error"
eval_str = "__import__('" + className + "')." + className + '()'
newInstance = eval(eval_str)
try:
return publicObject(newInstance, reqAction)
except Exception as e:
return mw.getTracebackInfo()
@app.route('/<reqClass>/<reqAction>', methods=['POST', 'GET']) @app.route('/<reqClass>/<reqAction>', methods=['POST', 'GET'])
@ -467,14 +506,14 @@ def index(reqClass=None, reqAction=None, reqData=None):
return render_template(reqClass + '.html', data=data) return render_template(reqClass + '.html', data=data)
if not isLogined(): if not isLogined():
return 'request error!' return 'error request!'
# API请求 # API请求
classFile = ('config_api', 'crontab_api', 'files_api', 'firewall_api', classFile = ('config_api', 'crontab_api', 'files_api', 'firewall_api',
'plugins_api', 'system_api', 'site_api', 'task_api') 'plugins_api', 'system_api', 'site_api', 'task_api')
className = reqClass + '_api' className = reqClass + '_api'
if not className in classFile: if not className in classFile:
return "api request error" return "api error request"
eval_str = "__import__('" + className + "')." + className + '()' eval_str = "__import__('" + className + "')." + className + '()'
newInstance = eval(eval_str) newInstance = eval(eval_str)

@ -0,0 +1,94 @@
<?php
/**
* MW API接口示例Demo
* 仅供参考,请根据实际项目需求开发,并做好安全处理
* date 2022-11-28
* author midoks
*/
class mwApi {
private $MW_KEY = "j7GQhzNcBV4KU9QKYPXvtjSzCcmfkc0e"; //接口密钥
private $MW_PANEL = "http://127.0.0.1:7200"; //面板地址
//如果希望多台面板,可以在实例化对象时,将面板地址与密钥传入
public function __construct($mw_panel = null, $mw_key = null) {
if ($mw_panel) {
$this->MW_PANEL = $mw_panel;
}
if ($mw_key) {
$this->MW_KEY = $mw_key;
}
}
/**
* 发起POST请求
* @param String $url 目标网填,带http://
* @param Array|String $data 欲提交的数据
* @return string
*/
private function httpPostCookie($url, $data, $timeout = 60) {
//定义cookie保存位置
$cookie_file = './' . md5($this->MW_PANEL) . '.cookie';
if (!file_exists($cookie_file)) {
$fp = fopen($cookie_file, 'w+');
fclose($fp);
}
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_TIMEOUT, $timeout);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_COOKIEJAR, $cookie_file);
curl_setopt($ch, CURLOPT_COOKIEFILE, $cookie_file);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$output = curl_exec($ch);
curl_close($ch);
return $output;
}
/**
* 构造带有签名的关联数组
*/
private function getKeyData() {
$now_time = time();
$ready_data = array(
'request_token' => md5($now_time . '' . md5($this->MW_KEY)),
'request_time' => $now_time,
);
return $ready_data;
}
//示例取面板日志
public function getLogsList() {
//拼接URL地址
$url = $this->MW_PANEL . '/api/firewall/get_log_list';
//准备POST数据
$post_data = $this->getKeyData(); //取签名
$post_data['p'] = '1';
$post_data['limit'] = 10;
//请求面板接口
$result = $this->httpPostCookie($url, $post_data);
//解析JSON数据
$data = json_decode($result, true);
return $data;
}
}
//实例化对象
$api = new mwApi();
//获取面板日志
$rdata = $api->getLogsList();
// var_dump($rdata);
//输出JSON数据到浏览器
echo json_encode($rdata);
?>

@ -0,0 +1,122 @@
# coding: utf-8
# +-----------------------------------------------------------------------------------
# | MW Linux面板
# +-----------------------------------------------------------------------------------
# | Copyright (c) 2015-2099 MW(http://github.com/midoks/mdserver) All rights reserved.
# +-----------------------------------------------------------------------------------
# | Author: midoks
# +-----------------------------------------------------------------------------------
#------------------------------
# API-Demo of Python
#------------------------------
import time
import hashlib
import sys
import os
import json
class mwApi:
__MW_KEY = 'j7GQhzNcBV4KU9QKYPXvtjSzCcmfkc0e'
__MW_PANEL = 'http://127.0.0.1:7200'
# 如果希望多台面板,可以在实例化对象时,将面板地址与密钥传入
def __init__(self, mw_panel=None, mw_key=None):
if mw_panel:
self.__MW_PANEL = mw_panel
self.__MW_KEY = mw_key
# 计算MD5
def __get_md5(self, s):
m = hashlib.md5()
m.update(s.encode('utf-8'))
return m.hexdigest()
# 构造带有签名的关联数组
def __get_key_data(self):
now_time = int(time.time())
ready_data = {
'request_token': self.__get_md5(str(now_time) + '' + self.__get_md5(self.__MW_KEY)),
'request_time': now_time
}
return ready_data
# 发送POST请求并保存Cookie
#@url 被请求的URL地址(必需)
#@data POST参数,可以是字符串或字典(必需)
#@timeout 超时时间默认1800秒
# return string
def __http_post_cookie(self, url, p_data, timeout=1800):
cookie_file = './' + self.__get_md5(self.__MW_PANEL) + '.cookie'
if sys.version_info[0] == 2:
# Python2
import urllib
import urllib2
import ssl
import cookielib
# 创建cookie对象
cookie_obj = cookielib.MozillaCookieJar(cookie_file)
# 加载已保存的cookie
if os.path.exists(cookie_file):
cookie_obj.load(cookie_file, ignore_discard=True,
ignore_expires=True)
ssl._create_default_https_context = ssl._create_unverified_context
data = urllib.urlencode(p_data)
req = urllib2.Request(url, data)
opener = urllib2.build_opener(
urllib2.HTTPCookieProcessor(cookie_obj))
response = opener.open(req, timeout=timeout)
# 保存cookie
cookie_obj.save(ignore_discard=True, ignore_expires=True)
return response.read()
else:
# Python3
import urllib.request
import ssl
import http.cookiejar
cookie_obj = http.cookiejar.MozillaCookieJar(cookie_file)
cookie_obj.load(cookie_file, ignore_discard=True,
ignore_expires=True)
handler = urllib.request.HTTPCookieProcessor(cookie_obj)
data = urllib.parse.urlencode(p_data).encode('utf-8')
req = urllib.request.Request(url, data)
opener = urllib.request.build_opener(handler)
response = opener.open(req, timeout=timeout)
cookie_obj.save(ignore_discard=True, ignore_expires=True)
result = response.read()
if type(result) == bytes:
result = result.decode('utf-8')
return result
# 取面板日志
def getLogs(self):
# 拼接URL地址
url = self.__MW_PANEL + '/api/firewall/get_log_list'
# 准备POST数据
post_data = self.__get_key_data() # 取签名
post_data['limit'] = 10
post_data['p'] = '1'
# 请求面板接口
result = self.__http_post_cookie(url, post_data)
# 解析JSON数据
return json.loads(result)
if __name__ == '__main__':
# 实例化宝塔API对象
api = mwApi()
# 调用get_logs方法
rdata = api.getLogs()
# 打印响应数据
print(rdata)
Loading…
Cancel
Save