改进:授权策略编辑界面关于账号显示不完整的问题;

调整:将重建授权映射按钮从运维授权和审计授权界面移除,并在系统设置的安全配置页面中加入重建授权映射的按钮。
pull/105/head
Apex Liu 2018-03-26 02:21:44 +08:00
parent 00ead99bb1
commit 6d8ca92513
12 changed files with 188 additions and 35 deletions

3
.gitignore vendored
View File

@ -76,6 +76,9 @@ __pycache__
/client/tp_rdp /client/tp_rdp
/server/tp_core/protocol/rdp /server/tp_core/protocol/rdp
/client/tools/tprdp /client/tools/tprdp
/server/tp_core/testssh
/client/tp_assist_win_it_doctor
/dist/client/windows/assist-it-doctor
# for MacOS. # for MacOS.
.DS_Store .DS_Store

View File

@ -249,12 +249,16 @@ $app.on_table_groups_render_created = function (render) {
var ret = []; var ret = [];
for (var i = 0; i < fields.members.length; ++i) { for (var i = 0; i < fields.members.length; ++i) {
ret.push('<div class="acc-info-wrap"><div class="acc-info'); ret.push('<div class="acc-info-wrap"><div class="acc-info');
if(fields.members[i].router_ip.length > 0) if(fields.members[i]._host.router_ip.length > 0)
ret.push(' acc-info-router" title="由 ' + fields.members[i].router_ip + ':' + fields.members[i].router_port + ' 路由"'); ret.push(' acc-info-router" title="由 ' + fields.members[i]._host.router_ip + ':' + fields.members[i]._host.router_port + ' 路由"');
else else
ret.push('"'); ret.push('"');
ret.push('>'); ret.push('>');
ret.push(fields.members[i].username+'@'+fields.members[i].host_ip);
ret.push(fields.members[i].username+'@' + fields.members[i]._host.ip);
if(fields.members[i]._host.name.length > 0)
ret.push(' (' + fields.members[i]._host.name +')');
ret.push('</div></div>'); ret.push('</div></div>');
} }

View File

@ -994,7 +994,12 @@ $app.on_table_sel_auditor_user_render_created = function (render) {
render.user_info = function (row_id, fields) { render.user_info = function (row_id, fields) {
var ret = []; var ret = [];
if(fields.surname.length > 0) {
ret.push('<span class="field-name">' + fields.surname + '</span>'); ret.push('<span class="field-name">' + fields.surname + '</span>');
}
else {
ret.push('<span class="field-name">' + fields.username + '</span>');
}
ret.push('<span class="field-desc mono">'); ret.push('<span class="field-desc mono">');
ret.push(fields.username); ret.push(fields.username);
if (fields.email.length > 0) if (fields.email.length > 0)

View File

@ -1016,7 +1016,12 @@ $app.on_table_sel_user_render_created = function (render) {
render.user_info = function (row_id, fields) { render.user_info = function (row_id, fields) {
var ret = []; var ret = [];
if(fields.surname.length > 0) {
ret.push('<span class="field-name">' + fields.surname + '</span>'); ret.push('<span class="field-name">' + fields.surname + '</span>');
}
else {
ret.push('<span class="field-name">' + fields.username + '</span>');
}
ret.push('<span class="field-desc mono">'); ret.push('<span class="field-desc mono">');
ret.push(fields.username); ret.push(fields.username);
if (fields.email.length > 0) if (fields.email.length > 0)

View File

@ -315,7 +315,10 @@ $app.create_config_sec = function () {
// btn_auth_username_password: $('#sec-auth-username-password'), // btn_auth_username_password: $('#sec-auth-username-password'),
btn_auth_username_password_captcha: $('#sec-auth-username-password-captcha'), btn_auth_username_password_captcha: $('#sec-auth-username-password-captcha'),
// btn_auth_username_oath: $('#sec-auth-username-oath'), // btn_auth_username_oath: $('#sec-auth-username-oath'),
btn_auth_username_password_oath: $('#sec-auth-username-password-oath') btn_auth_username_password_oath: $('#sec-auth-username-password-oath'),
btn_rebuild_ops_auz_map: $('#btn-rebuild-ops-auz-map'),
btn_rebuild_audit_auz_map: $('#btn-rebuild-audit-auz-map')
}; };
_sec.init = function (cb_stack) { _sec.init = function (cb_stack) {
@ -333,6 +336,14 @@ $app.create_config_sec = function () {
_sec.on_btn_save(); _sec.on_btn_save();
}); });
_sec.dom.btn_rebuild_ops_auz_map.click(function () {
_sec.on_rebuild_ops_auz_map();
});
_sec.dom.btn_rebuild_audit_auz_map.click(function () {
_sec.on_rebuild_audit_auz_map();
});
cb_stack.exec(); cb_stack.exec();
}; };
@ -451,6 +462,36 @@ $app.create_config_sec = function () {
}; };
_sec.on_rebuild_ops_auz_map = function () {
$tp.ajax_post_json('/system/rebuild-ops-auz-map', {},
function (ret) {
if (ret.code === TPE_OK) {
$tp.notify_success('重建运维授权映射成功!');
} else {
$tp.notify_error('重建运维授权映射失败:' + tp_error_msg(ret.code, ret.message));
}
},
function () {
$tp.notify_error('网络故障,重建运维授权映射失败!');
}
);
};
_sec.on_rebuild_audit_auz_map = function () {
$tp.ajax_post_json('/system/rebuild-audit-auz-map', {},
function (ret) {
if (ret.code === TPE_OK) {
$tp.notify_success('重建审计授权映射成功!');
} else {
$tp.notify_error('重建审计授权映射失败:' + tp_error_msg(ret.code, ret.message));
}
},
function () {
$tp.notify_error('网络故障,重建审计授权映射失败!');
}
);
};
return _sec; return _sec;
}; };

