mirror of https://github.com/tp4a/teleport
add audit policy, not completed yet.
parent
0171e54acb
commit
940bc682e9
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,683 @@
|
||||||
|
"use strict";
|
||||||
|
|
||||||
|
$app.on_init = function (cb_stack) {
|
||||||
|
$app.dom = {
|
||||||
|
btn_refresh_policy: $('#btn-refresh-policy'),
|
||||||
|
btn_create_policy: $('#btn-create-policy'),
|
||||||
|
select_all_policy: $('#table-auz-select-all'),
|
||||||
|
|
||||||
|
btn_lock: $('#btn-lock'),
|
||||||
|
btn_unlock: $('#btn-unlock'),
|
||||||
|
btn_remove: $('#btn-remove')
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.drag = {
|
||||||
|
dragging: false,
|
||||||
|
drag_row_id: '0',
|
||||||
|
hover_row_id: '0',
|
||||||
|
drag_index: -1,
|
||||||
|
hover_index: -1,
|
||||||
|
insert_before: true, // 是插入到拖放目标之前还是之后
|
||||||
|
items: [],
|
||||||
|
|
||||||
|
dom: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
$('#btn-rebuild').click(function () {
|
||||||
|
$app.on_rebuild();
|
||||||
|
});
|
||||||
|
|
||||||
|
$(document).mousemove(function (e) {
|
||||||
|
$app.on_dragging(e);
|
||||||
|
}).mouseup(function (e) {
|
||||||
|
$app.on_drag_end(e);
|
||||||
|
});
|
||||||
|
|
||||||
|
cb_stack
|
||||||
|
.add($app.create_controls)
|
||||||
|
.add($app.load_role_list);
|
||||||
|
|
||||||
|
cb_stack.exec();
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.on_rebuild = function () {
|
||||||
|
$tp.ajax_post_json('/audit/build-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('网络故障,重建授权映射成功失败!');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
//===================================
|
||||||
|
// 创建页面控件对象
|
||||||
|
//===================================
|
||||||
|
$app.create_controls = function (cb_stack) {
|
||||||
|
|
||||||
|
//-------------------------------
|
||||||
|
// 资产列表表格
|
||||||
|
//-------------------------------
|
||||||
|
var table_policy_options = {
|
||||||
|
dom_id: 'table-policy',
|
||||||
|
data_source: {
|
||||||
|
type: 'ajax-post',
|
||||||
|
url: '/audit/get-policies'
|
||||||
|
},
|
||||||
|
column_default: {sort: false, align: 'left'},
|
||||||
|
columns: [
|
||||||
|
{
|
||||||
|
//title: '<a href="javascript:;" data-reset-filter><i class="fa fa-rotate-left fa-fw"></i></a>',
|
||||||
|
title: '',
|
||||||
|
key: 'chkbox',
|
||||||
|
sort: false,
|
||||||
|
width: 36,
|
||||||
|
align: 'center',
|
||||||
|
render: 'make_check_box',
|
||||||
|
fields: {id: 'id'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '顺序',
|
||||||
|
key: 'rank',
|
||||||
|
// sort: true,
|
||||||
|
align: 'center',
|
||||||
|
width: 60,
|
||||||
|
// header_render: 'filter_search',
|
||||||
|
render: 'rank',
|
||||||
|
fields: {rank: 'rank'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '授权策略',
|
||||||
|
key: 'name',
|
||||||
|
// sort: true,
|
||||||
|
// header_render: 'filter_search',
|
||||||
|
render: 'policy_info',
|
||||||
|
fields: {id: 'id', name: 'name', desc: 'desc'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: "状态",
|
||||||
|
key: "state",
|
||||||
|
// sort: true,
|
||||||
|
width: 90,
|
||||||
|
align: 'center',
|
||||||
|
//header_render: 'filter_state',
|
||||||
|
render: 'state',
|
||||||
|
fields: {state: 'state'}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
title: '',
|
||||||
|
key: 'action',
|
||||||
|
// sort: false,
|
||||||
|
align: 'center',
|
||||||
|
width: 80,
|
||||||
|
render: 'make_action_btn',
|
||||||
|
fields: {id: 'id', state: 'state'}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
|
||||||
|
// 重载回调函数
|
||||||
|
on_header_created: $app.on_table_policy_header_created,
|
||||||
|
on_render_created: $app.on_table_policy_render_created,
|
||||||
|
on_cell_created: $app.on_table_policy_cell_created
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.table_policy = $tp.create_table(table_policy_options);
|
||||||
|
cb_stack
|
||||||
|
.add($app.table_policy.load_data)
|
||||||
|
.add($app.table_policy.init);
|
||||||
|
|
||||||
|
//-------------------------------
|
||||||
|
// 用户列表相关过滤器
|
||||||
|
//-------------------------------
|
||||||
|
$tp.create_table_header_filter_search($app.table_policy, {
|
||||||
|
name: 'search',
|
||||||
|
place_holder: '搜索:授权策略名称/描述/等等...'
|
||||||
|
});
|
||||||
|
$tp.create_table_header_filter_state($app.table_policy, 'state', $app.obj_states, [TP_STATE_LOCKED]);
|
||||||
|
// 从cookie中读取用户分页限制的选择
|
||||||
|
$tp.create_table_paging($app.table_policy, 'table-auz-paging',
|
||||||
|
{
|
||||||
|
per_page: Cookies.get($app.page_id('ops_auz') + '_per_page'),
|
||||||
|
on_per_page_changed: function (per_page) {
|
||||||
|
Cookies.set($app.page_id('ops_auz') + '_per_page', per_page, {expires: 365});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$tp.create_table_pagination($app.table_policy, 'table-auz-pagination');
|
||||||
|
|
||||||
|
//-------------------------------
|
||||||
|
// 对话框
|
||||||
|
//-------------------------------
|
||||||
|
$app.dlg_edit_policy = $app.create_dlg_edit_policy();
|
||||||
|
cb_stack.add($app.dlg_edit_policy.init);
|
||||||
|
|
||||||
|
//-------------------------------
|
||||||
|
// 页面控件事件绑定
|
||||||
|
//-------------------------------
|
||||||
|
$app.dom.btn_create_policy.click(function () {
|
||||||
|
// $app.dom.dlg_edit_user.modal();
|
||||||
|
$app.dlg_edit_policy.show_add();
|
||||||
|
});
|
||||||
|
$app.dom.btn_refresh_policy.click(function () {
|
||||||
|
$app.table_policy.load_data();
|
||||||
|
});
|
||||||
|
$app.dom.select_all_policy.click(function () {
|
||||||
|
var _objects = $('#' + $app.table_policy.dom_id + ' tbody').find('[data-check-box]');
|
||||||
|
if ($(this).is(':checked')) {
|
||||||
|
$.each(_objects, function (i, _obj) {
|
||||||
|
$(_obj).prop('checked', true);
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
$.each(_objects, function (i, _obj) {
|
||||||
|
$(_obj).prop('checked', false);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
$app.dom.btn_lock.click($app.on_btn_lock_click);
|
||||||
|
$app.dom.btn_unlock.click($app.on_btn_unlock_click);
|
||||||
|
$app.dom.btn_remove.click($app.on_btn_remove_click);
|
||||||
|
|
||||||
|
cb_stack.exec();
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.on_table_policy_cell_created = function (tbl, row_id, col_key, cell_obj) {
|
||||||
|
if (col_key === 'chkbox') {
|
||||||
|
cell_obj.find('[data-check-box]').click(function () {
|
||||||
|
$app.check_host_all_selected();
|
||||||
|
});
|
||||||
|
} else if (col_key === 'rank') {
|
||||||
|
cell_obj.find('.reorder').mousedown(function (e) {
|
||||||
|
$app.on_drag_begin(e, row_id);
|
||||||
|
});
|
||||||
|
} else if (col_key === 'action') {
|
||||||
|
// 绑定系统选择框事件
|
||||||
|
cell_obj.find('[data-action]').click(function () {
|
||||||
|
var action = $(this).attr('data-action');
|
||||||
|
if (action === 'edit') {
|
||||||
|
$app.dlg_edit_policy.show_edit(row_id);
|
||||||
|
// } else if (action === 'account') {
|
||||||
|
// $app.dlg_accounts.show(row_id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
} else if (col_key === 'name') {
|
||||||
|
cell_obj.find('[data-action="edit-policy"]').click(function () {
|
||||||
|
$app.dlg_accounts.show(row_id);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.on_drag_begin = function (e, row_id) {
|
||||||
|
$(document).bind('selectstart', function () {
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$app.drag = {
|
||||||
|
dragging: false,
|
||||||
|
drag_row_id: '0',
|
||||||
|
hover_row_id: '0',
|
||||||
|
drag_index: -1,
|
||||||
|
hover_index: -1,
|
||||||
|
items: [],
|
||||||
|
|
||||||
|
dom: {}
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.drag.drag_row_id = row_id;
|
||||||
|
|
||||||
|
var body = $('body');
|
||||||
|
// create a drag-div
|
||||||
|
var policy = $app.table_policy.get_row(row_id);
|
||||||
|
|
||||||
|
body.after($('<div id="tp-drag-move-box" style="display:none;position:absolute;font-size:13px;cursor:move;opacity:0.7;padding:5px;background:#999;border:1px solid #666;"><i class="fa fa-reorder fa-fw"></i> ' + policy.rank + ' ' + policy.name + '</div>'));
|
||||||
|
|
||||||
|
$app.drag.dom.move_box = $('#tp-drag-move-box');
|
||||||
|
$app.drag.move_box_height = $app.drag.dom.move_box.height();
|
||||||
|
$app.drag.dom.move_box.css({left: e.pageX - 5, top: e.pageY - $app.drag.move_box_height / 2}).show();
|
||||||
|
|
||||||
|
// create a location-pointer
|
||||||
|
body.after($('<div id="tp-drag-insert" style="display:none;position:absolute;color:#97d262"><i class="fa fa-chevron-right fa-fw"></i></div>'));
|
||||||
|
$app.drag.dom.loc_insert = $('#tp-drag-insert');
|
||||||
|
|
||||||
|
var tr_item = $('tr[data-row-id]');
|
||||||
|
for (var i = 0; i < tr_item.length; ++i) {
|
||||||
|
var item = $(tr_item[i]);
|
||||||
|
var _row_id = item.attr('data-row-id');
|
||||||
|
if (_row_id === row_id)
|
||||||
|
$app.drag.drag_index = i;
|
||||||
|
$app.drag.items.push([item.offset().top, item.offset().top + item.height(), _row_id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
$app.drag.dragging = true;
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.on_dragging = function (e) {
|
||||||
|
if (!$app.drag.dragging)
|
||||||
|
return;
|
||||||
|
|
||||||
|
$app.drag.dom.move_box.css({left: e.pageX - 5, top: e.pageY - $app.drag.move_box_height / 2});
|
||||||
|
|
||||||
|
// check which <tr> we are moving on.
|
||||||
|
$app.drag.hover_row_id = null;
|
||||||
|
for (var i = 0; i < $app.drag.items.length; ++i) {
|
||||||
|
if (e.pageY < $app.drag.items[i][0])
|
||||||
|
continue;
|
||||||
|
if (e.pageY > $app.drag.items[i][1])
|
||||||
|
continue;
|
||||||
|
if ($app.drag_row_id === $app.drag.items[i][2])
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if ($app.drag.drag_row_id === $app.drag.items[i][2])
|
||||||
|
break;
|
||||||
|
|
||||||
|
var idx = -1;
|
||||||
|
if (e.pageY <= $app.drag.items[i][0] + ($app.drag.items[i][1] - $app.drag.items[i][0]) / 2) {
|
||||||
|
$app.drag.insert_before = true;
|
||||||
|
idx = i - 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$app.drag.insert_before = false;
|
||||||
|
idx = i + 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (idx === $app.drag.drag_index)
|
||||||
|
break;
|
||||||
|
|
||||||
|
$app.drag.hover_row_id = $app.drag.items[i][2];
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($app.drag.hover_row_id === null) {
|
||||||
|
$app.drag.dom.loc_insert.hide();
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
$app.drag.dom.loc_insert.show();
|
||||||
|
}
|
||||||
|
|
||||||
|
var hover_obj = $('tr[data-row-id="' + $app.drag.hover_row_id + '"]');
|
||||||
|
|
||||||
|
|
||||||
|
var x = hover_obj.offset().left - $app.drag.dom.loc_insert.width();
|
||||||
|
var y = 0;
|
||||||
|
if ($app.drag.insert_before)
|
||||||
|
y = hover_obj.offset().top - $app.drag.dom.loc_insert.height() / 2;
|
||||||
|
else
|
||||||
|
y = hover_obj.offset().top + hover_obj.height() - $app.drag.dom.loc_insert.height() / 2;
|
||||||
|
$app.drag.dom.loc_insert.css({left: x, top: y});
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.on_drag_end = function (e) {
|
||||||
|
if (!$app.drag.dragging)
|
||||||
|
return;
|
||||||
|
|
||||||
|
$app.drag.dom.move_box.remove();
|
||||||
|
$app.drag.dom.loc_insert.remove();
|
||||||
|
$(document).unbind('selectstart');
|
||||||
|
$app.drag.dragging = false;
|
||||||
|
|
||||||
|
if ($app.drag.hover_row_id === null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var policy_drag = $app.table_policy.get_row($app.drag.drag_row_id);
|
||||||
|
var policy_target = $app.table_policy.get_row($app.drag.hover_row_id);
|
||||||
|
|
||||||
|
var direct = -1; // 移动方向,-1=向前移动,1=向后移动
|
||||||
|
var start_rank = 0, end_rank = 0; // 导致rank变化的范围: start_rank <= rank <= end_rank
|
||||||
|
var new_rank = 0;//policy_target.rank; // 被移动的条目的新rank
|
||||||
|
|
||||||
|
if (policy_drag.rank > policy_target.rank) {
|
||||||
|
// 这是向前移动
|
||||||
|
direct = 1;
|
||||||
|
end_rank = policy_drag.rank - 1;
|
||||||
|
if ($app.drag.insert_before) {
|
||||||
|
new_rank = policy_target.rank;
|
||||||
|
start_rank = policy_target.rank;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
new_rank = policy_target.rank + 1;
|
||||||
|
start_rank = policy_target.rank + 1;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
// 这是向后移动
|
||||||
|
direct = -1;
|
||||||
|
start_rank = policy_drag.rank + 1;
|
||||||
|
if ($app.drag.insert_before) {
|
||||||
|
new_rank = policy_target.rank - 1;
|
||||||
|
end_rank = policy_target.rank - 1;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
new_rank = policy_target.rank;
|
||||||
|
end_rank = policy_target.rank;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
$tp.ajax_post_json('/audit/policy/rank-reorder', {
|
||||||
|
pid: policy_drag.id,
|
||||||
|
new_rank: new_rank,
|
||||||
|
start_rank: start_rank,
|
||||||
|
end_rank: end_rank,
|
||||||
|
direct: direct
|
||||||
|
},
|
||||||
|
function (ret) {
|
||||||
|
if (ret.code === TPE_OK) {
|
||||||
|
$tp.notify_success('授权策略顺序调整成功!');
|
||||||
|
$app.table_policy.load_data();
|
||||||
|
} else {
|
||||||
|
$tp.notify_error('授权策略顺序调整失败:' + tp_error_msg(ret.code, ret.message));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
$tp.notify_error('网络故障,授权策略顺序调整失败!');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.check_host_all_selected = function (cb_stack) {
|
||||||
|
var _all_checked = true;
|
||||||
|
var _objs = $('#' + $app.table_policy.dom_id + ' tbody').find('[data-check-box]');
|
||||||
|
if (_objs.length === 0) {
|
||||||
|
_all_checked = false;
|
||||||
|
} else {
|
||||||
|
$.each(_objs, function (i, _obj) {
|
||||||
|
if (!$(_obj).is(':checked')) {
|
||||||
|
_all_checked = false;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (_all_checked) {
|
||||||
|
$app.dom.select_all_policy.prop('checked', true);
|
||||||
|
} else {
|
||||||
|
$app.dom.select_all_policy.prop('checked', false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cb_stack)
|
||||||
|
cb_stack.exec();
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.on_table_policy_render_created = function (render) {
|
||||||
|
|
||||||
|
// render.filter_search = function (header, title, col) {
|
||||||
|
// var _ret = ['<div class="tp-table-filter tp-table-filter-input">'];
|
||||||
|
// _ret.push('<div class="tp-table-filter-inner">');
|
||||||
|
// _ret.push('<div class="search-title">' + title + '</div>');
|
||||||
|
//
|
||||||
|
// // 表格内嵌过滤器的DOM实体在这时生成
|
||||||
|
// var filter_ctrl = header._table_ctrl.get_filter_ctrl('search');
|
||||||
|
// _ret.push(filter_ctrl.render());
|
||||||
|
//
|
||||||
|
// _ret.push('</div></div>');
|
||||||
|
//
|
||||||
|
// return _ret.join('');
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// render.filter_state = function (header, title, col) {
|
||||||
|
// var _ret = ['<div class="tp-table-filter tp-table-filter-' + col.cell_align + '">'];
|
||||||
|
// _ret.push('<div class="tp-table-filter-inner">');
|
||||||
|
// _ret.push('<div class="search-title">' + title + '</div>');
|
||||||
|
//
|
||||||
|
// // 表格内嵌过滤器的DOM实体在这时生成
|
||||||
|
// var filter_ctrl = header._table_ctrl.get_filter_ctrl('state');
|
||||||
|
// _ret.push(filter_ctrl.render());
|
||||||
|
//
|
||||||
|
// _ret.push('</div></div>');
|
||||||
|
//
|
||||||
|
// return _ret.join('');
|
||||||
|
// };
|
||||||
|
|
||||||
|
render.rank = function (row_id, fields) {
|
||||||
|
return '<span class="reorder"><i class="fa fa-reorder fa-fw"></i> ' + fields.rank + '</span>'
|
||||||
|
};
|
||||||
|
|
||||||
|
render.make_check_box = function (row_id, fields) {
|
||||||
|
return '<span><input type="checkbox" data-check-box="' + fields.id + '" data-row-id="' + row_id + '"></span>';
|
||||||
|
};
|
||||||
|
|
||||||
|
render.policy_info = function (row_id, fields) {
|
||||||
|
return '<a href="/audit/policy/detail/' + fields.id + '">' + fields.name + '</a><span class="policy-desc">' + fields.desc + '</span>'
|
||||||
|
};
|
||||||
|
|
||||||
|
render.state = function (row_id, fields) {
|
||||||
|
var _style, _state;
|
||||||
|
|
||||||
|
for (var i = 0; i < $app.obj_states.length; ++i) {
|
||||||
|
if ($app.obj_states[i].id === fields.state) {
|
||||||
|
_style = $app.obj_states[i].style;
|
||||||
|
_state = $app.obj_states[i].name;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (i === $app.obj_states.length) {
|
||||||
|
_style = 'info';
|
||||||
|
_state = '<i class="fa fa-question-circle"></i> 未知';
|
||||||
|
}
|
||||||
|
|
||||||
|
return '<span class="label label-sm label-' + _style + '">' + _state + '</span>'
|
||||||
|
};
|
||||||
|
|
||||||
|
render.make_action_btn = function (row_id, fields) {
|
||||||
|
var ret = [];
|
||||||
|
ret.push('<div class="btn-group btn-group-sm" role="group">');
|
||||||
|
ret.push('<btn class="btn btn-primary" data-action="edit"><i class="fa fa-edit"></i> 编辑</btn>');
|
||||||
|
// ret.push('<btn class="btn btn-info" data-btn-disable="' + fields.id + '"><i class="fa fa-trash-o"></i> 禁用</btn>');
|
||||||
|
// ret.push('<btn class="btn btn-danger" data-btn-remove="' + fields.id + '"><i class="fa fa-trash-o"></i> 删除</btn>');
|
||||||
|
ret.push('</div>');
|
||||||
|
return ret.join('');
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.on_table_policy_header_created = function (header) {
|
||||||
|
// $('#' + header._table_ctrl.dom_id + ' a[data-reset-filter]').click(function () {
|
||||||
|
// CALLBACK_STACK.create()
|
||||||
|
// .add(header._table_ctrl.load_data)
|
||||||
|
// .add(header._table_ctrl.reset_filters)
|
||||||
|
// .exec();
|
||||||
|
// });
|
||||||
|
|
||||||
|
// 表格内嵌过滤器的事件绑定在这时进行(也可以延期到整个表格创建完成时进行)
|
||||||
|
// header._table_ctrl.get_filter_ctrl('search').on_created();
|
||||||
|
// header._table_ctrl.get_filter_ctrl('state').on_created();
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.get_selected_policy = function (tbl) {
|
||||||
|
var users = [];
|
||||||
|
var _objs = $('#' + $app.table_policy.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;
|
||||||
|
users.push(_row_data.id);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
return users;
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.on_btn_lock_click = function () {
|
||||||
|
var items = $app.get_selected_policy($app.table_policy);
|
||||||
|
if (items.length === 0) {
|
||||||
|
$tp.notify_error('请选择要禁用的授权策略!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$tp.ajax_post_json('/audit/policies/update', {
|
||||||
|
action: 'lock',
|
||||||
|
policy_ids: items
|
||||||
|
},
|
||||||
|
function (ret) {
|
||||||
|
if (ret.code === TPE_OK) {
|
||||||
|
CALLBACK_STACK.create()
|
||||||
|
.add($app.check_host_all_selected)
|
||||||
|
.add($app.table_policy.load_data)
|
||||||
|
.exec();
|
||||||
|
$tp.notify_success('禁用授权策略操作成功!');
|
||||||
|
} else {
|
||||||
|
$tp.notify_error('禁用授权策略操作失败:' + tp_error_msg(ret.code, ret.message));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
$tp.notify_error('网络故障,禁用授权策略操作失败!');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.on_btn_unlock_click = function () {
|
||||||
|
var items = $app.get_selected_policy($app.table_policy);
|
||||||
|
if (items.length === 0) {
|
||||||
|
$tp.notify_error('请选择要解禁的授权策略!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
$tp.ajax_post_json('/audit/policies/update', {
|
||||||
|
action: 'unlock',
|
||||||
|
policy_ids: items
|
||||||
|
},
|
||||||
|
function (ret) {
|
||||||
|
if (ret.code === TPE_OK) {
|
||||||
|
CALLBACK_STACK.create()
|
||||||
|
.add($app.check_host_all_selected)
|
||||||
|
.add($app.table_policy.load_data)
|
||||||
|
.exec();
|
||||||
|
$tp.notify_success('解禁授权策略操作成功!');
|
||||||
|
} else {
|
||||||
|
$tp.notify_error('解禁授权策略操作失败:' + tp_error_msg(ret.code, ret.message));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
$tp.notify_error('网络故障,解禁授权策略操作失败!');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.on_btn_remove_click = function () {
|
||||||
|
var items = $app.get_selected_policy($app.table_policy);
|
||||||
|
if (items.length === 0) {
|
||||||
|
$tp.notify_error('请选择要删除的授权策略!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var _fn_sure = function (cb_stack, cb_args) {
|
||||||
|
$tp.ajax_post_json('/audit/policies/update', {
|
||||||
|
action: 'remove',
|
||||||
|
policy_ids: items
|
||||||
|
},
|
||||||
|
function (ret) {
|
||||||
|
if (ret.code === TPE_OK) {
|
||||||
|
cb_stack.add($app.check_host_all_selected);
|
||||||
|
cb_stack.add($app.table_policy.load_data);
|
||||||
|
$tp.notify_success('删除授权策略操作成功!');
|
||||||
|
} 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></div><p>如果您希望临时禁止指定的授权策略,可将其“禁用”!</p><p>您确定要移除选定的' + items.length + '个授权策略吗?</p>',
|
||||||
|
fn_yes: _fn_sure
|
||||||
|
});
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
$app.create_dlg_edit_policy = function () {
|
||||||
|
var dlg = {};
|
||||||
|
dlg.dom_id = 'dlg-edit-policy';
|
||||||
|
dlg.field_id = -1;
|
||||||
|
dlg.field_name = '';
|
||||||
|
dlg.field_desc = '';
|
||||||
|
|
||||||
|
dlg.dom = {
|
||||||
|
dialog: $('#' + dlg.dom_id),
|
||||||
|
dlg_title: $('#' + dlg.dom_id + ' [data-field="dlg-title"]'),
|
||||||
|
edit_name: $('#edit-name'),
|
||||||
|
edit_desc: $('#edit-desc'),
|
||||||
|
btn_save: $('#btn-edit-policy-save')
|
||||||
|
};
|
||||||
|
|
||||||
|
dlg.init = function (cb_stack) {
|
||||||
|
dlg.dom.btn_save.click(dlg.on_save);
|
||||||
|
cb_stack.exec();
|
||||||
|
};
|
||||||
|
|
||||||
|
dlg.init_fields = function (policy) {
|
||||||
|
dlg.field_id = -1;
|
||||||
|
dlg.field_os_type = -1;
|
||||||
|
|
||||||
|
if (_.isUndefined(policy)) {
|
||||||
|
dlg.dom.dlg_title.html('创建授权策略');
|
||||||
|
|
||||||
|
dlg.dom.edit_name.val('');
|
||||||
|
dlg.dom.edit_desc.val('');
|
||||||
|
} else {
|
||||||
|
dlg.field_id = policy.id;
|
||||||
|
dlg.dom.dlg_title.html('编辑授权策略:');
|
||||||
|
dlg.dom.edit_name.val(policy.name);
|
||||||
|
dlg.dom.edit_desc.val(policy.desc);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
dlg.show_add = function () {
|
||||||
|
dlg.init_fields();
|
||||||
|
dlg.dom.dialog.modal({backdrop: 'static'});
|
||||||
|
};
|
||||||
|
|
||||||
|
dlg.show_edit = function (row_id) {
|
||||||
|
var host = $app.table_policy.get_row(row_id);
|
||||||
|
dlg.init_fields(host);
|
||||||
|
dlg.dom.dialog.modal({backdrop: 'static'});
|
||||||
|
};
|
||||||
|
|
||||||
|
dlg.check_input = function () {
|
||||||
|
dlg.field_name = dlg.dom.edit_name.val();
|
||||||
|
dlg.field_desc = dlg.dom.edit_desc.val();
|
||||||
|
|
||||||
|
if (dlg.field_name.length === 0) {
|
||||||
|
dlg.dom.edit_name.focus();
|
||||||
|
$tp.notify_error('请设定授权策略名称!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
};
|
||||||
|
|
||||||
|
dlg.on_save = function () {
|
||||||
|
if (!dlg.check_input())
|
||||||
|
return;
|
||||||
|
|
||||||
|
var action = (dlg.field_id === -1) ? '添加' : '更新';
|
||||||
|
|
||||||
|
// 如果id为-1表示创建,否则表示更新
|
||||||
|
$tp.ajax_post_json('/audit/policy/update', {
|
||||||
|
id: dlg.field_id,
|
||||||
|
name: dlg.field_name,
|
||||||
|
desc: dlg.field_desc
|
||||||
|
},
|
||||||
|
function (ret) {
|
||||||
|
if (ret.code === TPE_OK) {
|
||||||
|
$tp.notify_success('授权策略' + action + '成功!');
|
||||||
|
$app.table_policy.load_data();
|
||||||
|
dlg.dom.dialog.modal('hide');
|
||||||
|
} else {
|
||||||
|
$tp.notify_error('授权策略' + action + '失败:' + tp_error_msg(ret.code, ret.message));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
$tp.notify_error('网络故障,授权策略' + action + '失败!');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return dlg;
|
||||||
|
};
|
|
@ -0,0 +1,369 @@
|
||||||
|
<%!
|
||||||
|
page_icon_class_ = 'fa fa-server fa-fw'
|
||||||
|
page_title_ = ['审计', '审计授权']
|
||||||
|
page_id_ = ['audit', 'auz']
|
||||||
|
%>
|
||||||
|
<%inherit file="../page_base.mako"/>
|
||||||
|
|
||||||
|
<%block name="extend_js_file">
|
||||||
|
<script type="text/javascript" src="${ static_url('js/audit/auz-info.js') }"></script>
|
||||||
|
</%block>
|
||||||
|
|
||||||
|
<%block name="breadcrumb">
|
||||||
|
<ol class="breadcrumb">
|
||||||
|
%for i in range(len(self.attr.page_title_)):
|
||||||
|
%if i == 0:
|
||||||
|
<li><i class="${self.attr.page_icon_class_}"></i> ${self.attr.page_title_[i]}</li>
|
||||||
|
%else:
|
||||||
|
<li>${self.attr.page_title_[i]}</li>
|
||||||
|
%endif
|
||||||
|
%endfor
|
||||||
|
<li><strong id="group-name-breadcrumb"></strong><span data-field="policy-name"></span></li>
|
||||||
|
</ol>
|
||||||
|
</%block>
|
||||||
|
|
||||||
|
<%block name="embed_js">
|
||||||
|
<script type="text/javascript">
|
||||||
|
$app.add_options(${page_param});
|
||||||
|
if ($app.options.policy_id !== 0) {
|
||||||
|
$('[data-field="policy-name"]').text($app.options.policy_name);
|
||||||
|
$('[data-field="policy-desc"]').text($app.options.policy_desc);
|
||||||
|
} else {
|
||||||
|
## $tp.notify_error('授权策略不存在!');
|
||||||
|
$tp.disable_dom('#work-area', '授权策略不存在!');
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
</%block>
|
||||||
|
|
||||||
|
|
||||||
|
<%block name="embed_css">
|
||||||
|
<style type="text/css">
|
||||||
|
.nav-tabs-title {
|
||||||
|
padding: 0 0 10px 0;
|
||||||
|
font-size: 1.2rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tabs-title .title {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
|
||||||
|
.nav-tabs-title .sub-title {
|
||||||
|
display: inline-block;
|
||||||
|
color: #878787;
|
||||||
|
padding-left: 15px;
|
||||||
|
font-size: 1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
#area-auditor, #area-auditee {
|
||||||
|
border: 1px solid #d6d6d6;
|
||||||
|
}
|
||||||
|
|
||||||
|
.area-title {
|
||||||
|
padding: 5px;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
}
|
||||||
|
|
||||||
|
.area-title .name {
|
||||||
|
font-size: 110%;
|
||||||
|
}
|
||||||
|
|
||||||
|
.area-title .desc {
|
||||||
|
color: #858585;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-name {
|
||||||
|
padding-right: 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.field-desc {
|
||||||
|
display: inline-block;
|
||||||
|
color: #878787;
|
||||||
|
}
|
||||||
|
|
||||||
|
</style>
|
||||||
|
</%block>
|
||||||
|
|
||||||
|
## Begin Main Body.
|
||||||
|
|
||||||
|
<div class="page-content-inner">
|
||||||
|
|
||||||
|
<div class="box" id="work-area">
|
||||||
|
<div class="nav-tabs-title">
|
||||||
|
<div class="title">授权策略:<span data-field="policy-name"></span></div>
|
||||||
|
<div class="sub-title" data-field="policy-desc"></div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div id="area-auditor">
|
||||||
|
<div class="area-title"><span class="name">审计操作者</span><span class="desc">(执行审计操作的用户)</span></div>
|
||||||
|
|
||||||
|
<div style="padding:5px;">
|
||||||
|
<div class="table-extend-area">
|
||||||
|
<div class="table-extend-cell">
|
||||||
|
<div class="btn-group btn-group-sm">
|
||||||
|
<btn class="btn btn-default" id="btn-refresh-auditor"><i class="fa fa-rotate-right"></i> 刷新列表</btn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="table-extend-cell table-item-counter">
|
||||||
|
<div class="btn-group btn-group-sm">
|
||||||
|
<btn class="btn btn-success" id="btn-add-auditor-user"><i class="fa fa-plus"></i> 添加用户</btn>
|
||||||
|
<btn class="btn btn-primary" id="btn-add-auditor-user-group"><i class="fa fa-plus-circle"></i> 添加用户组</btn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table id="table-auditor" class="table table-striped table-bordered table-hover table-data no-footer dtr-inline"></table>
|
||||||
|
|
||||||
|
<div class="table-extend-area">
|
||||||
|
<div class="table-extend-cell checkbox-select-all"><input id="table-auditor-select-all" type="checkbox"/></div>
|
||||||
|
<div class="table-extend-cell group-actions">
|
||||||
|
<div class="btn-group" role="group">
|
||||||
|
<button id="btn-remove-auditor" 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-auditor-paging"></ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table-extend-area">
|
||||||
|
<div class="table-extend-cell">
|
||||||
|
<div style="text-align:right;">
|
||||||
|
<nav>
|
||||||
|
<ul id="table-auditor-pagination" class="pagination"></ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="col-md-6">
|
||||||
|
<div id="area-auditee">
|
||||||
|
<div class="area-title"><span class="name">被审计者</span><span class="desc">(被审计的用户或主机)</span></div>
|
||||||
|
|
||||||
|
<div style="padding:5px;">
|
||||||
|
<div class="table-extend-area">
|
||||||
|
<div class="table-extend-cell">
|
||||||
|
<div class="btn-group btn-group-sm">
|
||||||
|
<btn class="btn btn-default" id="btn-refresh-auditee"><i class="fa fa-rotate-right"></i> 刷新列表</btn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="table-extend-cell table-item-counter">
|
||||||
|
<div class="btn-group btn-group-sm">
|
||||||
|
<btn class="btn btn-success" id="btn-add-auditee-user"><i class="fa fa-plus"></i> 添加用户</btn>
|
||||||
|
<btn class="btn btn-primary" id="btn-add-auditee-user-group"><i class="fa fa-plus-circle"></i> 添加用户组</btn>
|
||||||
|
<btn class="btn btn-success" id="btn-add-auditee-host"><i class="fa fa-plus"></i> 添加主机</btn>
|
||||||
|
<btn class="btn btn-primary" id="btn-add-auditee-host-group"><i class="fa fa-plus-circle"></i> 添加主机组</btn>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table id="table-auditee" class="table table-striped table-bordered table-hover table-data no-footer dtr-inline"></table>
|
||||||
|
|
||||||
|
<div class="table-extend-area">
|
||||||
|
<div class="table-extend-cell checkbox-select-all"><input id="table-auditee-select-all" type="checkbox"/></div>
|
||||||
|
<div class="table-extend-cell group-actions">
|
||||||
|
<div class="btn-group" role="group">
|
||||||
|
<button id="btn-remove-auditee" 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-auditee-paging"></ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table-extend-area">
|
||||||
|
<div class="table-extend-cell">
|
||||||
|
<div style="text-align:right;">
|
||||||
|
<nav>
|
||||||
|
<ul id="table-auditee-pagination" class="pagination"></ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="box">
|
||||||
|
<p>说明:</p>
|
||||||
|
<ul class="help-list">
|
||||||
|
<li>授权对象表格表示左侧“审计操作者”可以访问右侧“被审计者”相关的运维操作记录。</li>
|
||||||
|
<li>按“组”进行授权,则后续加入对应组的用户或主机均自动获得本策略的授权。</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<%block name="extend_content">
|
||||||
|
<div class="modal fade" id="dlg-sel-user" tabindex="-1" role="dialog">
|
||||||
|
<div class="modal-dialog modal-lg" role="document">
|
||||||
|
<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>
|
||||||
|
<h3 data-field="dlg-title" class="modal-title">选择用户</h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
|
||||||
|
<table id="table-sel-user" class="table table-striped table-bordered table-hover table-data no-footer dtr-inline"></table>
|
||||||
|
<div class="table-extend-area">
|
||||||
|
<div class="table-extend-cell checkbox-select-all"><input data-action="sel-all" type="checkbox"/></div>
|
||||||
|
<div class="table-extend-cell group-actions">
|
||||||
|
<div class="btn-group" role="group">
|
||||||
|
<button data-action="use-selected" type="button" class="btn btn-primary"><i class="fa fa-edit fa-fw"></i> 添加为授权操作者</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="table-extend-cell table-item-counter">
|
||||||
|
<ol id="table-sel-user-paging"></ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="table-extend-area">
|
||||||
|
<div class="table-extend-cell">
|
||||||
|
<div style="text-align:right;">
|
||||||
|
<nav>
|
||||||
|
<ul id="table-sel-user-pagination" class="pagination"></ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="dlg-sel-user-group" tabindex="-1" role="dialog">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<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>
|
||||||
|
<h3 data-field="dlg-title" class="modal-title">选择用户组</h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
|
||||||
|
<table id="table-sel-user-group" class="table table-striped table-bordered table-hover table-data no-footer dtr-inline"></table>
|
||||||
|
<div class="table-extend-area">
|
||||||
|
<div class="table-extend-cell checkbox-select-all"><input data-action="sel-all" type="checkbox"/></div>
|
||||||
|
<div class="table-extend-cell group-actions">
|
||||||
|
<div class="btn-group" role="group">
|
||||||
|
<button data-action="use-selected" type="button" class="btn btn-primary"><i class="fa fa-edit fa-fw"></i> 添加为授权操作者</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="table-extend-cell table-item-counter">
|
||||||
|
<ol id="table-sel-user-group-paging"></ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="table-extend-area">
|
||||||
|
<div class="table-extend-cell">
|
||||||
|
<div style="text-align:right;">
|
||||||
|
<nav>
|
||||||
|
<ul id="table-sel-user-group-pagination" class="pagination"></ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="dlg-sel-host" tabindex="-1" role="dialog">
|
||||||
|
<div class="modal-dialog modal-lg" role="document">
|
||||||
|
<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>
|
||||||
|
<h3 data-field="dlg-title" class="modal-title">选择主机</h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
|
||||||
|
<table id="table-sel-host" class="table table-striped table-bordered table-hover table-data no-footer dtr-inline"></table>
|
||||||
|
<div class="table-extend-area">
|
||||||
|
<div class="table-extend-cell checkbox-select-all"><input data-action="sel-all" type="checkbox"/></div>
|
||||||
|
<div class="table-extend-cell group-actions">
|
||||||
|
<div class="btn-group" role="group">
|
||||||
|
<button data-action="use-selected" type="button" class="btn btn-primary"><i class="fa fa-edit fa-fw"></i> 添加为被授权资产</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="table-extend-cell table-item-counter">
|
||||||
|
<ol id="table-sel-host-paging"></ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="table-extend-area">
|
||||||
|
<div class="table-extend-cell">
|
||||||
|
<div style="text-align:right;">
|
||||||
|
<nav>
|
||||||
|
<ul id="table-sel-host-pagination" class="pagination"></ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="dlg-sel-host-group" tabindex="-1" role="dialog">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<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>
|
||||||
|
<h3 data-field="dlg-title" class="modal-title">选择主机组</h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
|
||||||
|
<table id="table-sel-host-group" class="table table-striped table-bordered table-hover table-data no-footer dtr-inline"></table>
|
||||||
|
<div class="table-extend-area">
|
||||||
|
<div class="table-extend-cell checkbox-select-all"><input data-action="sel-all" type="checkbox"/></div>
|
||||||
|
<div class="table-extend-cell group-actions">
|
||||||
|
<div class="btn-group" role="group">
|
||||||
|
<button data-action="use-selected" type="button" class="btn btn-primary"><i class="fa fa-edit fa-fw"></i> 添加为被授权资产</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="table-extend-cell table-item-counter">
|
||||||
|
<ol id="table-sel-host-group-paging"></ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="table-extend-area">
|
||||||
|
<div class="table-extend-cell">
|
||||||
|
<div style="text-align:right;">
|
||||||
|
<nav>
|
||||||
|
<ul id="table-sel-host-group-pagination" class="pagination"></ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</%block>
|
|
@ -0,0 +1,134 @@
|
||||||
|
<%!
|
||||||
|
page_icon_class_ = 'fa fa-server fa-fw'
|
||||||
|
page_title_ = ['审计', '审计授权']
|
||||||
|
page_id_ = ['audit', 'auz']
|
||||||
|
%>
|
||||||
|
<%inherit file="../page_base.mako"/>
|
||||||
|
|
||||||
|
<%block name="extend_js_file">
|
||||||
|
<script type="text/javascript" src="${ static_url('js/audit/auz-list.js') }"></script>
|
||||||
|
</%block>
|
||||||
|
|
||||||
|
<%block name="embed_css">
|
||||||
|
<style>
|
||||||
|
.policy-desc {
|
||||||
|
margin-left: 8px;
|
||||||
|
color: #7f7f7f;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</%block>
|
||||||
|
|
||||||
|
## Begin Main Body.
|
||||||
|
|
||||||
|
<div class="page-content-inner">
|
||||||
|
|
||||||
|
<!-- begin box -->
|
||||||
|
<div class="box box-nav-tabs">
|
||||||
|
|
||||||
|
<!-- Nav tabs -->
|
||||||
|
<ul class="nav nav-tabs">
|
||||||
|
<li class="active"><a href="#tab-policy" data-toggle="tab">授权策略</a></li>
|
||||||
|
<li><a href="#tab-search" data-toggle="tab">快速查找</a></li>
|
||||||
|
</ul>
|
||||||
|
|
||||||
|
<div class="tab-content">
|
||||||
|
<div class="tab-pane active" style="padding:15px;" id="tab-policy">
|
||||||
|
|
||||||
|
<div class="table-prefix-area">
|
||||||
|
<div class="table-extend-cell">
|
||||||
|
<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-rebuild" class="btn btn-sm btn-danger"><i class="fa fa-flash fa-fw"></i> 重建授权映射</button>
|
||||||
|
</div>
|
||||||
|
<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>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<table id="table-policy" class="table table-striped table-bordered table-hover table-data no-footer dtr-inline"></table>
|
||||||
|
|
||||||
|
<div class="table-extend-area">
|
||||||
|
<div class="table-extend-cell checkbox-select-all"><input id="table-auz-select-all" type="checkbox"/></div>
|
||||||
|
<div class="table-extend-cell group-actions">
|
||||||
|
<div class="btn-group" role="group">
|
||||||
|
## <button id="btn-edit-host" type="button" class="btn btn-default"><i class="fa fa-edit fa-fw"></i> 编辑</button>
|
||||||
|
|
||||||
|
<button id="btn-lock" type="button" class="btn btn-default"><i class="fa fa-lock fa-fw"></i> 禁用</button>
|
||||||
|
<button id="btn-unlock" type="button" class="btn btn-default"><i class="fa fa-unlock fa-fw"></i> 解禁</button>
|
||||||
|
<button id="btn-remove" 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-auz-paging"></ol>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="table-extend-area">
|
||||||
|
<div class="table-extend-cell">
|
||||||
|
<div style="text-align:right;">
|
||||||
|
<nav>
|
||||||
|
<ul id="table-auz-pagination" class="pagination"></ul>
|
||||||
|
</nav>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="tab-pane" style="padding:15px;" id="tab-search">
|
||||||
|
<div class="alert alert-danger">快速查找功能尚未实现</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
<!-- end of box -->
|
||||||
|
|
||||||
|
<div class="box">
|
||||||
|
<p>说明:</p>
|
||||||
|
<ul class="help-list">
|
||||||
|
<li><span class="error">编辑了授权策略或调整策略顺序之后,请点击“重建授权映射”来使之生效!</span>正式版本将会改进为自动进行重建。</li>
|
||||||
|
<li>上下拖动“顺序”栏中的 <i class="fa fa-reorder fa-fw"></i> 可以调节策略的检查顺序。</li>
|
||||||
|
<li>可以在“快速查找”中快速定位用户或主机的授权关系。</li>
|
||||||
|
</ul>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<%block name="extend_content">
|
||||||
|
|
||||||
|
<div class="modal fade" id="dlg-edit-policy" tabindex="-1">
|
||||||
|
<div class="modal-dialog" role="document">
|
||||||
|
<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>
|
||||||
|
<h3 data-field="dlg-title" class="modal-title"></h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
|
||||||
|
<div class="form-horizontal">
|
||||||
|
|
||||||
|
<div class="form-group form-group-sm">
|
||||||
|
<label for="edit-name" class="col-sm-2 control-label require">策略名称:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input id="edit-name" type="text" class="form-control" placeholder=""/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group form-group-sm">
|
||||||
|
<label for="edit-desc" class="col-sm-2 control-label">策略描述:</label>
|
||||||
|
<div class="col-sm-10">
|
||||||
|
<input id="edit-desc" type="text" class="form-control"/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
|
||||||
|
<div class="modal-footer">
|
||||||
|
<button type="button" class="btn btn-sm btn-primary" id="btn-edit-policy-save"><i class="fa fa-check 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>
|
||||||
|
</div>
|
||||||
|
</%block>
|
|
@ -295,7 +295,7 @@
|
||||||
<li>授权对象表格表示左侧“授权操作者”可以访问右侧“被授权资产”。</li>
|
<li>授权对象表格表示左侧“授权操作者”可以访问右侧“被授权资产”。</li>
|
||||||
<li>修改授权对象和连接控制选项不会影响当前已经建立的连接。</li>
|
<li>修改授权对象和连接控制选项不会影响当前已经建立的连接。</li>
|
||||||
<li>如被授权资产为主机/主机组,则允许用户以对应主机相关的任意账号进行连接。</li>
|
<li>如被授权资产为主机/主机组,则允许用户以对应主机相关的任意账号进行连接。</li>
|
||||||
<li>按“组”进行授权,则后续加入对应组的用户、账号或主机均自动获得本授权策略的授权。</li>
|
<li>按“组”进行授权,则后续加入对应组的用户、账号或主机均自动获得本策略的授权。</li>
|
||||||
</ul>
|
</ul>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
|
|
@ -561,30 +561,10 @@ class DatabaseInit:
|
||||||
f.append('`name` varchar(128) DEFAULT ""')
|
f.append('`name` varchar(128) DEFAULT ""')
|
||||||
# desc: 策略描述
|
# desc: 策略描述
|
||||||
f.append('`desc` varchar(255) DEFAULT ""')
|
f.append('`desc` varchar(255) DEFAULT ""')
|
||||||
# start_time: 策略有效期起始时间(为0则忽略)
|
|
||||||
f.append('`start_time` int(11) DEFAULT 0')
|
|
||||||
# end_time: 策略有效期结束时间(为0则忽略)
|
|
||||||
f.append('`end_time` int(11) DEFAULT 0')
|
|
||||||
|
|
||||||
# state: 状态,1=正常,2=禁用
|
# state: 状态,1=正常,2=禁用
|
||||||
f.append('`state` int(3) DEFAULT 1')
|
f.append('`state` int(3) DEFAULT 1')
|
||||||
|
|
||||||
# limit_ip: 是否启用来源限制,0=不限制,1=白名单,2=黑名单(尚未实现)
|
|
||||||
f.append('`limit_ip` int(3) DEFAULT 0')
|
|
||||||
# ip_list: 限制IP列表(白名单或者黑名单)
|
|
||||||
f.append('`ip_list` TEXT')
|
|
||||||
|
|
||||||
# limit_time: 是否启用限时连接,0=不限制,1=限制(尚未实现)
|
|
||||||
f.append('`limit_time` int(3) DEFAULT 0')
|
|
||||||
# 每一个weekX表示一天的时间段,按位异或表示24个小时的每个小时是否限制连接,对应位为0表示不限制(允许连接)
|
|
||||||
f.append('`limit_week1` int(11) DEFAULT 0')
|
|
||||||
f.append('`limit_week2` int(11) DEFAULT 0')
|
|
||||||
f.append('`limit_week3` int(11) DEFAULT 0')
|
|
||||||
f.append('`limit_week4` int(11) DEFAULT 0')
|
|
||||||
f.append('`limit_week5` int(11) DEFAULT 0')
|
|
||||||
f.append('`limit_week6` int(11) DEFAULT 0')
|
|
||||||
f.append('`limit_week7` int(11) DEFAULT 0')
|
|
||||||
|
|
||||||
# creator_id: 授权者的id,0=系统默认创建
|
# creator_id: 授权者的id,0=系统默认创建
|
||||||
f.append('`creator_id` int(11) DEFAULT 0')
|
f.append('`creator_id` int(11) DEFAULT 0')
|
||||||
# create_time: 授权时间
|
# create_time: 授权时间
|
||||||
|
@ -605,7 +585,7 @@ class DatabaseInit:
|
||||||
# policy_id: 所属的策略
|
# policy_id: 所属的策略
|
||||||
f.append('`policy_id` int(11) DEFAULT 0')
|
f.append('`policy_id` int(11) DEFAULT 0')
|
||||||
|
|
||||||
# type 指明本条记录是授权还是被授权,0=授权(用户/用户组),1=被授权(资产:主机/主机组)
|
# type 指明本条记录是授权还是被授权,0=授权(用户/用户组),1=被授权(资产:用户/用户组/主机/主机组)
|
||||||
f.append('`type` int(11) DEFAULT 0')
|
f.append('`type` int(11) DEFAULT 0')
|
||||||
|
|
||||||
# rtype : 外链类型
|
# rtype : 外链类型
|
||||||
|
|
|
@ -172,6 +172,16 @@ controllers = [
|
||||||
(r'/audit/record', audit.RecordHandler),
|
(r'/audit/record', audit.RecordHandler),
|
||||||
# - [json] 审计页面(录像列表)
|
# - [json] 审计页面(录像列表)
|
||||||
(r'/audit/get-records', audit.DoGetRecordsHandler),
|
(r'/audit/get-records', audit.DoGetRecordsHandler),
|
||||||
|
# - 某个策略的管理页面
|
||||||
|
(r'/audit/policy/detail/(.*)', audit.PolicyDetailHandler),
|
||||||
|
# - [json] 获取策略列表
|
||||||
|
(r'/audit/get-policies', audit.DoGetPoliciesHandler),
|
||||||
|
# - [json] 添加/更新策略
|
||||||
|
(r'/audit/policy/update', audit.DoUpdatePolicyHandler),
|
||||||
|
# - [json] 禁用/解禁/删除策略
|
||||||
|
(r'/audit/policies/update', audit.DoUpdatePoliciesHandler),
|
||||||
|
# - [json] 调整顺序(rank)
|
||||||
|
(r'/audit/policy/rank-reorder', audit.DoRankReorderHandler),
|
||||||
#
|
#
|
||||||
# - ssh录像回放页面
|
# - ssh录像回放页面
|
||||||
(r'/audit/replay/(.*)/(.*)', audit.ReplayHandler),
|
(r'/audit/replay/(.*)/(.*)', audit.ReplayHandler),
|
||||||
|
|
|
@ -1,18 +1,15 @@
|
||||||
# -*- coding: utf-8 -*-
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
# import ctypes
|
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
# import platform
|
|
||||||
import shutil
|
import shutil
|
||||||
|
|
||||||
from app.const import *
|
from app.const import *
|
||||||
from app.base.configs import tp_cfg
|
from app.base.configs import tp_cfg
|
||||||
from app.base.logger import *
|
from app.base.logger import *
|
||||||
|
from app.model import audit
|
||||||
from app.model import record
|
from app.model import record
|
||||||
# from app.model import user
|
|
||||||
from app.base.controller import TPBaseHandler, TPBaseJsonHandler
|
from app.base.controller import TPBaseHandler, TPBaseJsonHandler
|
||||||
# import tornado.web
|
|
||||||
import tornado.gen
|
import tornado.gen
|
||||||
|
|
||||||
|
|
||||||
|
@ -31,7 +28,195 @@ class AuzListHandler(TPBaseHandler):
|
||||||
ret = self.check_privilege(TP_PRIVILEGE_AUDIT_AUZ)
|
ret = self.check_privilege(TP_PRIVILEGE_AUDIT_AUZ)
|
||||||
if ret != TPE_OK:
|
if ret != TPE_OK:
|
||||||
return
|
return
|
||||||
self.show_error_page(TPE_NOT_IMPLEMENT)
|
self.render('audit/auz-list.mako')
|
||||||
|
|
||||||
|
|
||||||
|
class PolicyDetailHandler(TPBaseHandler):
|
||||||
|
def get(self, pid):
|
||||||
|
ret = self.check_privilege(TP_PRIVILEGE_AUDIT_AUZ)
|
||||||
|
if ret != TPE_OK:
|
||||||
|
return
|
||||||
|
pid = int(pid)
|
||||||
|
err, policy = audit.get_by_id(pid)
|
||||||
|
if err == TPE_OK:
|
||||||
|
param = {
|
||||||
|
'policy_id': pid,
|
||||||
|
'policy_name': policy['name'],
|
||||||
|
'policy_desc': policy['desc']
|
||||||
|
}
|
||||||
|
else:
|
||||||
|
param = {
|
||||||
|
'policy_id': 0,
|
||||||
|
'policy_name': '',
|
||||||
|
'policy_desc': ''
|
||||||
|
}
|
||||||
|
self.render('audit/auz-info.mako', page_param=json.dumps(param))
|
||||||
|
|
||||||
|
|
||||||
|
class DoGetPoliciesHandler(TPBaseJsonHandler):
|
||||||
|
def post(self):
|
||||||
|
ret = self.check_privilege(TP_PRIVILEGE_AUDIT_AUZ)
|
||||||
|
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)
|
||||||
|
|
||||||
|
sql_filter = {}
|
||||||
|
sql_order = dict()
|
||||||
|
sql_order['name'] = 'rank'
|
||||||
|
sql_order['asc'] = True
|
||||||
|
sql_limit = dict()
|
||||||
|
sql_limit['page_index'] = 0
|
||||||
|
sql_limit['per_page'] = 25
|
||||||
|
|
||||||
|
try:
|
||||||
|
tmp = list()
|
||||||
|
_filter = args['filter']
|
||||||
|
for i in _filter:
|
||||||
|
if i == 'state' and _filter[i] == 0:
|
||||||
|
tmp.append(i)
|
||||||
|
continue
|
||||||
|
if i == 'search':
|
||||||
|
if len(_filter[i].strip()) == 0:
|
||||||
|
tmp.append(i)
|
||||||
|
|
||||||
|
for i in tmp:
|
||||||
|
del _filter[i]
|
||||||
|
|
||||||
|
sql_filter.update(_filter)
|
||||||
|
|
||||||
|
_limit = args['limit']
|
||||||
|
if _limit['page_index'] < 0:
|
||||||
|
_limit['page_index'] = 0
|
||||||
|
if _limit['per_page'] < 10:
|
||||||
|
_limit['per_page'] = 10
|
||||||
|
if _limit['per_page'] > 100:
|
||||||
|
_limit['per_page'] = 100
|
||||||
|
|
||||||
|
sql_limit.update(_limit)
|
||||||
|
|
||||||
|
# _order = args['order']
|
||||||
|
# if _order is not None:
|
||||||
|
# sql_order['name'] = _order['k']
|
||||||
|
# sql_order['asc'] = _order['v']
|
||||||
|
|
||||||
|
except:
|
||||||
|
return self.write_json(TPE_PARAM)
|
||||||
|
|
||||||
|
err, total, page_index, row_data = audit.get_policies(sql_filter, sql_order, sql_limit)
|
||||||
|
ret = dict()
|
||||||
|
ret['page_index'] = page_index
|
||||||
|
ret['total'] = total
|
||||||
|
ret['data'] = row_data
|
||||||
|
self.write_json(err, data=ret)
|
||||||
|
|
||||||
|
|
||||||
|
class DoUpdatePolicyHandler(TPBaseJsonHandler):
|
||||||
|
def post(self):
|
||||||
|
ret = self.check_privilege(TP_PRIVILEGE_AUDIT_AUZ)
|
||||||
|
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:
|
||||||
|
args['id'] = int(args['id'])
|
||||||
|
args['name'] = args['name'].strip()
|
||||||
|
args['desc'] = args['desc'].strip()
|
||||||
|
except:
|
||||||
|
log.e('\n')
|
||||||
|
return self.write_json(TPE_PARAM)
|
||||||
|
|
||||||
|
if len(args['name']) == 0:
|
||||||
|
return self.write_json(TPE_PARAM)
|
||||||
|
|
||||||
|
if args['id'] == -1:
|
||||||
|
err, info = audit.create_policy(self, args)
|
||||||
|
else:
|
||||||
|
err = audit.update_policy(self, args)
|
||||||
|
info = {}
|
||||||
|
self.write_json(err, data=info)
|
||||||
|
|
||||||
|
|
||||||
|
class DoUpdatePoliciesHandler(TPBaseJsonHandler):
|
||||||
|
def post(self):
|
||||||
|
ret = self.check_privilege(TP_PRIVILEGE_AUDIT_AUZ)
|
||||||
|
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']
|
||||||
|
p_ids = args['policy_ids']
|
||||||
|
except:
|
||||||
|
log.e('\n')
|
||||||
|
return self.write_json(TPE_PARAM)
|
||||||
|
|
||||||
|
if action == 'lock':
|
||||||
|
err = audit.update_policies_state(self, p_ids, TP_STATE_DISABLED)
|
||||||
|
return self.write_json(err)
|
||||||
|
elif action == 'unlock':
|
||||||
|
err = audit.update_policies_state(self, p_ids, TP_STATE_NORMAL)
|
||||||
|
return self.write_json(err)
|
||||||
|
elif action == 'remove':
|
||||||
|
err = audit.remove_policies(self, p_ids)
|
||||||
|
return self.write_json(err)
|
||||||
|
else:
|
||||||
|
return self.write_json(TPE_PARAM)
|
||||||
|
|
||||||
|
|
||||||
|
class DoRankReorderHandler(TPBaseJsonHandler):
|
||||||
|
def post(self):
|
||||||
|
ret = self.check_privilege(TP_PRIVILEGE_AUDIT_AUZ)
|
||||||
|
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:
|
||||||
|
pid = int(args['pid'])
|
||||||
|
new_rank = int(args['new_rank'])
|
||||||
|
start_rank = int(args['start_rank'])
|
||||||
|
end_rank = int(args['end_rank'])
|
||||||
|
direct = int(args['direct'])
|
||||||
|
except:
|
||||||
|
log.e('\n')
|
||||||
|
return self.write_json(TPE_PARAM)
|
||||||
|
|
||||||
|
if direct == -1:
|
||||||
|
direct = '-1'
|
||||||
|
elif direct == 1:
|
||||||
|
direct = '+1'
|
||||||
|
else:
|
||||||
|
return self.write_json(TPE_PARAM)
|
||||||
|
|
||||||
|
err = audit.rank_reorder(self, pid, new_rank, start_rank, end_rank, direct)
|
||||||
|
self.write_json(err)
|
||||||
|
|
||||||
|
|
||||||
class RecordHandler(TPBaseHandler):
|
class RecordHandler(TPBaseHandler):
|
||||||
|
|
|
@ -0,0 +1,775 @@
|
||||||
|
# -*- coding: utf-8 -*-
|
||||||
|
|
||||||
|
from app.const import *
|
||||||
|
from app.base.logger import log
|
||||||
|
from app.base.db import get_db, SQL
|
||||||
|
from app.model import syslog
|
||||||
|
from app.base.utils import AttrDict, tp_timestamp_utc_now
|
||||||
|
|
||||||
|
|
||||||
|
def get_by_id(pid):
|
||||||
|
s = SQL(get_db())
|
||||||
|
s.select_from('audit_policy', ['id', 'name', 'desc'], alt_name='p')
|
||||||
|
s.where('p.id={}'.format(pid))
|
||||||
|
err = s.query()
|
||||||
|
if err != TPE_OK:
|
||||||
|
return err, {}
|
||||||
|
|
||||||
|
if len(s.recorder) == 0:
|
||||||
|
return TPE_NOT_EXISTS, {}
|
||||||
|
|
||||||
|
return TPE_OK, s.recorder[0]
|
||||||
|
|
||||||
|
|
||||||
|
def get_policies(sql_filter, sql_order, sql_limit):
|
||||||
|
dbtp = get_db().table_prefix
|
||||||
|
s = SQL(get_db())
|
||||||
|
s.select_from('audit_policy', ['id', 'rank', 'name', 'desc', 'state'], alt_name='p')
|
||||||
|
|
||||||
|
str_where = ''
|
||||||
|
_where = list()
|
||||||
|
|
||||||
|
if len(sql_filter) > 0:
|
||||||
|
for k in sql_filter:
|
||||||
|
if k == 'search':
|
||||||
|
_where.append('(p.name LIKE "%{filter}%" OR p.desc LIKE "%{filter}%")'.format(filter=sql_filter[k]))
|
||||||
|
if k == 'state':
|
||||||
|
_where.append('p.state={}'.format(sql_filter[k]))
|
||||||
|
else:
|
||||||
|
log.e('unknown filter field: {}\n'.format(k))
|
||||||
|
return TPE_PARAM, s.total_count, 0, s.recorder
|
||||||
|
|
||||||
|
if len(_where) > 0:
|
||||||
|
str_where = '( {} )'.format(' AND '.join(_where))
|
||||||
|
|
||||||
|
s.where(str_where)
|
||||||
|
|
||||||
|
s.order_by('p.rank', True)
|
||||||
|
|
||||||
|
if len(sql_limit) > 0:
|
||||||
|
s.limit(sql_limit['page_index'], sql_limit['per_page'])
|
||||||
|
|
||||||
|
err = s.query()
|
||||||
|
return err, s.total_count, s.page_index, s.recorder
|
||||||
|
|
||||||
|
|
||||||
|
def create_policy(handler, args):
|
||||||
|
"""
|
||||||
|
创建一个授权策略
|
||||||
|
"""
|
||||||
|
db = get_db()
|
||||||
|
_time_now = tp_timestamp_utc_now()
|
||||||
|
|
||||||
|
# 1. 判断此账号是否已经存在了
|
||||||
|
s = SQL(db)
|
||||||
|
err = s.reset().select_from('audit_policy', ['id']).where('audit_policy.name="{}"'.format(args['name'])).query()
|
||||||
|
if err != TPE_OK:
|
||||||
|
return err, 0
|
||||||
|
if len(s.recorder) > 0:
|
||||||
|
return TPE_EXISTS, 0
|
||||||
|
|
||||||
|
# 2. get total count
|
||||||
|
sql = 'SELECT COUNT(*) FROM {}audit_policy'.format(db.table_prefix)
|
||||||
|
db_ret = db.query(sql)
|
||||||
|
if not db_ret or len(db_ret) == 0:
|
||||||
|
return TPE_DATABASE, 0
|
||||||
|
rank = db_ret[0][0] + 1
|
||||||
|
|
||||||
|
sql = 'INSERT INTO `{}audit_policy` (`rank`, `name`, `desc`, `creator_id`, `create_time`) VALUES ' \
|
||||||
|
'({rank}, "{name}", "{desc}", {creator_id}, {create_time});' \
|
||||||
|
''.format(db.table_prefix,
|
||||||
|
rank=rank, name=args['name'], desc=args['desc'],
|
||||||
|
creator_id=handler.get_current_user()['id'],
|
||||||
|
create_time=_time_now)
|
||||||
|
db_ret = db.exec(sql)
|
||||||
|
if not db_ret:
|
||||||
|
return TPE_DATABASE, 0
|
||||||
|
|
||||||
|
_id = db.last_insert_id()
|
||||||
|
|
||||||
|
syslog.sys_log(handler.get_current_user(), handler.request.remote_ip, TPE_OK, "创建审计授权策略:{}".format(args['name']))
|
||||||
|
|
||||||
|
return TPE_OK, _id
|
||||||
|
|
||||||
|
|
||||||
|
def update_policy(handler, args):
|
||||||
|
db = get_db()
|
||||||
|
|
||||||
|
# 1. 判断此账号是否已经存在
|
||||||
|
s = SQL(db)
|
||||||
|
err = s.reset().select_from('audit_policy', ['id']).where('audit_policy.id={}'.format(args['id'])).query()
|
||||||
|
if err != TPE_OK:
|
||||||
|
return err
|
||||||
|
if len(s.recorder) == 0:
|
||||||
|
return TPE_NOT_EXISTS
|
||||||
|
|
||||||
|
sql = 'UPDATE `{}audit_policy` SET `name`="{name}", `desc`="{desc}" WHERE `id`={p_id};' \
|
||||||
|
''.format(db.table_prefix,
|
||||||
|
name=args['name'], desc=args['desc'], p_id=args['id']
|
||||||
|
)
|
||||||
|
db_ret = db.exec(sql)
|
||||||
|
if not db_ret:
|
||||||
|
return TPE_DATABASE
|
||||||
|
|
||||||
|
return TPE_OK
|
||||||
|
|
||||||
|
|
||||||
|
def update_policies_state(handler, p_ids, state):
|
||||||
|
db = get_db()
|
||||||
|
|
||||||
|
p_ids = ','.join([str(i) for i in p_ids])
|
||||||
|
|
||||||
|
sql_list = []
|
||||||
|
|
||||||
|
sql = 'UPDATE `{}audit_policy` SET `state`={state} WHERE `id` IN ({p_ids});'.format(db.table_prefix, state=state, p_ids=p_ids)
|
||||||
|
sql_list.append(sql)
|
||||||
|
|
||||||
|
sql = 'UPDATE `{}audit_auz` SET `state`={state} WHERE `policy_id` IN ({p_ids});'.format(db.table_prefix, state=state, p_ids=p_ids)
|
||||||
|
sql_list.append(sql)
|
||||||
|
|
||||||
|
sql = 'UPDATE `{}audit_map` SET `p_state`={state} WHERE `p_id` IN ({p_ids});'.format(db.table_prefix, state=state, p_ids=p_ids)
|
||||||
|
sql_list.append(sql)
|
||||||
|
|
||||||
|
if db.transaction(sql_list):
|
||||||
|
return TPE_OK
|
||||||
|
else:
|
||||||
|
return TPE_DATABASE
|
||||||
|
|
||||||
|
|
||||||
|
def remove_policies(handler, p_ids):
|
||||||
|
db = get_db()
|
||||||
|
|
||||||
|
p_ids = ','.join([str(i) for i in p_ids])
|
||||||
|
|
||||||
|
sql_list = []
|
||||||
|
|
||||||
|
sql = 'DELETE FROM `{}audit_policy` WHERE `id` IN ({p_ids});'.format(db.table_prefix, p_ids=p_ids)
|
||||||
|
sql_list.append(sql)
|
||||||
|
|
||||||
|
sql = 'DELETE FROM `{}audit_auz` WHERE `policy_id` IN ({p_ids});'.format(db.table_prefix, p_ids=p_ids)
|
||||||
|
sql_list.append(sql)
|
||||||
|
|
||||||
|
sql = 'DELETE FROM `{}audit_map` WHERE `p_id` IN ({p_ids});'.format(db.table_prefix, p_ids=p_ids)
|
||||||
|
sql_list.append(sql)
|
||||||
|
|
||||||
|
if db.transaction(sql_list):
|
||||||
|
return TPE_OK
|
||||||
|
else:
|
||||||
|
return TPE_DATABASE
|
||||||
|
|
||||||
|
|
||||||
|
def add_members(handler, policy_id, policy_type, ref_type, members):
|
||||||
|
# step 1: select exists rid.
|
||||||
|
s = SQL(get_db())
|
||||||
|
s.select_from('audit_auz', ['rid'], alt_name='p')
|
||||||
|
_where = list()
|
||||||
|
_where.append('p.policy_id={}'.format(policy_id))
|
||||||
|
_where.append('p.type={}'.format(policy_type))
|
||||||
|
_where.append('p.rtype={}'.format(ref_type))
|
||||||
|
s.where('( {} )'.format(' AND '.join(_where)))
|
||||||
|
err = s.query()
|
||||||
|
if err != TPE_OK:
|
||||||
|
return err
|
||||||
|
exists_ids = [r['rid'] for r in s.recorder]
|
||||||
|
|
||||||
|
operator = handler.get_current_user()
|
||||||
|
|
||||||
|
db = get_db()
|
||||||
|
_time_now = tp_timestamp_utc_now()
|
||||||
|
|
||||||
|
sql = []
|
||||||
|
# for uid in members:
|
||||||
|
# sql.append('INSERT INTO `{}group_map` (type, gid, mid) VALUES ({}, {}, {});'.format(db.table_prefix, gtype, gid, uid))
|
||||||
|
# print(args['members'])
|
||||||
|
for m in members:
|
||||||
|
if m['id'] in exists_ids:
|
||||||
|
continue
|
||||||
|
str_sql = 'INSERT INTO `{}audit_auz` (policy_id, type, rtype, rid, `name`, creator_id, create_time) VALUES ' \
|
||||||
|
'({pid}, {t}, {rtype}, {rid}, "{name}", {creator_id}, {create_time});' \
|
||||||
|
''.format(db.table_prefix,
|
||||||
|
pid=policy_id, t=policy_type, rtype=ref_type,
|
||||||
|
rid=m['id'], name=m['name'],
|
||||||
|
creator_id=operator['id'], create_time=_time_now)
|
||||||
|
sql.append(str_sql)
|
||||||
|
|
||||||
|
if db.transaction(sql):
|
||||||
|
return TPE_OK
|
||||||
|
else:
|
||||||
|
return TPE_DATABASE
|
||||||
|
|
||||||
|
|
||||||
|
def remove_members(handler, policy_id, policy_type, ids):
|
||||||
|
s = SQL(get_db())
|
||||||
|
|
||||||
|
auz_ids = [str(i) for i in ids]
|
||||||
|
|
||||||
|
# 将用户从所在组中移除
|
||||||
|
where = 'policy_id={} AND type={} AND id IN ({})'.format(policy_id, policy_type, ','.join(auz_ids))
|
||||||
|
err = s.reset().delete_from('audit_auz').where(where).exec()
|
||||||
|
if err != TPE_OK:
|
||||||
|
return err
|
||||||
|
|
||||||
|
return TPE_OK
|
||||||
|
|
||||||
|
|
||||||
|
def get_operators(sql_filter, sql_order, sql_limit):
|
||||||
|
ss = SQL(get_db())
|
||||||
|
ss.select_from('audit_auz', ['id', 'policy_id', 'rtype', 'rid', 'name'], alt_name='p')
|
||||||
|
|
||||||
|
_where = list()
|
||||||
|
_where.append('p.type=0')
|
||||||
|
if len(sql_filter) > 0:
|
||||||
|
for k in sql_filter:
|
||||||
|
if k == 'policy_id':
|
||||||
|
# _where.append('(p.name LIKE "%{filter}%" OR p.desc LIKE "%{filter}%")'.format(filter=sql_filter[k]))
|
||||||
|
_where.append('p.policy_id={}'.format(sql_filter[k]))
|
||||||
|
elif k == 'search':
|
||||||
|
_where.append('(p.name LIKE "%{filter}%")'.format(filter=sql_filter[k]))
|
||||||
|
else:
|
||||||
|
log.e('unknown filter field: {}\n'.format(k))
|
||||||
|
return TPE_PARAM, 0, 0, {}
|
||||||
|
if len(_where) > 0:
|
||||||
|
ss.where('( {} )'.format(' AND '.join(_where)))
|
||||||
|
|
||||||
|
if sql_order is not None:
|
||||||
|
_sort = False if not sql_order['asc'] else True
|
||||||
|
if 'name' == sql_order['name']:
|
||||||
|
ss.order_by('p.name', _sort)
|
||||||
|
elif 'rtype' == sql_order['name']:
|
||||||
|
ss.order_by('p.rtype', _sort)
|
||||||
|
else:
|
||||||
|
log.e('unknown order field: {}\n'.format(sql_order['name']))
|
||||||
|
return TPE_PARAM, ss.total_count, 0, ss.recorder
|
||||||
|
|
||||||
|
if len(sql_limit) > 0:
|
||||||
|
ss.limit(sql_limit['page_index'], sql_limit['per_page'])
|
||||||
|
|
||||||
|
err = ss.query()
|
||||||
|
if err != TPE_OK:
|
||||||
|
return err, 0, 0, {}
|
||||||
|
|
||||||
|
# print(ss.recorder)
|
||||||
|
return TPE_OK, ss.total_count, ss.page_index, ss.recorder
|
||||||
|
|
||||||
|
|
||||||
|
def get_asset(sql_filter, sql_order, sql_limit):
|
||||||
|
ss = SQL(get_db())
|
||||||
|
ss.select_from('audit_auz', ['id', 'policy_id', 'rtype', 'rid', 'name'], alt_name='p')
|
||||||
|
|
||||||
|
_where = list()
|
||||||
|
_where.append('p.type=1')
|
||||||
|
if len(sql_filter) > 0:
|
||||||
|
for k in sql_filter:
|
||||||
|
if k == 'policy_id':
|
||||||
|
# _where.append('(p.name LIKE "%{filter}%" OR p.desc LIKE "%{filter}%")'.format(filter=sql_filter[k]))
|
||||||
|
_where.append('p.policy_id={}'.format(sql_filter[k]))
|
||||||
|
elif k == 'search':
|
||||||
|
_where.append('(p.name LIKE "%{filter}%")'.format(filter=sql_filter[k]))
|
||||||
|
else:
|
||||||
|
log.e('unknown filter field: {}\n'.format(k))
|
||||||
|
return TPE_PARAM, 0, 0, {}
|
||||||
|
if len(_where) > 0:
|
||||||
|
ss.where('( {} )'.format(' AND '.join(_where)))
|
||||||
|
|
||||||
|
if sql_order is not None:
|
||||||
|
_sort = False if not sql_order['asc'] else True
|
||||||
|
if 'name' == sql_order['name']:
|
||||||
|
ss.order_by('p.name', _sort)
|
||||||
|
elif 'rtype' == sql_order['name']:
|
||||||
|
ss.order_by('p.rtype', _sort)
|
||||||
|
else:
|
||||||
|
log.e('unknown order field: {}\n'.format(sql_order['name']))
|
||||||
|
return TPE_PARAM, ss.total_count, 0, ss.recorder
|
||||||
|
|
||||||
|
if len(sql_limit) > 0:
|
||||||
|
ss.limit(sql_limit['page_index'], sql_limit['per_page'])
|
||||||
|
|
||||||
|
err = ss.query()
|
||||||
|
if err != TPE_OK:
|
||||||
|
return err, 0, 0, {}
|
||||||
|
|
||||||
|
# print(ss.recorder)
|
||||||
|
return TPE_OK, ss.total_count, ss.page_index, ss.recorder
|
||||||
|
|
||||||
|
|
||||||
|
def rank_reorder(handler, pid, new_rank, start_rank, end_rank, direct):
|
||||||
|
db = get_db()
|
||||||
|
|
||||||
|
# 调节顺序:
|
||||||
|
# 由pid获取被移动的策略,得到其rank,即,p_rank
|
||||||
|
# p_rank > new_rank,向前移动
|
||||||
|
# 所有 new_rank <= rank < p_rank 的条目,其rank+1
|
||||||
|
# p_rank < new_rank,向后移动
|
||||||
|
# 所有 new_rank >= rank > p_rank 的条目,其rank-1
|
||||||
|
# 最后令pid条目的rank为new_rank
|
||||||
|
|
||||||
|
# 1. 判断此账号是否已经存在
|
||||||
|
s = SQL(db)
|
||||||
|
err = s.select_from('audit_policy', ['id', 'name', 'rank']).where('audit_policy.id={}'.format(pid)).query()
|
||||||
|
if err != TPE_OK:
|
||||||
|
return err
|
||||||
|
if len(s.recorder) == 0:
|
||||||
|
return TPE_NOT_EXISTS
|
||||||
|
|
||||||
|
p_name = s.recorder[0]['name']
|
||||||
|
p_rank = s.recorder[0]['rank']
|
||||||
|
|
||||||
|
sql = 'UPDATE `{dbtp}audit_policy` SET rank=rank{direct} WHERE (rank>={start_rank} AND rank<={end_rank});' \
|
||||||
|
''.format(dbtp=db.table_prefix, direct=direct, start_rank=start_rank, end_rank=end_rank)
|
||||||
|
db_ret = db.exec(sql)
|
||||||
|
if not db_ret:
|
||||||
|
return TPE_DATABASE
|
||||||
|
|
||||||
|
sql = 'UPDATE `{dbtp}audit_policy` SET rank={new_rank} WHERE id={pid};' \
|
||||||
|
''.format(dbtp=db.table_prefix, new_rank=new_rank, pid=pid)
|
||||||
|
db_ret = db.exec(sql)
|
||||||
|
if not db_ret:
|
||||||
|
return TPE_DATABASE
|
||||||
|
|
||||||
|
syslog.sys_log(handler.get_current_user(), handler.request.remote_ip, TPE_OK, "调整审计授权策略顺序:{},从{}到{}".format(p_name, p_rank, new_rank))
|
||||||
|
|
||||||
|
return TPE_OK
|
||||||
|
|
||||||
|
|
||||||
|
def get_auth(auth_id):
|
||||||
|
db = get_db()
|
||||||
|
s = SQL(db)
|
||||||
|
err = s.select_from('audit_map', ['id', 'h_id', 'u_id', 'a_id']).where('audit_map.uni_id="{}"'.format(auth_id)).query()
|
||||||
|
if err != TPE_OK:
|
||||||
|
return None, err
|
||||||
|
if len(s.recorder) == 0:
|
||||||
|
return None, TPE_NOT_EXISTS
|
||||||
|
|
||||||
|
if len(s.recorder) != 1:
|
||||||
|
return None, TPE_FAILED
|
||||||
|
|
||||||
|
log.v(s.recorder[0])
|
||||||
|
return s.recorder[0], TPE_OK
|
||||||
|
|
||||||
|
|
||||||
|
def get_remotes(handler, sql_filter, sql_order, sql_limit):
|
||||||
|
"""
|
||||||
|
获取当前登录用户的可以远程登录的主机(及账号)
|
||||||
|
步骤:
|
||||||
|
1. 查询满足条件的项(用户->账号),按授权策略顺序排序
|
||||||
|
2. 在此基础上选出非重复的(用户->账号)关系项
|
||||||
|
3. 继续在上一步基础上选出非重复的主机项
|
||||||
|
4. 为每一个主机查询满足条件的账号项
|
||||||
|
"""
|
||||||
|
operator = handler.get_current_user()
|
||||||
|
db = get_db()
|
||||||
|
|
||||||
|
######################################################
|
||||||
|
# step 1.
|
||||||
|
######################################################
|
||||||
|
s1 = []
|
||||||
|
s1.append('SELECT * FROM {}ops_map'.format(db.table_prefix))
|
||||||
|
s1_where = []
|
||||||
|
s1_where.append('u_id={}'.format(operator.id))
|
||||||
|
s1_where.append('p_state={state}'.format(state=TP_STATE_NORMAL))
|
||||||
|
s1.append('WHERE ({})'.format(') AND ('.join(s1_where)))
|
||||||
|
s1.append('ORDER BY p_rank DESC')
|
||||||
|
sql_1 = ' '.join(s1)
|
||||||
|
|
||||||
|
######################################################
|
||||||
|
# step 2.
|
||||||
|
######################################################
|
||||||
|
sql_2 = 'SELECT * FROM ({}) AS s1 GROUP BY ua_id'.format(sql_1)
|
||||||
|
|
||||||
|
_f = ['id', 'p_id', 'h_id', 'h_state', 'gh_state', 'h_name', 'ip', 'router_ip', 'router_port']
|
||||||
|
|
||||||
|
######################################################
|
||||||
|
# step 3.
|
||||||
|
######################################################
|
||||||
|
sql = []
|
||||||
|
sql.append('SELECT {}'.format(','.join(_f)))
|
||||||
|
sql.append('FROM')
|
||||||
|
sql.append('({}) AS s2'.format(sql_2))
|
||||||
|
sql.append('GROUP BY h_id')
|
||||||
|
sql.append('ORDER BY ip')
|
||||||
|
sql.append('LIMIT {},{}'.format(sql_limit['page_index'] * sql_limit['per_page'], sql_limit['per_page']))
|
||||||
|
sql.append(';')
|
||||||
|
|
||||||
|
sql_counter = []
|
||||||
|
sql_counter.append('SELECT COUNT(*)')
|
||||||
|
sql_counter.append('FROM')
|
||||||
|
sql_counter.append('({}) AS s3'.format(sql_2))
|
||||||
|
sql_counter.append('GROUP BY h_id')
|
||||||
|
sql_counter.append(';')
|
||||||
|
|
||||||
|
db_ret = db.query(' '.join(sql_counter))
|
||||||
|
if db_ret is None or len(db_ret) == 0:
|
||||||
|
return TPE_OK, 0, 1, []
|
||||||
|
|
||||||
|
total = len(db_ret)
|
||||||
|
|
||||||
|
ret_recorder = [] # 用于构建最终返回的数据
|
||||||
|
h_ids = [] # 涉及到的主机的ID列表
|
||||||
|
|
||||||
|
db_ret = db.query(' '.join(sql))
|
||||||
|
if db_ret is None:
|
||||||
|
return TPE_OK, 0, 1, []
|
||||||
|
|
||||||
|
for db_item in db_ret:
|
||||||
|
item = AttrDict()
|
||||||
|
for i in range(len(_f)):
|
||||||
|
item[_f[i]] = db_item[i]
|
||||||
|
|
||||||
|
item.accounts_ = []
|
||||||
|
ret_recorder.append(item)
|
||||||
|
h_ids.append(item.h_id)
|
||||||
|
|
||||||
|
######################################################
|
||||||
|
# step 4.
|
||||||
|
######################################################
|
||||||
|
host_ids = [str(i) for i in h_ids]
|
||||||
|
s4 = []
|
||||||
|
s4.append('SELECT * FROM {}ops_map'.format(db.table_prefix))
|
||||||
|
s4_where = []
|
||||||
|
s4_where.append('u_id={}'.format(operator.id))
|
||||||
|
s4_where.append('p_state={state}'.format(state=TP_STATE_NORMAL))
|
||||||
|
s4_where.append('h_id IN ({})'.format(','.join(host_ids)))
|
||||||
|
s4.append('WHERE ({})'.format(') AND ('.join(s4_where)))
|
||||||
|
s4.append('ORDER BY p_rank DESC')
|
||||||
|
sql_4 = ' '.join(s4)
|
||||||
|
|
||||||
|
sql = []
|
||||||
|
_f = ['id', 'uni_id', 'policy_auth_type', 'p_id', 'h_id', 'a_id', 'a_state', 'ga_state', 'a_name', 'protocol_type']
|
||||||
|
sql.append('SELECT {}'.format(','.join(_f)))
|
||||||
|
sql.append('FROM')
|
||||||
|
sql.append('({}) AS s4'.format(sql_4))
|
||||||
|
sql.append('GROUP BY ua_id')
|
||||||
|
sql.append(';')
|
||||||
|
|
||||||
|
db_ret = db.query(' '.join(sql))
|
||||||
|
if db_ret is None:
|
||||||
|
return TPE_OK, 0, 1, []
|
||||||
|
|
||||||
|
p_ids = [] # 涉及到的策略的ID列表
|
||||||
|
|
||||||
|
for db_item in db_ret:
|
||||||
|
item = AttrDict()
|
||||||
|
for i in range(len(_f)):
|
||||||
|
item[_f[i]] = db_item[i]
|
||||||
|
|
||||||
|
if item.p_id not in p_ids:
|
||||||
|
p_ids.append(item.p_id)
|
||||||
|
|
||||||
|
for j in range(len(ret_recorder)):
|
||||||
|
if ret_recorder[j].h_id == item.h_id:
|
||||||
|
ret_recorder[j].accounts_.append(item)
|
||||||
|
|
||||||
|
# 查询所有相关的授权策略的详细信息
|
||||||
|
# print('p-ids:', p_ids)
|
||||||
|
policy_ids = [str(i) for i in p_ids]
|
||||||
|
_f = ['id', 'flag_rdp', 'flag_ssh']
|
||||||
|
sql = []
|
||||||
|
sql.append('SELECT {}'.format(','.join(_f)))
|
||||||
|
sql.append('FROM {}ops_policy'.format(db.table_prefix))
|
||||||
|
sql.append('WHERE id IN ({})'.format(','.join(policy_ids)))
|
||||||
|
sql.append(';')
|
||||||
|
db_ret = db.query(' '.join(sql))
|
||||||
|
# print('', db_ret)
|
||||||
|
for db_item in db_ret:
|
||||||
|
item = AttrDict()
|
||||||
|
for i in range(len(_f)):
|
||||||
|
item[_f[i]] = db_item[i]
|
||||||
|
|
||||||
|
for i in range(len(ret_recorder)):
|
||||||
|
for j in range(len(ret_recorder[i].accounts_)):
|
||||||
|
if ret_recorder[i].accounts_[j].p_id == item.id:
|
||||||
|
ret_recorder[i].accounts_[j].policy_ = item
|
||||||
|
|
||||||
|
# print(json.dumps(ret_recorder, indent=' '))
|
||||||
|
return TPE_OK, total, sql_limit['page_index'], ret_recorder
|
||||||
|
|
||||||
|
|
||||||
|
def build_auz_map():
|
||||||
|
_users = {}
|
||||||
|
_hosts = {}
|
||||||
|
_accs = {}
|
||||||
|
_gusers = {}
|
||||||
|
_ghosts = {}
|
||||||
|
_gaccs = {}
|
||||||
|
_groups = {}
|
||||||
|
_policies = {}
|
||||||
|
|
||||||
|
_p_users = {}
|
||||||
|
_p_assets = {}
|
||||||
|
|
||||||
|
_map = []
|
||||||
|
|
||||||
|
s = SQL(get_db())
|
||||||
|
|
||||||
|
# 加载所有策略
|
||||||
|
err = s.reset().select_from('ops_policy', ['id', 'rank', 'state'], alt_name='p').query()
|
||||||
|
if err != TPE_OK:
|
||||||
|
return err
|
||||||
|
if 0 == len(s.recorder):
|
||||||
|
return TPE_OK
|
||||||
|
for i in s.recorder:
|
||||||
|
_policies[i.id] = i
|
||||||
|
|
||||||
|
# 加载所有的用户
|
||||||
|
err = s.reset().select_from('user', ['id', 'username', 'surname', 'state'], alt_name='u').query()
|
||||||
|
if err != TPE_OK:
|
||||||
|
return err
|
||||||
|
if 0 == len(s.recorder):
|
||||||
|
return TPE_OK
|
||||||
|
for i in s.recorder:
|
||||||
|
_users[i.id] = i
|
||||||
|
|
||||||
|
# 加载所有的主机
|
||||||
|
err = s.reset().select_from('host', ['id', 'name', 'ip', 'router_ip', 'router_port', 'state'], alt_name='h').query()
|
||||||
|
if err != TPE_OK:
|
||||||
|
return err
|
||||||
|
if 0 == len(s.recorder):
|
||||||
|
return TPE_OK
|
||||||
|
for i in s.recorder:
|
||||||
|
_hosts[i.id] = i
|
||||||
|
|
||||||
|
# 加载所有的账号
|
||||||
|
err = s.reset().select_from('acc', ['id', 'host_id', 'username', 'protocol_type', 'protocol_port', 'auth_type', 'state'], alt_name='a').query()
|
||||||
|
if err != TPE_OK:
|
||||||
|
return err
|
||||||
|
if 0 == len(s.recorder):
|
||||||
|
return TPE_OK
|
||||||
|
for i in s.recorder:
|
||||||
|
_accs[i.id] = i
|
||||||
|
|
||||||
|
# 加载所有的组
|
||||||
|
err = s.reset().select_from('group', ['id', 'type', 'state'], alt_name='g').query()
|
||||||
|
if err != TPE_OK:
|
||||||
|
return err
|
||||||
|
for i in s.recorder:
|
||||||
|
_groups[i.id] = i
|
||||||
|
if i.type == TP_GROUP_USER:
|
||||||
|
_gusers[i.id] = []
|
||||||
|
elif i.type == TP_GROUP_HOST:
|
||||||
|
_ghosts[i.id] = []
|
||||||
|
elif i.type == TP_GROUP_ACCOUNT:
|
||||||
|
_gaccs[i.id] = []
|
||||||
|
|
||||||
|
# 加载所有的组
|
||||||
|
err = s.reset().select_from('group_map', ['id', 'type', 'gid', 'mid'], alt_name='g').query()
|
||||||
|
if err != TPE_OK:
|
||||||
|
return err
|
||||||
|
for g in s.recorder:
|
||||||
|
if g.type == TP_GROUP_USER:
|
||||||
|
# if g.gid not in _gusers:
|
||||||
|
# _gusers[g.gid] = []
|
||||||
|
_gusers[g.gid].append(_users[g.mid])
|
||||||
|
elif g.type == TP_GROUP_HOST:
|
||||||
|
# if g.gid not in _ghosts:
|
||||||
|
# _ghosts[g.gid] = []
|
||||||
|
_ghosts[g.gid].append(_hosts[g.mid])
|
||||||
|
elif g.type == TP_GROUP_ACCOUNT:
|
||||||
|
# if g.gid not in _gaccs:
|
||||||
|
# _gaccs[g.gid] = []
|
||||||
|
_gaccs[g.gid].append(_accs[g.mid])
|
||||||
|
|
||||||
|
# 加载所有策略明细
|
||||||
|
err = s.reset().select_from('ops_auz', ['id', 'policy_id', 'type', 'rtype', 'rid'], alt_name='o').query()
|
||||||
|
if err != TPE_OK:
|
||||||
|
return err
|
||||||
|
if 0 == len(s.recorder):
|
||||||
|
return TPE_OK
|
||||||
|
|
||||||
|
# 分解各个策略中操作者和被操作资产的信息
|
||||||
|
for i in s.recorder:
|
||||||
|
if i.type == TP_POLICY_OPERATOR:
|
||||||
|
|
||||||
|
if i.policy_id not in _p_users:
|
||||||
|
_p_users[i.policy_id] = []
|
||||||
|
|
||||||
|
if i.rtype == TP_USER:
|
||||||
|
u = _users[i.rid]
|
||||||
|
_p_users[i.policy_id].append({
|
||||||
|
'u_id': i.rid,
|
||||||
|
'u_state': u.state,
|
||||||
|
'gu_id': 0,
|
||||||
|
'gu_state': 0,
|
||||||
|
'u_name': u.username,
|
||||||
|
'u_surname': u.surname,
|
||||||
|
'auth_from_': 'USER'
|
||||||
|
})
|
||||||
|
elif i.rtype == TP_GROUP_USER:
|
||||||
|
for u in _gusers[i.rid]:
|
||||||
|
_p_users[i.policy_id].append({
|
||||||
|
'u_id': u.id,
|
||||||
|
'u_state': u.state,
|
||||||
|
'gu_id': i.rid,
|
||||||
|
'gu_state': _groups[i.rid].state,
|
||||||
|
'u_name': u.username,
|
||||||
|
'u_surname': u.surname,
|
||||||
|
'auth_from_': 'gUSER'
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
log.e('invalid operator type.\n')
|
||||||
|
return TPE_FAILED
|
||||||
|
|
||||||
|
elif i.type == TP_POLICY_ASSET:
|
||||||
|
|
||||||
|
if i.policy_id not in _p_assets:
|
||||||
|
_p_assets[i.policy_id] = []
|
||||||
|
|
||||||
|
if i.rtype == TP_ACCOUNT:
|
||||||
|
a = _accs[i.rid]
|
||||||
|
h = _hosts[a.host_id]
|
||||||
|
_p_assets[i.policy_id].append({
|
||||||
|
'a_id': i.rid,
|
||||||
|
'a_state': a.state,
|
||||||
|
'ga_id': 0,
|
||||||
|
'ga_state': 0,
|
||||||
|
'h_id': h.id,
|
||||||
|
'h_state': h.state,
|
||||||
|
'gh_id': 0,
|
||||||
|
'gh_state': 0,
|
||||||
|
'a_name': a.username,
|
||||||
|
'protocol_type': a.protocol_type,
|
||||||
|
'protocol_port': a.protocol_port,
|
||||||
|
'h_name': h.name,
|
||||||
|
'ip': h.ip,
|
||||||
|
'router_ip': h.router_ip,
|
||||||
|
'router_port': h.router_port,
|
||||||
|
'auth_to_': 'ACC'
|
||||||
|
})
|
||||||
|
elif i.rtype == TP_GROUP_ACCOUNT:
|
||||||
|
for a in _gaccs[i.rid]:
|
||||||
|
h = _hosts[a.host_id]
|
||||||
|
_p_assets[i.policy_id].append({
|
||||||
|
'a_id': a.id,
|
||||||
|
'a_state': a.state,
|
||||||
|
'ga_id': i.rid,
|
||||||
|
'ga_state': _groups[i.rid].state,
|
||||||
|
'h_id': h.id,
|
||||||
|
'h_state': h.state,
|
||||||
|
'gh_id': 0,
|
||||||
|
'gh_state': 0,
|
||||||
|
'a_name': a.username,
|
||||||
|
'protocol_type': a.protocol_type,
|
||||||
|
'protocol_port': a.protocol_port,
|
||||||
|
'h_name': h.name,
|
||||||
|
'ip': h.ip,
|
||||||
|
'router_ip': h.router_ip,
|
||||||
|
'router_port': h.router_port,
|
||||||
|
'auth_to_': 'gACC'
|
||||||
|
})
|
||||||
|
elif i.rtype == TP_HOST:
|
||||||
|
for aid in _accs:
|
||||||
|
if _accs[aid].host_id == i.rid:
|
||||||
|
a = _accs[aid]
|
||||||
|
h = _hosts[i.rid]
|
||||||
|
_p_assets[i.policy_id].append({
|
||||||
|
'a_id': aid,
|
||||||
|
'a_state': a.state,
|
||||||
|
'ga_id': 0,
|
||||||
|
'ga_state': 0,
|
||||||
|
'h_id': h.id,
|
||||||
|
'h_state': h.state,
|
||||||
|
'gh_id': 0,
|
||||||
|
'gh_state': 0,
|
||||||
|
'a_name': a.username,
|
||||||
|
'protocol_type': a.protocol_type,
|
||||||
|
'protocol_port': a.protocol_port,
|
||||||
|
'h_name': h.name,
|
||||||
|
'ip': h.ip,
|
||||||
|
'router_ip': h.router_ip,
|
||||||
|
'router_port': h.router_port,
|
||||||
|
'auth_to_': 'HOST'
|
||||||
|
})
|
||||||
|
elif i.rtype == TP_GROUP_HOST:
|
||||||
|
for h in _ghosts[i.rid]:
|
||||||
|
for aid in _accs:
|
||||||
|
if _accs[aid].host_id == h.id:
|
||||||
|
a = _accs[aid]
|
||||||
|
_p_assets[i.policy_id].append({
|
||||||
|
'a_id': aid,
|
||||||
|
'a_state': a.state,
|
||||||
|
'ga_id': 0,
|
||||||
|
'ga_state': 0,
|
||||||
|
'h_id': h.id,
|
||||||
|
'h_state': h.state,
|
||||||
|
'gh_id': i.rid,
|
||||||
|
'gh_state': _groups[i.rid].state,
|
||||||
|
'a_name': a.username,
|
||||||
|
'protocol_type': a.protocol_type,
|
||||||
|
'protocol_port': a.protocol_port,
|
||||||
|
'h_name': h.name,
|
||||||
|
'ip': h.ip,
|
||||||
|
'router_ip': h.router_ip,
|
||||||
|
'router_port': h.router_port,
|
||||||
|
'auth_to_': 'gHOST'
|
||||||
|
})
|
||||||
|
else:
|
||||||
|
log.e('invalid asset type.\n')
|
||||||
|
return TPE_FAILED
|
||||||
|
|
||||||
|
else:
|
||||||
|
return TPE_FAILED
|
||||||
|
|
||||||
|
# 3. 建立所有一一对应的映射关系
|
||||||
|
for pid in _policies:
|
||||||
|
if pid not in _p_users:
|
||||||
|
continue
|
||||||
|
for u in _p_users[pid]:
|
||||||
|
if pid not in _p_assets:
|
||||||
|
continue
|
||||||
|
for a in _p_assets[pid]:
|
||||||
|
x = AttrDict()
|
||||||
|
x.update({
|
||||||
|
'p_id': pid,
|
||||||
|
'p_rank': _policies[pid].rank,
|
||||||
|
'p_state': _policies[pid].state
|
||||||
|
})
|
||||||
|
x.update(u)
|
||||||
|
x.update(a)
|
||||||
|
|
||||||
|
x.uni_id = '{}-{}-{}-{}-{}-{}-{}'.format(x.p_id, x.gu_id, x.u_id, x.gh_id, x.h_id, x.ga_id, x.a_id)
|
||||||
|
x.ua_id = 'u{}-a{}'.format(x.u_id, x.a_id)
|
||||||
|
|
||||||
|
x.policy_auth_type = TP_POLICY_AUTH_UNKNOWN
|
||||||
|
if u['auth_from_'] == 'USER' and a['auth_to_'] == 'ACC':
|
||||||
|
x.policy_auth_type = TP_POLICY_AUTH_USER_ACC
|
||||||
|
elif u['auth_from_'] == 'USER' and a['auth_to_'] == 'gACC':
|
||||||
|
x.policy_auth_type = TP_POLICY_AUTH_USER_gACC
|
||||||
|
elif u['auth_from_'] == 'USER' and a['auth_to_'] == 'HOST':
|
||||||
|
x.policy_auth_type = TP_POLICY_AUTH_USER_HOST
|
||||||
|
elif u['auth_from_'] == 'USER' and a['auth_to_'] == 'gHOST':
|
||||||
|
x.policy_auth_type = TP_POLICY_AUTH_USER_gHOST
|
||||||
|
elif u['auth_from_'] == 'gUSER' and a['auth_to_'] == 'ACC':
|
||||||
|
x.policy_auth_type = TP_POLICY_AUTH_gUSER_ACC
|
||||||
|
elif u['auth_from_'] == 'gUSER' and a['auth_to_'] == 'gACC':
|
||||||
|
x.policy_auth_type = TP_POLICY_AUTH_gUSER_gACC
|
||||||
|
elif u['auth_from_'] == 'gUSER' and a['auth_to_'] == 'HOST':
|
||||||
|
x.policy_auth_type = TP_POLICY_AUTH_gUSER_HOST
|
||||||
|
elif u['auth_from_'] == 'gUSER' and a['auth_to_'] == 'gHOST':
|
||||||
|
x.policy_auth_type = TP_POLICY_AUTH_gUSER_gHOST
|
||||||
|
|
||||||
|
_map.append(x)
|
||||||
|
|
||||||
|
db = get_db()
|
||||||
|
dbtp = db.table_prefix
|
||||||
|
|
||||||
|
db.exec('DELETE FROM {}ops_map'.format(dbtp))
|
||||||
|
|
||||||
|
values = []
|
||||||
|
for i in _map:
|
||||||
|
v = '("{uni_id}","{ua_id}",{p_id},{p_rank},{p_state},{policy_auth_type},{u_id},{u_state},{gu_id},{gu_state},{h_id},{h_state},{gh_id},{gh_state},{a_id},{a_state},{ga_id},{ga_state},' \
|
||||||
|
'"{u_name}","{u_surname}","{h_name}","{ip}","{router_ip}",{router_port},"{a_name}",{protocol_type},{protocol_port})' \
|
||||||
|
''.format(uni_id=i.uni_id, ua_id=i.ua_id, p_id=i.p_id, p_rank=i.p_rank, p_state=i.p_state,policy_auth_type=i.policy_auth_type,
|
||||||
|
u_id=i.u_id, u_state=i.u_state, gu_id=i.gu_id, gu_state=i.gu_state, h_id=i.h_id, h_state=i.h_state,
|
||||||
|
gh_id=i.gh_id, gh_state=i.gh_state, a_id=i.a_id, a_state=i.a_state, ga_id=i.ga_id, ga_state=i.ga_state,
|
||||||
|
u_name=i.u_name, u_surname=i.u_surname, h_name=i.h_name, ip=i.ip, router_ip=i.router_ip, router_port=i.router_port,
|
||||||
|
a_name=i.a_name, protocol_type=i.protocol_type, protocol_port=i.protocol_port)
|
||||||
|
values.append(v)
|
||||||
|
|
||||||
|
sql = 'INSERT INTO `{dbtp}ops_map` (uni_id,ua_id,p_id,p_rank,p_state,policy_auth_type,u_id,u_state,gu_id,gu_state,h_id,h_state,gh_id,gh_state,a_id,a_state,ga_id,ga_state,' \
|
||||||
|
'u_name,u_surname,h_name,ip,router_ip,router_port,a_name,protocol_type,protocol_port) VALUES \n{values};' \
|
||||||
|
''.format(dbtp=dbtp, values=',\n'.join(values))
|
||||||
|
|
||||||
|
db_ret = db.exec(sql)
|
||||||
|
if not db_ret:
|
||||||
|
return TPE_DATABASE
|
||||||
|
|
||||||
|
return TPE_OK
|
Loading…
Reference in New Issue