fix: add missing files for tp-api.

dev
Apex Liu 2020-07-02 00:17:51 +08:00
parent 9cd7c609f9
commit 856a762b56
2 changed files with 183 additions and 0 deletions

View File

@ -0,0 +1,82 @@
# -*- coding: utf-8 -*-
import os
import json
from app.base.configs import tp_cfg
from app.base.logger import log
class ExtSrvCfg(object):
def __init__(self):
super().__init__()
import builtins
if '__ext_srv_cfg__' in builtins.__dict__:
raise RuntimeError('ExtSrvCfg object exists, you can not create more than one instance.')
# session表session_id为索引每个项为一个字典包括 v(value), t(last access), e(expire seconds)
self._cfg = dict()
def init(self):
cfg = tp_cfg()
cfg_file = os.path.join(cfg.cfg_path, 'extsrv.json')
# 如果配置文件不存在则不支持第三方服务调用TP-API
if not os.path.exists(cfg_file):
return True
log.i('Loading external server configuration...\n')
with open(cfg_file, encoding='utf_8') as f:
c = f.read()
try:
sc = json.loads(c)
except:
return False
if 'version' not in sc:
return False
if 'ext_srv' not in sc:
return False
srv = sc['ext_srv']
try:
for i in range(len(srv)):
srv_name = srv[i]['name']
srv_desc = srv[i]['desc']
for j in range(len(srv[i]['access'])):
key = srv[i]['access'][j]['key']
secret = srv[i]['access'][j]['secret']
privilege = int(srv[i]['access'][j]['privilege'])
if key in self._cfg:
log.e('Invalid extsrv.json, duplicated key: {}\n'.format(key))
return False
self._cfg[key] = {
'name': srv_name,
'desc': srv_desc,
'secret': secret,
'privilege': privilege
}
except:
log.e('Invalid extsrv.json\n')
return False
return True
def get_secret_info(self, key):
if key not in self._cfg:
return None
return self._cfg[key]
def tp_ext_srv_cfg():
"""
:rtype : ExtSrvCfg
"""
import builtins
if '__ext_srv_cfg__' not in builtins.__dict__:
builtins.__dict__['__ext_srv_cfg__'] = ExtSrvCfg()
return builtins.__dict__['__ext_srv_cfg__']

View File

@ -0,0 +1,101 @@
# -*- coding: utf-8 -*-
import hmac
import base64
import hashlib
import json
import tornado.gen
from app.const import *
from app.model import host
from app.base.logger import *
from app.base.controller import TPBaseJsonHandler
from app.base.utils import tp_bin, tp_str, tp_timestamp_sec
from app.base.extsrv import tp_ext_srv_cfg
@tornado.gen.coroutine
def _parse_api_args(handler):
raw_req = handler.request.body.decode('utf-8')
if raw_req == '':
return False, handler.write_json(TPE_PARAM)
try:
raw_req = json.loads(raw_req)
if 'auth' not in raw_req or 'arg' not in raw_req or 'sign' not in raw_req:
return False, handler.write_json(TPE_PARAM)
except:
return False, handler.write_json(TPE_JSON_FORMAT)
_auth = raw_req['auth'].split(':')
if len(_auth) <= 1:
return False, handler.write_json(TPE_PARAM)
if _auth[0] == '1': # 目前的API请求格式版本为1
if len(_auth) != 4: # VERSION:ACCESS_KEY:TIMESTAMP:EXPIRES
return False, handler.write_json(TPE_PARAM)
req_access_key = _auth[1]
req_timestamp = int(_auth[2])
req_expires = int(_auth[3])
else:
return False, handler.write_json(TPE_PARAM)
# 从数据库中根据access-key查找access-secret
sec_info = tp_ext_srv_cfg().get_secret_info(req_access_key)
if sec_info is None:
return False, handler.write_json(TPE_INVALID_API_KEY)
access_secret = sec_info['secret']
# 是否超时
if tp_timestamp_sec() > req_timestamp + req_expires:
return False, handler.write_json(TPE_EXPIRED)
# 验证
be_sign = '{}|{}'.format(raw_req['auth'], raw_req['arg'])
_h = hmac.new(tp_bin(access_secret), tp_bin(be_sign), hashlib.sha1)
_s = base64.urlsafe_b64decode(tp_bin(raw_req['sign']))
if _s != _h.digest():
return False, handler.write_json(TPE_INVALID_API_SIGN)
# 一切都OK解码得到实际参数
_param = base64.urlsafe_b64decode(tp_bin(raw_req['arg']))
try:
args = json.loads(tp_str(_param))
except:
return False, handler.write_json(TPE_JSON_FORMAT)
log.d('api:get_host, param=', args, '\n')
return True, args
class GetHostHandler(TPBaseJsonHandler):
@tornado.gen.coroutine
def post(self):
ok, args = yield _parse_api_args(self)
if not ok:
return
if 'addr' not in args:
return self.write_json(TPE_PARAM)
if len(args['addr']) == 0:
return self.write_json(TPE_OK)
# 查询数据库
err, data = host.api_v1_get_host(args['addr'])
if err != TPE_OK:
return self.write_json(err)
return self.write_json(TPE_OK, data=data)
class RequestSessionHandler(TPBaseJsonHandler):
@tornado.gen.coroutine
def post(self):
ok, args = yield _parse_api_args(self)
if not ok:
return
return self.write_json(TPE_NOT_IMPLEMENT)