View File

@ -38,7 +38,7 @@
<div class="table-extend-cell"> <div class="table-extend-cell">
<span class="table-name"><i class="fa fa-list fa-fw"></i> 授权策略列表</span> <span class="table-name"><i class="fa fa-list fa-fw"></i> 授权策略列表</span>
<button id="btn-refresh-policy" class="btn btn-sm btn-default"><i class="fa fa-rotate-right fa-fw"></i> 刷新列表</button> <button id="btn-refresh-policy" class="btn btn-sm btn-default"><i class="fa fa-rotate-right fa-fw"></i> 刷新列表</button>
<button id="btn-rebuild" class="btn btn-sm btn-danger"><i class="fa fa-flash fa-fw"></i> 重建授权映射</button> ## <button id="btn-rebuild" class="btn btn-sm btn-danger"><i class="fa fa-flash fa-fw"></i> 重建授权映射</button>
</div> </div>
<div class="table-extend-cell table-extend-cell-right group-actions"> <div class="table-extend-cell table-extend-cell-right group-actions">
<button id="btn-create-policy" class="btn btn-sm btn-primary"><i class="fa fa-plus-circle fa-fw"></i> 新建授权策略</button> <button id="btn-create-policy" class="btn btn-sm btn-primary"><i class="fa fa-plus-circle fa-fw"></i> 新建授权策略</button>
@ -86,7 +86,7 @@
<div class="box"> <div class="box">
<p>说明:</p> <p>说明:</p>
<ul class="help-list"> <ul class="help-list">
<li><span class="error">编辑了授权策略或调整策略顺序之后,请点击“重建授权映射”来使之生效!</span>正式版本将会改进为自动进行重建。</li> ## <li><span class="error">编辑了授权策略或调整策略顺序之后,请点击“重建授权映射”来使之生效!</span>正式版本将会改进为自动进行重建。</li>
<li>上下拖动“顺序”栏中的 <i class="fa fa-reorder fa-fw"></i> 可以调节策略的检查顺序。</li> <li>上下拖动“顺序”栏中的 <i class="fa fa-reorder fa-fw"></i> 可以调节策略的检查顺序。</li>
<li>可以在“快速查找”中快速定位用户或主机的授权关系。</li> <li>可以在“快速查找”中快速定位用户或主机的授权关系。</li>
</ul> </ul>

View File

