修正:MySQL长时间未通讯会丢失连接;改进:导入导出数据库时增加对数据库版本的检查;改进:页面上总是显示teleport服务器的时间(配合检查身份认证器的时间是否同步);

pull/32/merge
Apex Liu 2017-06-04 18:07:50 +08:00
parent 1a3f7f3378
commit 7208f39aa0
12 changed files with 260 additions and 272 deletions

View File

@ -156,11 +156,12 @@ class BaseAppConfig(dict):
self._on_init()
def __getattr__(self, name):
if name in self['_kvs']:
return self['_kvs'][name]
_name = name.replace('-', '_')
if _name in self['_kvs']:
return self['_kvs'][_name]
else:
if name in self['_kvs']['_']:
return self['_kvs']['_'][name]
if _name in self['_kvs']['_']:
return self['_kvs']['_'][_name]
else:
return AttrDict()
@ -168,7 +169,7 @@ class BaseAppConfig(dict):
x = key.split('::')
if 1 == len(x):
_sec = '_'
_key = x[0]
_key = x[0].replace('-', '_')
elif 2 == len(x):
_sec = x[0].replace('-', '_')
_key = x[1].replace('-', '_')
@ -199,7 +200,7 @@ class BaseAppConfig(dict):
x = key.split('::')
if 1 == len(x):
_sec = '_'
_key = x[0]
_key = x[0].replace('-', '_')
elif 2 == len(x):
_sec = x[0].replace('-', '_')
_key = x[1].replace('-', '_')
@ -215,7 +216,7 @@ class BaseAppConfig(dict):
x = key.split('::')
if 1 == len(x):
_sec = '_'
_key = x[0]
_key = x[0].replace('-', '_')
elif 2 == len(x):
_sec = x[0].replace('-', '_')
_key = x[1].replace('-', '_')
@ -311,10 +312,10 @@ class BaseAppConfig(dict):
x = key.split('::')
if 1 == len(x):
_sec = '_'
_key = x[0]
_key = x[0].replace('-', '_')
elif 2 == len(x):
_sec = x[0]
_key = x[1]
_sec = x[0].replace('-', '_')
_key = x[1].replace('-', '_')
else:
return def_value, False
@ -322,16 +323,20 @@ class BaseAppConfig(dict):
return def_value, False
if _key not in self['_kvs'][_sec]:
return def_value, False
if self['_kvs'][_sec][_key] is None:
return def_value, False
return str(self['_kvs'][_sec][_key]), True
def get_int(self, key, def_value=-1):
x = key.split('::')
if 1 == len(x):
_sec = '_'
_key = x[0]
_key = x[0].replace('-', '_')
elif 2 == len(x):
_sec = x[0]
_key = x[1]
_sec = x[0].replace('-', '_')
_key = x[1].replace('-', '_')
else:
return def_value, False
@ -340,6 +345,9 @@ class BaseAppConfig(dict):
if _key not in self['_kvs'][_sec]:
return def_value, False
if self['_kvs'][_sec][_key] is None:
return def_value, False
try:
return int(self['_kvs'][_sec][_key]), True
except ValueError as e:
@ -350,10 +358,10 @@ class BaseAppConfig(dict):
x = key.split('::')
if 1 == len(x):
_sec = '_'
_key = x[0]
_key = x[0].replace('-', '_')
elif 2 == len(x):
_sec = x[0]
_key = x[1]
_sec = x[0].replace('-', '_')
_key = x[1].replace('-', '_')
else:
return def_value, False
@ -362,6 +370,9 @@ class BaseAppConfig(dict):
if _key not in self['_kvs'][_sec]:
return def_value, False
if self['_kvs'][_sec][_key] is None:
return def_value, False
tmp = str(self['_kvs'][_sec][_key]).lower()
if tmp in ['yes', 'true', '1']:
@ -415,14 +426,6 @@ class AppConfig(BaseAppConfig):
self.set_default('database::sqlite-file', None,
'sqlite-file=/var/lib/teleport/data/ts_db.db'
)
# self.set_default('database::mysql-host', None,
# 'mysql-host=127.0.0.1\n'
# 'mysql-port=3306\n'
# 'mysql-db=teleport\n'
# 'mysql-prefix=tp_\n'
# 'mysql-user=teleport\n'
# 'mysql-password=password'
# )
self.set_default('database::mysql-host', '127.0.0.1', 'mysql-host=127.0.0.1')
self.set_default('database::mysql-port', 3306, 'mysql-port=3306')
self.set_default('database::mysql-db', 'teleport', 'mysql-db=teleport')
@ -507,7 +510,7 @@ class AppConfig(BaseAppConfig):
self.set_kv('database::mysql-password', _tmp_str)
_log_file, ok = self.get_str('common::log-file')
if ok:
if ok and _log_file:
self.log_path = os.path.abspath(os.path.dirname(_log_file))
else:
_log_file = os.path.join(self.log_path, 'tpweb.log')

