diff --git a/server/www/teleport/static/js/audit/auz-info.js b/server/www/teleport/static/js/audit/auz-info.js new file mode 100644 index 0000000..da1728e --- /dev/null +++ b/server/www/teleport/static/js/audit/auz-info.js @@ -0,0 +1,1898 @@ +"use strict"; + +$app.on_init = function (cb_stack) { + $app.dom = { + area_auditor: $('#area-auditor'), + area_auditee: $('#area-auditee'), + + btn_refresh_auditor: $('#btn-refresh-auditor'), + btn_add_auditor_user: $('#btn-add-auditor-user'), + btn_add_auditor_user_group: $('#btn-add-auditor-user-group'), + select_all_auditor: $('#table-auditor-select-all'), + btn_remove_auditor: $('#btn-remove-auditor'), + + btn_refresh_auditee: $('#btn-refresh-auditee'), + btn_add_auditee_user: $('#btn-add-auditee-user'), + btn_add_auditee_user_group: $('#btn-add-auditee-user-group'), + btn_add_auditee_host: $('#btn-add-auditee-host'), + btn_add_auditee_host_group: $('#btn-add-auditee-host-group'), + select_all_auditee: $('#table-auditee-select-all'), + btn_remove_auditee: $('#btn-remove-auditee') + }; + + if ($app.options.policy_id !== 0) { + window.onresize = $app.on_win_resize; + cb_stack + .add($app.sync_height) + .add($app.create_controls); + } + + + cb_stack.exec(); +}; + +//=================================== +// 创建页面控件对象 +//=================================== +$app.create_controls = function (cb_stack) { + + //------------------------------- + // 操作者列表表格 + //------------------------------- + var table_operator_options = { + dom_id: 'table-operator', + data_source: { + type: 'ajax-post', + url: '/audit/policy/get-operators' + }, + message_no_data: '还没有授权的操作者...', + column_default: {sort: false, align: 'left'}, + columns: [ + { + title: '', + key: 'chkbox', + sort: false, + width: 36, + align: 'center', + render: 'make_check_box', + fields: {id: 'id'} + }, + { + title: '类型', + key: 'rtype', + sort: true, + width: 80, + render: 'ref_type', + fields: {rtype: 'rtype'} + }, + { + title: '操作者', + key: 'name', + sort: true, + header_render: 'filter_search', + fields: {name: 'name'} + } + ], + + // 重载回调函数 + on_header_created: $app.on_table_operator_header_created, + on_render_created: $app.on_table_operator_render_created, + on_cell_created: $app.on_table_operator_cell_created + }; + + $app.table_operator = $tp.create_table(table_operator_options); + cb_stack + .add($app.table_operator.load_data) + .add($app.table_operator.init); + + $tp.create_table_header_filter_search($app.table_operator, { + name: 'search', + place_holder: '搜索:用户名/用户组名' + }); + $tp.create_table_filter_fixed_value($app.table_operator, {policy_id: $app.options.policy_id}); + + $tp.create_table_paging($app.table_operator, 'table-operator-paging', + { + per_page: Cookies.get($app.page_id('audit_auz') + '_operator_per_page'), + on_per_page_changed: function (per_page) { + Cookies.set($app.page_id('audit_auz') + '_operator_per_page', per_page, {expires: 365}); + } + }); + $tp.create_table_pagination($app.table_operator, 'table-operator-pagination'); + + $app.dom.btn_refresh_auditor.click(function () { + $app.table_operator.load_data(); + }); + $app.dom.select_all_auditor.click(function () { + var _objects = $('#' + $app.table_operator.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_remove_auditor.click($app.on_btn_remove_operator_click); + + //------------------------------- + // 资产列表表格 + //------------------------------- + var table_asset_options = { + dom_id: 'table-asset', + data_source: { + type: 'ajax-post', + url: '/audit/policy/get-asset' + }, + message_no_data: '还没有分配被授权访问的资产哦...', + column_default: {sort: false, align: 'left'}, + columns: [ + { + title: '', + key: 'chkbox', + sort: false, + width: 36, + align: 'center', + render: 'make_check_box', + fields: {id: 'id'} + }, + { + title: '类型', + key: 'rtype', + sort: true, + width: 80, + render: 'ref_type', + fields: {rtype: 'rtype'} + }, + { + title: '资产', + key: 'name', + sort: true, + header_render: 'filter_search', + fields: {name: 'name'} + } + ], + + // 重载回调函数 + on_header_created: $app.on_table_asset_header_created, + on_render_created: $app.on_table_asset_render_created, + on_cell_created: $app.on_table_asset_cell_created + }; + + $app.table_asset = $tp.create_table(table_asset_options); + cb_stack + .add($app.table_asset.load_data) + .add($app.table_asset.init); + + $tp.create_table_header_filter_search($app.table_asset, { + name: 'search', + place_holder: '搜索:账号名/账号组名/主机名/主机组名' + }); + $tp.create_table_filter_fixed_value($app.table_asset, {policy_id: $app.options.policy_id}); + + $tp.create_table_paging($app.table_asset, 'table-asset-paging', + { + per_page: Cookies.get($app.page_id('audit_auz') + '_asset_per_page'), + on_per_page_changed: function (per_page) { + Cookies.set($app.page_id('audit_auz') + '_asset_per_page', per_page, {expires: 365}); + } + }); + $tp.create_table_pagination($app.table_asset, 'table-asset-pagination'); + + $app.dom.btn_refresh_auditee.click(function () { + $app.table_asset.load_data(); + }); + $app.dom.select_all_auditee.click(function () { + var _objects = $('#' + $app.table_asset.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_remove_auditee.click($app.on_btn_remove_asset_click); + + //------------------------------- + // 选择用户对话框 + //------------------------------- + var table_sel_user_options = { + dom_id: 'table-sel-user', + data_source: { + type: 'ajax-post', + url: '/user/get-users', + exclude: {'audit_policy_id': $app.options.policy_id} + }, + message_no_data: '所有用户都被授权了哦...', + column_default: {sort: false, align: 'left'}, + columns: [ + { + title: '', + key: 'chkbox', + sort: false, + width: 36, + align: 'center', + render: 'make_check_box', + fields: {id: 'id'} + }, + { + title: "用户", + key: "username", + sort: true, + header_render: 'filter_search', + render: 'user_info', + fields: {id: 'id', username: 'username', surname: 'surname', email: 'email'} + }, + { + title: "角色", + key: "role_id", + width: 120, + sort: true, + header_render: 'filter_role', + render: 'role', + fields: {role_id: 'role_id'} + }, + { + title: "状态", + key: "state", + sort: true, + width: 120, + align: 'center', + header_render: 'filter_state', + render: 'state', + fields: {state: 'state'} + } + ], + + // 重载回调函数 + on_header_created: $app.on_table_sel_user_header_created, + on_render_created: $app.on_table_sel_user_render_created, + on_cell_created: $app.on_table_sel_user_cell_created + }; + $app.table_sel_user = $tp.create_table(table_sel_user_options); + cb_stack.add($app.table_sel_user.init); + + $tp.create_table_header_filter_search($app.table_sel_user, { + name: 'search', + place_holder: '搜索:用户账号/姓名/邮箱/描述/等等...' + }); + $tp.create_table_filter_role($app.table_sel_user, $app.role_list); + $tp.create_table_header_filter_state($app.table_sel_user, 'state', $app.obj_states); + + $tp.create_table_paging($app.table_sel_user, 'table-sel-user-paging', + { + per_page: Cookies.get($app.page_id('audit_auz_detail') + '_sel_user_per_page'), + on_per_page_changed: function (per_page) { + Cookies.set($app.page_id('audit_auz_detail') + '_sel_user_per_page', per_page, {expires: 365}); + } + }); + $tp.create_table_pagination($app.table_sel_user, 'table-sel-user-pagination'); + + $app.dlg_sel_user = $app.create_dlg_sel_user(); + cb_stack.add($app.dlg_sel_user.init); + cb_stack.add($app.load_role_list); + + + //------------------------------- + // 选择用户组对话框 + //------------------------------- + var table_sel_user_group_options = { + dom_id: 'table-sel-user-group', + data_source: { + type: 'ajax-post', + url: '/group/get-groups', + exclude: {'audit_policy_id': {pid: $app.options.policy_id, gtype: TP_GROUP_USER}} // 排除指定成员 + }, + message_no_data: '所有用户组都被授权了哦...', + column_default: {sort: false, align: 'left'}, + columns: [ + { + title: '', + key: 'chkbox', + sort: false, + width: 36, + align: 'center', + render: 'make_check_box', + fields: {id: 'id'} + }, + { + title: "用户组", + key: "name", + sort: true, + header_render: 'filter_search', + render: 'name', + fields: {name: 'name', desc: 'desc'} + } + ], + + // 重载回调函数 + on_header_created: $app.on_table_sel_user_group_header_created, + on_render_created: $app.on_table_sel_user_group_render_created, + on_cell_created: $app.on_table_sel_user_group_cell_created + }; + $app.table_sel_user_group = $tp.create_table(table_sel_user_group_options); + cb_stack.add($app.table_sel_user_group.init); + + $tp.create_table_header_filter_search($app.table_sel_user_group, { + name: 'search', + place_holder: '搜索:用户组名称/描述/等等...' + }); + $tp.create_table_filter_fixed_value($app.table_sel_user_group, {type: TP_GROUP_USER}); + $tp.create_table_paging($app.table_sel_user_group, 'table-sel-user-group-paging', + { + per_page: Cookies.get($app.page_id('audit_auz_detail') + '_user_group_per_page'), + on_per_page_changed: function (per_page) { + Cookies.set($app.page_id('audit_auz_detail') + '_user_group_per_page', per_page, {expires: 365}); + } + }); + $tp.create_table_pagination($app.table_sel_user_group, 'table-sel-user-group-pagination'); + + $app.dlg_sel_user_group = $app.create_dlg_sel_user_group(); + cb_stack.add($app.dlg_sel_user_group.init); + + + //------------------------------- + // 选择账号对话框 + //------------------------------- + var table_sel_acc_options = { + dom_id: 'table-sel-acc', + data_source: { + type: 'ajax-post', + url: '/asset/get-accounts', + exclude: {'audit_policy_id': $app.options.policy_id} // 排除指定成员 + }, + message_no_data: '所有账号都被授权了哦...', + column_default: {sort: false, align: 'left'}, + columns: [ + { + title: '', + key: 'chkbox', + sort: false, + width: 36, + align: 'center', + render: 'make_check_box', + fields: {id: 'id'} + }, + { + title: "账号", + key: "username", + sort: true, + header_render: 'filter_search', + render: 'acc_info', + fields: {id: 'id', username: 'username', host_ip: 'host_ip', router_ip: 'router_ip', router_port: 'router_port'} + }, + { + title: "远程连接协议", + key: "protocol_type", + sort: true, + width: 120, + align: 'center', + render: 'protocol', + fields: {protocol_type: 'protocol_type'} + }, + { + title: "认证方式", + key: "auth_type", + width: 80, + align: 'center', + render: 'auth_type', + fields: {auth_type: 'auth_type'} + }, + { + title: "状态", + key: "state", + sort: true, + width: 80, + align: 'center', + render: 'state', + fields: {state: 'state'} + } + ], + + // 重载回调函数 + on_header_created: $app.on_table_sel_acc_header_created, + on_render_created: $app.on_table_sel_acc_render_created, + on_cell_created: $app.on_table_sel_acc_cell_created + }; + $app.table_sel_acc = $tp.create_table(table_sel_acc_options); + cb_stack.add($app.table_sel_acc.init); + + $tp.create_table_header_filter_search($app.table_sel_acc, { + name: 'search', + place_holder: '搜索:账号/主机IP/等等...' + }); + // 从cookie中读取用户分页限制的选择 + $tp.create_table_paging($app.table_sel_acc, 'table-sel-acc-paging', + { + per_page: Cookies.get($app.page_id('audit_auz_detail') + '_sel_acc_per_page'), + on_per_page_changed: function (per_page) { + Cookies.set($app.page_id('audit_auz_detail') + '_sel_acc_per_page', per_page, {expires: 365}); + } + }); + $tp.create_table_pagination($app.table_sel_acc, 'table-sel-acc-pagination'); + + $app.dlg_sel_acc = $app.create_dlg_sel_acc(); + cb_stack.add($app.dlg_sel_acc.init); + + + //------------------------------- + // 选择账号组对话框 + //------------------------------- + var table_sel_acc_group_options = { + dom_id: 'table-sel-acc-group', + data_source: { + type: 'ajax-post', + url: '/group/get-groups', + exclude: {'audit_policy_id': {pid: $app.options.policy_id, gtype: TP_GROUP_ACCOUNT}} // 排除指定成员 + }, + message_no_data: '所有账号组都被授权了哦...', + column_default: {sort: false, align: 'left'}, + columns: [ + { + title: '', + key: 'chkbox', + sort: false, + width: 36, + align: 'center', + render: 'make_check_box', + fields: {id: 'id'} + }, + { + title: "账号组", + key: "name", + sort: true, + header_render: 'filter_search', + render: 'name', + fields: {name: 'name', desc: 'desc'} + } + ], + + // 重载回调函数 + on_header_created: $app.on_table_sel_acc_group_header_created, + on_render_created: $app.on_table_sel_acc_group_render_created, + on_cell_created: $app.on_table_sel_acc_group_cell_created + }; + $app.table_sel_acc_group = $tp.create_table(table_sel_acc_group_options); + cb_stack.add($app.table_sel_acc_group.init); + + $tp.create_table_header_filter_search($app.table_sel_acc_group, { + name: 'search', + place_holder: '搜索:账号组名称/描述/等等...' + }); + $tp.create_table_filter_fixed_value($app.table_sel_acc_group, {type: TP_GROUP_ACCOUNT}); + $tp.create_table_paging($app.table_sel_acc_group, 'table-sel-acc-group-paging', + { + per_page: Cookies.get($app.page_id('audit_auz_detail') + '_acc_group_per_page'), + on_per_page_changed: function (per_page) { + Cookies.set($app.page_id('audit_auz_detail') + '_acc_group_per_page', per_page, {expires: 365}); + } + }); + $tp.create_table_pagination($app.table_sel_acc_group, 'table-sel-acc-group-pagination'); + + $app.dlg_sel_acc_group = $app.create_dlg_sel_acc_group(); + cb_stack.add($app.dlg_sel_acc_group.init); + + + //------------------------------- + // 选择主机对话框 + //------------------------------- + var table_sel_host_options = { + dom_id: 'table-sel-host', + data_source: { + type: 'ajax-post', + url: '/asset/get-hosts', + exclude: {'audit_policy_id': $app.options.policy_id} // 排除指定成员 + }, + message_no_data: '所有主机都被授权了哦...', + column_default: {sort: false, align: 'left'}, + columns: [ + { + title: '', + key: 'chkbox', + sort: false, + width: 36, + align: 'center', + render: 'make_check_box', + fields: {id: 'id'} + }, + { + title: "主机", + key: "ip", + sort: true, + // width: 240, + header_render: 'filter_search', + render: 'host_info', + fields: {id: 'id', ip: 'ip', name: 'name', router_ip: 'router_ip', router_port: 'router_port'} + }, + { + title: "系统", + key: "os_type", + width: 36, + align: 'center', + sort: true, + render: 'os_type', + fields: {os_type: 'os_type'} + }, + { + title: "资产编号", + key: "cid", + sort: true, + // width: 80, + // align: 'center', + //render: 'auth_type', + fields: {cid: 'cid'} + }, + { + title: "状态", + key: "state", + sort: true, + width: 90, + align: 'center', + render: 'state', + fields: {state: 'state'} + } + ], + + // 重载回调函数 + on_header_created: $app.on_table_sel_host_header_created, + on_render_created: $app.on_table_sel_host_render_created, + on_cell_created: $app.on_table_sel_host_cell_created + }; + $app.table_sel_host = $tp.create_table(table_sel_host_options); + cb_stack.add($app.table_sel_host.init); + + $tp.create_table_header_filter_search($app.table_sel_host, { + name: 'search', + place_holder: '搜索:主机IP/名称/等等...' + }); + // 从cookie中读取用户分页限制的选择 + $tp.create_table_paging($app.table_sel_host, 'table-sel-host-paging', + { + per_page: Cookies.get($app.page_id('audit_auz_detail') + '_sel_host_per_page'), + on_per_page_changed: function (per_page) { + Cookies.set($app.page_id('audit_auz_detail') + '_sel_host_per_page', per_page, {expires: 365}); + } + }); + $tp.create_table_pagination($app.table_sel_acc, 'table-sel-host-pagination'); + + $app.dlg_sel_host = $app.create_dlg_sel_host(); + cb_stack.add($app.dlg_sel_host.init); + + + //------------------------------- + // 选择主机组对话框 + //------------------------------- + var table_sel_host_group_options = { + dom_id: 'table-sel-host-group', + data_source: { + type: 'ajax-post', + url: '/group/get-groups', + exclude: {'audit_policy_id': {pid: $app.options.policy_id, gtype: TP_GROUP_HOST}} // 排除指定成员 + }, + message_no_data: '所有主机组都被授权了哦...', + column_default: {sort: false, align: 'left'}, + columns: [ + { + title: '', + key: 'chkbox', + sort: false, + width: 36, + align: 'center', + render: 'make_check_box', + fields: {id: 'id'} + }, + { + title: "主机组", + key: "name", + sort: true, + header_render: 'filter_search', + render: 'name', + fields: {name: 'name', desc: 'desc'} + } + ], + + // 重载回调函数 + on_header_created: $app.on_table_sel_host_group_header_created, + on_render_created: $app.on_table_sel_host_group_render_created, + on_cell_created: $app.on_table_sel_host_group_cell_created + }; + $app.table_sel_host_group = $tp.create_table(table_sel_host_group_options); + cb_stack.add($app.table_sel_host_group.init); + + $tp.create_table_header_filter_search($app.table_sel_host_group, { + name: 'search', + place_holder: '搜索:主机组名称/描述/等等...' + }); + $tp.create_table_filter_fixed_value($app.table_sel_host_group, {type: TP_GROUP_HOST}); + $tp.create_table_paging($app.table_sel_host_group, 'table-sel-host-group-paging', + { + per_page: Cookies.get($app.page_id('audit_auz_detail') + '_host_group_per_page'), + on_per_page_changed: function (per_page) { + Cookies.set($app.page_id('audit_auz_detail') + '_host_group_per_page', per_page, {expires: 365}); + } + }); + $tp.create_table_pagination($app.table_sel_host_group, 'table-sel-host-group-pagination'); + + $app.dlg_sel_host_group = $app.create_dlg_sel_host_group(); + cb_stack.add($app.dlg_sel_host_group.init); + + + //------------------------------- + // 页面控件事件绑定 + //------------------------------- + $app.dom.btn_add_auditor_user.click(function () { + $app.dlg_sel_user.show(); + }); + $app.dom.btn_add_auditor_user_group.click(function () { + $app.dlg_sel_user_group.show(); + }); + $app.dom.btn_add_auditee_user.click(function () { + $app.dlg_sel_acc.show(); + }); + $app.dom.btn_add_auditee_user_group.click(function () { + $app.dlg_sel_acc_group.show(); + }); + $app.dom.btn_add_auditee_host.click(function () { + $app.dlg_sel_host.show(); + }); + $app.dom.btn_add_auditee_host_group.click(function () { + $app.dlg_sel_host_group.show(); + }); + + cb_stack.exec(); +}; + +// 为保证界面美观,两个表格的高度不一致时,自动调整到一致。 +$app.on_win_resize = function () { + $app.sync_height(); +}; +$app.sync_height = function (cb_stack) { + var o_top = $app.dom.area_auditor.offset().top; + var a_top = $app.dom.area_auditee.offset().top; + + // 如果两个表格的top不一致,说明是页面宽度缩小到一定程度后,两个表格上下排列了。 + if (o_top !== a_top) { + $app.dom.area_auditor.css({height: 'auto', minHeight: 'auto'}); + $app.dom.area_auditee.css({height: 'auto', minHeight: 'auto'}); + return; + } + + $app.dom.area_auditor.css({height: 'auto', minHeight: 'auto'}); + $app.dom.area_auditee.css({height: 'auto', minHeight: 'auto'}); + + var o_height = $app.dom.area_auditor.height(); + var a_height = $app.dom.area_auditee.height(); + + var h = _.max([o_height, a_height]); + + if (o_height <= h) { + $app.dom.area_auditor.css({minHeight: h}); + } else { + $app.dom.area_auditor.css({height: 'auto', minHeight: 'auto'}); + } + if (a_height <= h) { + $app.dom.area_auditee.css({minHeight: h}); + } else { + $app.dom.area_auditee.css({height: 'auto', minHeight: 'auto'}); + } + + if (cb_stack) + cb_stack.exec(); +}; + +//------------------------------- +// 通用渲染器 +//------------------------------- +$app._add_common_render = function (render) { + render.filter_search = function (header, title, col) { + var _ret = ['
']; + _ret.push('
'); + _ret.push('
' + title + '
'); + + // 表格内嵌过滤器的DOM实体在这时生成 + var filter_ctrl = header._table_ctrl.get_filter_ctrl('search'); + _ret.push(filter_ctrl.render()); + + _ret.push('
'); + + return _ret.join(''); + }; + + render.filter_state = function (header, title, col) { + var _ret = ['
']; + _ret.push('
'); + _ret.push('
' + title + '
'); + + // 表格内嵌过滤器的DOM实体在这时生成 + var filter_ctrl = header._table_ctrl.get_filter_ctrl('state'); + _ret.push(filter_ctrl.render()); + + _ret.push('
'); + + return _ret.join(''); + }; + + render.make_check_box = function (row_id, fields) { + return ''; + }; + + 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 = ' 未知'; + } + + return '' + _state + '' + }; + + render.ref_type = function (row_id, fields) { + switch (fields.rtype) { + case TP_USER: + return ' 用户'; + case TP_GROUP_USER: + return ' 用户组'; + case TP_ACCOUNT: + return ' 账号'; + case TP_GROUP_ACCOUNT: + return ' 账号组'; + case TP_HOST: + return ' 主机'; + case TP_GROUP_HOST: + return ' 主机组'; + default: + return '未知' + } + }; +}; + +//------------------------------- +// 操作者列表 +//------------------------------- + +$app.check_operator_all_selected = function (cb_stack) { + var _all_checked = true; + var _objs = $('#' + $app.table_operator.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_auditor.prop('checked', true); + } else { + $app.dom.select_all_auditor.prop('checked', false); + } + + if (cb_stack) + cb_stack.exec(); +}; + +$app.on_table_operator_cell_created = function (tbl, row_id, col_key, cell_obj) { + if (col_key === 'chkbox') { + cell_obj.find('[data-check-box]').click(function () { + $app.check_operator_all_selected(); + }); + } +}; + +$app.on_table_operator_render_created = function (render) { + + $app._add_common_render(render); + +}; + +$app.on_table_operator_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(); +}; + +$app.get_selected_operator = function (tbl) { + var items = []; + var _objs = $('#' + $app.table_operator.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); + items.push(_row_data.id); + } + }); + return items; +}; + +$app.on_btn_remove_operator_click = function () { + var items = $app.get_selected_operator($app.table_operator); + if (items.length === 0) { + $tp.notify_error('请选择要移除的操作者!'); + return; + } + + var _fn_sure = function (cb_stack) { + $tp.ajax_post_json('/audit/policy/remove-members', {policy_id: $app.options.policy_id, policy_type: TP_POLICY_OPERATOR, ids: items}, + function (ret) { + if (ret.code === TPE_OK) { + cb_stack + .add($app.sync_height) + .add($app.check_operator_all_selected) + .add($app.check_operator_all_selected) + .add($app.table_operator.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: '