@ -38,7 +38,7 @@
<div class="table-extend-cell"> <div class="table-extend-cell">
<span class="table-name"><i class="fa fa-list fa-fw"></i> 授权策略列表</span> <span class="table-name"><i class="fa fa-list fa-fw"></i> 授权策略列表</span>
<button id="btn-refresh-policy" class="btn btn-sm btn-default"><i class="fa fa-rotate-right fa-fw"></i> 刷新列表</button> <button id="btn-refresh-policy" class="btn btn-sm btn-default"><i class="fa fa-rotate-right fa-fw"></i> 刷新列表</button>
<button id="btn-rebuild" class="btn btn-sm btn-danger"><i class="fa fa-flash fa-fw"></i> 重建授权映射</button> ## <button id="btn-rebuild" class="btn btn-sm btn-danger"><i class="fa fa-flash fa-fw"></i> 重建授权映射</button>
</div> </div>
<div class="table-extend-cell table-extend-cell-right group-actions"> <div class="table-extend-cell table-extend-cell-right group-actions">
<button id="btn-create-policy" class="btn btn-sm btn-primary"><i class="fa fa-plus-circle fa-fw"></i> 新建授权策略</button> <button id="btn-create-policy" class="btn btn-sm btn-primary"><i class="fa fa-plus-circle fa-fw"></i> 新建授权策略</button>
@ -86,7 +86,7 @@
<div class="box"> <div class="box">
<p>说明:</p> <p>说明:</p>
<ul class="help-list"> <ul class="help-list">
<li><span class="error">编辑了授权策略或调整策略顺序之后,请点击“重建授权映射”来使之生效!</span>正式版本将会改进为自动进行重建。</li> ## <li><span class="error">编辑了授权策略或调整策略顺序之后,请点击“重建授权映射”来使之生效!</span>正式版本将会改进为自动进行重建。</li>
<li>上下拖动“顺序”栏中的 <i class="fa fa-reorder fa-fw"></i> 可以调节策略的检查顺序。</li> <li>上下拖动“顺序”栏中的 <i class="fa fa-reorder fa-fw"></i> 可以调节策略的检查顺序。</li>
<li>可以在“快速查找”中快速定位用户或主机的授权关系。</li> <li>可以在“快速查找”中快速定位用户或主机的授权关系。</li>
</ul> </ul>

View File

@ -34,12 +34,12 @@
<!-- begin page-nav --> <!-- begin page-nav -->
<div class="table-extend-area"> <div class="table-extend-area">
<div class="table-extend-cell checkbox-select-all"><input id="table-session-select-all" type="checkbox"/></div> ## <div class="table-extend-cell checkbox-select-all"><input id="table-session-select-all" type="checkbox"/></div>
<div class="table-extend-cell group-actions"> ## <div class="table-extend-cell group-actions">
<div class="btn-group" role="group"> ## <div class="btn-group" role="group">
<button id="btn-kill-sessions" type="button" class="btn btn-danger"><i class="fa fa-times-circle fa-fw"></i> 强行中断</button> ## <button id="btn-kill-sessions" type="button" class="btn btn-danger"><i class="fa fa-times-circle fa-fw"></i> 强行中断</button>
</div> ## </div>
</div> ## </div>
<div class="table-extend-cell table-item-counter"> <div class="table-extend-cell table-item-counter">
<ol id="table-session-paging"></ol> <ol id="table-session-paging"></ol>
</div> </div>

View File

@ -117,6 +117,26 @@
</tr> </tr>
</table> </table>
<hr/> <hr/>
<table class="table table-config-list">
<tr>
<td colspan="2" class="title">授权策略映射</td>
</tr>
<tr>
<td colspan="2" class="value">
<div class="alert alert-warning">授权策略映射是根据运维授权策略和审计授权策略构建的用户权限列表。<br/>如果您的系统中用户授权出现异常,可以重建授权策略映射。构建授权策略映射可能会耗费一点时间,请谨慎操作!</div>
</td>
</tr>
<tr>
<td class="key"></td>
<td class="value">
<button id="btn-rebuild-ops-auz-map" class="btn btn-sm btn-danger"><i class="fa fa-leaf fa-fw"></i> 立即重建运维授权映射</button>
<button id="btn-rebuild-audit-auz-map" class="btn btn-sm btn-danger"><i class="fa fa-leaf fa-fw"></i> 立即重建审计授权映射</button>
</td>
</tr>
</table>
<hr/>
<button id="btn-save-secure-config" class="btn btn-sm btn-primary"><i class="fa fa-check-circle fa-fw"></i> 保存安全设置</button> <button id="btn-save-secure-config" class="btn btn-sm btn-primary"><i class="fa fa-check-circle fa-fw"></i> 保存安全设置</button>
</div> </div>

View File

