调整主机账号界面中账号管理对话框,允许批量禁用/解禁/删除账号。

pull/105/head
Apex Liu 2017-11-02 17:12:09 +08:00
parent e06d90d248
commit 0f25a5e372
16 changed files with 296 additions and 363 deletions

File diff suppressed because one or more lines are too long

View File

@ -965,14 +965,10 @@ $app.create_dlg_accounts = function () {
dlg.dom_id = 'dlg-accounts';
dlg.host_row_id = -1;
dlg.host = null;
dlg.accounts = [];
// dlg.row_id = -1;
dlg.dom = {
dialog: $('#' + dlg.dom_id),
dlg_title: $('#' + dlg.dom_id + ' [data-field="dlg-title"]'),
// info: $('#' + dlg.dom_id + ' [data-field="user-info"]'),
//btn_add: $('#' + dlg.dom_id + ' [data-btn="btn-add-account"]'),
btn_refresh_acc: $('#btn-refresh-acc'),
btn_add_acc: $('#btn-add-acc'),
@ -980,9 +976,7 @@ $app.create_dlg_accounts = function () {
btn_lock_acc: $('#btn-lock-acc'),
btn_unlock_acc: $('#btn-unlock-acc'),
btn_remove_acc: $('#btn-remove-acc'),
acc_list: $('#' + dlg.dom_id + ' [data-field="account-list"]')
btn_remove_acc: $('#btn-remove-acc')
};
dlg.init = function (cb_stack) {
@ -1067,42 +1061,26 @@ $app.create_dlg_accounts = function () {
};
$app.table_acc = $tp.create_table(table_acc_options);
cb_stack
//.add($app.table_host.load_data)
.add($app.table_acc.init);
//-------------------------------
// 账号列表相关过滤器
//-------------------------------
// $tp.create_table_header_filter_search($app.table_host, {
// name: 'search',
// place_holder: '搜索主机IP/名称/描述/资产编号/等等...'
// });
// $app.table_host_role_filter = $tp.create_table_filter_role($app.table_host, $app.role_list);
// 主机没有“临时锁定”状态,因此要排除掉
// $tp.create_table_header_filter_state($app.table_host, 'state', $app.obj_states, [TP_STATE_LOCKED]);
// 从cookie中读取用户分页限制的选择
// $tp.create_table_paging($app.table_acc, 'table-acc-paging',
// {
// per_page: Cookies.get($app.page_id('asset_host') + '_acc_per_page'),
// on_per_page_changed: function (per_page) {
// Cookies.set($app.page_id('asset_host') + '_acc_per_page', per_page, {expires: 365});
// }
// });
// $tp.create_table_pagination($app.table_acc, 'table-acc-pagination');
cb_stack.add($app.table_acc.init);
dlg.dom.btn_add_acc.click(function () {
// dlg.show_edit_account = true;
$app.dlg_edit_account.show_add(dlg.host_row_id);
});
dlg.dom.btn_refresh_acc.click(function () {
dlg.load_accounts();
});
dlg.dom.btn_lock_acc.click(function () {
dlg.on_btn_lock_acc_click();
});
dlg.dom.btn_unlock_acc.click(function () {
dlg.on_btn_unlock_acc_click();
});
dlg.dom.btn_remove_acc.click(function () {
dlg.on_btn_remove_acc_click();
});
dlg.dom.chkbox_acc_select_all.click(function () {
var _objects = $('#' + $app.table_acc.dom_id + ' tbody').find('[data-check-box]');
if ($(this).is(':checked')) {
@ -1115,26 +1093,16 @@ $app.create_dlg_accounts = function () {
});
}
});
dlg.dom.btn_lock_acc.click(function () {
$app.on_btn_lock_acc_click();
});
dlg.dom.btn_unlock_acc.click(function () {
$app.on_btn_unlock_acc_click();
});
dlg.dom.btn_remove_acc.click(function () {
$app.on_btn_remove_acc_click();
});
cb_stack.exec();
};
dlg.get_selected_host = function (tbl) {
dlg.get_selected_acc = function (tbl) {
var items = [];
var _objs = $('#' + $app.table_acc.dom_id + ' tbody tr td input[data-check-box]');
var _objs = $('#' + tbl.dom_id + ' tbody tr td input[data-check-box]');
$.each(_objs, function (i, _obj) {
if ($(_obj).is(':checked')) {
var _row_data = tbl.get_row(_obj);
// _all_checked = false;
items.push(_row_data.id);
}
});
@ -1142,65 +1110,80 @@ $app.create_dlg_accounts = function () {
};
dlg._lock_acc = function (acc_ids) {
$tp.ajax_post_json('/asset/update-hosts', {action: 'lock', hosts: host_ids},
$tp.ajax_post_json('/asset/update-accounts', {action: 'lock', host_id: dlg.host.id, accounts: acc_ids},
function (ret) {
if (ret.code === TPE_OK) {
$app.table_host.load_data();
$tp.notify_success('禁用主机操作成功!');
CALLBACK_STACK.create()
.add(dlg.check_acc_all_selected)
.add(dlg.load_accounts)
.exec();
$tp.notify_success('禁用账号操作成功!');
} else {
$tp.notify_error('禁用主机操作失败:' + tp_error_msg(ret.code, ret.message));
$tp.notify_error('禁用账号操作失败:' + tp_error_msg(ret.code, ret.message));
}
},
function () {
$tp.notify_error('网络故障,禁用主机操作失败!');
$tp.notify_error('网络故障,禁用账号操作失败!');
}
);
};
dlg.on_btn_lock_host_click = function () {
dlg.on_btn_lock_acc_click = function () {
var items = dlg.get_selected_acc($app.table_acc);
if (items.length === 0) {
$tp.notify_error('请选择要禁用的主机');
$tp.notify_error('请选择要禁用的账号');
return;
}
$app._lock_hosts(items);
dlg._lock_acc(items);
};
$app._unlock_hosts = function (host_ids) {
$tp.ajax_post_json('/asset/update-hosts', {action: 'unlock', hosts: host_ids},
dlg._unlock_acc = function (acc_ids) {
$tp.ajax_post_json('/asset/update-accounts', {action: 'unlock', host_id: dlg.host.id, accounts: acc_ids},
function (ret) {
if (ret.code === TPE_OK) {
$app.table_host.load_data();
$tp.notify_success('解禁主机操作成功!');
CALLBACK_STACK.create()
.add(dlg.check_acc_all_selected)
.add(dlg.load_accounts)
.exec();
dlg.load_accounts();
$tp.notify_success('解禁账号操作成功!');
} else {
$tp.notify_error('解禁主机操作失败:' + tp_error_msg(ret.code, ret.message));
$tp.notify_error('解禁账号操作失败:' + tp_error_msg(ret.code, ret.message));
}
},
function () {
$tp.notify_error('网络故障,解禁主机操作失败!');
$tp.notify_error('网络故障,解禁账号操作失败!');
}
);
};
$app.on_btn_unlock_host_click = function () {
var items = $app.get_selected_host($app.table_host);
dlg.on_btn_unlock_acc_click = function () {
var items = dlg.get_selected_acc($app.table_acc);
if (items.length === 0) {
$tp.notify_error('请选择要解禁的主机');
$tp.notify_error('请选择要解禁的账号');
return;
}
$app._unlock_hosts(items);
dlg._unlock_acc(items);
};
$app._remove_hosts = function (host_ids) {
dlg._remove_acc = function (acc_ids) {
var _fn_sure = function (cb_stack) {
$tp.ajax_post_json('/asset/update-hosts', {action: 'remove', hosts: host_ids},
$tp.ajax_post_json('/asset/update-accounts', {action: 'remove', host_id: dlg.host.id, accounts: acc_ids},
function (ret) {
if (ret.code === TPE_OK) {
cb_stack.add($app.check_host_all_selected);
cb_stack.add($app.table_host.load_data);
cb_stack
.add(dlg.check_acc_all_selected)
.add(dlg.load_accounts)
.exec();
$tp.notify_success('删除主机操作成功!');
var update_args = {
acc_count: dlg.host.acc_count - acc_ids.length
};
$app.table_host.update_row(dlg.host_row_id, update_args);
} else {
$tp.notify_error('删除主机操作失败:' + tp_error_msg(ret.code, ret.message));
}
@ -1216,185 +1199,49 @@ $app.create_dlg_accounts = function () {
var cb_stack = CALLBACK_STACK.create();
$tp.dlg_confirm(cb_stack, {
msg: '<div class="alert alert-danger"><p><strong>注意:删除操作不可恢复!!</strong></p><p>删除主机将同时删除与之相关的账号,并将主机和账号从所在分组中移除,同时删除所有相关授权!</p></div><p>如果您希望临时禁止登录指定主机,可将其“禁用”!</p><p>您确定要移除选定的' + host_ids.length + '个主机吗?</p>',
msg: '<div class="alert alert-danger"><p><strong>注意:删除操作不可恢复!!</strong></p></div><p>如果您希望临时禁止以指定账号登录远程主机,可将其“禁用”!</p><p>您确定要移除选定的' + acc_ids.length + '个账号吗?</p>',
fn_yes: _fn_sure
});
};
dlg.on_btn_remove_acc_click = function () {
var items = dlg.get_selected_acc($app.table_acc);
if (items.length === 0) {
$tp.notify_error('请选择要删除的账号!');
return;
}
dlg._remove_acc(items);
};
dlg.show = function (host_row_id) {
dlg.dom.acc_list.empty().html('<i class="fa fa-spinner fa-spin"></i> 正在加载...');
dlg.host_row_id = host_row_id;
dlg.host = $app.table_host.get_row(host_row_id);
dlg.dom.dialog.modal();
dlg.load_accounts();
};
dlg.load_accounts = function () {
$tp.ajax_post_json('/asset/get-accounts', {
host_id: dlg.host.id
},
dlg.load_accounts = function (cb_stack) {
cb_stack = cb_stack || CALLBACK_STACK.create();
$tp.ajax_post_json('/asset/get-accounts', {host_id: dlg.host.id},
function (ret) {
if (ret.code === TPE_OK) {
console.log('account:', ret.data);
var cb_stack = CALLBACK_STACK.create();
$app.table_acc.set_data(cb_stack, {}, {total: ret.data.length, page_index: 1, data: ret.data});
//$app.table_acc.set_data(cb_stack, {}, ret.data);
dlg.accounts = ret.data;
} else {
// $tp.notify_error('远程账号' + action + '失败:' + tp_error_msg(ret.code, ret.message));
$app.table_acc.set_data(cb_stack, {}, {total: 0, page_index: 1, data: {}});
console.error('failed.', tp_error_msg(ret.code, ret.message));
dlg.accounts = [];
}
dlg.show_account_list();
cb_stack.exec();
},
function () {
$tp.notify_error('网络故障,获取账号信息失败!');
cb_stack.exec();
}
);
};
dlg.show_account_list = function () {
var html = [];
if (dlg.accounts.length === 0) {
dlg.dom.acc_list.empty();
return;
}
for (var i = 0; i < dlg.accounts.length; ++i) {
var acc = dlg.accounts[i];
var pro_name = '未知';
if (acc.protocol_type === TP_PROTOCOL_TYPE_RDP) {
pro_name = 'RDP';
} else if (acc.protocol_type === TP_PROTOCOL_TYPE_SSH) {
pro_name = 'SSH';
} else if (acc.protocol_type === TP_PROTOCOL_TYPE_TELNET) {
pro_name = 'TELNET';
}
var auth_name = "未知";
if (acc.auth_type === TP_AUTH_TYPE_NONE) {
auth_name = '无';
} else if (acc.auth_type === TP_AUTH_TYPE_PASSWORD) {
auth_name = '密码';
} else if (acc.auth_type === TP_AUTH_TYPE_PRIVATE_KEY) {
auth_name = '私钥';
}
html.push('<div class="remote-action-group" id =' + "account-id-" + acc.id + '"><ul>');
html.push('<li class="remote-action-name">' + acc.username + '</li>');
html.push('<li class="remote-action-protocol">' + pro_name + '</li>');
html.push('<li class="remote-action-noauth">' + auth_name + '</li>');
html.push('<li class="remote-action-btn">');
html.push('<button type="button" class="btn btn-sm btn-primary" data-action="modify-account" data-id="' + acc.id + '"><i class="fa fa-edit fa-fw"></i> 修改</button>');
html.push('</li>');
if (acc.state === TP_STATE_NORMAL) {
html.push('<li class="remote-action-btn">');
html.push('<button type="button" class="btn btn-sm btn-info" data-action="lock-account" data-id="' + acc.id + '"><i class="fa fa-lock fa-fw"></i> 禁用</button>');
html.push('</li>');
} else {
html.push('<li class="remote-action-btn">');
html.push('<button type="button" class="btn btn-sm btn-success" data-action="unlock-account" data-id="' + acc.id + '"><i class="fa fa-unlock fa-fw"></i> 解禁</button>');
html.push('</li>');
}
html.push('<li class="remote-action-btn">');
html.push('<button type="button" class="btn btn-sm btn-danger" data-action="delete-account" data-id="' + acc.id + '"><i class="fa fa-trash-o fa-fw"></i> 删除</button>');
html.push('</li>');
html.push('</ul></div>');
}
dlg.dom.acc_list.empty().append($(html.join('')));
// 绑定账号操作按钮点击事件
$('#' + dlg.dom_id + ' [data-action="modify-account"]').click(function () {
var acc_id = parseInt($(this).attr('data-id'));
for (var i = 0; i < dlg.accounts.length; ++i) {
if (dlg.accounts[i].id === acc_id) {
$app.dlg_edit_account.show_edit(dlg.host_row_id, dlg.accounts[i]);
return;
}
}
});
// 删除账号
$('#' + dlg.dom_id + ' [data-action="delete-account"]').click(function () {
var acc_id = parseInt($(this).attr('data-id'));
var _fn_sure = function (cb_stack, cb_args) {
// $tp.ajax_post_json('/asset/remove-account', {host_id: dlg.host.id, acc_id: acc_id},
$tp.ajax_post_json('/asset/update-account', {action: 'remove', host_id: dlg.host.id, acc_id: acc_id},
function (ret) {
if (ret.code === TPE_OK) {
// cb_stack.add($app.check_user_list_all_selected);
// cb_stack.add($app.table_user_list.load_data);
$tp.notify_success('删除账号操作成功!');
var update_args = {
acc_count: dlg.host.acc_count - 1
};
$app.table_host.update_row(dlg.host_row_id, update_args);
dlg.load_accounts();
} else {
$tp.notify_error('删除账号操作失败:' + tp_error_msg(ret.code, ret.message));
}
cb_stack.exec();
},
function () {
$tp.notify_error('网络故障,删除用户账号操作失败!');
cb_stack.exec();
}
);
};
var cb_stack = CALLBACK_STACK.create();
$tp.dlg_confirm(cb_stack, {
msg: '<div class="alert alert-danger"><p><strong>注意:删除操作不可恢复!!</strong></p><p>如果您只是想临时禁止以此账号登录远程主机,可以<strong>禁用</strong>此账号。</p><p>您确定要删除此远程账号吗?</p>',
fn_yes: _fn_sure
});
});
// 禁用账号
$('#' + dlg.dom_id + ' [data-action="lock-account"]').click(function () {
var acc_id = parseInt($(this).attr('data-id'));
$tp.ajax_post_json('/asset/update-account', {action: 'lock', host_id: dlg.host.id, acc_id: acc_id},
function (ret) {
if (ret.code === TPE_OK) {
$tp.notify_success('远程账号已禁用!');
dlg.load_accounts();
} else {
$tp.notify_error('禁用远程账号操作失败:' + tp_error_msg(ret.code, ret.message));
}
},
function () {
$tp.notify_error('网络故障,禁用远程账号操作失败!');
}
);
});
// 解禁账号
$('#' + dlg.dom_id + ' [data-action="unlock-account"]').click(function () {
var acc_id = parseInt($(this).attr('data-id'));
$tp.ajax_post_json('/asset/update-account', {action: 'unlock', host_id: dlg.host.id, acc_id: acc_id},
function (ret) {
if (ret.code === TPE_OK) {
$tp.notify_success('远程账号解禁成功!');
dlg.load_accounts();
} else {
$tp.notify_error('远程账号解禁失败:' + tp_error_msg(ret.code, ret.message));
}
},
function () {
$tp.notify_error('网络故障,远程账号解禁失败!');
}
);
});
};
//-------------------------------
// 账号表格相关
//-------------------------------
@ -1579,9 +1426,9 @@ $app.create_dlg_accounts = function () {
}
if (_all_checked) {
$app.dlg_accounts.dom.chkbox_acc_select_all.prop('checked', true);
dlg.dom.chkbox_acc_select_all.prop('checked', true);
} else {
$app.dlg_accounts.dom.chkbox_acc_select_all.prop('checked', false);
dlg.dom.chkbox_acc_select_all.prop('checked', false);
}
if (cb_stack)
@ -1839,7 +1686,6 @@ $app.create_dlg_edit_account = function () {
// 如果id为-1表示创建否则表示更新
$tp.ajax_post_json('/asset/update-account', {
action: 'update',
host_id: dlg.host.id,
acc_id: dlg.field_id,
param: {

View File

@ -1,6 +1,15 @@
"use strict";
var BLUR_BG_COUNT = 8;
var BLUR_BG_IMG = [
'login-bg-0.png',
'login-bg-1.png',
'login-bg-2.png',
'login-bg-3.png',
'login-bg-4.png',
'login-bg-5.png',
'login-bg-6.png',
'login-bg-7.png'
];
var SLOGAN = [
'我感谢那段时光,<br/>因为不曾把我打倒的,<br/>最终让我变得更加强大!',
'宁愿在做事中犯错,<br/>也不要为了不犯错而什么都不做。',
@ -34,6 +43,9 @@ $app.on_init = function (cb_stack) {
message: $('#message')
};
$app.last_img_idx = 0;
$app.last_slogan_idx = 0;
console.log($app.options);
if ($app.options.username.length > 0) {
$app.dom.input_username.val($app.options.username);
@ -207,31 +219,47 @@ $app.on_screen_resize = function () {
};
$app.init_blur_bg = function () {
var img_id = Math.floor(Math.random() * (BLUR_BG_COUNT));
$app.last_img_idx = Math.floor(Math.random() * (BLUR_BG_IMG.length));
$('body').backgroundBlur({
imageURL: '/static/img/login/login-bg-' + img_id + '.png?' + Math.random(),
blurAmount: 10,
imageURL: '/static/img/login/' + BLUR_BG_IMG[$app.last_img_idx] + '?' + Math.random(),
blurAmount: 15,
duration: 1000,
imageClass: 'bg-blur',
overlayClass: 'bg-blur-overlay'
});
setInterval($app._update_blur_bg, 20000);
setInterval($app._update_blur_bg, 20500);
};
$app._update_blur_bg = function () {
var img_id = Math.floor(Math.random() * (BLUR_BG_COUNT));
$('body').backgroundBlur('/static/img/login/login-bg-' + img_id + '.png?' + Math.random());
for(;;) {
var img_id = Math.floor(Math.random() * (BLUR_BG_IMG.length));
if(img_id !== $app.last_img_idx) {
$app.last_img_idx = img_id;
break;
}
}
$('body').backgroundBlur('/static/img/login/' + BLUR_BG_IMG[$app.last_img_idx] + '?' + Math.random());
};
$app.init_slogan = function () {
$app._update_slogan();
setInterval($app._update_slogan, 8000);
$app.last_slogan_idx = Math.floor(Math.random() * SLOGAN.length);
$app.dom.slogan.html(SLOGAN[$app.last_slogan_idx]).fadeIn(1000);
// $app._update_slogan();
setInterval($app._update_slogan, 8100);
};
$app._update_slogan = function () {
var msg_id = Math.floor(Math.random() * SLOGAN.length);
for(;;) {
var msg_id = Math.floor(Math.random() * (SLOGAN.length));
if(msg_id !== $app.last_slogan_idx) {
$app.last_slogan_idx = msg_id;
break;
}
}
$app.dom.slogan.fadeOut(1000, function () {
$(this).html(SLOGAN[msg_id]).fadeIn(1000);
$(this).html(SLOGAN[$app.last_slogan_idx]).fadeIn(1000);
});
};

View File

@ -9,6 +9,16 @@
padding: 20px 25px;
}
.sys-msg {
border: 1px solid #ff8987;
border-radius: 5px;
background-color: #ffbdb7;
padding:10px;
margin-bottom: 10px;
text-align: center;
display: none;
}
.col-sm-1, .col-sm-2, .col-sm-3, .col-sm-4, .col-sm-5, .col-sm-6, .col-sm-7, .col-sm-8, .col-sm-9, .col-sm-10, .col-sm-11, .col-sm-12 {
padding-right: 10px;
padding-left: 10px;
@ -216,7 +226,7 @@
font-size: 130px;
line-height: 130px;
top:5px;
right:-20px;
right:-40px;
position: absolute;
color: rgba(0, 0, 0, 0.07);
}

View File

@ -98,7 +98,7 @@
'name': '审计授权',
},
{
'privilege': const.TP_PRIVILEGE_AUDIT_OPS_HISTORY,
'privilege': const.TP_PRIVILEGE_AUDIT_OPS_HISTORY | const.TP_PRIVILEGE_OPS,
'id': 'record',
'link': '/audit/record',
'name': '会话审计',
@ -180,7 +180,7 @@
</a>
<ul class="sub-menu" id="sidebar_submenu_${menu['id']}" style="display:none;">
%for sub in menu['sub']:
%if menu['privilege'] & current_user['privilege'] != 0:
%if (sub['privilege'] & current_user['privilege']) != 0:
<li id="sidebar_menu_${menu['id']}_${sub['id']}"><a href="${sub['link']}"><span>${sub['name']}</span></a></li>
%endif
%endfor

View File

@ -204,7 +204,7 @@
</div>
<div class="modal fade" id="dlg-accounts" tabindex="-1">
<div class="modal-dialog" role="document">
<div class="modal-dialog" style="width:800px;">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fa fa-times-circle fa-fw"></i></button>
@ -212,8 +212,6 @@
</div>
<div class="modal-body">
<div data-field="account-list"></div>
<div class="table-prefix-area">
<div class="table-extend-cell">
@ -236,27 +234,12 @@
<button id="btn-remove-acc" type="button" class="btn btn-default"><i class="fa fa-times-circle fa-fw"></i> 删除</button>
</div>
</div>
## <div class="table-extend-cell table-item-counter">
## <ol id="table-acc-paging"></ol>
## </div>
</div>
## <div class="table-extend-area">
## <div class="table-extend-cell">
## <div style="text-align:right;">
## <nav>
## <ul id="table-acc-pagination" class="pagination"></ul>
## </nav>
## </div>
## </div>
## </div>
## <button type="button" class="btn btn-sm btn-primary" data-btn="btn-add-account" style="margin-top:8px;"><i class="fa fa-plus-circle fa-fw"></i> 添加账号</button>
</div>
<div class="modal-footer">
<button type="button" class="btn btn-sm btn-default" data-dismiss="modal"><i class="fa fa-close fa-fw"></i> 关闭</button>
<button type="button" class="btn btn-sm btn-default" data-dismiss="modal"><i class="fa fa-close fa-fw"></i> 完成</button>
</div>
</div>
</div>

View File

@ -17,7 +17,7 @@
<div class="container">
<div class="row">
<div id="slogan-box" class="col-md-5">
<div id="msg-slogan"></div>
<div id="msg-slogan" style="display: none;"></div>
</div>
<div class="col-md-6">

View File

@ -17,18 +17,9 @@
<div class="page-content-inner">
<div class="sys-msg">abc</div>
<div class="row">
<div class="col-sm-3">
<div class="stats stats-box stats-id-host">
<div class="stats-icon">
<i class="fa fa-cubes fa-fw"></i>
</div>
<div class="stats-content">
<div class="stats-name">主机</div>
<div class="stats-value">128</div>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="stats stats-box stats-id-user">
<div class="stats-icon">
@ -40,10 +31,21 @@
</div>
</div>
</div>
<div class="col-sm-3">
<div class="stats stats-box stats-id-host">
<div class="stats-icon">
<i class="fa fa-cubes fa-fw"></i>
</div>
<div class="stats-content">
<div class="stats-name">主机</div>
<div class="stats-value">128</div>
</div>
</div>
</div>
<div class="col-sm-3">
<div class="stats stats-box stats-id-account">
<div class="stats-icon">
<i class="fa fa-user-circle fa-fw"></i>
<i class="fa fa-user-secret fa-fw"></i>
</div>
<div class="stats-content">
<div class="stats-name">主机账号</div>

View File

@ -132,7 +132,7 @@ class TPBaseHandler(tornado.web.RequestHandler):
raise RuntimeError("invalid request mode.")
return TPE_NEED_LOGIN
else:
if self._user['privilege'] & require_privilege != 0:
if (self._user['privilege'] & require_privilege) != 0:
return TPE_OK
if self._mode == self.MODE_HTTP:

View File

@ -22,8 +22,8 @@ from . import system
__all__ = ['controllers', 'fix_controller']
controllers = [
# (r'/', index.IndexHandler),
(r'/', user.UserListHandler),
(r'/', index.IndexHandler),
# (r'/', user.UserListHandler),
# ====================================================
# 控制台
@ -121,10 +121,10 @@ controllers = [
(r'/asset/account-group', account.AccGroupListHandler),
# - 某个账号组的管理页面
(r'/asset/account-group/(.*)', account.AccGroupInfoHandler),
# - [json] 添加/更新/删除/禁用/解禁 远程账号
# - [json] 添加/更新 远程账号
(r'/asset/update-account', account.DoUpdateAccountHandler),
# - [json] 删除账号
# (r'/asset/remove-account', account.DoRemoveAccountHandler),
# - [json] 禁用/解禁/删除 远程账号
(r'/asset/update-accounts', account.DoUpdateAccountsHandler),
# - [json] 获取账号列表
(r'/asset/get-accounts', account.DoGetAccountsHandler),
# - [json] 获取账号组列表包括不超过5个组内成员

View File

@ -212,72 +212,93 @@ class DoUpdateAccountHandler(TPBaseJsonHandler):
return self.write_json(TPE_JSON_FORMAT)
try:
action = args['action']
host_id = int(args['host_id'])
acc_id = int(args['acc_id'])
except:
log.e('\n')
return self.write_json(TPE_PARAM)
if action == 'remove':
err = account.remove_account(self, host_id, acc_id)
return self.write_json(err)
elif action == 'lock':
err = account.update_account_state(self, host_id, acc_id, TP_STATE_DISABLED)
return self.write_json(err)
elif action == 'unlock':
err = account.update_account_state(self, host_id, acc_id, TP_STATE_NORMAL)
return self.write_json(err)
elif action == 'update':
try:
param = dict()
# args['id'] = int(args['id'])
# args['host_id'] = int(args['host_id'])
param['host_ip'] = args['param']['host_ip']
param['router_ip'] = args['param']['router_ip']
param['router_port'] = args['param']['router_port']
param['protocol_type'] = int(args['param']['protocol'])
param['protocol_port'] = int(args['param']['port'])
param['auth_type'] = int(args['param']['auth_type'])
param['username'] = args['param']['username'].strip()
param['password'] = args['param']['password']
param['pri_key'] = args['param']['pri_key'].strip()
except:
log.e('\n')
return self.write_json(TPE_PARAM)
if len(param['username']) == 0:
return self.write_json(TPE_PARAM)
if acc_id == -1:
# 新增账号
if param['auth_type'] == TP_AUTH_TYPE_PASSWORD and len(param['password']) == 0:
return self.write_json(TPE_PARAM)
elif param['auth_type'] == TP_AUTH_TYPE_PRIVATE_KEY and len(param['pri_key']) == 0:
return self.write_json(TPE_PARAM)
if param['auth_type'] == TP_AUTH_TYPE_PASSWORD and len(param['password']) > 0:
code, ret_data = yield core_service_async_enc(param['password'])
if code != TPE_OK:
return self.write_json(code, '无法加密存储密码!')
else:
param['password'] = ret_data
elif param['auth_type'] == TP_AUTH_TYPE_PRIVATE_KEY and len(param['pri_key']) > 0:
code, ret_data = yield core_service_async_enc(param['pri_key'])
if code != TPE_OK:
return self.write_json(code, '无法加密存储私钥!')
else:
param['pri_key'] = ret_data
if acc_id == -1:
err, info = account.add_account(self, host_id, param)
else:
err = account.update_account(self, host_id, acc_id, param)
info = {}
return self.write_json(err, data=info)
else:
try:
param = dict()
param['host_ip'] = args['param']['host_ip']
param['router_ip'] = args['param']['router_ip']
param['router_port'] = args['param']['router_port']
param['protocol_type'] = int(args['param']['protocol'])
param['protocol_port'] = int(args['param']['port'])
param['auth_type'] = int(args['param']['auth_type'])
param['username'] = args['param']['username'].strip()
param['password'] = args['param']['password']
param['pri_key'] = args['param']['pri_key'].strip()
except:
log.e('\n')
return self.write_json(TPE_PARAM)
if len(param['username']) == 0:
return self.write_json(TPE_PARAM)
if acc_id == -1:
# 新增账号
if param['auth_type'] == TP_AUTH_TYPE_PASSWORD and len(param['password']) == 0:
return self.write_json(TPE_PARAM)
elif param['auth_type'] == TP_AUTH_TYPE_PRIVATE_KEY and len(param['pri_key']) == 0:
return self.write_json(TPE_PARAM)
if param['auth_type'] == TP_AUTH_TYPE_PASSWORD and len(param['password']) > 0:
code, ret_data = yield core_service_async_enc(param['password'])
if code != TPE_OK:
return self.write_json(code, '无法加密存储密码!')
else:
param['password'] = ret_data
elif param['auth_type'] == TP_AUTH_TYPE_PRIVATE_KEY and len(param['pri_key']) > 0:
code, ret_data = yield core_service_async_enc(param['pri_key'])
if code != TPE_OK:
return self.write_json(code, '无法加密存储私钥!')
else:
param['pri_key'] = ret_data
if acc_id == -1:
err, info = account.add_account(self, host_id, param)
else:
err = account.update_account(self, host_id, acc_id, param)
info = {}
self.write_json(err, data=info)
class DoUpdateAccountsHandler(TPBaseJsonHandler):
@tornado.gen.coroutine
def post(self):
ret = self.check_privilege(TP_PRIVILEGE_ACCOUNT | TP_PRIVILEGE_ACCOUNT_GROUP)
if ret != TPE_OK:
return
args = self.get_argument('args', None)
if args is None:
return self.write_json(TPE_PARAM)
try:
args = json.loads(args)
except:
return self.write_json(TPE_JSON_FORMAT)
try:
action = args['action']
host_id = int(args['host_id'])
accounts = args['accounts']
except:
log.e('\n')
return self.write_json(TPE_PARAM)
if action == 'remove':
err = account.remove_accounts(self, host_id, accounts)
return self.write_json(err)
elif action == 'lock':
err = account.update_accounts_state(self, host_id, accounts, TP_STATE_DISABLED)
return self.write_json(err)
elif action == 'unlock':
err = account.update_accounts_state(self, host_id, accounts, TP_STATE_NORMAL)
return self.write_json(err)
else:
return self.write_json(TPE_PARAM)
# class DoRemoveAccountHandler(TPBaseJsonHandler):
# def post(self):

View File

@ -45,7 +45,7 @@ def get_free_space_bytes(folder):
class RecordHandler(TPBaseHandler):
def get(self):
ret = self.check_privilege(TP_PRIVILEGE_OPS_AUZ | TP_PRIVILEGE_AUDIT_AUZ | TP_PRIVILEGE_AUDIT_OPS_HISTORY)
ret = self.check_privilege(TP_PRIVILEGE_OPS | TP_PRIVILEGE_OPS_AUZ | TP_PRIVILEGE_AUDIT_AUZ | TP_PRIVILEGE_AUDIT_OPS_HISTORY)
if ret != TPE_OK:
return
@ -66,7 +66,9 @@ class RecordHandler(TPBaseHandler):
class DoGetRecordsHandler(TPBaseJsonHandler):
def post(self):
# return self.write_json(0, data=[])
ret = self.check_privilege(TP_PRIVILEGE_OPS | TP_PRIVILEGE_OPS_AUZ | TP_PRIVILEGE_AUDIT_AUZ | TP_PRIVILEGE_AUDIT_OPS_HISTORY)
if ret != TPE_OK:
return
args = self.get_argument('args', None)
if args is None:

View File

@ -1,9 +1,13 @@
# -*- coding: utf-8 -*-
# import tornado.ioloop
from app.const import *
from app.base.controller import TPBaseHandler
class IndexHandler(TPBaseHandler):
def get(self):
ret = self.check_privilege(TP_PRIVILEGE_LOGIN_WEB)
if ret != TPE_OK:
return
self.render('dashboard/index.mako')

View File

@ -9,7 +9,17 @@ from tornado.escape import json_encode
class IndexHandler(TPBaseHandler):
def get(self):
# self.redirect('/system/role')
ret = self.check_privilege(TP_PRIVILEGE_LOGIN_WEB)
if ret != TPE_OK:
return
up = self._user['privilege']
if (up & TP_PRIVILEGE_SYS_CONFIG) != 0:
return self.redirect('/dashboard')
elif (up & TP_PRIVILEGE_OPS) != 0:
return self.redirect('/ops/remote')
self.redirect('/user/me')

View File

@ -225,7 +225,7 @@ def update_account(handler, host_id, acc_id, args):
db = get_db()
# 1. 判断是否存在
sql = 'SELECT id FROM {}acc WHERE id={};'.format(db.table_prefix, acc_id)
sql = 'SELECT id FROM {}acc WHERE host_id={host_id} AND id={acc_id};'.format(db.table_prefix, host_id=host_id, acc_id=acc_id)
db_ret = db.query(sql)
if db_ret is None or len(db_ret) == 0:
return TPE_NOT_EXISTS
@ -254,28 +254,29 @@ def update_account(handler, host_id, acc_id, args):
return TPE_OK
def update_account_state(handler, host_id, acc_id, state):
def update_accounts_state(handler, host_id, acc_ids, state):
db = get_db()
acc_ids = ','.join([str(uid) for uid in acc_ids])
# 1. 判断是否存在
sql = 'SELECT id FROM {}acc WHERE host_id={host_id} AND id={acc_id};'.format(db.table_prefix, host_id=host_id, acc_id=acc_id)
sql = 'SELECT id FROM {}acc WHERE host_id={host_id} AND id IN ({ids});'.format(db.table_prefix, host_id=host_id, ids=acc_ids)
db_ret = db.query(sql)
if db_ret is None or len(db_ret) == 0:
return TPE_NOT_EXISTS
sql_list = []
sql = 'UPDATE `{}acc` SET state={state} WHERE id={acc_id};' \
''.format(db.table_prefix, state=state, acc_id=acc_id)
sql = 'UPDATE `{}acc` SET state={state} WHERE id IN ({ids});' \
''.format(db.table_prefix, state=state, ids=acc_ids)
sql_list.append(sql)
# sync to update the ops-audit table.
sql = 'UPDATE `{}ops_auz` SET state={state} WHERE rtype={rtype} AND rid={rid};' \
''.format(db.table_prefix, state=state, rtype=TP_ACCOUNT, rid=acc_id)
sql = 'UPDATE `{}ops_auz` SET state={state} WHERE rtype={rtype} AND rid IN ({rid});' \
''.format(db.table_prefix, state=state, rtype=TP_ACCOUNT, rid=acc_ids)
sql_list.append(sql)
sql = 'UPDATE `{}ops_map` SET a_state={state} WHERE a_id={acc_id};' \
''.format(db.table_prefix, state=state, acc_id=acc_id)
sql = 'UPDATE `{}ops_map` SET a_state={state} WHERE a_id IN ({acc_id});' \
''.format(db.table_prefix, state=state, acc_id=acc_ids)
sql_list.append(sql)
if db.transaction(sql_list):
@ -284,48 +285,74 @@ def update_account_state(handler, host_id, acc_id, state):
return TPE_DATABASE
def remove_account(handler, host_id, acc_id):
def remove_accounts(handler, host_id, acc_ids):
"""
删除一个远程账号
删除远程账号
"""
db = get_db()
acc_count = len(acc_ids)
print(acc_count)
acc_ids = ','.join([str(uid) for uid in acc_ids])
# 1. 判断是否存在
s = SQL(db)
s.select_from('acc', ['host_ip', 'router_ip', 'router_port', 'username'], alt_name='a')
s.where('a.id={} AND a.host_id={}'.format(acc_id, host_id))
# 1. 判断是否存在
s.select_from('host', ['acc_count'], alt_name='a')
s.where('a.id={h_id}'.format(h_id=host_id, ids=acc_ids))
err = s.query()
if err != TPE_OK:
return err
if len(s.recorder) == 0:
return TPE_NOT_EXISTS
print(s.recorder)
s.reset().select_from('acc', ['host_ip', 'router_ip', 'router_port', 'username'], alt_name='a')
s.where('a.host_id={h_id} AND a.id IN ({ids}) '.format(h_id=host_id, ids=acc_ids))
err = s.query()
if err != TPE_OK:
return err
if len(s.recorder) == 0:
return TPE_NOT_EXISTS
acc_name = '{}@{}'.format(s.recorder[0]['username'], s.recorder[0]['host_ip'])
if len(s.recorder[0]['router_ip']) > 0:
acc_name += '(由{}:{}路由)'.format(s.recorder[0]['router_ip'], s.recorder[0]['router_port'])
acc_names = []
for a in s.recorder:
acc_name = '{}@{}'.format(a.username, a.host_ip)
if len(a.router_ip) > 0:
acc_name += '(由{}:{}路由)'.format(a.router_ip, a.router_port)
acc_names.append(acc_name)
sql_list = []
sql = 'DELETE FROM `{}group_map` WHERE type={} AND mid={};'.format(db.table_prefix, TP_GROUP_ACCOUNT, acc_id)
sql = 'DELETE FROM `{}acc` WHERE host_id={} AND id IN ({});'.format(db.table_prefix, host_id, acc_ids)
sql_list.append(sql)
sql = 'DELETE FROM `{}acc` WHERE id={} AND host_id={};'.format(db.table_prefix, acc_id, host_id)
sql = 'DELETE FROM `{}group_map` WHERE type={} AND mid IN ({});'.format(db.table_prefix, TP_GROUP_ACCOUNT, acc_ids)
sql_list.append(sql)
# 更新主机相关账号数量
sql = 'UPDATE `{}host` SET acc_count=acc_count-1 WHERE id={host_id};'.format(db.table_prefix, host_id=host_id)
sql = 'UPDATE `{}host` SET acc_count=acc_count-{acc_count} WHERE id={host_id};'.format(db.table_prefix, acc_count=acc_count, host_id=host_id)
sql_list.append(sql)
sql = 'DELETE FROM `{}ops_auz` WHERE rtype={rtype} AND rid={rid};'.format(db.table_prefix, rtype=TP_ACCOUNT, rid=acc_id)
sql = 'DELETE FROM `{}ops_auz` WHERE rtype={rtype} AND rid IN ({rid});'.format(db.table_prefix, rtype=TP_ACCOUNT, rid=acc_ids)
sql_list.append(sql)
sql = 'DELETE FROM `{}ops_map` WHERE a_id={acc_id};'.format(db.table_prefix, acc_id=acc_id)
sql = 'DELETE FROM `{}ops_map` WHERE a_id IN ({acc_id});'.format(db.table_prefix, acc_id=acc_ids)
sql_list.append(sql)
if not db.transaction(sql_list):
return TPE_DATABASE
syslog.sys_log(handler.get_current_user(), handler.request.remote_ip, TPE_OK, "删除账号:{}".format(acc_name))
s.reset().select_from('host', ['acc_count'], alt_name='a')
s.where('a.id={h_id}'.format(h_id=host_id, ids=acc_ids))
err = s.query()
if err != TPE_OK:
return err
if len(s.recorder) == 0:
return TPE_NOT_EXISTS
print(s.recorder)
syslog.sys_log(handler.get_current_user(), handler.request.remote_ip, TPE_OK, "删除账号:{}".format(''.join(acc_names)))
return TPE_OK

View File

@ -229,7 +229,7 @@ def update_host(handler, args):
sql_list.append(sql)
# 更新所有此主机相关的账号
sql = 'UPDATE `{}acc` SET ip="{ip}", router_ip="{router_ip}", router_port={router_port} WHERE host_id={id};' \
sql = 'UPDATE `{}acc` SET host_ip="{ip}", router_ip="{router_ip}", router_port={router_port} WHERE host_id={id};' \
''.format(db.table_prefix,
ip=args['ip'], router_ip=args['router_ip'], router_port=args['router_port'], id=args['id'])
sql_list.append(sql)