注意:移除操作不可恢复!!

您确定要移除选定的' + items.length + '个授权操作者吗?

', + fn_yes: _fn_sure + }); + +}; + + +//------------------------------- +// 资产列表 +//------------------------------- + +$app.check_asset_all_selected = function (cb_stack) { + var _all_checked = true; + var _objs = $('#' + $app.table_asset.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_auditee.prop('checked', true); + } else { + $app.dom.select_all_auditee.prop('checked', false); + } + + if (cb_stack) + cb_stack.exec(); +}; + +$app.on_table_asset_cell_created = function (tbl, row_id, col_key, cell_obj) { + if (col_key === 'chkbox') { + cell_obj.find('[data-check-box]').click(function () { + $app.check_asset_all_selected(); + }); + } +}; + +$app.on_table_asset_render_created = function (render) { + $app._add_common_render(render); +}; + +$app.on_table_asset_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(); +}; + +$app.get_selected_asset = function (tbl) { + var items = []; + var _objs = $('#' + $app.table_asset.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); + items.push(_row_data.id); + } + }); + return items; +}; + +$app.on_btn_remove_asset_click = function () { + var items = $app.get_selected_asset($app.table_asset); + if (items.length === 0) { + $tp.notify_error('请选择要移除的被授权资产!'); + return; + } + + var _fn_sure = function (cb_stack) { + $tp.ajax_post_json('/audit/policy/remove-members', {policy_id: $app.options.policy_id, policy_type: TP_POLICY_ASSET, ids: items}, + function (ret) { + if (ret.code === TPE_OK) { + cb_stack + .add($app.sync_height) + .add($app.check_asset_all_selected) + .add($app.check_asset_all_selected) + .add($app.table_asset.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: '