@ -251,6 +251,9 @@ controllers = [
# #
# - [json] 获取服务器时间 # - [json] 获取服务器时间
(r'/system/get-time', system.DoGetTimeHandler), (r'/system/get-time', system.DoGetTimeHandler),
# - [json] 重建授权映射
(r'/system/rebuild-ops-auz-map', system.DoRebuildOpsAuzMapHandler),
(r'/system/rebuild-audit-auz-map', system.DoRebuildAuditAuzMapHandler),
# ==================================================== # ====================================================
# 安装维护相关 # 安装维护相关

View File

@ -15,6 +15,8 @@ from app.const import *
from app.base.db import get_db from app.base.db import get_db
from app.model import syslog from app.model import syslog
from app.model import record from app.model import record
from app.model import ops
from app.model import audit
from app.base.core_server import core_service_async_post_http from app.base.core_server import core_service_async_post_http
from app.base.session import tp_session from app.base.session import tp_session
@ -354,3 +356,25 @@ class DoCleanupStorageHandler(TPBaseJsonHandler):
code, msg = yield record.cleanup_storage(self) code, msg = yield record.cleanup_storage(self)
self.write_json(code, data=msg) self.write_json(code, data=msg)
class DoRebuildOpsAuzMapHandler(TPBaseJsonHandler):
def post(self):
ret = self.check_privilege(TP_PRIVILEGE_OPS_AUZ)
if ret != TPE_OK:
return
err = audit.build_auz_map()
self.write_json(err)
class DoRebuildAuditAuzMapHandler(TPBaseJsonHandler):
def post(self):
ret = self.check_privilege(TP_PRIVILEGE_AUDIT_AUZ)
if ret != TPE_OK:
return
err = ops.build_auz_map()
self.write_json(err)

View File

@ -10,7 +10,8 @@ from app.base.stats import tp_stats
def get_account_info(acc_id): def get_account_info(acc_id):
s = SQL(get_db()) s = SQL(get_db())
s.select_from('acc', ['id', 'password', 'pri_key', 'state', 'host_ip', 'router_ip', 'router_port', 'protocol_type', 'protocol_port', 'auth_type', 'username'], alt_name='a') # s.select_from('acc', ['id', 'password', 'pri_key', 'state', 'host_ip', 'router_ip', 'router_port', 'protocol_type', 'protocol_port', 'auth_type', 'username'], alt_name='a')
s.select_from('acc', ['id', 'password', 'pri_key', 'state', 'host_id', 'protocol_type', 'protocol_port', 'auth_type', 'username'], alt_name='a')
s.where('a.id={}'.format(acc_id)) s.where('a.id={}'.format(acc_id))
err = s.query() err = s.query()
if err != TPE_OK: if err != TPE_OK:
@ -18,13 +19,25 @@ def get_account_info(acc_id):
if len(s.recorder) != 1: if len(s.recorder) != 1:
return TPE_DATABASE, None return TPE_DATABASE, None
sh = SQL(get_db())
sh.select_from('host', ['id', 'name', 'ip', 'router_ip', 'router_port', 'state'], alt_name='h')
sh.where('h.id={}'.format(s.recorder[0].host_id))
err = sh.query()
if err != TPE_OK:
return err, None
if len(s.recorder) != 1:
return TPE_DATABASE, None
s.recorder[0]['_host'] = sh.recorder[0]
return TPE_OK, s.recorder[0] return TPE_OK, s.recorder[0]
def get_host_accounts(host_id): def get_host_accounts(host_id):
# 获取指定主机的所有账号 # 获取指定主机的所有账号
s = SQL(get_db()) s = SQL(get_db())
s.select_from('acc', ['id', 'state', 'host_ip', 'router_ip', 'router_port', 'protocol_type', 'protocol_port', 'auth_type', 'username', 'pri_key'], alt_name='a') # s.select_from('acc', ['id', 'state', 'host_ip', 'router_ip', 'router_port', 'protocol_type', 'protocol_port', 'auth_type', 'username', 'pri_key'], alt_name='a')
s.select_from('acc', ['id', 'state', 'protocol_type', 'protocol_port', 'auth_type', 'username', 'pri_key'], alt_name='a')
s.where('a.host_id={}'.format(host_id)) s.where('a.host_id={}'.format(host_id))
s.order_by('a.username', True) s.order_by('a.username', True)
@ -37,8 +50,9 @@ def get_group_with_member(sql_filter, sql_order, sql_limit):
""" """
获取用户组列表以及每个组的总成员数以及不超过5个的成员 获取用户组列表以及每个组的总成员数以及不超过5个的成员
""" """
db = get_db()
# 首先获取要查询的组的信息 # 首先获取要查询的组的信息
sg = SQL(get_db()) sg = SQL(db)
sg.select_from('group', ['id', 'name', 'state', 'desc'], alt_name='g') sg.select_from('group', ['id', 'name', 'state', 'desc'], alt_name='g')
_where = list() _where = list()
@ -106,7 +120,8 @@ def get_group_with_member(sql_filter, sql_order, sql_limit):
users = list(set(users)) users = list(set(users))
su = SQL(get_db()) su = SQL(get_db())
su.select_from('acc', ['id', 'host_ip', 'router_ip', 'router_port', 'username', 'protocol_type'], alt_name='a') # su.select_from('acc', ['id', 'host_ip', 'router_ip', 'router_port', 'username', 'protocol_type'], alt_name='a')
su.select_from('acc', ['id', 'host_id', 'username', 'protocol_type'], alt_name='a')
su.where('a.id IN ({})'.format(','.join([str(uid) for uid in users]))) su.where('a.id IN ({})'.format(','.join([str(uid) for uid in users])))
su.order_by('a.username') su.order_by('a.username')
@ -114,6 +129,26 @@ def get_group_with_member(sql_filter, sql_order, sql_limit):
if err != TPE_OK or len(su.recorder) == 0: if err != TPE_OK or len(su.recorder) == 0:
return err, sg.total_count, 0, sg.recorder return err, sg.total_count, 0, sg.recorder
# 得到主机id列表然后查询相关主机的详细信息
host_ids = []
for _acc in su.recorder:
if _acc.host_id not in host_ids:
host_ids.append(_acc.host_id)
s_host = SQL(db)
s_host.select_from('host', ['id', 'name', 'ip', 'router_ip', 'router_port', 'state'], alt_name='h')
str_host_ids = ','.join([str(i) for i in host_ids])
s_host.where('h.id IN ({ids})'.format(ids=str_host_ids))
err = s_host.query()
if err != TPE_OK:
return err, sg.total_count, 0, sg.recorder
hosts = {}
for _host in s_host.recorder:
if _host.id not in hosts:
hosts[_host.id] = _host
for _acc in su.recorder:
_acc['_host'] = hosts[_acc.host_id]
# 现在可以将具体的用户信息追加到组信息中了 # 现在可以将具体的用户信息追加到组信息中了
for g in sg.recorder: for g in sg.recorder:
for u in su.recorder: for u in su.recorder:
@ -155,6 +190,7 @@ def get_accounts(sql_filter, sql_order, sql_limit, sql_restrict, sql_exclude):
for k in sql_filter: for k in sql_filter:
if k == 'search': if k == 'search':
_where.append('(a.username LIKE "%{filter}%" OR a.host_ip LIKE "%{filter}%" OR a.router_ip LIKE "%{filter}%")'.format(filter=sql_filter[k])) _where.append('(a.username LIKE "%{filter}%" OR a.host_ip LIKE "%{filter}%" OR a.router_ip LIKE "%{filter}%")'.format(filter=sql_filter[k]))
# _where.append('(a.username LIKE "%{filter}%")'.format(filter=sql_filter[k]))
if len(_where) > 0: if len(_where) > 0:
str_where = '( {} )'.format(' AND '.join(_where)) str_where = '( {} )'.format(' AND '.join(_where))
@ -217,10 +253,18 @@ def add_account(handler, host_id, args):
if db_ret is not None and len(db_ret) > 0: if db_ret is not None and len(db_ret) > 0:
return TPE_EXISTS, 0 return TPE_EXISTS, 0
sql = 'INSERT INTO `{}acc` (host_id, host_ip, router_ip, router_port, protocol_type, protocol_port, state, auth_type, username, password, pri_key, creator_id, create_time) VALUES ' \ # sql = 'INSERT INTO `{}acc` (host_id, host_ip, router_ip, router_port, protocol_type, protocol_port, state, auth_type, username, password, pri_key, creator_id, create_time) VALUES ' \
'({host_id}, "{host_ip}", "{router_ip}", {router_port}, {protocol_type}, {protocol_port}, {state}, {auth_type}, "{username}", "{password}", "{pri_key}", {creator_id}, {create_time});' \ # '({host_id}, "{host_ip}", "{router_ip}", {router_port}, {protocol_type}, {protocol_port}, {state}, {auth_type}, "{username}", "{password}", "{pri_key}", {creator_id}, {create_time});' \
# ''.format(db.table_prefix,
# host_id=host_id, host_ip=args['host_ip'], router_ip=args['router_ip'], router_port=args['router_port'],
# protocol_type=args['protocol_type'], protocol_port=args['protocol_port'], state=TP_STATE_NORMAL,
# auth_type=args['auth_type'], username=args['username'], password=args['password'], pri_key=args['pri_key'],
# creator_id=operator['id'], create_time=_time_now)
sql = 'INSERT INTO `{}acc` (host_id, protocol_type, protocol_port, state, auth_type, username, password, pri_key, creator_id, create_time) VALUES ' \
'({host_id}, {protocol_type}, {protocol_port}, {state}, {auth_type}, "{username}", "{password}", "{pri_key}", {creator_id}, {create_time});' \
''.format(db.table_prefix, ''.format(db.table_prefix,
host_id=host_id, host_ip=args['host_ip'], router_ip=args['router_ip'], router_port=args['router_port'], host_id=host_id,
protocol_type=args['protocol_type'], protocol_port=args['protocol_port'], state=TP_STATE_NORMAL, protocol_type=args['protocol_type'], protocol_port=args['protocol_port'], state=TP_STATE_NORMAL,
auth_type=args['auth_type'], username=args['username'], password=args['password'], pri_key=args['pri_key'], auth_type=args['auth_type'], username=args['username'], password=args['password'], pri_key=args['pri_key'],
creator_id=operator['id'], create_time=_time_now) creator_id=operator['id'], create_time=_time_now)
@ -324,15 +368,19 @@ def remove_accounts(handler, host_id, acc_ids):
s = SQL(db) s = SQL(db)
# 1. 判断是否存在 # 1. 判断是否存在
s.select_from('host', ['acc_count'], alt_name='a') s.select_from('host', ['name', 'ip', 'router_ip', 'router_port', 'acc_count'], alt_name='a')
s.where('a.id={h_id}'.format(h_id=host_id, ids=acc_ids)) s.where('a.id={h_id}'.format(h_id=host_id, ids=acc_ids))
err = s.query() err = s.query()
if err != TPE_OK: if err != TPE_OK:
return err return err
if len(s.recorder) == 0: if len(s.recorder) == 0:
return TPE_NOT_EXISTS return TPE_NOT_EXISTS
_h_name = s.recorder[0].name
_h_ip = s.recorder[0].ip
_h_router_ip = s.recorder[0].router_ip
_h_router_port = s.recorder[0].router_port
s.reset().select_from('acc', ['host_ip', 'router_ip', 'router_port', 'username'], alt_name='a') s.reset().select_from('acc', ['username'], alt_name='a')
s.where('a.host_id={h_id} AND a.id IN ({ids}) '.format(h_id=host_id, ids=acc_ids)) s.where('a.host_id={h_id} AND a.id IN ({ids}) '.format(h_id=host_id, ids=acc_ids))
err = s.query() err = s.query()
if err != TPE_OK: if err != TPE_OK:
@ -342,9 +390,9 @@ def remove_accounts(handler, host_id, acc_ids):
acc_names = [] acc_names = []
for a in s.recorder: for a in s.recorder:
acc_name = '{}@{}'.format(a.username, a.host_ip) acc_name = '{}@{}'.format(a.username, _h_ip)
if len(a.router_ip) > 0: if len(_h_router_ip) > 0:
acc_name += '(由{}:{}路由)'.format(a.router_ip, a.router_port) acc_name += '(由{}:{}路由)'.format(_h_router_ip, _h_router_port)
acc_names.append(acc_name) acc_names.append(acc_name)
sql_list = [] sql_list = []
@ -368,13 +416,13 @@ def remove_accounts(handler, host_id, acc_ids):
if not db.transaction(sql_list): if not db.transaction(sql_list):
return TPE_DATABASE return TPE_DATABASE
s.reset().select_from('host', ['acc_count'], alt_name='a') # s.reset().select_from('host', ['acc_count'], alt_name='a')
s.where('a.id={h_id}'.format(h_id=host_id, ids=acc_ids)) # s.where('a.id={h_id}'.format(h_id=host_id, ids=acc_ids))
err = s.query() # err = s.query()
if err != TPE_OK: # if err != TPE_OK:
return err # return err
if len(s.recorder) == 0: # if len(s.recorder) == 0:
return TPE_NOT_EXISTS # return TPE_NOT_EXISTS
syslog.sys_log(handler.get_current_user(), handler.request.remote_ip, TPE_OK, "删除账号:{}".format(''.join(acc_names))) syslog.sys_log(handler.get_current_user(), handler.request.remote_ip, TPE_OK, "删除账号:{}".format(''.join(acc_names)))