整理代码,准备加入安装/升级界面。

pull/32/merge
apexliu 2017-03-13 03:01:23 +08:00
parent 4b594ed274
commit 9b50a624e0
29 changed files with 335 additions and 897 deletions

1
.gitignore vendored
View File

@ -73,3 +73,4 @@ __pycache__
# for not finished code
/common/libex/test
/client/tp_rdp
/server/share/etc/maintenance-mode

View File

@ -13,6 +13,9 @@ WIN_WEB_SERVICE_NAME = 'EOM Teleport Web Service'
class InstallerBase:
def __init__(self):
self._all_ok = True
self._err_msg = list()
self._is_installed = False
self._install_path = ''
self._config_path = ''
@ -26,7 +29,7 @@ class InstallerBase:
ver_file = os.path.join(env.root_path, 'data', 'www', 'teleport', 'app', 'eom_ver.py')
try:
with open(ver_file) as f:
with open(ver_file, 'r') as f:
x = f.readlines()
for i in x:
s = i.split('=', 1)
@ -369,6 +372,13 @@ class InstallerWin(InstallerBase):
utils.copy_ex(os.path.join(env.src_path, 'bin'), os.path.join(self._install_path, 'bin'))
utils.copy_ex(os.path.join(env.src_path, 'www'), os.path.join(self._install_path, 'www'))
# 创建一个标志文件,这样访问后台时会进入维护模式
try:
with open(os.path.join(self._install_path, 'www', 'teleport', 'maintenance-mode'), 'w') as f:
f.write('!!! DO NOT TOUCH !!!')
except:
pass
if not os.path.exists(self._config_path):
utils.copy_ex(os.path.join(env.src_path, 'tmp', 'etc'), self._config_path)

View File

@ -14,7 +14,10 @@ port=7190
# LOG_LEVEL_INFO 2 log infomation/warning/error message.
# LOG_LEVEL_WARN 3 log warning and error message.
# LOG_LEVEL_ERROR 4 log error message only.
log-level=0
log-level=1
; running in debug mode. default to 0.
; in debug mode, log-level set to 0 and trace call stack while exception raise.
debug=0
core-server-rpc=http://127.0.0.1:52080/rpc

View File

@ -60,6 +60,7 @@ class ConfigFile(AttrDict):
if self['log_file'] is not None:
self['log_path'] = os.path.dirname(self['log_file'])
self['log_level'] = LOG_INFO
_level = _comm.getint('log-level', 2)
if _level == 0:
self['log_level'] = LOG_DEBUG
@ -76,6 +77,12 @@ class ConfigFile(AttrDict):
# log.set_attribute(min_level=self['log_level'])
self['debug'] = False
_debug = _comm.getint('debug', 0)
if _debug == 1:
self['log_level'] = LOG_DEBUG
self['debug'] = True
self['core_server_rpc'] = _comm.get('core-server-rpc', 'http://127.0.0.1:52080/rpc')
return True

View File

@ -1,7 +1,4 @@
# -*- coding: utf-8 -*-
APP_MODE_UNKNOWN = 0
APP_MODE_NORMAL = 1
APP_MODE_INSTALL = 2
APP_MODE_UPGRADE = 3
APP_MODE_MAINTENANCE = 4
APP_MODE_MAINTENANCE = 2

View File

@ -37,12 +37,11 @@ class WebServerCore:
cfg.res_path = os.path.abspath(options['res_path'])
cfg.cfg_path = os.path.abspath(options['cfg_path'])
cfg.app_mode = APP_MODE_NORMAL
# cfg.app_mode = APP_MODE_UNKNOWN
# if os.path.exists(os.path.join(cfg.cfg_path, 'maintenance-mode')):
# cfg.app_mode = APP_MODE_UPGRADE
# else:
# cfg.app_mode = APP_MODE_NORMAL
# cfg.app_mode = APP_MODE_NORMAL
if os.path.exists(os.path.join(cfg.cfg_path, 'maintenance-mode')):
cfg.app_mode = APP_MODE_MAINTENANCE
else:
cfg.app_mode = APP_MODE_NORMAL
_cfg_file = os.path.join(cfg.cfg_path, 'web.ini')
if not cfg.load_web(_cfg_file):
@ -58,7 +57,8 @@ class WebServerCore:
return False
log.set_attribute(min_level=cfg.log_level, filename=cfg.log_file)
# log.set_attribute(min_level=self['log_level'])
if cfg.debug:
log.set_attribute(trace_error=log.TRACE_ERROR_FULL)
# 尝试通过CORE-JSON-RPC获取core服务的配置主要是ssh/rdp/telnet的端口
self._get_core_server_config()
@ -109,16 +109,13 @@ class WebServerCore:
# 'debug': True,
# Debug Mode.
'compiled_template_cache': False,
'static_hash_cache': False,
'compiled_template_cache': True,
'static_hash_cache': True,
}
# TODO: 配置文件中应该增加 debug 选项
# if cfg.debug:
# settings['compiled_template_cache'] = False
# settings['static_hash_cache'] = False
# settings['compiled_template_cache'] = False
# settings['static_hash_cache'] = False
if cfg.debug:
settings['compiled_template_cache'] = False
settings['static_hash_cache'] = False
from eom_app.controller import controllers
web_app = tornado.web.Application(controllers, **settings)

View File

@ -98,9 +98,10 @@ class WebSession(threading.Thread):
else:
return _default
def web_session():
"""
取得 SwxSession 的唯一实例
取得Session管理器的唯一实例
:rtype : WebSession
"""

View File

@ -4,11 +4,11 @@ import json
from eom_app.module import user
from eom_common.eomcore.logger import *
from .base import SwxAppHandler, SwxJsonpHandler, SwxAuthJsonHandler
from .base import TPBaseHandler, TPBaseUserAuthHandler, TPBaseJsonHandler, TPBaseUserAuthJsonHandler
from eom_app.app.util import gen_captcha
class LoginHandler(SwxAppHandler):
class LoginHandler(TPBaseHandler):
def get(self):
_user = self.get_current_user()
if _user['id'] == 0:
@ -23,30 +23,33 @@ class LoginHandler(SwxAppHandler):
self.render('auth/login.mako', page_param=json.dumps(param))
class VerifyUser(SwxJsonpHandler):
def get(self):
class VerifyUser(TPBaseJsonHandler):
def post(self):
code = self.get_session('captcha')
if code is None:
self.write_jsonp(-1)
return
captcha = self.get_argument('captcha', None)
username = self.get_argument('username', None)
userpwd = self.get_argument('userpwd', None)
if captcha is None or username is None:
self.write_jsonp(-1)
return
if code.lower() != captcha.lower():
self.write_jsonp(-1)
self.write_json(-1, 'can not get captcha')
return
self.del_session('captcha')
args = self.get_argument('args', None)
if args is not None:
args = json.loads(args)
captcha = args['captcha']
username = args['username']
userpwd = args['userpwd']
else:
self.write_json(-1, 'invalid param')
return
if code.lower() != captcha.lower():
self.write_json(-1, 'invalid captcha')
return
try:
user_id, account_type, nickname = user.verify_user(username, userpwd)
if user_id == 0:
self.write_jsonp(-1)
self.write_json(-1, 'no such user or password.')
return
_user = self.get_session('user')
@ -68,14 +71,14 @@ class VerifyUser(SwxJsonpHandler):
_user['type'] = account_type
self.set_session('user', _user)
return self.write_jsonp(0)
return self.write_json(0)
except:
log.e('can not set session.')
self.write_jsonp(-1)
self.write_json(-1, 'session error.')
class LogoutHandler(SwxAppHandler):
class LogoutHandler(TPBaseUserAuthHandler):
def get(self):
_user = self.get_current_user()
_user['is_login'] = False
@ -84,7 +87,7 @@ class LogoutHandler(SwxAppHandler):
self.redirect('/auth/login')
class GetCaptchaHandler(SwxAppHandler):
class GetCaptchaHandler(TPBaseHandler):
def get(self):
code, img_data = gen_captcha()
self.set_session('captcha', code)
@ -92,26 +95,29 @@ class GetCaptchaHandler(SwxAppHandler):
self.write(img_data)
class VerifyCaptchaHandler(SwxJsonpHandler):
def get(self):
class VerifyCaptchaHandler(TPBaseJsonHandler):
def post(self):
code = self.get_session('captcha')
if code is None:
self.write_jsonp(-1)
self.write_json(-1)
return
captcha = self.get_argument('captcha', None)
if captcha is None:
self.write_jsonp(-1)
args = self.get_argument('args', None)
if args is not None:
args = json.loads(args)
captcha = args['captcha']
else:
self.write_json(-1)
return
if code.lower() != captcha.lower():
self.write_jsonp(-1)
self.write_json(-1)
return
self.write_jsonp(0)
self.write_json(0)
class ModifyPwd(SwxAuthJsonHandler):
class ModifyPwd(TPBaseUserAuthJsonHandler):
def post(self):
args = self.get_argument('args', None)
if args is not None:

View File

@ -17,12 +17,21 @@ from eom_app.app.const import *
cfg = app_cfg()
class SwxBaseHandler(tornado.web.RequestHandler):
class TPBaseHandler(tornado.web.RequestHandler):
"""
所有http请求处理的基类只有极少数的请求如登录维护直接从本类继承其他的所有类均从本类的子类控制权限的类继承
"""
MODE_HTTP = 0
MODE_JSON = 1
# MODE_JSONP = 2
def __init__(self, application, request, **kwargs):
super().__init__(application, request, **kwargs)
self._s_id = None
# self._s_val = dict()
self._mode = self.MODE_HTTP
# self._jsonp_callback = ''
def initialize(self):
template_path = self.get_template_path()
@ -35,10 +44,48 @@ class SwxBaseHandler(tornado.web.RequestHandler):
return template.render(**namespace)
def render(self, template_path, **kwargs):
if self._mode != self.MODE_HTTP:
self.write_json(-1, 'should be web page request.')
return
self.finish(self.render_string(template_path, **kwargs))
def write_json(self, code, message='', data=None):
if self._mode != self.MODE_JSON:
self.write('should be json request.')
self.finish()
return
if not isinstance(code, int):
raise RuntimeError('`code` must be a integer.')
if not isinstance(message, str):
raise RuntimeError('`msg` must be a string.')
if data is None:
data = list()
_ret = {'code': code, 'message': message, 'data': data}
self.set_header("Content-Type", "application/json")
self.write(json_encode(_ret))
self.finish()
def write_raw_json(self, data=None):
if self._mode != self.MODE_JSON:
self.write('should be json request.')
self.finish()
return
if data is None:
data = list()
self.set_header("Content-Type", "application/json")
self.write(json_encode(data))
self.finish()
def prepare(self):
super().prepare()
if self._finished:
return
# if self.application.settings.get("xsrf_cookies"):
# x = self.xsrf_token
@ -76,58 +123,26 @@ class SwxBaseHandler(tornado.web.RequestHandler):
return user
class SwxAppHandler(SwxBaseHandler):
def __init__(self, application, request, **kwargs):
super().__init__(application, request, **kwargs)
def prepare(self):
super().prepare()
if self._finished:
return
if cfg.app_mode == APP_MODE_NORMAL:
return
# self.redirect('/maintenance')
self.render('maintenance/index.mako')
# class TPBaseAppHandler(TPBaseHandler):
# """
# 权限控制:如果处于维护模式,只有管理员登录后方可操作,其他用户均显示维护页面
# """
# def __init__(self, application, request, **kwargs):
# super().__init__(application, request, **kwargs)
#
# def prepare(self):
# super().prepare()
# if self._finished:
# return
#
# if cfg.app_mode == APP_MODE_NORMAL:
# return
#
# # self.redirect('/maintenance')
# self.render('maintenance/index.mako')
class SwxJsonpHandler(SwxAppHandler):
def __init__(self, application, request, **kwargs):
super().__init__(application, request, **kwargs)
self._js_callback = ''
def prepare(self):
super().prepare()
if self._finished:
return
self._js_callback = self.get_argument('callback', None)
if self._js_callback is None:
raise RuntimeError('no callback in URL param.')
def write_jsonp(self, err_code, data=None):
self.write(self._js_callback)
self.write('({code:')
self.write('{}'.format(err_code))
if data is None:
self.write('})')
self.finish()
return
if not isinstance(data, dict):
raise RuntimeError('jsonp data should be dict.')
self.write(',data:')
self.write(json_encode(data))
self.write('})')
self.finish()
class SwxJsonHandler(SwxAppHandler):
class TPBaseJsonHandler(TPBaseHandler):
"""
所有返回JSON数据的控制器均从本类集成返回的数据格式一律包含三个字段code/msg/data
code: 0=成功其他=失败
@ -137,33 +152,10 @@ class SwxJsonHandler(SwxAppHandler):
def __init__(self, application, request, **kwargs):
super().__init__(application, request, **kwargs)
def write_json(self, code, message='', data=None):
if not isinstance(code, int):
raise RuntimeError('`code` must be a integer.')
if not isinstance(message, str):
raise RuntimeError('`msg` must be a string.')
if data is None:
data = list()
_ret = {'code': code, 'message': message, 'data': data}
self.set_header("Content-Type", "application/json")
self.write(json_encode(_ret))
self.finish()
def write_raw_json(self, data=None):
if data is None:
data = list()
self.set_header("Content-Type", "application/json")
self.write(json_encode(data))
self.finish()
self._mode = self.MODE_JSON
class SwxAuthHandler(SwxAppHandler):
class TPBaseUserAuthHandler(TPBaseHandler):
def __init__(self, application, request, **kwargs):
super().__init__(application, request, **kwargs)
@ -181,9 +173,14 @@ class SwxAuthHandler(SwxAppHandler):
self.redirect('/auth/login?ref={}'.format(x))
else:
self.redirect('/auth/login')
else:
if cfg.app_mode == APP_MODE_MAINTENANCE and user['type'] != 100:
self.render('maintenance/index.mako')
else:
pass
class SwxAdminHandler(SwxAppHandler):
class TPBaseAdminAuthHandler(TPBaseHandler):
def __init__(self, application, request, **kwargs):
super().__init__(application, request, **kwargs)
@ -195,20 +192,21 @@ class SwxAdminHandler(SwxAppHandler):
reference = self.request.uri
user = self.get_current_user()
if user['type'] != 100:
if reference != '/auth/login':
if not user['is_login'] or user['type'] != 100:
if reference != '/auth/login': # 防止循环重定向
x = quote(reference)
self.redirect('/auth/login?ref={}'.format(x))
else:
self.redirect('/auth/login')
else:
if cfg.app_mode == APP_MODE_MAINTENANCE:
# TODO: 如果是维护模式,且尚未建立数据库,则引导用户进入安装界面,否则检查数据库版本,可能引导用户进入升级界面。
self.render('maintenance/index.mako')
else:
pass
# class SwxAuthJsonpHandler(SwxAppHandler):
# def __init__(self, application, request, **kwargs):
# super().__init__(application, request, **kwargs)
class SwxAuthJsonHandler(SwxJsonHandler):
class TPBaseUserAuthJsonHandler(TPBaseJsonHandler):
def __init__(self, application, request, **kwargs):
super().__init__(application, request, **kwargs)
@ -226,8 +224,14 @@ class SwxAuthJsonHandler(SwxJsonHandler):
else:
self.write_json(-99)
else:
if cfg.app_mode == APP_MODE_MAINTENANCE and user['type'] != 100:
self.write_json(-1, 'maintenance mode')
else:
pass
class SwxAdminJsonHandler(SwxJsonHandler):
class TPBaseAdminAuthJsonHandler(TPBaseJsonHandler):
def __init__(self, application, request, **kwargs):
super().__init__(application, request, **kwargs)
@ -239,6 +243,6 @@ class SwxAdminJsonHandler(SwxJsonHandler):
reference = self.request.uri
user = self.get_current_user()
if user['type'] != 100:
if not user['is_login'] or user['type'] != 100:
if reference != '/auth/login':
self.write_json(-99)

View File

@ -2,17 +2,17 @@
from eom_app.app.configs import app_cfg
from eom_app.module import host
from .base import SwxAdminHandler, SwxAdminJsonHandler
from .base import TPBaseAdminAuthHandler, TPBaseAdminAuthJsonHandler
cfg = app_cfg()
class IndexHandler(SwxAdminHandler):
class IndexHandler(TPBaseAdminAuthHandler):
def get(self):
self.render('cert/index.mako')
class GetListHandler(SwxAdminJsonHandler):
class GetListHandler(TPBaseAdminAuthJsonHandler):
def post(self):
_certs = host.get_cert_list()
ret = dict()

View File

@ -2,17 +2,17 @@
from eom_app.app.configs import app_cfg
from eom_app.module import host
from .base import SwxAdminHandler, SwxAdminJsonHandler
from .base import TPBaseAdminAuthHandler, TPBaseAdminAuthJsonHandler
cfg = app_cfg()
class IndexHandler(SwxAdminHandler):
class IndexHandler(TPBaseAdminAuthHandler):
def get(self):
self.render('group/index.mako')
class GetListHandler(SwxAdminJsonHandler):
class GetListHandler(TPBaseAdminAuthJsonHandler):
def post(self):
group_list = host.get_group_list()
ret = dict()

View File

@ -13,7 +13,7 @@ from eom_app.app.util import *
from eom_app.module import host
from eom_common.eomcore.logger import *
from eom_app.app.session import web_session
from .base import SwxAuthHandler, SwxAdminHandler, SwxAuthJsonHandler, SwxAdminJsonHandler
from .base import TPBaseUserAuthHandler, TPBaseAdminAuthHandler, TPBaseUserAuthJsonHandler, TPBaseAdminAuthJsonHandler
cfg = app_cfg()
@ -22,7 +22,7 @@ tmp_auth_id_base = -1
tmp_auth_id_lock = threading.RLock()
class IndexHandler(SwxAuthHandler):
class IndexHandler(TPBaseUserAuthHandler):
def get(self):
_user = self.get_session('user')
if _user is None:
@ -45,7 +45,7 @@ class IndexHandler(SwxAuthHandler):
self.render('host/common_index.mako', page_param=json.dumps(param))
class UploadAndImportHandler(SwxAdminJsonHandler):
class UploadAndImportHandler(TPBaseAdminAuthJsonHandler):
# TODO: 导入操作可能会比较耗时,应该分离导入和获取导入状态两个过程,在页面上可以呈现导入进度,并列出导出成功/失败的项
@tornado.gen.coroutine
@ -208,7 +208,7 @@ class UploadAndImportHandler(SwxAdminJsonHandler):
os.remove(csv_filename)
class GetListHandler(SwxAuthJsonHandler):
class GetListHandler(TPBaseUserAuthJsonHandler):
def post(self):
_user = self.get_session('user')
if _user is None:
@ -279,13 +279,13 @@ class GetListHandler(SwxAuthJsonHandler):
# self.write(json_encode(data))
class GetGrouplist(SwxAuthJsonHandler):
class GetGrouplist(TPBaseUserAuthJsonHandler):
def post(self):
group_list = host.get_group_list()
self.write_json(0, data=group_list)
class UpdateHandler(SwxAuthJsonHandler):
class UpdateHandler(TPBaseUserAuthJsonHandler):
def post(self):
args = self.get_argument('args', None)
if args is not None:
@ -311,7 +311,7 @@ class UpdateHandler(SwxAuthJsonHandler):
self.write_json(-1)
class AddHost(SwxAuthJsonHandler):
class AddHost(TPBaseUserAuthJsonHandler):
def post(self):
args = self.get_argument('args', None)
if args is not None:
@ -334,7 +334,7 @@ class AddHost(SwxAuthJsonHandler):
return
class LockHost(SwxAuthJsonHandler):
class LockHost(TPBaseUserAuthJsonHandler):
def post(self):
args = self.get_argument('args', None)
if args is not None:
@ -359,7 +359,7 @@ class LockHost(SwxAuthJsonHandler):
return
class DeleteHost(SwxAuthJsonHandler):
class DeleteHost(TPBaseUserAuthJsonHandler):
def post(self):
args = self.get_argument('args', None)
if args is not None:
@ -382,7 +382,7 @@ class DeleteHost(SwxAuthJsonHandler):
return
class ExportHostHandler(SwxAdminHandler):
class ExportHostHandler(TPBaseAdminAuthHandler):
def get(self):
self.set_header('Content-Type', 'application/octet-stream')
self.set_header('Content-Disposition', 'attachment; filename=teleport-host-export.csv')
@ -451,7 +451,7 @@ class ExportHostHandler(SwxAdminHandler):
self.finish()
class GetCertList(SwxAuthJsonHandler):
class GetCertList(TPBaseUserAuthJsonHandler):
def post(self):
# args = self.get_argument('args', None)
# if args is not None:
@ -470,7 +470,7 @@ class GetCertList(SwxAuthJsonHandler):
return
class AddCert(SwxAuthJsonHandler):
class AddCert(TPBaseUserAuthJsonHandler):
@tornado.gen.coroutine
def post(self):
args = self.get_argument('args', None)
@ -508,7 +508,7 @@ class AddCert(SwxAuthJsonHandler):
return self.write_json(-1)
class DeleteCert(SwxAuthJsonHandler):
class DeleteCert(TPBaseUserAuthJsonHandler):
def post(self):
args = self.get_argument('args', None)
if args is not None:
@ -531,7 +531,7 @@ class DeleteCert(SwxAuthJsonHandler):
return
class UpdateCert(SwxAuthJsonHandler):
class UpdateCert(TPBaseUserAuthJsonHandler):
@tornado.gen.coroutine
def post(self):
args = self.get_argument('args', None)
@ -570,7 +570,7 @@ class UpdateCert(SwxAuthJsonHandler):
return
class AddGroup(SwxAuthJsonHandler):
class AddGroup(TPBaseUserAuthJsonHandler):
def post(self):
args = self.get_argument('args', None)
if args is not None:
@ -593,7 +593,7 @@ class AddGroup(SwxAuthJsonHandler):
return
class UpdateGroup(SwxAuthJsonHandler):
class UpdateGroup(TPBaseUserAuthJsonHandler):
def post(self):
args = self.get_argument('args', None)
if args is not None:
@ -617,7 +617,7 @@ class UpdateGroup(SwxAuthJsonHandler):
return
class DeleteGroup(SwxAuthJsonHandler):
class DeleteGroup(TPBaseUserAuthJsonHandler):
def post(self):
args = self.get_argument('args', None)
if args is not None:
@ -640,7 +640,7 @@ class DeleteGroup(SwxAuthJsonHandler):
return
class AddHostToGroup(SwxAuthJsonHandler):
class AddHostToGroup(TPBaseUserAuthJsonHandler):
def post(self):
args = self.get_argument('args', None)
if args is not None:
@ -664,7 +664,7 @@ class AddHostToGroup(SwxAuthJsonHandler):
return
class GetSessionId(SwxAuthJsonHandler):
class GetSessionId(TPBaseUserAuthJsonHandler):
@tornado.gen.coroutine
def post(self, *args, **kwargs):
args = self.get_argument('args', None)
@ -704,7 +704,7 @@ class GetSessionId(SwxAuthJsonHandler):
return self.write_json(0, data=data)
class AdminGetSessionId(SwxAuthJsonHandler):
class AdminGetSessionId(TPBaseUserAuthJsonHandler):
@tornado.gen.coroutine
def post(self, *args, **kwargs):
args = self.get_argument('args', None)
@ -765,7 +765,7 @@ class AdminGetSessionId(SwxAuthJsonHandler):
return self.write_json(0, data=data)
class AdminFastGetSessionId(SwxAdminJsonHandler):
class AdminFastGetSessionId(TPBaseAdminAuthJsonHandler):
@tornado.gen.coroutine
def post(self, *args, **kwargs):
args = self.get_argument('args', None)
@ -855,7 +855,7 @@ class AdminFastGetSessionId(SwxAdminJsonHandler):
return self.write_json(0, data=data)
class SysUserList(SwxAuthJsonHandler):
class SysUserList(TPBaseUserAuthJsonHandler):
def post(self, *args, **kwargs):
args = self.get_argument('args', None)
if args is not None:
@ -873,7 +873,7 @@ class SysUserList(SwxAuthJsonHandler):
return self.write_json(0, data=data)
class SysUserAdd(SwxAuthJsonHandler):
class SysUserAdd(TPBaseUserAuthJsonHandler):
@tornado.gen.coroutine
def post(self, *args, **kwargs):
args = self.get_argument('args', None)
@ -909,7 +909,7 @@ class SysUserAdd(SwxAuthJsonHandler):
return self.write_json(0)
class SysUserUpdate(SwxAuthJsonHandler):
class SysUserUpdate(TPBaseUserAuthJsonHandler):
@tornado.gen.coroutine
def post(self, *args, **kwargs):
args = self.get_argument('args', None)
@ -957,7 +957,7 @@ class SysUserUpdate(SwxAuthJsonHandler):
return self.write_json(-1)
class SysUserDelete(SwxAuthJsonHandler):
class SysUserDelete(TPBaseUserAuthJsonHandler):
def post(self, *args, **kwargs):
args = self.get_argument('args', None)
if args is not None:

View File

@ -1,15 +1,15 @@
# -*- coding: utf-8 -*-
import sys
import tornado.ioloop
from .base import SwxBaseHandler, SwxAuthHandler
from .base import TPBaseHandler, TPBaseUserAuthHandler
class IndexHandler(SwxAuthHandler):
class IndexHandler(TPBaseUserAuthHandler):
def get(self):
self.redirect('/host')
class ExitHandler(SwxBaseHandler):
class ExitHandler(TPBaseHandler):
def get(self):
self.write('exit ok')
tornado.ioloop.IOLoop.instance().stop()

View File

@ -1,9 +1,9 @@
# -*- coding: utf-8 -*-
from .base import SwxBaseHandler
from .base import TPBaseHandler
class IndexHandler(SwxBaseHandler):
class IndexHandler(TPBaseHandler):
def get(self):
self.render('maintenance/index.mako')

View File

@ -1,8 +1,8 @@
# -*- coding: utf-8 -*-
from .base import SwxAuthHandler
from .base import TPBaseUserAuthHandler
class IndexHandler(SwxAuthHandler):
class IndexHandler(TPBaseUserAuthHandler):
def get(self):
self.render('pwd/index.mako')

View File

@ -9,7 +9,7 @@ from eom_app.app.configs import app_cfg
# from eom_app.module import host
from eom_app.module import record
from eom_app.module import user
from .base import SwxAdminHandler, SwxAdminJsonHandler
from .base import TPBaseAdminAuthHandler, TPBaseAdminAuthJsonHandler
cfg = app_cfg()
@ -31,7 +31,7 @@ def get_free_space_bytes(folder):
return total_bytes, free_bytes
class LogHandler(SwxAdminHandler):
class LogHandler(TPBaseAdminAuthHandler):
def get(self):
user_list = user.get_user_list()
total_size, free_size = get_free_space_bytes(cfg.data_path)
@ -47,7 +47,7 @@ class LogHandler(SwxAdminHandler):
self.render('log/index.mako', page_param=json.dumps(param))
class RecordHandler(SwxAdminHandler):
class RecordHandler(TPBaseAdminAuthHandler):
def get(self, protocol, record_id):
protocol = int(protocol)
if protocol == 1:
@ -56,7 +56,7 @@ class RecordHandler(SwxAdminHandler):
self.render('log/record.mako', record_id=record_id)
# class PlayRdpHandler(SwxAdminHandler):
# class PlayRdpHandler(TPBaseAdminAuthHandler):
# def get(self, ip, record_id):
# # protocol = int(protocol)
# # if protocol == 1:
@ -68,7 +68,7 @@ class RecordHandler(SwxAdminHandler):
# filename = os.path.join(cfg.data_path, 'replay', 'rdp', '{}'.format(record_id), 'tp-rdp.tpr')
class ComandLogHandler(SwxAdminHandler):
class ComandLogHandler(TPBaseAdminAuthHandler):
def get(self, protocol, record_id):
param = dict()
@ -93,7 +93,7 @@ class ComandLogHandler(SwxAdminHandler):
self.render('log/record-ssh-cmd.mako', page_param=json.dumps(param))
class RecordGetHeader(SwxAdminJsonHandler):
class RecordGetHeader(TPBaseAdminAuthJsonHandler):
def post(self):
args = self.get_argument('args', None)
if args is not None:
@ -111,7 +111,7 @@ class RecordGetHeader(SwxAdminJsonHandler):
self.write_json(0, data=ret)
class RecordGetInfo(SwxAdminJsonHandler):
class RecordGetInfo(TPBaseAdminAuthJsonHandler):
def post(self):
args = self.get_argument('args', None)
if args is not None:
@ -124,7 +124,7 @@ class RecordGetInfo(SwxAdminJsonHandler):
self.write_json(0, data=data)
class DeleteLog(SwxAdminJsonHandler):
class DeleteLog(TPBaseAdminAuthJsonHandler):
# TODO: 用户可能会批量删除大量录像文件因此io操作可能会比较耗时这里应该改为异步方式。
def post(self):
args = self.get_argument('args', None)
@ -136,7 +136,7 @@ class DeleteLog(SwxAdminJsonHandler):
self.write_json(0)
class LogList(SwxAdminJsonHandler):
class LogList(TPBaseAdminAuthJsonHandler):
def post(self):
filter = dict()
order = dict()

View File

@ -10,12 +10,12 @@ from eom_app.app.util import async_post_http
from eom_app.module import host, record
from eom_common.eomcore.logger import *
from .base import SwxJsonHandler
from .base import TPBaseJsonHandler
cfg = app_cfg()
class RpcHandler(SwxJsonHandler):
class RpcHandler(TPBaseJsonHandler):
@tornado.gen.coroutine
def get(self):
_uri = self.request.uri.split('?', 1)

View File

@ -12,7 +12,7 @@ import time
from eom_app.app.configs import app_cfg
from eom_app.module import host
from eom_app.module import set
from .base import SwxAdminHandler, SwxAdminJsonHandler
from .base import TPBaseAdminAuthHandler, TPBaseAdminAuthJsonHandler
cfg = app_cfg()
@ -40,7 +40,7 @@ def get_local_ip():
return iplist
class IndexHandler(SwxAdminHandler):
class IndexHandler(TPBaseAdminAuthHandler):
def get(self):
# static_path = cfg.static_path
# var_js = os.path.join(static_path, 'js', 'var.js')
@ -114,7 +114,7 @@ def restart_service():
t.start()
class UpdateConfig(SwxAdminJsonHandler):
class UpdateConfig(TPBaseAdminAuthJsonHandler):
def post(self):
args = self.get_argument('args', None)
if args is not None:
@ -159,7 +159,7 @@ class UpdateConfig(SwxAdminJsonHandler):
except:
self.write_json(-2)
# class OsOperator(SwxAuthJsonHandler):
# class OsOperator(TPBaseUserAuthJsonHandler):
# def post(self):
# args = self.get_argument('args', None)
# if args is not None:

View File

@ -4,17 +4,17 @@ import json
from eom_app.app.configs import app_cfg
from eom_app.module import host
from eom_app.module import user
from .base import SwxAuthJsonHandler, SwxAdminHandler, SwxAdminJsonHandler
from .base import TPBaseUserAuthJsonHandler, TPBaseAdminAuthHandler, TPBaseAdminAuthJsonHandler
cfg = app_cfg()
class IndexHandler(SwxAdminHandler):
class IndexHandler(TPBaseAdminAuthHandler):
def get(self):
self.render('user/index.mako')
class AuthHandler(SwxAdminHandler):
class AuthHandler(TPBaseAdminAuthHandler):
def get(self, user_name):
group_list = host.get_group_list()
cert_list = host.get_cert_list()
@ -23,7 +23,7 @@ class AuthHandler(SwxAdminHandler):
cert_list=cert_list, user_name=user_name)
class GetListHandler(SwxAdminJsonHandler):
class GetListHandler(TPBaseAdminAuthJsonHandler):
def post(self):
user_list = user.get_user_list()
ret = dict()
@ -33,7 +33,7 @@ class GetListHandler(SwxAdminJsonHandler):
self.write_json(0, data=ret)
class DeleteUser(SwxAuthJsonHandler):
class DeleteUser(TPBaseUserAuthJsonHandler):
def post(self):
args = self.get_argument('args', None)
if args is not None:
@ -56,7 +56,7 @@ class DeleteUser(SwxAuthJsonHandler):
return
class ModifyUser(SwxAuthJsonHandler):
class ModifyUser(TPBaseUserAuthJsonHandler):
def post(self):
args = self.get_argument('args', None)
if args is not None:
@ -82,7 +82,7 @@ class ModifyUser(SwxAuthJsonHandler):
return
class AddUser(SwxAuthJsonHandler):
class AddUser(TPBaseUserAuthJsonHandler):
def post(self):
args = self.get_argument('args', None)
if args is not None:
@ -106,7 +106,7 @@ class AddUser(SwxAuthJsonHandler):
return
class LockUser(SwxAuthJsonHandler):
class LockUser(TPBaseUserAuthJsonHandler):
def post(self):
args = self.get_argument('args', None)
if args is not None:
@ -131,7 +131,7 @@ class LockUser(SwxAuthJsonHandler):
return
class ResetUser(SwxAuthJsonHandler):
class ResetUser(TPBaseUserAuthJsonHandler):
def post(self):
args = self.get_argument('args', None)
if args is not None:
@ -156,7 +156,7 @@ class ResetUser(SwxAuthJsonHandler):
return
class HostList(SwxAuthJsonHandler):
class HostList(TPBaseUserAuthJsonHandler):
def post(self):
filter = dict()
# user = self.get_current_user()
@ -217,7 +217,7 @@ class HostList(SwxAuthJsonHandler):
self.write_json(0, data=ret)
class AllocHost(SwxAuthJsonHandler):
class AllocHost(TPBaseUserAuthJsonHandler):
def post(self):
args = self.get_argument('args', None)
if args is not None:
@ -239,7 +239,7 @@ class AllocHost(SwxAuthJsonHandler):
self.write_json(-2)
class AllocHostUser(SwxAuthJsonHandler):
class AllocHostUser(TPBaseUserAuthJsonHandler):
def post(self):
args = self.get_argument('args', None)
if args is not None:
@ -261,7 +261,7 @@ class AllocHostUser(SwxAuthJsonHandler):
self.write_json(-2)
class DeleteHost(SwxAuthJsonHandler):
class DeleteHost(TPBaseUserAuthJsonHandler):
def post(self):
args = self.get_argument('args', None)
if args is not None:
@ -283,7 +283,7 @@ class DeleteHost(SwxAuthJsonHandler):
self.write_json(-2)
class DeleteHostUser(SwxAuthJsonHandler):
class DeleteHostUser(TPBaseUserAuthJsonHandler):
def post(self):
args = self.get_argument('args', None)
if args is not None:

View File

@ -1,20 +1,34 @@
# -*- coding: utf-8 -*-
import hashlib
from eom_app.app.const import *
from eom_app.app.configs import app_cfg
from .common import *
cfg = app_cfg()
def verify_user(username, userpwd):
sql_exec = get_db_con()
userpwd = hashlib.sha256(userpwd.encode()).hexdigest()
def verify_user(name, password):
_password = hashlib.sha256(password.encode()).hexdigest()
string_sql = 'select account_id, account_type, ' \
'account_name FROM ts_account WHERE account_name =\'{}\' AND account_pwd = \'{}\''.format(username, userpwd)
'account_name FROM ts_account WHERE account_name =\'{}\' AND account_pwd = \'{}\''.format(name, _password)
sql_exec = get_db_con()
db_ret = sql_exec.ExecProcQuery(string_sql)
if db_ret is None:
# 特别地,如果无法取得数据库连接,有可能是新安装的系统,尚未建立数据库,此时应该处于维护模式
# 因此可以特别地处理用户验证用户名admin密码admin可以登录为管理员
if cfg.app_mode == APP_MODE_MAINTENANCE:
if name == 'admin' and password == 'admin':
return 1, 100, 'admin'
else:
return 0, 0, ''
if len(db_ret) != 1:
return 0, 0, ''
user_id, account_type, username = db_ret[0]
return user_id, account_type, username
user_id, account_type, name = db_ret[0]
return user_id, account_type, name
def modify_pwd(old_pwd, new_pwd, user_id):

View File

@ -1,203 +0,0 @@
# -*- coding: utf-8 -*-
"""
运行环境检测
"""
import os
import sys
import platform
from eom_common.common.const import *
from eom_common.eomcore.logger import log
from . import utils
class EomEnvBase(object):
def __init__(self):
self._os_type = OS_UNKNOWN
self._linux_dist = OS_LINUX_UNKNOWN
self._os_name = 'unknown'
self._os_id = 0 # 0 = unknown, 1 = windows, 200=Linux, 201=Ubuntu...
# # 脚本是由Python运行还是由我们自己的主程序运行
self._is_self_exec = False
#
# 是否运行于管理员身份
self._is_run_as_root = False
#
self._app_path = ''
self._conf_path = ''
self._log_path = ''
self._data_path = ''
self._check()
# def init(self, app_path):
# self._app_path = app_path
# self._conf_path = os.path.join(self._app_path, 'conf')
# # self._log_path = os.path.join(self._app_path, 'log')
def _check(self):
# 判断操作系统
if 'win32' == sys.platform:
self._os_type = OS_WIN32
self._os_name = 'windows'
self._os_id = 1
elif 'linux' == sys.platform:
self._os_type = OS_LINUX
self._os_name = 'linux'
self._os_id = 200
elif 'darwin' == sys.platform:
self._os_type = OS_MAC
self._os_name = 'macos'
self._os_id = 300
else:
log.e('[ERROR] Can not detect system type.\n')
return
# 如果是Linux判断其发行版
if OS_LINUX == self._os_type:
(dist, ver, sys_id) = platform.dist()
dist = dist.lower()
if 'centos' == dist:
self._linux_dist = OS_LINUX_CENTOS
self._os_id = 201
elif 'ubuntu' == dist:
self._linux_dist = OS_LINUX_UBUNTU
self._os_id = 202
elif 'debian' == dist:
self._linux_dist = OS_LINUX_DEBIAN
self._os_id = 203
elif 'redhat' == dist:
self._linux_dist = OS_LINUX_REDHAT
self._os_id = 204
elif 'gentoo' == dist:
self._linux_dist = OS_LINUX_GENTOO
self._os_id = 205
else:
log.w('[WARNING] Can not detect linux distribution, try default settings.\n')
self._linux_dist = OS_LINUX_DEFAULT
# 判断宿主程序是python还是我们自己的主程序
exec_names = os.path.split(sys.executable)
# print(sys.executable)
if 'python3' == exec_names[1] or 'python.exe' == exec_names[1]:
self._is_self_exec = False
else:
self._is_self_exec = True
# 判断是否是以root身份运行
if self._os_type == OS_WIN32:
# 在windows平台没有直接的方式可以尝试在特定目录下创建文件然后根据成功与否来判断
tmp_file = '%s\\System32\\6A5D77DDFCFB40CEB26A8444EEC5757E_%s.tmp' % (os.getenv('SystemRoot'), utils.gen_random(4))
try:
f = open(tmp_file, 'w')
f.close()
os.remove(tmp_file)
self._is_run_as_root = True
except IOError:
pass
else:
if 0 == os.getuid():
self._is_run_as_root = True
# # 确定路径
# tmp = os.path.abspath(os.path.join(os.path.dirname(__file__), '..'))
# if tmp[-4:] == '.zip':
# self._app_path = os.path.abspath(os.path.join(tmp, '..', '..'))
# else:
# self._app_path = os.path.abspath(os.path.join(tmp, '..'))
# self._conf_path = os.path.join(self._app_path, 'conf')
def is_self_exec(self):
return self._is_self_exec
def is_root(self):
return self._is_run_as_root
def get_os_type(self):
return self._os_type
def get_os_name(self):
return self._os_name
def get_os_id(self):
return self._os_id
def is_windows(self):
return True if self._os_type == OS_WIN32 else False
def is_macos(self):
return True if self._os_type == OS_MAC else False
def is_linux(self):
return True if self._os_type == OS_LINUX else False
def get_linux_dist(self):
return self._linux_dist
def is_ubuntu(self):
return True if self._linux_dist == OS_LINUX_UBUNTU else False
def is_centos(self):
return True if self._linux_dist == OS_LINUX_CENTOS else False
def is_debian(self):
return True if self._linux_dist == OS_LINUX_DEBIAN else False
def is_redhat(self):
return True if self._linux_dist == OS_LINUX_REDHAT else False
def is_gentoo(self):
return True if self._linux_dist == OS_LINUX_GENTOO else False
# def get_log_file_path(self):
# if self.is_windows():
# path = os.path.join(self.app_path, 'log', 'eom-agent')
# elif self.is_macos():
# path = '/var/log/eom-agent'
# else:
# path = '/var/log/eom-agent'
#
# return path
def log_path(self):
return self._log_path
@property
def app_path(self):
"""
返回的路径是app脚本文件所在路径的上一级路径可用于合成logconf等路径
:rtype : str
"""
return self._app_path
@property
def conf_path(self):
return self._conf_path
@property
def data_path(self):
return self._data_path
#
#
# # eom_env = EomEnv()
# # del EomEnv
# eom_env = None
#
#
# def get_env():
# """
#
# :rtype : EomEnv
# """
# global eom_env
# if eom_env is None:
# eom_env = EomEnv()
# # del EomEnv
# return eom_env