注意:移除操作不可恢复!!

您确定要移除选定的' + items.length + '个被授权资产吗?

', + fn_yes: _fn_sure + }); + +}; + + +//------------------------------- +// 选择用户对话框 +//------------------------------- + +$app.on_table_sel_user_cell_created = function (tbl, row_id, col_key, cell_obj) { + if (col_key === 'chkbox') { + cell_obj.find('[data-check-box]').click(function () { + $app.dlg_sel_user.check_all_selected(); + }); + } +}; + +$app.on_table_sel_user_render_created = function (render) { + $app._add_common_render(render); + + render.filter_role = function (header, title, col) { + var _ret = ['
']; + _ret.push('
'); + _ret.push('
' + title + '
'); + + // 表格内嵌过滤器的DOM实体在这时生成 + var filter_ctrl = header._table_ctrl.get_filter_ctrl('role'); + _ret.push(filter_ctrl.render()); + + _ret.push('
'); + + return _ret.join(''); + }; + + render.user_info = function (row_id, fields) { + var ret = []; + ret.push('' + fields.surname + ''); + ret.push(''); + ret.push(fields.username); + if (fields.email.length > 0) + ret.push(' <' + fields.email + '>'); + ret.push(''); + return ret.join('') + }; + + render.role = function (row_id, fields) { + for (var i = 0; i < $app.role_list.length; ++i) { + if ($app.role_list[i].id === fields.role_id) + return $app.role_list[i].name; + } + return ' 未设置'; + }; +}; + +$app.on_table_sel_user_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('role').on_created(); + header._table_ctrl.get_filter_ctrl('state').on_created(); +}; + +$app.create_dlg_sel_user = function () { + var dlg = {}; + dlg.dom_id = 'dlg-sel-user'; + dlg.field_id = -1; + dlg.field_name = ''; + dlg.field_desc = ''; + + dlg.dom = { + dialog: $('#' + dlg.dom_id), + btn_sel_all: $('#' + dlg.dom_id + ' input[data-action="sel-all"]'), + btn_add: $('#' + dlg.dom_id + ' button[data-action="use-selected"]') + }; + + dlg.init = function (cb_stack) { + dlg.dom.btn_add.click(dlg.on_add); + dlg.dom.btn_sel_all.click(dlg.on_sel_all); + cb_stack.exec(); + }; + + dlg.show = function () { + $app.table_sel_user.load_data(); + dlg.dom.dialog.modal(); + }; + + dlg.on_sel_all = function () { + var _objects = $('#' + $app.table_sel_user.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); + }); + } + }; + + dlg.check_all_selected = function (cb_stack) { + var _all_checked = true; + var _objs = $('#' + dlg.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) { + dlg.dom.btn_sel_all.prop('checked', true); + } else { + dlg.dom.btn_sel_all.prop('checked', false); + } + if (cb_stack) + cb_stack.exec(); + }; + + dlg.get_selected_items = function () { + var items = []; + var _objs = $('#' + dlg.dom_id + ' tbody tr td input[data-check-box]'); + $.each(_objs, function (i, _obj) { + if ($(_obj).is(':checked')) { + var _row_data = $app.table_sel_user.get_row(_obj); + + var name = _row_data.username; + if (_row_data.surname.length > 0 && _row_data.surname !== name) + name += '(' + _row_data.surname + ')'; + + items.push({id: _row_data.id, name: name}); + } + }); + + return items; + }; + + dlg.on_add = function () { + var items = dlg.get_selected_items(); + + $tp.ajax_post_json('/audit/policy/add-members', { + policy_id: $app.options.policy_id, + type: TP_POLICY_OPERATOR, // 授权操作者 + rtype: TP_USER, // 用户 + members: items + }, + function (ret) { + if (ret.code === TPE_OK) { + $tp.notify_success('授权操作者添加成功!'); + CALLBACK_STACK.create() + .add($app.sync_height) + .add(dlg.check_all_selected) + .add($app.table_operator.load_data) + .add($app.table_sel_user.load_data) + .exec(); + } else { + $tp.notify_error('授权操作者添加失败:' + tp_error_msg(ret.code, ret.message)); + } + }, + function () { + $tp.notify_error('网络故障,授权操作者添加失败!'); + } + ); + + }; + + return dlg; +}; + + +//------------------------------- +// 选择用户组对话框 +//------------------------------- + +$app.on_table_sel_user_group_cell_created = function (tbl, row_id, col_key, cell_obj) { + if (col_key === 'chkbox') { + cell_obj.find('[data-check-box]').click(function () { + $app.dlg_sel_user_group.check_all_selected(); + }); + } +}; + +$app.on_table_sel_user_group_render_created = function (render) { + + $app._add_common_render(render); + + render.name = function (row_id, fields) { + return '' + fields.name + '' + fields.desc + ''; + }; +}; + +$app.on_table_sel_user_group_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(); +}; + +$app.create_dlg_sel_user_group = function () { + var dlg = {}; + dlg.dom_id = 'dlg-sel-user-group'; + dlg.field_id = -1; // 用户id + dlg.field_name = ''; + dlg.field_desc = ''; + + dlg.dom = { + dialog: $('#' + dlg.dom_id), + btn_sel_all: $('#' + dlg.dom_id + ' input[data-action="sel-all"]'), + btn_add: $('#' + dlg.dom_id + ' button[data-action="use-selected"]') + }; + + dlg.init = function (cb_stack) { + dlg.dom.btn_add.click(dlg.on_add); + dlg.dom.btn_sel_all.click(dlg.on_sel_all); + cb_stack.exec(); + }; + + dlg.show = function () { + $app.table_sel_user_group.load_data(); + dlg.dom.dialog.modal(); + }; + + dlg.on_sel_all = function () { + var _objects = $('#' + $app.table_sel_user_group.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); + }); + } + }; + + dlg.check_all_selected = function (cb_stack) { + var _all_checked = true; + var _objs = $('#' + dlg.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) { + dlg.dom.btn_sel_all.prop('checked', true); + } else { + dlg.dom.btn_sel_all.prop('checked', false); + } + if (cb_stack) + cb_stack.exec(); + }; + + dlg.get_selected_items = function () { + var items = []; + var _objs = $('#' + dlg.dom_id + ' tbody tr td input[data-check-box]'); + $.each(_objs, function (i, _obj) { + if ($(_obj).is(':checked')) { + var _row_data = $app.table_sel_user_group.get_row(_obj); + items.push({id: _row_data.id, name: _row_data.name}); + } + }); + + return items; + }; + + dlg.on_add = function () { + var items = dlg.get_selected_items(); + + $tp.ajax_post_json('/audit/policy/add-members', { + policy_id: $app.options.policy_id, + type: TP_POLICY_OPERATOR, // 授权操作者 + rtype: TP_GROUP_USER, // 用户组 + members: items + }, + function (ret) { + if (ret.code === TPE_OK) { + $tp.notify_success('授权操作者添加成功!'); + CALLBACK_STACK.create() + .add($app.sync_height) + .add(dlg.check_all_selected) + .add($app.table_operator.load_data) + .add($app.table_sel_user_group.load_data) + .exec(); + } else { + $tp.notify_error('授权操作者添加失败:' + tp_error_msg(ret.code, ret.message)); + } + }, + function () { + $tp.notify_error('网络故障,授权操作者添加失败!'); + } + ); + + }; + + return dlg; +}; + +//------------------------------- +// 选择账号对话框 +//------------------------------- + +$app.on_table_sel_acc_cell_created = function (tbl, row_id, col_key, cell_obj) { + if (col_key === 'chkbox') { + cell_obj.find('[data-check-box]').click(function () { + $app.dlg_sel_acc.check_all_selected(); + }); + } +}; + +$app.on_table_sel_acc_render_created = function (render) { + + $app._add_common_render(render); + + render.acc_info = function (row_id, fields) { + var ret = []; + + ret.push('' + fields.username + '@' + fields.host_ip + ''); + if (fields.router_ip.length > 0) + ret.push('由 ' + fields.router_ip + ':' + fields.router_port + ' 路由'); + + return ret.join(''); + }; + + render.protocol = function (row_id, fields) { + switch (fields.protocol_type) { + case TP_PROTOCOL_TYPE_RDP: + return ' RDP'; + case TP_PROTOCOL_TYPE_SSH: + return ' SSH'; + case TP_PROTOCOL_TYPE_TELNET: + return ' TELNET'; + default: + return ' 未设置'; + } + }; + + render.auth_type = function (row_id, fields) { + switch (fields.auth_type) { + case TP_AUTH_TYPE_NONE: + return ''; + case TP_AUTH_TYPE_PASSWORD: + return '密码'; + case TP_AUTH_TYPE_PRIVATE_KEY: + return '私钥'; + default: + return '未设置'; + } + }; +}; + +$app.on_table_sel_acc_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(); +}; + +$app.create_dlg_sel_acc = function () { + var dlg = {}; + dlg.dom_id = 'dlg-sel-acc'; + dlg.field_id = -1; + dlg.field_name = ''; + dlg.field_desc = ''; + + dlg.dom = { + dialog: $('#' + dlg.dom_id), + btn_sel_all: $('#' + dlg.dom_id + ' input[data-action="sel-all"]'), + btn_add: $('#' + dlg.dom_id + ' button[data-action="use-selected"]') + }; + + dlg.init = function (cb_stack) { + dlg.dom.btn_add.click(dlg.on_add); + dlg.dom.btn_sel_all.click(dlg.on_sel_all); + cb_stack.exec(); + }; + + dlg.show = function () { + // dlg.init_fields(); + $app.table_sel_acc.load_data(); + dlg.dom.dialog.modal(); + }; + + dlg.on_sel_all = function () { + var _objects = $('#' + $app.table_sel_acc.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); + }); + } + }; + + dlg.check_all_selected = function (cb_stack) { + var _all_checked = true; + var _objs = $('#' + dlg.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) { + dlg.dom.btn_sel_all.prop('checked', true); + } else { + dlg.dom.btn_sel_all.prop('checked', false); + } + if (cb_stack) + cb_stack.exec(); + }; + + dlg.get_selected_items = function () { + var items = []; + var _objs = $('#' + dlg.dom_id + ' tbody tr td input[data-check-box]'); + $.each(_objs, function (i, _obj) { + if ($(_obj).is(':checked')) { + var _row_data = $app.table_sel_acc.get_row(_obj); + + var name = _row_data.username + '@' + _row_data.host_ip; + if (_row_data.router_ip.length > 0) + name += ' (由 ' + _row_data.router_ip + ':' + _row_data.router_port + ' 路由)'; + + + items.push({id: _row_data.id, name: name}); + } + }); + + return items; + }; + + dlg.on_add = function () { + var items = dlg.get_selected_items(); + + $tp.ajax_post_json('/audit/policy/add-members', { + policy_id: $app.options.policy_id, + type: TP_POLICY_ASSET, // 被授权资产 + rtype: TP_ACCOUNT, // 账号 + members: items + }, + function (ret) { + if (ret.code === TPE_OK) { + $tp.notify_success('被授权资产添加成功!'); + CALLBACK_STACK.create() + .add($app.sync_height) + .add(dlg.check_all_selected) + .add($app.table_asset.load_data) + .add($app.table_sel_acc.load_data) + .exec(); + } else { + $tp.notify_error('被授权资产添加失败:' + tp_error_msg(ret.code, ret.message)); + } + }, + function () { + $tp.notify_error('网络故障,被授权资产添加失败!'); + } + ); + + }; + + return dlg; +}; + +//------------------------------- +// 选择账号组对话框 +//------------------------------- + +$app.on_table_sel_acc_group_cell_created = function (tbl, row_id, col_key, cell_obj) { + if (col_key === 'chkbox') { + cell_obj.find('[data-check-box]').click(function () { + // $app.check_users_all_selected(); + $app.dlg_sel_acc_group.check_all_selected(); + }); + } +}; + +$app.on_table_sel_acc_group_render_created = function (render) { + + $app._add_common_render(render); + + render.name = function (row_id, fields) { + return '' + fields.name + '' + fields.desc + ''; + }; +}; + +$app.on_table_sel_acc_group_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(); +}; + +$app.create_dlg_sel_acc_group = function () { + var dlg = {}; + dlg.dom_id = 'dlg-sel-acc-group'; + dlg.field_id = -1; // 用户id + dlg.field_name = ''; + dlg.field_desc = ''; + + dlg.dom = { + dialog: $('#' + dlg.dom_id), + btn_sel_all: $('#' + dlg.dom_id + ' input[data-action="sel-all"]'), + btn_add: $('#' + dlg.dom_id + ' button[data-action="use-selected"]') + }; + + dlg.init = function (cb_stack) { + dlg.dom.btn_add.click(dlg.on_add); + dlg.dom.btn_sel_all.click(dlg.on_sel_all); + cb_stack.exec(); + }; + + dlg.show = function () { + // dlg.init_fields(); + $app.table_sel_acc_group.load_data(); + dlg.dom.dialog.modal(); + }; + + dlg.on_sel_all = function () { + var _objects = $('#' + $app.table_sel_acc_group.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); + }); + } + }; + + dlg.check_all_selected = function (cb_stack) { + var _all_checked = true; + var _objs = $('#' + dlg.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) { + dlg.dom.btn_sel_all.prop('checked', true); + } else { + dlg.dom.btn_sel_all.prop('checked', false); + } + if (cb_stack) + cb_stack.exec(); + }; + + dlg.get_selected_items = function () { + var items = []; + var _objs = $('#' + dlg.dom_id + ' tbody tr td input[data-check-box]'); + $.each(_objs, function (i, _obj) { + if ($(_obj).is(':checked')) { + var _row_data = $app.table_sel_acc_group.get_row(_obj); + items.push({id: _row_data.id, name: _row_data.name}); + } + }); + + return items; + }; + + dlg.on_add = function () { + var items = dlg.get_selected_items(); + + $tp.ajax_post_json('/audit/policy/add-members', { + policy_id: $app.options.policy_id, + type: TP_POLICY_ASSET, // 授权操作者 + rtype: TP_GROUP_ACCOUNT, // 账号组 + members: items + }, + function (ret) { + if (ret.code === TPE_OK) { + $tp.notify_success('被授权资产添加成功!'); + CALLBACK_STACK.create() + .add($app.sync_height) + .add(dlg.check_all_selected) + .add($app.table_asset.load_data) + .add($app.table_sel_acc_group.load_data) + .exec(); + } else { + $tp.notify_error('被授权资产添加失败:' + tp_error_msg(ret.code, ret.message)); + } + }, + function () { + $tp.notify_error('网络故障,被授权资产添加失败!'); + } + ); + + }; + + return dlg; +}; + +//------------------------------- +// 选择主机对话框 +//------------------------------- + +$app.on_table_sel_host_cell_created = function (tbl, row_id, col_key, cell_obj) { + if (col_key === 'chkbox') { + cell_obj.find('[data-check-box]').click(function () { + $app.dlg_sel_host.check_all_selected(); + }); + } +}; + +$app.on_table_sel_host_render_created = function (render) { + + $app._add_common_render(render); + + render.host_info = function (row_id, fields) { + var ret = []; + + var name = fields.name; + if (name.length === 0) + name = fields.ip; + var ip = fields.ip; + ret.push('' + name + '
[' + ip + ']'); + if (fields.router_ip.length > 0) + ret.push(' 由 ' + fields.router_ip + ':' + fields.router_port + ' 路由'); + ret.push('
'); + + return ret.join(''); + }; + +}; + +$app.on_table_sel_host_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(); +}; + +$app.create_dlg_sel_host = function () { + var dlg = {}; + dlg.dom_id = 'dlg-sel-host'; + dlg.field_id = -1; + dlg.field_name = ''; + dlg.field_desc = ''; + + dlg.dom = { + dialog: $('#' + dlg.dom_id), + btn_sel_all: $('#' + dlg.dom_id + ' input[data-action="sel-all"]'), + btn_add: $('#' + dlg.dom_id + ' button[data-action="use-selected"]') + }; + + dlg.init = function (cb_stack) { + dlg.dom.btn_add.click(dlg.on_add); + dlg.dom.btn_sel_all.click(dlg.on_sel_all); + cb_stack.exec(); + }; + + dlg.show = function () { + $app.table_sel_host.load_data(); + dlg.dom.dialog.modal(); + }; + + dlg.on_sel_all = function () { + var _objects = $('#' + $app.table_sel_host.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); + }); + } + }; + + dlg.check_all_selected = function (cb_stack) { + var _all_checked = true; + var _objs = $('#' + dlg.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) { + dlg.dom.btn_sel_all.prop('checked', true); + } else { + dlg.dom.btn_sel_all.prop('checked', false); + } + if (cb_stack) + cb_stack.exec(); + }; + + dlg.get_selected_items = function () { + var items = []; + var _objs = $('#' + dlg.dom_id + ' tbody tr td input[data-check-box]'); + $.each(_objs, function (i, _obj) { + if ($(_obj).is(':checked')) { + var _row_data = $app.table_sel_host.get_row(_obj); + + var name = ''; + if (_row_data.name.length > 0) + name = _row_data.name + ' [' + _row_data.ip + ']'; + else + name = _row_data.ip; + + if (_row_data.router_ip.length > 0) + name += ' (由 ' + _row_data.router_ip + ':' + _row_data.router_port + ' 路由)'; + + + items.push({id: _row_data.id, name: name}); + } + }); + + return items; + }; + + dlg.on_add = function () { + var items = dlg.get_selected_items(); + + $tp.ajax_post_json('/audit/policy/add-members', { + policy_id: $app.options.policy_id, + type: TP_POLICY_ASSET, // 被授权资产 + rtype: TP_HOST, // 主机 + members: items + }, + function (ret) { + if (ret.code === TPE_OK) { + $tp.notify_success('被授权资产添加成功!'); + CALLBACK_STACK.create() + .add($app.sync_height) + .add(dlg.check_all_selected) + .add($app.table_asset.load_data) + .add($app.table_sel_host.load_data) + .exec(); + } else { + $tp.notify_error('被授权资产添加失败:' + tp_error_msg(ret.code, ret.message)); + } + }, + function () { + $tp.notify_error('网络故障,被授权资产添加失败!'); + } + ); + + }; + + return dlg; +}; + +//------------------------------- +// 选择主机组对话框 +//------------------------------- + +$app.on_table_sel_host_group_cell_created = function (tbl, row_id, col_key, cell_obj) { + if (col_key === 'chkbox') { + cell_obj.find('[data-check-box]').click(function () { + // $app.check_users_all_selected(); + $app.dlg_sel_host_group.check_all_selected(); + }); + } +}; + +$app.on_table_sel_host_group_render_created = function (render) { + + $app._add_common_render(render); + + render.name = function (row_id, fields) { + return '' + fields.name + '' + fields.desc + ''; + }; +}; + +$app.on_table_sel_host_group_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(); +}; + +$app.create_dlg_sel_host_group = function () { + var dlg = {}; + dlg.dom_id = 'dlg-sel-host-group'; + dlg.field_id = -1; + dlg.field_name = ''; + dlg.field_desc = ''; + + dlg.dom = { + dialog: $('#' + dlg.dom_id), + btn_sel_all: $('#' + dlg.dom_id + ' input[data-action="sel-all"]'), + btn_add: $('#' + dlg.dom_id + ' button[data-action="use-selected"]') + }; + + dlg.init = function (cb_stack) { + dlg.dom.btn_add.click(dlg.on_add); + dlg.dom.btn_sel_all.click(dlg.on_sel_all); + cb_stack.exec(); + }; + + dlg.show = function () { + $app.table_sel_host_group.load_data(); + dlg.dom.dialog.modal(); + }; + + dlg.on_sel_all = function () { + var _objects = $('#' + $app.table_sel_host_group.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); + }); + } + }; + + dlg.check_all_selected = function (cb_stack) { + var _all_checked = true; + var _objs = $('#' + dlg.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) { + dlg.dom.btn_sel_all.prop('checked', true); + } else { + dlg.dom.btn_sel_all.prop('checked', false); + } + + if (cb_stack) + cb_stack.exec(); + }; + + dlg.get_selected_items = function () { + var items = []; + var _objs = $('#' + dlg.dom_id + ' tbody tr td input[data-check-box]'); + $.each(_objs, function (i, _obj) { + if ($(_obj).is(':checked')) { + var _row_data = $app.table_sel_host_group.get_row(_obj); + items.push({id: _row_data.id, name: _row_data.name}); + } + }); + + return items; + }; + + dlg.on_add = function () { + var items = dlg.get_selected_items(); + + $tp.ajax_post_json('/audit/policy/add-members', { + policy_id: $app.options.policy_id, + type: TP_POLICY_ASSET, // 授权操作者 + rtype: TP_GROUP_HOST, // 主机组 + members: items + }, + function (ret) { + if (ret.code === TPE_OK) { + $tp.notify_success('被授权资产添加成功!'); + CALLBACK_STACK.create() + .add($app.sync_height) + .add(dlg.check_all_selected) + .add($app.table_asset.load_data) + .add($app.table_sel_host_group.load_data) + .exec(); + } else { + $tp.notify_error('被授权资产添加失败:' + tp_error_msg(ret.code, ret.message)); + } + }, + function () { + $tp.notify_error('网络故障,被授权资产添加失败!'); + } + ); + + }; + + return dlg; +}; diff --git a/server/www/teleport/static/js/audit/auz-list.js b/server/www/teleport/static/js/audit/auz-list.js new file mode 100644 index 0000000..3962c29 --- /dev/null +++ b/server/www/teleport/static/js/audit/auz-list.js @@ -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: '', + 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($('')); + + $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($('')); + $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 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 = ['
']; + // _ret.push('
'); + // _ret.push('
' + title + '
'); + // + // // 表格内嵌过滤器的DOM实体在这时生成 + // var filter_ctrl = header._table_ctrl.get_filter_ctrl('search'); + // _ret.push(filter_ctrl.render()); + // + // _ret.push('
'); + // + // return _ret.join(''); + // }; + // + // render.filter_state = function (header, title, col) { + // var _ret = ['
']; + // _ret.push('
'); + // _ret.push('
' + title + '
'); + // + // // 表格内嵌过滤器的DOM实体在这时生成 + // var filter_ctrl = header._table_ctrl.get_filter_ctrl('state'); + // _ret.push(filter_ctrl.render()); + // + // _ret.push('
'); + // + // return _ret.join(''); + // }; + + render.rank = function (row_id, fields) { + return ' ' + fields.rank + '' + }; + + render.make_check_box = function (row_id, fields) { + return ''; + }; + + render.policy_info = function (row_id, fields) { + return '' + fields.name + '' + fields.desc + '' + }; + + 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 = ' 未知'; + } + + return '' + _state + '' + }; + + render.make_action_btn = function (row_id, fields) { + var ret = []; + ret.push('
'); + ret.push(' 编辑'); + // ret.push(' 禁用'); + // ret.push(' 删除'); + ret.push('
'); + 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: '