View File

@ -101,7 +101,8 @@ class WebServerCore:
'static_hash_cache': False,
}
from eom_app.controller import controllers
from eom_app.controller import controllers, fix_controller
fix_controller()
web_app = tornado.web.Application(controllers, **settings)
server = tornado.httpserver.HTTPServer(web_app)
@ -118,9 +119,12 @@ class WebServerCore:
# 启动session超时管理
web_session().start()
# 启动数据库定时事务例如MySQL防丢失连接
get_db().start_keep_alive()
tornado.ioloop.IOLoop.instance().start()
get_db().stop_keep_alive()
web_session().stop()
return 0

View File

@ -46,7 +46,13 @@ def export_database(db):
elif db.db_type == db.DB_TYPE_MYSQL:
ret.append('-- export from MySQL Database')
else:
return 'Unknown Database Type'
return '未知的数据库类型', False
db_ret = db.query('SELECT `value` FROM `{}config` WHERE `name`="db_ver";'.format(db.table_prefix))
if db_ret is None or 0 == len(db_ret):
return '无法获取数据库版本', False
else:
ret.append('-- DATABASE VERSION {}'.format(db_ret[0][0]))
_fields = ['account_id', 'account_type', 'account_name', 'account_pwd', 'account_status', 'account_lock', 'account_desc', 'oath_secret']
ret.append(_export_table(db, 'account', _fields))
@ -65,4 +71,4 @@ def export_database(db):
_fields = ['id', 'session_id', 'account_name', 'host_ip', 'host_port', 'sys_type', 'auth_type', 'protocol', 'user_name', 'ret_code', 'begin_time', 'end_time', 'log_time']
ret.append(_export_table(db, 'log', _fields))
return '\r\n'.join(ret)
return '\r\n'.join(ret), True

View File

@ -530,14 +530,14 @@ class DatabaseUpgrade:
def _upgrade_to_v6(self):
_step = self.step_begin('检查数据库版本v6...')
# 服务端升级到版本2.2.9.1为增加双因子认证为account表增加oath_secret字段
# db_ret = self.db.is_field_exists('{}account'.format(self.db.table_prefix), 'oath_secret')
# if db_ret is None:
# self.step_end(_step, -1, '无法连接到数据库')
# return False
# if db_ret:
# self.step_end(_step, 0, '跳过 v5 到 v6 的升级操作')
# return True
# 服务端升级到版本2.2.9为增加双因子认证为account表增加oath_secret字段
db_ret = self.db.is_field_exists('{}account'.format(self.db.table_prefix), 'oath_secret')
if db_ret is None:
self.step_end(_step, -1, '无法连接到数据库')
return False
if db_ret:
self.step_end(_step, 0, '跳过 v5 到 v6 的升级操作')
return True
self.step_end(_step, 0, '需要升级到v6')
@ -556,7 +556,6 @@ class DatabaseUpgrade:
self.step_end(_step, 0)
return True
except:
log.e('failed.\n')
self.step_end(_step, -1)

View File