View File

@ -1,20 +1,9 @@
# coding=utf-8
# !/usr/bin/env python
# -------------------------------------------------------------------------------
# Name: pymssqlTest.py
# Purpose: 测试 pymssql库该库到这里下载http://www.lfd.uci.edu/~gohlke/pythonlibs/#pymssql
#
# Author: scott
#
# Created: 04/02/2012
# -------------------------------------------------------------------------------
# -*- coding: utf-8 -*-
import pymysql
import threading
from .logger import *
# import logic.config_file
# eom_comm_conf = logic.config_file.get_comm_conf()
mysql_pool = None

View File

@ -28,6 +28,8 @@ class eom_sqlite:
self._conn = None
def connect(self):
if not os.path.exists(self._db_file):
return None
try:
self._conn = sqlite3.connect(self._db_file)
except:

View File

@ -10,7 +10,7 @@ import traceback
__all__ = ['log',
'CR_DEBUG', 'CR_VERBOSE', 'CR_INFO', 'CR_WARN', 'CR_ERROR',
'LOG_DEBUG', 'LOG_VERBOSE', 'LOG_INFO', 'LOG_WARN', 'LOG_ERROR', 'TRACE_ERROR_NONE', 'TRACE_ERROR_FULL']
'LOG_DEBUG', 'LOG_VERBOSE', 'LOG_INFO', 'LOG_WARN', 'LOG_ERROR']
LOG_DEBUG = 0
LOG_VERBOSE = 1
@ -32,9 +32,6 @@ try:
except ImportError:
pass
TRACE_ERROR_NONE = 0
TRACE_ERROR_FULL = 999999
# ======================================
# 颜色
# ======================================
@ -95,6 +92,9 @@ class EomLogger:
:type _win_color : Win32ColorConsole
"""
TRACE_ERROR_NONE = 0
TRACE_ERROR_FULL = 999999
def __init__(self):
atexit.register(self.finalize)
@ -104,7 +104,7 @@ class EomLogger:
# self._end = '\n'
self._min_level = LOG_INFO # 大于等于此值的日志信息才会记录
self._trace_error = TRACE_ERROR_NONE # 记录错误信息时,是否追加记录调用栈
self._trace_error = self.TRACE_ERROR_NONE # 记录错误信息时,是否追加记录调用栈
self._log_datetime = True # 是否记录日志时间
self._file_handle = None # 日志文件的句柄为None时表示不记录到文件
@ -257,7 +257,7 @@ class EomLogger:
self._console_set_color(CR_ERROR)
self._do_log(LOG_ERROR, *args, **kwargs)
if self._trace_error == TRACE_ERROR_NONE:
if self._trace_error == self.TRACE_ERROR_NONE:
return
s = traceback.extract_stack()

View File

@ -1,152 +0,0 @@
# -*- coding: utf-8 -*-
"""
执行系统命令的模块
"""
import subprocess
from .logger import *
class SysExec:
def __init__(self, cmd, line_processor=None):
self.__cmd = cmd
self.__process_ret = 0
self.__console_output = bytes()
self.__line_processor = line_processor
def get_exec_ret(self):
return self.__process_ret
def get_console_output(self):
return self.__console_output
def run(self, direct_output=False, output_codec=None):
# 注意output_codec在windows默认为gb2312其他平台默认utf8
if output_codec is None:
if env.is_windows():
output_codec = 'gb2312'
else:
output_codec = 'utf8'
p = None
"""type: subprocess.Popen"""
if env.is_windows():
try:
p = subprocess.Popen(self.__cmd, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
except WindowsError as e:
self.__process_ret = e.errno
msg = 'Unknown error.'
if 2 == e.errno:
msg = 'The system cannot find the file specified.'
elif 3 == e.errno:
msg = 'The system cannot find the path specified.'
elif 5 == e.errno:
msg = 'Access is denied.'
elif 13 == e.errno:
msg = 'The process cannot access the file because it is being used by another process.'
self.__console_output = msg.encode(output_codec)
return
except:
msg = 'Unknown error.'
self.__process_ret = 999
self.__console_output = msg.encode(output_codec)
return
else:
try:
# Test under Mac, shell must be True.
p = subprocess.Popen(self.__cmd, close_fds=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
except:
msg = 'Unknown error.'
self.__process_ret = 999
self.__console_output = msg.encode(output_codec)
f = p.stdout
while True:
line = f.readline()
if 0 == len(line):
break
# if '\n' == line[-1]:
# line = line[:-1]
if line[-2:] == '\r\n':
line = line[:-2]
line += '\n'
if line[-1:] == '\r':
line = line[:-1]
line += '\n'
if self.__line_processor is not None:
self.__line_processor(line)
if direct_output:
log.d(line.decode(output_codec))
self.__console_output += line
# # 捕获输出的字符串在内部使用时先转换为unicode再根据需要转为其他编码格式
# # 例如存储时总是转换为utf-8输出时在Win平台上转换为gb2312其他平台上会是utf-8.
# _line = None
# if const.CONSOLE_WIN_CMD == self.console_type:
# _line = unicode(line, output_codec)
# else:
# log.v('tab\n')
# _line = utf8_coder.decode(line)[0]#unicode(line, 'utf-8')
# if direct_output == True:
# log.cap(_line)
# strOutput += utf8_coder.encode(_line)[0]#_line.encode('utf-8')
self.__process_ret = p.wait()
# if bCompareRet:
# if retWanted != ret:
# self.error("\nExecute command returned %d, but we wanted %d.\n\n" % (ret, retWanted))
# print(self.__console_output.decode(output_codec))
return
def start(self):
# Start a command and return, not wait it end.
if env.is_windows():
try:
subprocess.Popen(self.__cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
except OSError as e:
self.__process_ret = e.errno
# msg = 'Unknown error.'
# if 2 == e.errno:
# msg = 'The system cannot find the file specified.'
# elif 3 == e.errno:
# msg = 'The system cannot find the path specified.'
# elif 5 == e.errno:
# msg = 'Access is denied.'
# elif 13 == e.errno:
# msg = 'The process cannot access the file because it is being used by another process.'
#
# self.__console_output = msg.encode(output_codec)
return False
except:
# msg = 'Unknown error.'
self.__process_ret = 999
# self.__console_output = msg.encode(output_codec)
return False
else:
try:
subprocess.Popen(self.__cmd, close_fds=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT, shell=True)
except:
# msg = 'Unknown error.'
self.__process_ret = 999
# self.__console_output = msg.encode(output_codec)
return False
return True

View File

@ -1,143 +0,0 @@
# -*- coding: utf-8 -*-
import ctypes
import os
import struct
from ctypes import windll, wintypes
# FSCTL_GET_REPARSE_POINT = 0x900a8
#
# FILE_ATTRIBUTE_READONLY = 0x0001
# FILE_ATTRIBUTE_HIDDEN = 0x0002
# FILE_ATTRIBUTE_DIRECTORY = 0x0010
# FILE_ATTRIBUTE_NORMAL = 0x0080
FILE_ATTRIBUTE_REPARSE_POINT = 0x0400
#
# GENERIC_READ = 0x80000000
# GENERIC_WRITE = 0x40000000
# OPEN_EXISTING = 3
# FILE_READ_ATTRIBUTES = 0x80
# FILE_FLAG_OPEN_REPARSE_POINT = 0x00200000
# INVALID_HANDLE_VALUE = wintypes.HANDLE(-1).value
#
# INVALID_FILE_ATTRIBUTES = 0xFFFFFFFF
#
# # FILE_FLAG_OPEN_REPARSE_POINT = 2097152
# FILE_FLAG_BACKUP_SEMANTICS = 33554432
# # FILE_FLAG_OPEN_REPARSE_POINT | FILE_FLAG_BACKUP_SEMANTI
# FILE_FLAG_REPARSE_BACKUP = 35651584
GetFileAttributes = windll.kernel32.GetFileAttributesW
# _CreateFileW = windll.kernel32.CreateFileW
# _DevIoCtl = windll.kernel32.DeviceIoControl
# _DevIoCtl.argtypes = [
# wintypes.HANDLE, # HANDLE hDevice
# wintypes.DWORD, # DWORD dwIoControlCode
# wintypes.LPVOID, # LPVOID lpInBuffer
# wintypes.DWORD, # DWORD nInBufferSize
# wintypes.LPVOID, # LPVOID lpOutBuffer
# wintypes.DWORD, # DWORD nOutBufferSize
# ctypes.POINTER(wintypes.DWORD), # LPDWORD lpBytesReturned
# wintypes.LPVOID] # LPOVERLAPPED lpOverlapped
# _DevIoCtl.restype = wintypes.BOOL
def islink(path):
assert os.path.isdir(path), path
if GetFileAttributes(path) & FILE_ATTRIBUTE_REPARSE_POINT:
return True
else:
return False
#
# def DeviceIoControl(hDevice, ioControlCode, input, output):
# # DeviceIoControl Function
# # http://msdn.microsoft.com/en-us/library/aa363216(v=vs.85).aspx
# if input:
# input_size = len(input)
# else:
# input_size = 0
# if isinstance(output, int):
# output = ctypes.create_string_buffer(output)
# output_size = len(output)
# assert isinstance(output, ctypes.Array)
# bytesReturned = wintypes.DWORD()
# status = _DevIoCtl(hDevice, ioControlCode, input,
# input_size, output, output_size, bytesReturned, None)
# print("status(%d)" % status)
# if status != 0:
# return output[:bytesReturned.value]
# else:
# return None
#
#
# def CreateFile(path, access, sharemode, creation, flags):
# return _CreateFileW(path, access, sharemode, None, creation, flags, None)
#
#
# SymbolicLinkReparseFormat = "LHHHHHHL"
# SymbolicLinkReparseSize = struct.calcsize(SymbolicLinkReparseFormat);
#
#
# def readlink(path):
# """ Windows readlink implementation. """
# # This wouldn't return true if the file didn't exist, as far as I know.
# assert islink(path)
# assert type(path) == unicode
#
# # Open the file correctly depending on the string type.
# hfile = CreateFile(path, GENERIC_READ, 0, OPEN_EXISTING,
# FILE_FLAG_REPARSE_BACKUP)
# # MAXIMUM_REPARSE_DATA_BUFFER_SIZE = 16384 = (16*1024)
# buffer = DeviceIoControl(hfile, FSCTL_GET_REPARSE_POINT, None, 16384)
# CloseHandle(hfile)
#
# # Minimum possible length (assuming length of the target is bigger than 0)
# if not buffer or len(buffer) < 9:
# return None
#
# # Parse and return our result.
# # typedef struct _REPARSE_DATA_BUFFER {
# # ULONG ReparseTag;
# # USHORT ReparseDataLength;
# # USHORT Reserved;
# # union {
# # struct {
# # USHORT SubstituteNameOffset;
# # USHORT SubstituteNameLength;
# # USHORT PrintNameOffset;
# # USHORT PrintNameLength;
# # ULONG Flags;
# # WCHAR PathBuffer[1];
# # } SymbolicLinkReparseBuffer;
# # struct {
# # USHORT SubstituteNameOffset;
# # USHORT SubstituteNameLength;
# # USHORT PrintNameOffset;
# # USHORT PrintNameLength;
# # WCHAR PathBuffer[1];
# # } MountPointReparseBuffer;
# # struct {
# # UCHAR DataBuffer[1];
# # } GenericReparseBuffer;
# # } DUMMYUNIONNAME;
# # } REPARSE_DATA_BUFFER, *PREPARSE_DATA_BUFFER;
#
# # Only handle SymbolicLinkReparseBuffer
# (tag, dataLength, reserver, SubstituteNameOffset, SubstituteNameLength,
# PrintNameOffset, PrintNameLength,
# Flags) = struct.unpack(SymbolicLinkReparseFormat,
# buffer[:SymbolicLinkReparseSize])
# print(tag, dataLength, reserver, SubstituteNameOffset, SubstituteNameLength)
# start = SubstituteNameOffset + SymbolicLinkReparseSize
# actualPath = buffer[start: start + SubstituteNameLength].decode("utf-16")
# # This utf-16 string is null terminated
# index = actualPath.find(u"\0")
# assert index > 0
# if index > 0:
# actualPath = actualPath[:index]
# if actualPath.startswith(u"?\\"):
# return actualPath[2:]
# else:
# return actualPath

View File

@ -1,139 +0,0 @@
# -*- coding: utf-8 -*-
import zipfile
import os
# class ZFile(object):
# def __init__(self, filename, mode='r', basedir=''):
# self.filename = filename
# self.mode = mode
# if self.mode in ('w', 'a'):
# self.zfile = zipfile.ZipFile(filename, self.mode, compression=zipfile.ZIP_DEFLATED)
# else:
# self.zfile = zipfile.ZipFile(filename, self.mode)
# self.basedir = basedir
# if not self.basedir:
# self.basedir = os.path.dirname(filename)
#
# def addfile(self, path, arcname=None):
# path = path.replace('//', '/')
# if not arcname:
# if path.startswith(self.basedir):
# arcname = path[len(self.basedir):]
# else:
# arcname = ''
# self.zfile.write(path, arcname)
#
# def addfiles(self, paths):
# for path in paths:
# if isinstance(path, tuple):
# self.addfile(*path)
# else:
# self.addfile(path)
#
# def close(self):
# self.zfile.close()
#
# def extract_to(self, path):
# for p in self.zfile.namelist():
# self.extract(p, path)
#
# def extract(self, filename, path):
# if not filename.endswith('/'):
# strtemp = type(filename)
# # filename = filename.encode()
# # filename = filename.decode('gbk')
# # filename.
# if sys.getfilesystemencoding() == 'mbcs':
# filename = filename.decode('mbcs')
# f = os.path.join(path, filename)
# dir = os.path.dirname(f)
# if not os.path.exists(dir):
# os.makedirs(dir)
# # file(f, 'wb').write(self.zfile.read(filename))
# file_object = open(f, 'wb')
# file_object.write(self.zfile.read(filename))
# file_object.close()
#
#
# def create(zfile, files):
# z = ZFile(zfile, 'w')
# z.addfiles(files)
# z.close()
#
#
# def extract(zfile, path):
# z = ZFile(zfile)
# z.extract_to(path)
# z.close()
def zip_dir(dirname, zipfilename):
ret = False
filelist = []
if os.path.isfile(dirname):
item = os.path.split(dirname)
dirname = item[0]
root = dirname
name = item[1]
filelist.append(os.path.join(root, name))
else:
for root, dirs, files in os.walk(dirname):
for name in files:
filelist.append(os.path.join(root, name))
if os.path.exists(zipfilename):
os.remove(zipfilename)
zf = zipfile.ZipFile(zipfilename, "w", zipfile.zlib.DEFLATED)
try:
for tar in filelist:
arcname = tar[len(dirname):]
# print arcname
zf.write(tar, arcname)
ret = True
except Exception as e:
ret = False
finally:
zf.close()
return ret
def unzip_file(zipfilename, unziptodir):
ret = False
if not os.path.exists(unziptodir):
os.makedirs(unziptodir, 0o777)
zfobj = zipfile.ZipFile(zipfilename)
try:
for name in zfobj.namelist():
name = name.replace('\\', '/')
if name.endswith('/'):
os.mkdir(os.path.join(unziptodir, name))
else:
ext_filename = os.path.join(unziptodir, name)
ext_dir = os.path.dirname(ext_filename)
if not os.path.exists(ext_dir):
os.mkdir(ext_dir, 0o777)
outfile = open(ext_filename, 'wb')
outfile.write(zfobj.read(name))
outfile.close()
ret = True
except Exception as e:
ret = False
finally:
zfobj.close()
return ret
# if __name__ == '__main__':
# try:
# # create('d:\\5.zip', 'd:\\1\\2.txt')
# # zip_dir('d:\\1\\', 'd:\\5.zip')
# # zip_dir('d:\\1\\2.txt', 'd:\\5.zip')
# unzip_file('d:\\5.zip', 'c:\\3\\3\\')
# # temp = sys.getfilesystemencoding()
# # extract('d:\\1.zip','c:\\')
# except Exception as e:
# temp = str(e)
# pass

View File

@ -9,7 +9,7 @@ from eom_env import *
from eom_common.eomcore.eom_sqlite import get_sqlite_pool
from eom_common.eomcore.logger import *
log.set_attribute(min_level=LOG_DEBUG, log_datetime=False, trace_error=TRACE_ERROR_FULL)
log.set_attribute(min_level=LOG_DEBUG, log_datetime=False, trace_error=log.TRACE_ERROR_FULL)
db_file = os.path.join(PATH_DATA, 'ts_db.db')

View File

@ -86,15 +86,9 @@ ywl.create_app = function () {
show_op_box('wait', '<i class="fa fa-circle-o-notch fa-spin"></i> 正在进行身份认证,请稍候...');
// 先判断一下captcha是否正确如果不正确拒绝登录
$.ajax({
type: 'GET',
url: '/auth/verify-captcha',
jsonp: "callback",
//jsonpCallback:"login_ret",
data: {captcha: str_captcha},
dataType: 'jsonp',
success: function (data) {
if (data.code == 0) {
ywl.ajax_post_json('/auth/verify-captcha', {captcha: str_captcha},
function (ret) {
if (ret.code == 0) {
// 验证成功
hide_op_box();
show_op_box('wait', '<i class="fa fa-circle-o-notch fa-spin"></i> 正在登录TELEPORT请稍候...');
@ -103,48 +97,98 @@ ywl.create_app = function () {
else {
hide_op_box();
show_op_box('error', '验证码错误!');
// renew the captcha.
//change_captcha();
$('#captcha_image').attr('src', '/auth/get-captcha?' + Math.random());
$('#captcha').focus().val('');
}
$('#btn_login').removeAttr('disabled');
},
error: function () {
},
function () {
hide_op_box();
show_op_box('error', '很抱歉,无法连接服务器!请稍后再试一次!');
$('#btn_login').removeAttr('disabled');
}
});
}
);
// $.ajax({
// type: 'GET',
// url: '/auth/verify-captcha',
// jsonp: "callback",
// //jsonpCallback:"login_ret",
// data: {captcha: str_captcha},
// dataType: 'jsonp',
// success: function (data) {
// if (data.code == 0) {
// // 验证成功
// hide_op_box();
// show_op_box('wait', '<i class="fa fa-circle-o-notch fa-spin"></i> 正在登录TELEPORT请稍候...');
// _app.do_account_login(str_username, str_password, str_captcha);
// }
// else {
// hide_op_box();
// show_op_box('error', '验证码错误!');
// // renew the captcha.
// //change_captcha();
// $('#captcha_image').attr('src', '/auth/get-captcha?' + Math.random());
// $('#captcha').focus().val('');
// }
//
// $('#btn_login').removeAttr('disabled');
// },
// error: function () {
// hide_op_box();
// show_op_box('error', '很抱歉,无法连接服务器!请稍后再试一次!');
// $('#btn_login').removeAttr('disabled');
// }
// });
};
_app.do_account_login = function (username, userpwd, captcha) {
$.ajax({
type: 'GET',
url: '/auth/verify-user',
jsonp: "callback",
data: {username: username, userpwd: userpwd, captcha: captcha},
dataType: 'jsonp',
success: function (data) {
if (data.code == 0) {
ywl.ajax_post_json('/auth/verify-user', {username: username, userpwd: userpwd, captcha: captcha},
function (ret) {
if (ret.code == 0) {
// 验证成功
window.location.href = ywl.page_options.ref;
}
else {
hide_op_box();
show_op_box('error', '无法登录TELEPORT');
console.log(ret);
}
$('#btn_login').removeAttr('disabled');
},
error: function () {
},
function () {
hide_op_box();
show_op_box('error', '很抱歉,无法连接服务器!请稍后再试一次!');
$('#btn_login').removeAttr('disabled');
}
});
}
);
// $.ajax({
// type: 'GET',
// url: '/auth/verify-user',
// jsonp: "callback",
// data: {username: username, userpwd: userpwd, captcha: captcha},
// dataType: 'jsonp',
// success: function (data) {
// if (data.code == 0) {
// // 验证成功
// window.location.href = ywl.page_options.ref;
// }
// else {
// hide_op_box();
// show_op_box('error', '无法登录TELEPORT');
// }
//
// $('#btn_login').removeAttr('disabled');
// },
// error: function () {
// hide_op_box();
// show_op_box('error', '很抱歉,无法连接服务器!请稍后再试一次!');
// $('#btn_login').removeAttr('disabled');
// }
// });
};
return _app;