注意:删除操作不可恢复!!

如果您希望临时禁止指定的授权策略,可将其“禁用”!

您确定要移除选定的' + items.length + '个授权策略吗?

', + 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; +}; diff --git a/server/www/teleport/view/audit/auz-info.mako b/server/www/teleport/view/audit/auz-info.mako new file mode 100644 index 0000000..6026518 --- /dev/null +++ b/server/www/teleport/view/audit/auz-info.mako @@ -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"> + + + +<%block name="breadcrumb"> + + + +<%block name="embed_js"> + + + + +<%block name="embed_css"> + + + +## Begin Main Body. + +
+ +
+ + +
+
+
+
审计操作者(执行审计操作的用户)
+ +
+
+
+
+ 刷新列表 +
+
+
+
+ 添加用户 + 添加用户组 +
+
+
+ + + +
+
+
+
+ +
+
+
+
    +
    +
    + +
    +
    +
    + +
    +
    +
    +
    +
    +
    + +
    +
    +
    被审计者(被审计的用户或主机)
    + +
    +
    +
    +
    + 刷新列表 +
    +
    +
    +
    + 添加用户 + 添加用户组 + 添加主机 + 添加主机组 +
    +
    +
    + + + +
    +
    +
    +
    + +
    +
    +
    +
      +
      +
      + +
      +
      +
      + +
      +
      +
      +
      +
      +
      +
      +
      + +
      +

      说明:

      +
        +
      • 授权对象表格表示左侧“审计操作者”可以访问右侧“被审计者”相关的运维操作记录。
      • +
      • 按“组”进行授权,则后续加入对应组的用户或主机均自动获得本策略的授权。
      • +
      +
      + +
      + + +<%block name="extend_content"> + + + + + + + + + diff --git a/server/www/teleport/view/audit/auz-list.mako b/server/www/teleport/view/audit/auz-list.mako new file mode 100644 index 0000000..0e7e2b8 --- /dev/null +++ b/server/www/teleport/view/audit/auz-list.mako @@ -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"> + + + +<%block name="embed_css"> + + + +## Begin Main Body. + +
      + + +
      + + + + +
      +
      + +
      +
      + 授权策略列表 + + +
      +
      + +
      +
      + + + +
      +
      +
      +
      + ## + + + + +
      +
      +
      +
        +
        +
        + +
        +
        +
        + +
        +
        +
        +
        + + +
        + +
        + + +
        +

        说明:

        +
          +
        • 编辑了授权策略或调整策略顺序之后,请点击“重建授权映射”来使之生效!正式版本将会改进为自动进行重建。
        • +
        • 上下拖动“顺序”栏中的 可以调节策略的检查顺序。
        • +
        • 可以在“快速查找”中快速定位用户或主机的授权关系。
        • +
        +
        +
        + + +<%block name="extend_content"> + + + diff --git a/server/www/teleport/view/ops/auz-info.mako b/server/www/teleport/view/ops/auz-info.mako index 025c412..7765763 100644 --- a/server/www/teleport/view/ops/auz-info.mako +++ b/server/www/teleport/view/ops/auz-info.mako @@ -295,7 +295,7 @@
      1. 授权对象表格表示左侧“授权操作者”可以访问右侧“被授权资产”。
      2. 修改授权对象和连接控制选项不会影响当前已经建立的连接。
      3. 如被授权资产为主机/主机组,则允许用户以对应主机相关的任意账号进行连接。
      4. -
      5. 按“组”进行授权,则后续加入对应组的用户、账号或主机均自动获得本授权策略的授权。
      6. +
      7. 按“组”进行授权,则后续加入对应组的用户、账号或主机均自动获得本策略的授权。
      8. diff --git a/server/www/teleport/webroot/app/base/database/create.py b/server/www/teleport/webroot/app/base/database/create.py index c519684..c3ddc33 100644 --- a/server/www/teleport/webroot/app/base/database/create.py +++ b/server/www/teleport/webroot/app/base/database/create.py @@ -561,30 +561,10 @@ class DatabaseInit: f.append('`name` varchar(128) DEFAULT ""') # desc: 策略描述 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=禁用 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=系统默认创建 f.append('`creator_id` int(11) DEFAULT 0') # create_time: 授权时间 @@ -605,7 +585,7 @@ class DatabaseInit: # policy_id: 所属的策略 f.append('`policy_id` int(11) DEFAULT 0') - # type 指明本条记录是授权还是被授权,0=授权(用户/用户组),1=被授权(资产:主机/主机组) + # type 指明本条记录是授权还是被授权,0=授权(用户/用户组),1=被授权(资产:用户/用户组/主机/主机组) f.append('`type` int(11) DEFAULT 0') # rtype : 外链类型 diff --git a/server/www/teleport/webroot/app/controller/__init__.py b/server/www/teleport/webroot/app/controller/__init__.py index 31d84b7..f6d04e5 100644 --- a/server/www/teleport/webroot/app/controller/__init__.py +++ b/server/www/teleport/webroot/app/controller/__init__.py @@ -172,6 +172,16 @@ controllers = [ (r'/audit/record', audit.RecordHandler), # - [json] 审计页面(录像列表) (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录像回放页面 (r'/audit/replay/(.*)/(.*)', audit.ReplayHandler), diff --git a/server/www/teleport/webroot/app/controller/audit.py b/server/www/teleport/webroot/app/controller/audit.py index e072598..b6dcff1 100644 --- a/server/www/teleport/webroot/app/controller/audit.py +++ b/server/www/teleport/webroot/app/controller/audit.py @@ -1,18 +1,15 @@ # -*- coding: utf-8 -*- -# import ctypes import json import os -# import platform import shutil from app.const import * from app.base.configs import tp_cfg from app.base.logger import * +from app.model import audit from app.model import record -# from app.model import user from app.base.controller import TPBaseHandler, TPBaseJsonHandler -# import tornado.web import tornado.gen @@ -31,7 +28,195 @@ class AuzListHandler(TPBaseHandler): ret = self.check_privilege(TP_PRIVILEGE_AUDIT_AUZ) if ret != TPE_OK: 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): diff --git a/server/www/teleport/webroot/app/model/audit.py b/server/www/teleport/webroot/app/model/audit.py new file mode 100644 index 0000000..8050b95 --- /dev/null +++ b/server/www/teleport/webroot/app/model/audit.py @@ -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