@ -46,6 +46,10 @@ class TPDatabase:
self._table_prefix = ''
self._conn_pool = None
self._stop_flag = False
self._thread_keep_alive_handle = None
self._thread_keep_alive_cond = threading.Condition()
@property
def table_prefix(self):
return self._table_prefix
@ -91,6 +95,30 @@ class TPDatabase:
return True
def start_keep_alive(self):
self._thread_keep_alive_handle = threading.Thread(target=self._thread_keep_alive)
self._thread_keep_alive_handle.start()
def stop_keep_alive(self):
self._stop_flag = True
self._thread_keep_alive_cond.acquire()
self._thread_keep_alive_cond.notify()
self._thread_keep_alive_cond.release()
if self._thread_keep_alive_handle is not None:
self._thread_keep_alive_handle.join()
log.v('database-keep-alive-thread stopped.\n')
def _thread_keep_alive(self):
while True:
self._thread_keep_alive_cond.acquire()
# 每一小时醒来执行一次查询,避免连接丢失
self._thread_keep_alive_cond.wait(3600)
self._thread_keep_alive_cond.release()
if self._stop_flag:
break
self.query('SELECT `value` FROM `{}config` WHERE `name`="db_ver";'.format(self._table_prefix))
def _init_sqlite(self, db_file):
self.db_type = self.DB_TYPE_SQLITE
self.auto_increment = 'AUTOINCREMENT'
@ -121,49 +149,6 @@ class TPDatabase:
return True
# def init__(self, db_source):
# self.db_source = db_source
#
# if db_source['type'] == self.DB_TYPE_MYSQL:
# log.e('MySQL not supported yet.')
# return False
# elif db_source['type'] == self.DB_TYPE_SQLITE:
# self._table_prefix = 'ts_'
# self._conn_pool = TPSqlitePool(db_source['file'])
#
# if not os.path.exists(db_source['file']):
# log.w('database need create.\n')
# self.need_create = True
# return True
# else:
# log.e('Unknown database type: {}'.format(db_source['type']))
# return False
#
# # 看看数据库中是否存在指定的数据表(如果不存在,可能是一个空数据库文件),则可能是一个新安装的系统
# # ret = self.query('SELECT COUNT(*) FROM `sqlite_master` WHERE `type`="table" AND `name`="{}account";'.format(self._table_prefix))
# ret = self.is_table_exists('{}group'.format(self._table_prefix))
# if ret is None or not ret:
# log.w('database need create.\n')
# self.need_create = True
# return True
#
# # 尝试从配置表中读取当前数据库版本号(如果不存在,说明是比较旧的版本了)
# ret = self.query('SELECT `value` FROM `{}config` WHERE `name`="db_ver";'.format(self._table_prefix))
# if ret is None or 0 == len(ret):
# self.current_ver = 1
# else:
# self.current_ver = int(ret[0][0])
#
# if self.current_ver < self.DB_VERSION:
# log.w('database need upgrade.\n')
# self.need_upgrade = True
# return True
#
# # DO TEST
# # self.alter_table('ts_account', [['account_id', 'id'], ['account_type', 'type']])
#
# return True
def is_table_exists(self, table_name):
"""
判断指定的表是否存在
@ -180,7 +165,6 @@ class TPDatabase:
return False
return True
elif self.db_type == self.DB_TYPE_MYSQL:
# select TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA='dbname' and TABLE_NAME='tablename' ;
ret = self.query('SELECT TABLE_NAME from INFORMATION_SCHEMA.TABLES where TABLE_SCHEMA="{}" and TABLE_NAME="{}";'.format(self.mysql_db, table_name))
if ret is None:
return None

View File

@ -1,112 +1,122 @@
# -*- coding: utf-8 -*-
# import pickle
import time
import datetime
import threading
# from pymemcache.client.base import Client as mem_client
from .configs import app_cfg
from eom_common.eomcore.logger import log
cfg = app_cfg()
SESSION_EXPIRE = 3600 # 60*60 默认超时时间为1小时
class WebSession(threading.Thread):
"""
:type _mem_client: pymemcache.client.base.Client
"""
def __init__(self):
super().__init__(name='session-manager-thread')
import builtins
if '__web_session__' in builtins.__dict__:
raise RuntimeError('WebSession object exists, you can not create more than one instance.')
# session表session_id为索引每个项为一个字典包括 v(Value), t(Timestamp when add or modify), e(Expire seconds)
self._session_dict = dict()
self._lock = threading.RLock()
self._stop_flag = False
def init(self):
return True
def stop(self):
self._stop_flag = True
self.join()
log.v('{} stopped.'.format(self.name))
def run(self):
while True:
_now = int(datetime.datetime.utcnow().timestamp())
with self._lock:
_keys = [k for k in self._session_dict]
for k in _keys:
if self._session_dict[k]['e'] == 0:
continue
if _now - self._session_dict[k]['t'] > self._session_dict[k]['e']:
del self._session_dict[k]
# 每隔一分钟检查一次超时的会话
for i in range(60):
if not self._stop_flag:
time.sleep(1)
def set(self, s_id, value, expire=SESSION_EXPIRE):
"""
设置一个会话数据如果expire为负数则立即删除已经存在的名为s_id的会话如果expire为0则此会话数据永不过期expire的单位为秒
@param s_id: string
@param value: string
@param expire: integer
@return: None
"""
if expire < 0:
with self._lock:
if s_id in self._session_dict:
del self._session_dict[s_id]
else:
self._session_dict[s_id] = {'v': value, 't': int(datetime.datetime.utcnow().timestamp()), 'e': expire}
def get(self, s_id, _default=None):
# 从session中获取一个数据读取并更新最后访问时间
with self._lock:
if s_id in self._session_dict:
if self._session_dict[s_id]['e'] == 0:
return self._session_dict[s_id]['v']
else:
if int(datetime.datetime.utcnow().timestamp()) - self._session_dict[s_id]['t'] > self._session_dict[s_id]['e']:
del self._session_dict[s_id]
return _default
else:
self._session_dict[s_id]['t'] = int(datetime.datetime.utcnow().timestamp())
return self._session_dict[s_id]['v']
else:
return _default
def taken(self, s_id, _default=None):
# 从session中取走一个数据读取并删除
with self._lock:
if s_id in self._session_dict:
ret = self._session_dict[s_id]['v']
del self._session_dict[s_id]
return ret
else:
return _default
def web_session():
"""
取得Session管理器的唯一实例
:rtype : WebSession
"""
import builtins
if '__web_session__' not in builtins.__dict__:
builtins.__dict__['__web_session__'] = WebSession()
return builtins.__dict__['__web_session__']
# -*- coding: utf-8 -*-
# import pickle
import time
import datetime
import threading
# from pymemcache.client.base import Client as mem_client
from .configs import app_cfg
from eom_common.eomcore.logger import log
cfg = app_cfg()
SESSION_EXPIRE = 3600 # 60*60 默认超时时间为1小时
class WebSession(threading.Thread):
"""
:type _mem_client: pymemcache.client.base.Client
"""
def __init__(self):
super().__init__(name='session-manager-thread')
import builtins
if '__web_session__' in builtins.__dict__:
raise RuntimeError('WebSession object exists, you can not create more than one instance.')
# session表session_id为索引每个项为一个字典包括 v(Value), t(Timestamp when add or modify), e(Expire seconds)
self._session_dict = dict()
self._lock = threading.RLock()
self._stop_flag = False
self._timer_cond = threading.Condition()
def init(self):
return True
def stop(self):
self._stop_flag = True
self._timer_cond.acquire()
self._timer_cond.notify()
self._timer_cond.release()
self.join()
log.v('{} stopped.\n'.format(self.name))
def run(self):
while True:
self._timer_cond.acquire()
# 每隔一分钟醒来检查一次超时的会话
self._timer_cond.wait(60)
self._timer_cond.release()
if self._stop_flag:
break
_now = int(datetime.datetime.utcnow().timestamp())
with self._lock:
_keys = [k for k in self._session_dict]
for k in _keys:
if self._session_dict[k]['e'] == 0:
continue
if _now - self._session_dict[k]['t'] > self._session_dict[k]['e']:
del self._session_dict[k]
# for i in range(60):
# if not self._stop_flag:
# time.sleep(1)
def set(self, s_id, value, expire=SESSION_EXPIRE):
"""
设置一个会话数据如果expire为负数则立即删除已经存在的名为s_id的会话如果expire为0则此会话数据永不过期expire的单位为秒
@param s_id: string
@param value: string
@param expire: integer
@return: None
"""
if expire < 0:
with self._lock:
if s_id in self._session_dict:
del self._session_dict[s_id]
else:
self._session_dict[s_id] = {'v': value, 't': int(datetime.datetime.utcnow().timestamp()), 'e': expire}
def get(self, s_id, _default=None):
# 从session中获取一个数据读取并更新最后访问时间
with self._lock:
if s_id in self._session_dict:
if self._session_dict[s_id]['e'] == 0:
return self._session_dict[s_id]['v']
else:
if int(datetime.datetime.utcnow().timestamp()) - self._session_dict[s_id]['t'] > self._session_dict[s_id]['e']:
del self._session_dict[s_id]
return _default
else:
self._session_dict[s_id]['t'] = int(datetime.datetime.utcnow().timestamp())
return self._session_dict[s_id]['v']
else:
return _default
def taken(self, s_id, _default=None):
# 从session中取走一个数据读取并删除
with self._lock:
if s_id in self._session_dict:
ret = self._session_dict[s_id]['v']
del self._session_dict[s_id]
return ret
else:
return _default
def web_session():
"""
取得Session管理器的唯一实例
:rtype : WebSession
"""
import builtins
if '__web_session__' not in builtins.__dict__:
builtins.__dict__['__web_session__'] = WebSession()
return builtins.__dict__['__web_session__']

View File

@ -7,24 +7,21 @@ from . import auth
from . import host
from . import cert
from . import user
from . import pwd
from . import config
from . import group
from . import index
from . import record
from . import maintenance
# import tornado.web
from eom_app.app.configs import app_cfg
cfg = app_cfg()
__all__ = ['controllers']
__all__ = ['controllers', 'fix_controller']
controllers = [
(r'/dashboard', dashboard.IndexHandler),
(r'/', index.IndexHandler),
(r'/dashboard', dashboard.IndexHandler),
(r'/maintenance/install', maintenance.InstallHandler),
(r'/maintenance/upgrade', maintenance.UpgradeHandler),
@ -53,7 +50,6 @@ controllers = [
(r'/cert/', cert.IndexHandler),
(r'/cert', cert.IndexHandler),
# (r'/pwd', pwd.IndexHandler),
(r'/user', user.IndexHandler),
(r'/user/list', user.GetListHandler),
(r'/user/personal', user.PersonalHandler),
@ -71,8 +67,6 @@ controllers = [
(r'/log/', record.LogHandler),
(r'/log', record.LogHandler),
(r'/exit', auth.LogoutHandler),
(r'/user/delete-user', user.DeleteUser),
(r'/user/modify-user', user.ModifyUser),
(r'/user/add-user', user.AddUser),
@ -114,19 +108,17 @@ controllers = [
(r'/host/sys-user/update', host.SysUserUpdate),
(r'/host/sys-user/delete', host.SysUserDelete),
# (r'/set/update-config', set.UpdateConfig),
# (r'/set/os-operator', set.OsOperator),
# (r'/set/info', config.InfoHandler),
# (r'/set/db', config.DatabaseHandler),
(r'/config/export-database', config.ExportDatabaseHandler),
(r'/config/import-database', config.ImportDatabaseHandler),
(r'/config/', config.IndexHandler),
(r'/config', config.IndexHandler),
(r'/uidesign', index.UIDesignHandler),
(r'/uidesign/without-sidebar', index.UIDesignWithoutSidebarHandler),
(r'/uidesign/table', index.UIDesignTableHandler),
# (r'/test/oath-code', index.OathCodeHandler)
]
def fix_controller():
dbg_mode, _ = cfg.get_bool('common::debug-mode', False)
if dbg_mode:
controllers.append((r'/exit/9E37CBAEE2294D9D9965112025CEE87F', index.ExitHandler))
controllers.append((r'/uidesign', index.UIDesignHandler))
controllers.append((r'/uidesign/without-sidebar', index.UIDesignWithoutSidebarHandler))
controllers.append((r'/uidesign/table', index.UIDesignTableHandler))

View File

@ -57,16 +57,17 @@ class IndexHandler(TPBaseAdminAuthHandler):
class ExportDatabaseHandler(TPBaseAdminAuthHandler):
def get(self):
now = time.localtime(time.time())
dt = '{:04d}{:02d}{:02d}-{:02d}{:02d}{:02d}'.format(now.tm_year, now.tm_mon, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec)
sql, ret = get_db().export_to_sql()
if ret:
now = time.localtime(time.time())
dt = '{:04d}{:02d}{:02d}-{:02d}{:02d}{:02d}'.format(now.tm_year, now.tm_mon, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec)
self.set_header('Content-Type', 'application/octet-stream')
self.set_header('Content-Disposition', 'attachment; filename=teleport-database-export-{}.sql'.format(dt))
self.set_header('Content-Type', 'application/octet-stream')
self.set_header('Content-Disposition', 'attachment; filename=teleport-database-export-{}.sql'.format(dt))
self.write(sql)
else:
self.write('<h1>错误</h1>导出数据时发生错误:{}'.format(sql))
sql = get_db().export_to_sql()
# self.write("分组ID, 操作系统, IP地址, 端口, 协议, 状态, 描述, 系统用户, 系统密码, 是否加密, 附加参数, 密钥ID, 认证类型\n".encode('gbk'))
self.write(sql)
self.finish()
@ -82,8 +83,7 @@ class ImportDatabaseHandler(TPBaseAdminAuthHandler):
ret = dict()
ret['code'] = 0
ret['message'] = ''
# ret['data'] = {}
# ret['data']['msg'] = list() # 记录跳过的行(格式不正确,或者数据重复等)
sql_filename = ''
try:
@ -114,23 +114,39 @@ class ImportDatabaseHandler(TPBaseAdminAuthHandler):
ret['message'] = 'upload sql file is not utf8 encode.'
return self.write(json.dumps(ret).encode('utf8'))
db_ver_checked = False
with open(sql_filename, encoding=file_encode) as f:
db = get_db()
sql = []
lines = f.readlines()
for line in lines:
line = line.strip('\r\n')
if line.startswith('-- DATABASE VERSION '):
x = line.split(' ')
if len(x) != 4:
ret['code'] = -1
ret['message'] = 'SQL文件格式错误无法解析数据库版本'
return self.write(json.dumps(ret).encode('utf8'))
db_ver_sql = int(x[3].strip())
if db.DB_VERSION != db_ver_sql:
ret['code'] = -1
ret['message'] = 'SQL文件数据库版本为 {},当前数据版本为 {},不允许导入!'.format(db_ver_sql, db.DB_VERSION)
return self.write(json.dumps(ret).encode('utf8'))
db_ver_checked = True
continue
if not db_ver_checked:
continue
if line .startswith('TRUNCATE TABLE '):
x = line.split(' ', 2)
_table_name = '`{}{}`'.format(get_db().table_prefix, x[2][1:-2])
_table_name = '`{}{}`'.format(db.table_prefix, x[2][1:-2])
if db.db_type == db.DB_TYPE_MYSQL:
x[2] = _table_name
line = ' '.join(x)
line += ';'
sql.append(line)
elif db.db_type == db.DB_TYPE_SQLITE:
#delete from TableName; //清空数据
# update sqlite_sequence SET seq = 0 where name ='TableName';//自增长ID为0
sql.append('DELETE FROM {};'.format(_table_name))
sql.append('UPDATE `sqlite_sequence` SET `seq`=0 WHERE `name`="{}";'.format(_table_name[1:-1]))
@ -139,22 +155,19 @@ class ImportDatabaseHandler(TPBaseAdminAuthHandler):
_table_name = '`{}{}`'.format(db.table_prefix, x[2][1:-1])
x[2] = _table_name
line = ' '.join(x)
# print(line)
sql.append(line)
if not db_ver_checked:
ret['code'] = -1
ret['message'] = 'SQL文件格式错误未能确定数据库版本'
return self.write(json.dumps(ret).encode('utf8'))
db_ret = db.transaction(sql)
if not db_ret:
ret['code'] = -1
ret['message'] = 'SQL语句执行出错'
return self.write(json.dumps(ret).encode('utf8'))
# for line in sql:
# db_ret = get_db().exec(line)
# if not db_ret:
# ret['code'] = -1
# ret['message'] = 'SQL语句执行出错: {}'.format(line)
# return self.write(json.dumps(ret).encode('utf8'))
ret['code'] = 0
return self.write(json.dumps(ret).encode('utf8'))
except:

View File

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

View File

@ -11,14 +11,9 @@ from eom_app.app.oath import verify_oath_code
def verify_user(name, password, oath_code):
cfg = app_cfg()
if cfg.app_mode == APP_MODE_MAINTENANCE:
if name == 'admin' and password == 'admin':
return 1, 100, '系统管理员', 0
db = get_db()
sql = 'SELECT `account_id`, `account_type`, `account_desc`, `account_pwd`, `account_lock`, `oath_secret` FROM `{}account` WHERE `account_name`="{}";'.format(db.table_prefix, name)
sql = 'SELECT `account_id`, `account_type`, `account_desc`, `account_pwd`, `account_lock` FROM `{}account` WHERE `account_name`="{}";'.format(db.table_prefix, name)
db_ret = db.query(sql)
if db_ret is None:
# 特别地,如果无法取得数据库连接,有可能是新安装的系统,尚未建立数据库,此时应该处于维护模式
@ -35,7 +30,6 @@ def verify_user(name, password, oath_code):
account_type = db_ret[0][1]
desc = db_ret[0][2]
locked = db_ret[0][4]
oath_secret = db_ret[0][5]
if locked == 1:
return 0, 0, '', locked
@ -50,7 +44,7 @@ def verify_user(name, password, oath_code):
db.exec(sql)
if oath_code is not None:
if not verify_oath_code(oath_secret, oath_code):
if not verify_oath(user_id, oath_code):
return 0, 0, '', 0
return user_id, account_type, desc, locked

View File

@ -111,24 +111,9 @@ ywl.do_upload_sql_file = function () {
$('#upload-file').remove();
var ret = JSON.parse(data);
if (ret.code === TPE_OK) {
// g_host_table.reload();
ywl.notify_success('导入sql成功');
// if (ret.data.msg.length > 0) {
// var html = [];
// html.push('<ul>');
// for (var i = 0, cnt = ret.data.msg.length; i < cnt; ++i) {
// html.push('<li>');
// html.push('<span style="font-weight:bold;color:#993333;">' + ret.data.msg[i].reason + '</span><br/>');
// html.push(ret.data.msg[i].line);
// html.push('</li>');
// }
// html.push('</ul>');
//
// // $('#batch_add_host_result').html(html.join(''));
//// $('#dialog_batch_add_host').modal({backdrop: 'static'});
// }
} else {
ywl.notify_error('导入sql失败 错误号:' + ret.code);
ywl.notify_error('导入sql失败<br/>[' + ret.code+'] '+ret.message);
}
},
error: function () {
@ -141,7 +126,6 @@ ywl.do_upload_sql_file = function () {
ywl._make_protocol_info = function (name, p) {
if (_.isUndefined(p))
return ywl._make_info(name, '未能检测到');
// <tr><td class="key">RDP 端口:</td><td class="value">52089</td></tr>
var val = p.port;
if (!p.enable) {
val = '<span class="disabled">' + val + '(未启用)</span>';

View File

@ -1,7 +1,9 @@
<!DOCTYPE html>
<%!
import time
page_title_ = ''
page_menu_ = []
time_now = int(time.time())
%>
<!--[if IE 8]> <html lang="en" class="ie8"> <![endif]-->
<!--[if !IE]><!-->
@ -38,6 +40,9 @@
<div class="breadcrumb-container">
<%block name="breadcrumb" />
</div>
<div style="display:inline-block;float:right;padding-top:12px;">
系统时间:<span id="system-timer">111</span>
</div>
</div>
</div>
<!-- end #header -->
@ -81,8 +86,6 @@
</div>
<%block name="extend_content" />
## <script type="text/javascript" src="${ static_url('js/var.js') }"></script>
<script type="text/javascript" src="${ static_url('plugins/underscore/underscore.js') }"></script>
<script type="text/javascript" src="${ static_url('plugins/jquery/jquery.min.js') }"></script>
<script type="text/javascript" src="${ static_url('plugins/jquery/ajaxfileupload.js') }"></script>
@ -102,7 +105,6 @@
<%block name="extend_js"/>
<script type="text/javascript">
ywl.add_page_options({
## 有些参数由后台python脚本生成到模板中无法直接生成到js文件中所以必须通过这种方式传递参数到js脚本中。
@ -110,10 +112,15 @@
});
$(document).ready(function () {
// once page ready, init ywl object.
## var teleport_ip_info = "请核对您的堡垒机IP地址当前为 " + teleport_ip;
## $("#teleport-server-ip").text(teleport_ip_info);
ywl.init();
var g_time_now = ${time_now};
var g_dom_timer = $('#system-timer');
g_dom_timer.text(format_datetime(g_time_now));
setInterval(function(){
g_dom_timer.text(format_datetime(g_time_now));
g_time_now += 1;
}, 1000);
});
</script>