mirror of https://github.com/tp4a/teleport
..LDAP配置功能完成,开始实现LDAP用户导入功能。
parent
46cd77420d
commit
4c14a58877
|
@ -1,2 +1,2 @@
|
||||||
<?xml version="1.0" encoding="UTF-8"?>
|
<?xml version="1.0" encoding="UTF-8"?>
|
||||||
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
<module classpath="CMake" type="CPP_MODULE" version="4" />
|
|
@ -470,9 +470,11 @@ $app.on_btn_do_upload_click = function () {
|
||||||
dataType: 'text',
|
dataType: 'text',
|
||||||
data: param,
|
data: param,
|
||||||
success: function (data) {
|
success: function (data) {
|
||||||
|
console.log(data);
|
||||||
$('#file-selector').remove();
|
$('#file-selector').remove();
|
||||||
|
|
||||||
var ret = JSON.parse(data);
|
var ret = JSON.parse(data);
|
||||||
|
console.log(ret);
|
||||||
|
|
||||||
if (ret.code === TPE_OK) {
|
if (ret.code === TPE_OK) {
|
||||||
$app.dom.upload_file_message
|
$app.dom.upload_file_message
|
||||||
|
|
|
@ -36,7 +36,7 @@ $app.on_init = function (cb_stack) {
|
||||||
};
|
};
|
||||||
|
|
||||||
$app.test = function (cb) {
|
$app.test = function (cb) {
|
||||||
cb.add($app.dlg_ldap_config.show);
|
cb.add($app.dlg_ldap_import.show);
|
||||||
cb.exec();
|
cb.exec();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -186,7 +186,15 @@ $app.create_controls = function (cb_stack) {
|
||||||
|
|
||||||
$app.dlg_ldap_config = $app.create_dlg_ldap_config();
|
$app.dlg_ldap_config = $app.create_dlg_ldap_config();
|
||||||
cb_stack.add($app.dlg_ldap_config.init);
|
cb_stack.add($app.dlg_ldap_config.init);
|
||||||
|
|
||||||
|
$app.dlg_ldap_import = $app.create_dlg_ldap_import();
|
||||||
|
cb_stack.add($app.dlg_ldap_import.init);
|
||||||
$app.dom.btn_ldap_import.click(function () {
|
$app.dom.btn_ldap_import.click(function () {
|
||||||
|
if(0 === $app.options.sys_cfg.ldap.server.length) {
|
||||||
|
$tp.notify_error('LDAP服务尚未设置,请先设置!');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
$app.dlg_ldap_import.show();
|
||||||
});
|
});
|
||||||
$app.dom.btn_ldap_config.click(function () {
|
$app.dom.btn_ldap_config.click(function () {
|
||||||
$app.dlg_ldap_config.show();
|
$app.dlg_ldap_config.show();
|
||||||
|
@ -1371,7 +1379,7 @@ $app.create_dlg_ldap_config = function () {
|
||||||
if (!dlg.check_fields())
|
if (!dlg.check_fields())
|
||||||
return;
|
return;
|
||||||
dlg.dom.btn_list_attr.attr('disabled', 'disabled');
|
dlg.dom.btn_list_attr.attr('disabled', 'disabled');
|
||||||
$tp.ajax_post_json('/user/do-ldap-config-list-attr', {
|
$tp.ajax_post_json('/system/do-ldap-config-list-attr', {
|
||||||
ldap: dlg.ldap_config
|
ldap: dlg.ldap_config
|
||||||
},
|
},
|
||||||
function (ret) {
|
function (ret) {
|
||||||
|
@ -1396,7 +1404,7 @@ $app.create_dlg_ldap_config = function () {
|
||||||
if (!dlg.check_fields())
|
if (!dlg.check_fields())
|
||||||
return;
|
return;
|
||||||
dlg.dom.btn_test.attr('disabled', 'disabled');
|
dlg.dom.btn_test.attr('disabled', 'disabled');
|
||||||
$tp.ajax_post_json('/user/do-ldap-config-test', {
|
$tp.ajax_post_json('/system/do-ldap-config-test', {
|
||||||
ldap: dlg.ldap_config
|
ldap: dlg.ldap_config
|
||||||
},
|
},
|
||||||
function (ret) {
|
function (ret) {
|
||||||
|
@ -1486,7 +1494,6 @@ $app.create_dlg_ldap_test_result = function () {
|
||||||
|
|
||||||
dlg.dom = {
|
dlg.dom = {
|
||||||
dialog: $('#' + dlg.dom_id),
|
dialog: $('#' + dlg.dom_id),
|
||||||
msg: $('#ldap-test-result-msg'),
|
|
||||||
table: $('#table-ldap-test-ret')
|
table: $('#table-ldap-test-ret')
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1497,33 +1504,6 @@ $app.create_dlg_ldap_test_result = function () {
|
||||||
dlg.show = function (data) {
|
dlg.show = function (data) {
|
||||||
dlg.dom.table.empty();
|
dlg.dom.table.empty();
|
||||||
|
|
||||||
// var h = [];
|
|
||||||
// var i, x;
|
|
||||||
// var th_created = false;
|
|
||||||
// for (i = 0; i < data.length; ++i) {
|
|
||||||
// if (!th_created) {
|
|
||||||
// h.push('<thead>');
|
|
||||||
// for (x in data[i]) {
|
|
||||||
// h.push('<th style="text-align:left;" class="mono">');
|
|
||||||
// h.push(x);
|
|
||||||
// h.push('</th>');
|
|
||||||
// }
|
|
||||||
// h.push('</thead>');
|
|
||||||
// th_created = true;
|
|
||||||
// }
|
|
||||||
//
|
|
||||||
// h.push('<tr>');
|
|
||||||
// for (x in data[i]) {
|
|
||||||
// h.push('<td style="text-align:left;" class="mono">');
|
|
||||||
// if (!_.isEmpty(data[i][x]))
|
|
||||||
// h.push(data[i][x]);
|
|
||||||
// else
|
|
||||||
// h.push('');
|
|
||||||
// h.push('</td>');
|
|
||||||
// }
|
|
||||||
// h.push('</tr>');
|
|
||||||
// }
|
|
||||||
|
|
||||||
var h = [];
|
var h = [];
|
||||||
var dn, x;
|
var dn, x;
|
||||||
var th_created = false;
|
var th_created = false;
|
||||||
|
@ -1551,10 +1531,117 @@ $app.create_dlg_ldap_test_result = function () {
|
||||||
h.push('</tr>');
|
h.push('</tr>');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
dlg.dom.table.append($(h.join('')));
|
dlg.dom.table.append($(h.join('')));
|
||||||
dlg.dom.dialog.modal();
|
dlg.dom.dialog.modal();
|
||||||
};
|
};
|
||||||
|
|
||||||
return dlg;
|
return dlg;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
$app.create_dlg_ldap_import = function () {
|
||||||
|
var dlg = {};
|
||||||
|
dlg.dom_id = 'dlg-ldap-import';
|
||||||
|
|
||||||
|
dlg.dom = {
|
||||||
|
dialog: $('#' + dlg.dom_id),
|
||||||
|
table: $('#table-ldap-import'),
|
||||||
|
|
||||||
|
btn_refresh: $('#btn-ldap-import-refresh'),
|
||||||
|
btn_import: $('#btn-ldap-import-import')
|
||||||
|
};
|
||||||
|
|
||||||
|
dlg.init = function (cb_stack) {
|
||||||
|
dlg.dom.btn_refresh.click(dlg.do_refresh);
|
||||||
|
dlg.dom.btn_import.click(dlg.do_import);
|
||||||
|
cb_stack.exec();
|
||||||
|
};
|
||||||
|
|
||||||
|
dlg.show = function () {
|
||||||
|
dlg.dom.dialog.modal({backdrop: 'static'});
|
||||||
|
dlg.do_refresh();
|
||||||
|
};
|
||||||
|
|
||||||
|
dlg.do_refresh = function () {
|
||||||
|
dlg.dom.btn_refresh.attr('disabled', 'disabled');
|
||||||
|
$tp.ajax_post_json('/system/do-ldap-get-users', {
|
||||||
|
},
|
||||||
|
function (ret) {
|
||||||
|
dlg.dom.btn_refresh.removeAttr('disabled');
|
||||||
|
if (ret.code === TPE_OK) {
|
||||||
|
// $tp.notify_success('列举LDAP用户成功!');
|
||||||
|
console.log(ret.data);
|
||||||
|
//$app.dlg_ldap_test_result.show(ret.data);
|
||||||
|
dlg._show_users(ret.data);
|
||||||
|
} else {
|
||||||
|
$tp.notify_error('获取LDAP用户列表失败:' + tp_error_msg(ret.code, ret.message));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
dlg.dom.btn_refresh.removeAttr('disabled');
|
||||||
|
$tp.notify_error('网络故障,获取LDAP用户列表失败!');
|
||||||
|
},
|
||||||
|
15000
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
dlg._show_users = function(data) {
|
||||||
|
dlg.dom.table.empty();
|
||||||
|
|
||||||
|
var attr_names = ['username', 'surname', 'email'];
|
||||||
|
|
||||||
|
var h = [];
|
||||||
|
var dn, x;
|
||||||
|
var th_created = false;
|
||||||
|
for (dn in data) {
|
||||||
|
if (!th_created) {
|
||||||
|
h.push('<thead>');
|
||||||
|
for (x in attr_names) {
|
||||||
|
h.push('<th style="text-align:left;" class="mono">');
|
||||||
|
h.push(attr_names[x]);
|
||||||
|
h.push('</th>');
|
||||||
|
}
|
||||||
|
h.push('</thead>');
|
||||||
|
th_created = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
h.push('<tr>');
|
||||||
|
for (x in attr_names) {
|
||||||
|
h.push('<td style="text-align:left;" class="mono">');
|
||||||
|
if (!_.isEmpty(data[dn][attr_names[x]]))
|
||||||
|
h.push(data[dn][attr_names[x]]);
|
||||||
|
else
|
||||||
|
h.push('');
|
||||||
|
h.push('</td>');
|
||||||
|
}
|
||||||
|
h.push('</tr>');
|
||||||
|
}
|
||||||
|
|
||||||
|
dlg.dom.table.append($(h.join('')));
|
||||||
|
dlg.dom.dialog.modal();
|
||||||
|
};
|
||||||
|
|
||||||
|
dlg.do_import = function () {
|
||||||
|
if (!dlg.check_fields())
|
||||||
|
return;
|
||||||
|
dlg.dom.btn_save.attr('disabled', 'disabled');
|
||||||
|
$tp.ajax_post_json('/system/do-ldap-import', {
|
||||||
|
},
|
||||||
|
function (ret) {
|
||||||
|
dlg.dom.btn_save.removeAttr('disabled');
|
||||||
|
if (ret.code === TPE_OK) {
|
||||||
|
$app.options.sys_cfg.ldap = dlg.ldap_config;
|
||||||
|
$tp.notify_success('保存LDAP设置成功!');
|
||||||
|
} else {
|
||||||
|
$tp.notify_error('保存LDAP设置失败:' + tp_error_msg(ret.code, ret.message));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
function () {
|
||||||
|
dlg.dom.btn_save.removeAttr('disabled');
|
||||||
|
$tp.notify_error('网络故障,保存LDAP设置失败!');
|
||||||
|
},
|
||||||
|
15000
|
||||||
|
);
|
||||||
|
};
|
||||||
|
|
||||||
|
return dlg;
|
||||||
|
};
|
||||||
|
|
|
@ -50,7 +50,7 @@
|
||||||
<button id="btn-create-user" class="btn btn-sm btn-primary"><i class="fa fa-plus-circle fa-fw"></i> 创建用户</button>
|
<button id="btn-create-user" class="btn btn-sm btn-primary"><i class="fa fa-plus-circle fa-fw"></i> 创建用户</button>
|
||||||
<button id="btn-import-user" class="btn btn-sm btn-default"><i class="fa fa-plus-square fa-fw"></i> 导入用户</button>
|
<button id="btn-import-user" class="btn btn-sm btn-default"><i class="fa fa-plus-square fa-fw"></i> 导入用户</button>
|
||||||
<div class="btn-group btn-group-sm dropdown" id="filter-host-group">
|
<div class="btn-group btn-group-sm dropdown" id="filter-host-group">
|
||||||
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown"><i class="fas fa-address-book fa-fw"></i> LDAP管理 <i class="fa fa-caret-right"></i></button>
|
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown"><i class="fas fa-address-book fa-fw"></i> LDAP管理(试验) <i class="fa fa-caret-right"></i></button>
|
||||||
<ul class="dropdown-menu dropdown-menu-right dropdown-menu-sm">
|
<ul class="dropdown-menu dropdown-menu-right dropdown-menu-sm">
|
||||||
<li>
|
<li>
|
||||||
<li><a href="javascript:;" data-action="ldap-import"><i class="fas fa-arrow-alt-circle-left fa-fw"></i> 导入LDAP用户</a></li>
|
<li><a href="javascript:;" data-action="ldap-import"><i class="fas fa-arrow-alt-circle-left fa-fw"></i> 导入LDAP用户</a></li>
|
||||||
|
@ -382,7 +382,7 @@
|
||||||
<div class="modal-content">
|
<div class="modal-content">
|
||||||
<div class="modal-header">
|
<div class="modal-header">
|
||||||
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fa fa-times-circle fa-fw"></i></button>
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fa fa-times-circle fa-fw"></i></button>
|
||||||
<h3 class="modal-title">LDAP设置</h3>
|
<h3 class="modal-title">LDAP设置 (实验性)</h3>
|
||||||
</div>
|
</div>
|
||||||
<div class="modal-body">
|
<div class="modal-body">
|
||||||
|
|
||||||
|
@ -540,8 +540,6 @@
|
||||||
|
|
||||||
<div class="col-sm-12">
|
<div class="col-sm-12">
|
||||||
<table id="table-ldap-test-ret" class="table table-striped table-bordered table-hover table-data no-footer dtr-inline"></table>
|
<table id="table-ldap-test-ret" class="table table-striped table-bordered table-hover table-data no-footer dtr-inline"></table>
|
||||||
|
|
||||||
<div id="ldap-test-result-msg"></div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -559,4 +557,42 @@
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
<div class="modal fade" id="dlg-ldap-import" tabindex="-1" role="dialog">
|
||||||
|
<div class="modal-dialog modal-lg" style="margin-top:50px;">
|
||||||
|
<div class="modal-content">
|
||||||
|
<div class="modal-header">
|
||||||
|
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><i class="fa fa-times-circle fa-fw"></i></button>
|
||||||
|
<h3 class="modal-title">导入LDAP用户(试验)</h3>
|
||||||
|
</div>
|
||||||
|
<div class="modal-body">
|
||||||
|
|
||||||
|
<div class="form-horizontal">
|
||||||
|
<div style="margin-bottom:8px;">
|
||||||
|
LDAP用户列表:
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="form-group form-group-sm">
|
||||||
|
|
||||||
|
<div class="col-sm-12">
|
||||||
|
<table id="table-ldap-import" class="table table-striped table-bordered table-hover table-data no-footer dtr-inline"></table>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="modal-footer">
|
||||||
|
<div class="row">
|
||||||
|
<div class="col-sm-12" style="text-align:right;">
|
||||||
|
<button type="button" class="btn btn-sm btn-success" id="btn-ldap-import-refresh"><i class="fa fa-redo fa-fw"></i> 刷新列表</button>
|
||||||
|
<button type="button" class="btn btn-sm btn-primary" id="btn-ldap-import-import"><i class="fa fa-check fa-fw"></i> 导入选中用户</button>
|
||||||
|
<button type="button" class="btn btn-sm btn-default" data-dismiss="modal"><i class="fa fa-times fa-fw"></i> 取消</button>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
</%block>
|
</%block>
|
||||||
|
|
|
@ -80,12 +80,6 @@ controllers = [
|
||||||
(r'/user/do-bind-oath', user.DoBindOathHandler),
|
(r'/user/do-bind-oath', user.DoBindOathHandler),
|
||||||
# - [json] 取消绑定身份认证器
|
# - [json] 取消绑定身份认证器
|
||||||
(r'/user/do-unbind-oath', user.DoUnBindOathHandler),
|
(r'/user/do-unbind-oath', user.DoUnBindOathHandler),
|
||||||
# - [json] 列出LDAP服务器的用户的属性,便于管理员做属性映射
|
|
||||||
(r'/user/do-ldap-config-list-attr', user.DoLdapListUserAttrHandler),
|
|
||||||
# - [json] 测试LDAP的配置
|
|
||||||
(r'/user/do-ldap-config-test', user.DoLdapConfigTestHandler),
|
|
||||||
# # - [json] 保存LDAP服务器配置项
|
|
||||||
# (r'/user/do-ldap-config-save', user.DoLdapConfigSaveHandler),
|
|
||||||
#
|
#
|
||||||
# - 用户组管理页面
|
# - 用户组管理页面
|
||||||
(r'/user/group', user.GroupListHandler),
|
(r'/user/group', user.GroupListHandler),
|
||||||
|
@ -258,6 +252,12 @@ controllers = [
|
||||||
(r'/system/send-test-mail', system.DoSendTestMailHandler),
|
(r'/system/send-test-mail', system.DoSendTestMailHandler),
|
||||||
# - [json] 系统配置-清理存储空间
|
# - [json] 系统配置-清理存储空间
|
||||||
(r'/system/cleanup-storage', system.DoCleanupStorageHandler),
|
(r'/system/cleanup-storage', system.DoCleanupStorageHandler),
|
||||||
|
# - [json] 列出LDAP服务器的用户的属性,便于管理员做属性映射
|
||||||
|
(r'/system/do-ldap-config-list-attr', system.DoLdapListUserAttrHandler),
|
||||||
|
# - [json] 测试LDAP的配置
|
||||||
|
(r'/system/do-ldap-config-test', system.DoLdapConfigTestHandler),
|
||||||
|
# - [json] 获取LDAP用户列表
|
||||||
|
(r'/system/do-ldap-get-users', system.DoLdapGetUsersHandler),
|
||||||
#
|
#
|
||||||
# - [json] 获取服务器时间
|
# - [json] 获取服务器时间
|
||||||
(r'/system/get-time', system.DoGetTimeHandler),
|
(r'/system/get-time', system.DoGetTimeHandler),
|
||||||
|
|
|
@ -100,7 +100,8 @@ class DoGetHostsHandler(TPBaseJsonHandler):
|
||||||
except:
|
except:
|
||||||
return self.write_json(TPE_PARAM)
|
return self.write_json(TPE_PARAM)
|
||||||
|
|
||||||
err, total_count, page_index, row_data = host.get_hosts(sql_filter, sql_order, sql_limit, sql_restrict, sql_exclude)
|
err, total_count, page_index, row_data = \
|
||||||
|
host.get_hosts(sql_filter, sql_order, sql_limit, sql_restrict, sql_exclude)
|
||||||
ret = dict()
|
ret = dict()
|
||||||
ret['page_index'] = page_index
|
ret['page_index'] = page_index
|
||||||
ret['total'] = total_count
|
ret['total'] = total_count
|
||||||
|
@ -160,7 +161,8 @@ class DoImportHandler(TPBaseHandler):
|
||||||
def post(self):
|
def post(self):
|
||||||
"""
|
"""
|
||||||
csv导入规则:
|
csv导入规则:
|
||||||
每一行的数据格式: 主机IP,操作系统类型,名称,路由IP,路由端口,资产编号,账号,协议类型,协议端口,认证类型,密码或私钥,账号提示,密码提示,分组,描述
|
每一行的数据格式:
|
||||||
|
主机IP,操作系统类型,名称,路由IP,路由端口,资产编号,账号,协议类型,协议端口,认证类型,密码或私钥,账号提示,密码提示,分组,描述
|
||||||
在导入时:
|
在导入时:
|
||||||
0. 以“#”作为行注释。
|
0. 以“#”作为行注释。
|
||||||
1. 首先必须是主机数据,随后可以跟多个账号数据(直到遇到下一个主机数据行之前,账号会与上一个主机关联)。
|
1. 首先必须是主机数据,随后可以跟多个账号数据(直到遇到下一个主机数据行之前,账号会与上一个主机关联)。
|
||||||
|
@ -171,7 +173,9 @@ class DoImportHandler(TPBaseHandler):
|
||||||
ret['code'] = TPE_OK
|
ret['code'] = TPE_OK
|
||||||
ret['message'] = ''
|
ret['message'] = ''
|
||||||
|
|
||||||
rv = self.check_privilege(TP_PRIVILEGE_ASSET_CREATE | TP_PRIVILEGE_ASSET_GROUP | TP_PRIVILEGE_USER_CREATE | TP_PRIVILEGE_USER_GROUP, need_process=False)
|
rv = self.check_privilege(
|
||||||
|
TP_PRIVILEGE_ASSET_CREATE | TP_PRIVILEGE_ASSET_GROUP | TP_PRIVILEGE_USER_CREATE | TP_PRIVILEGE_USER_GROUP,
|
||||||
|
need_process=False)
|
||||||
if rv != TPE_OK:
|
if rv != TPE_OK:
|
||||||
ret['code'] = rv
|
ret['code'] = rv
|
||||||
if rv == TPE_NEED_LOGIN:
|
if rv == TPE_NEED_LOGIN:
|
||||||
|
@ -194,7 +198,8 @@ class DoImportHandler(TPBaseHandler):
|
||||||
file_metas = self.request.files['csvfile'] # 提取表单中‘name’为‘file’的文件元数据
|
file_metas = self.request.files['csvfile'] # 提取表单中‘name’为‘file’的文件元数据
|
||||||
for meta in file_metas:
|
for meta in file_metas:
|
||||||
now = time.localtime(time.time())
|
now = time.localtime(time.time())
|
||||||
tmp_name = 'upload-{:04d}{:02d}{:02d}{:02d}{:02d}{:02d}.csv'.format(now.tm_year, now.tm_mon, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec)
|
tmp_name = 'upload-{:04d}{:02d}{:02d}{:02d}{:02d}{:02d}.csv'.format(
|
||||||
|
now.tm_year, now.tm_mon, now.tm_mday, now.tm_hour, now.tm_min, now.tm_sec)
|
||||||
csv_filename = os.path.join(upload_path, tmp_name)
|
csv_filename = os.path.join(upload_path, tmp_name)
|
||||||
with open(csv_filename, 'wb') as f:
|
with open(csv_filename, 'wb') as f:
|
||||||
f.write(meta['body'])
|
f.write(meta['body'])
|
||||||
|
@ -287,7 +292,10 @@ class DoImportHandler(TPBaseHandler):
|
||||||
_router_ip = csv_recorder[self.IDX_ROUTER_IP].strip()
|
_router_ip = csv_recorder[self.IDX_ROUTER_IP].strip()
|
||||||
_router_port = csv_recorder[self.IDX_ROUTER_PORT].strip()
|
_router_port = csv_recorder[self.IDX_ROUTER_PORT].strip()
|
||||||
|
|
||||||
if not ((len(_router_ip) == 0 and len(_router_port) == 0) or (len(_router_ip) > 0 and len(_router_port) > 0)):
|
if not (
|
||||||
|
(len(_router_ip) == 0 and len(_router_port) == 0)
|
||||||
|
or (len(_router_ip) > 0 and len(_router_port) > 0)
|
||||||
|
):
|
||||||
failed.append({'line': line, 'error': '格式错误,错误的路由IP及端口的组合。'})
|
failed.append({'line': line, 'error': '格式错误,错误的路由IP及端口的组合。'})
|
||||||
continue
|
continue
|
||||||
if len(_router_ip) > 0:
|
if len(_router_ip) > 0:
|
||||||
|
@ -498,10 +506,16 @@ class DoImportHandler(TPBaseHandler):
|
||||||
|
|
||||||
err, acc_id = account.add_account(self, host_id, args)
|
err, acc_id = account.add_account(self, host_id, args)
|
||||||
if err == TPE_EXISTS:
|
if err == TPE_EXISTS:
|
||||||
failed.append({'line': hosts[ip]['acc']['_line'], 'error': '增加账号{}@{}失败,账号已经存在。'.format(args['username'], ip)})
|
failed.append({
|
||||||
|
'line': hosts[ip]['acc']['_line'],
|
||||||
|
'error': '增加账号{}@{}失败,账号已经存在。'.format(args['username'], ip)
|
||||||
|
})
|
||||||
continue
|
continue
|
||||||
elif err != TPE_OK:
|
elif err != TPE_OK:
|
||||||
failed.append({'line': hosts[ip]['acc']['_line'], 'error': '增加账号{}@{}失败,数据库操作失败。'.format(args['username'], ip)})
|
failed.append({
|
||||||
|
'line': hosts[ip]['acc']['_line'],
|
||||||
|
'error': '增加账号{}@{}失败,数据库操作失败。'.format(args['username'], ip)
|
||||||
|
})
|
||||||
|
|
||||||
hosts[ip]['acc'][i]['acc_id'] = acc_id
|
hosts[ip]['acc'][i]['acc_id'] = acc_id
|
||||||
|
|
||||||
|
|
|
@ -19,6 +19,7 @@ from app.model import ops
|
||||||
from app.model import audit
|
from app.model import audit
|
||||||
from app.base.core_server import core_service_async_post_http
|
from app.base.core_server import core_service_async_post_http
|
||||||
from app.base.session import tp_session
|
from app.base.session import tp_session
|
||||||
|
from app.logic.auth.ldap import Ldap
|
||||||
|
|
||||||
|
|
||||||
class DoGetTimeHandler(TPBaseJsonHandler):
|
class DoGetTimeHandler(TPBaseJsonHandler):
|
||||||
|
@ -338,7 +339,7 @@ class DoSaveCfgHandler(TPBaseJsonHandler):
|
||||||
if 'ldap' in args:
|
if 'ldap' in args:
|
||||||
processed = True
|
processed = True
|
||||||
_cfg = args['ldap']
|
_cfg = args['ldap']
|
||||||
_password = _cfg['password']
|
# _password = _cfg['password']
|
||||||
_server = _cfg['server']
|
_server = _cfg['server']
|
||||||
_port = _cfg['port']
|
_port = _cfg['port']
|
||||||
_domain = _cfg['domain']
|
_domain = _cfg['domain']
|
||||||
|
@ -347,6 +348,12 @@ class DoSaveCfgHandler(TPBaseJsonHandler):
|
||||||
_filter = _cfg['filter']
|
_filter = _cfg['filter']
|
||||||
_attr_map = _cfg['attr_map']
|
_attr_map = _cfg['attr_map']
|
||||||
|
|
||||||
|
if len(_cfg['password']) == 0:
|
||||||
|
_cfg['password'] = tp_cfg().sys_ldap_password
|
||||||
|
|
||||||
|
if len(_cfg['password']) == 0:
|
||||||
|
return self.write_json(TPE_PARAM, '请设置LDAP管理员密码')
|
||||||
|
|
||||||
# TODO: encrypt the password before save by core-service.
|
# TODO: encrypt the password before save by core-service.
|
||||||
# TODO: if not send password, use pre-saved password.
|
# TODO: if not send password, use pre-saved password.
|
||||||
|
|
||||||
|
@ -360,7 +367,7 @@ class DoSaveCfgHandler(TPBaseJsonHandler):
|
||||||
tp_cfg().sys.ldap.filter = _filter
|
tp_cfg().sys.ldap.filter = _filter
|
||||||
tp_cfg().sys.ldap.attr_map = _attr_map
|
tp_cfg().sys.ldap.attr_map = _attr_map
|
||||||
# 特殊处理,防止前端拿到密码
|
# 特殊处理,防止前端拿到密码
|
||||||
tp_cfg().sys_ldap_password = _password
|
tp_cfg().sys_ldap_password = _cfg['password']
|
||||||
else:
|
else:
|
||||||
return self.write_json(err)
|
return self.write_json(err)
|
||||||
|
|
||||||
|
@ -413,6 +420,129 @@ class DoSendTestMailHandler(TPBaseJsonHandler):
|
||||||
self.write_json(code, message=msg)
|
self.write_json(code, message=msg)
|
||||||
|
|
||||||
|
|
||||||
|
class DoLdapListUserAttrHandler(TPBaseJsonHandler):
|
||||||
|
def post(self):
|
||||||
|
ret = self.check_privilege(TP_PRIVILEGE_USER_CREATE)
|
||||||
|
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:
|
||||||
|
cfg = args['ldap']
|
||||||
|
cfg['port'] = int(cfg['port'])
|
||||||
|
if len(cfg['password']) == 0:
|
||||||
|
if len(tp_cfg().sys_ldap_password) == 0:
|
||||||
|
return self.write_json(TPE_PARAM, message='需要设置LDAP管理员密码')
|
||||||
|
else:
|
||||||
|
cfg['password'] = tp_cfg().sys_ldap_password
|
||||||
|
except:
|
||||||
|
return self.write_json(TPE_PARAM)
|
||||||
|
|
||||||
|
try:
|
||||||
|
ldap = Ldap(cfg['server'], cfg['port'], cfg['base_dn'])
|
||||||
|
ret, data, err_msg = ldap.get_all_attr(cfg['admin'], cfg['password'], cfg['filter'])
|
||||||
|
if ret != TPE_OK:
|
||||||
|
return self.write_json(ret, message=err_msg)
|
||||||
|
else:
|
||||||
|
return self.write_json(ret, data=data)
|
||||||
|
except:
|
||||||
|
log.e('')
|
||||||
|
return self.write_json(TPE_PARAM)
|
||||||
|
|
||||||
|
|
||||||
|
class DoLdapConfigTestHandler(TPBaseJsonHandler):
|
||||||
|
@tornado.gen.coroutine
|
||||||
|
def post(self):
|
||||||
|
ret = self.check_privilege(TP_PRIVILEGE_USER_CREATE)
|
||||||
|
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:
|
||||||
|
cfg = args['ldap']
|
||||||
|
cfg['port'] = int(cfg['port'])
|
||||||
|
if len(cfg['password']) == 0:
|
||||||
|
if len(tp_cfg().sys_ldap_password) == 0:
|
||||||
|
return self.write_json(TPE_PARAM, message='需要设置LDAP管理员密码')
|
||||||
|
else:
|
||||||
|
cfg['password'] = tp_cfg().sys_ldap_password
|
||||||
|
except:
|
||||||
|
return self.write_json(TPE_PARAM)
|
||||||
|
|
||||||
|
try:
|
||||||
|
ldap = Ldap(cfg['server'], cfg['port'], cfg['base_dn'])
|
||||||
|
ret, data, err_msg = ldap.list_users(
|
||||||
|
cfg['admin'], cfg['password'], cfg['filter'], cfg['attr_map'], size_limit=10
|
||||||
|
)
|
||||||
|
|
||||||
|
if ret != TPE_OK:
|
||||||
|
return self.write_json(ret, message=err_msg)
|
||||||
|
else:
|
||||||
|
return self.write_json(ret, data=data)
|
||||||
|
except:
|
||||||
|
log.e('')
|
||||||
|
return self.write_json(TPE_PARAM)
|
||||||
|
|
||||||
|
|
||||||
|
class DoLdapGetUsersHandler(TPBaseJsonHandler):
|
||||||
|
@tornado.gen.coroutine
|
||||||
|
def post(self):
|
||||||
|
ret = self.check_privilege(TP_PRIVILEGE_USER_CREATE)
|
||||||
|
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:
|
||||||
|
if len(tp_cfg().sys_ldap_password) == 0:
|
||||||
|
return self.write_json(TPE_PARAM, message='需要设置LDAP管理员密码')
|
||||||
|
else:
|
||||||
|
_password = tp_cfg().sys_ldap_password
|
||||||
|
_server = tp_cfg().sys.ldap.server
|
||||||
|
_port = tp_cfg().sys.ldap.port
|
||||||
|
_admin = tp_cfg().sys.ldap.admin
|
||||||
|
_base_dn = tp_cfg().sys.ldap.base_dn
|
||||||
|
_filter = tp_cfg().sys.ldap.filter
|
||||||
|
_attr_map = tp_cfg().sys.ldap.attr_map
|
||||||
|
except:
|
||||||
|
return self.write_json(TPE_PARAM)
|
||||||
|
|
||||||
|
try:
|
||||||
|
ldap = Ldap(_server, _port, _base_dn)
|
||||||
|
ret, data, err_msg = ldap.list_users(_admin, _password, _filter, _attr_map)
|
||||||
|
|
||||||
|
if ret != TPE_OK:
|
||||||
|
return self.write_json(ret, message=err_msg)
|
||||||
|
else:
|
||||||
|
# TODO: search all user in database to check if the LDAP user have already bind.
|
||||||
|
for u in data:
|
||||||
|
data[u]['bind'] = False
|
||||||
|
return self.write_json(ret, data=data)
|
||||||
|
except:
|
||||||
|
log.e('')
|
||||||
|
return self.write_json(TPE_PARAM)
|
||||||
|
|
||||||
|
|
||||||
class DoCleanupStorageHandler(TPBaseJsonHandler):
|
class DoCleanupStorageHandler(TPBaseJsonHandler):
|
||||||
@tornado.gen.coroutine
|
@tornado.gen.coroutine
|
||||||
def post(self):
|
def post(self):
|
||||||
|
|
|
@ -905,69 +905,3 @@ class DoGetRoleListHandler(TPBaseJsonHandler):
|
||||||
self.write_json(err)
|
self.write_json(err)
|
||||||
else:
|
else:
|
||||||
self.write_json(TPE_OK, data=role_list)
|
self.write_json(TPE_OK, data=role_list)
|
||||||
|
|
||||||
|
|
||||||
class DoLdapListUserAttrHandler(TPBaseJsonHandler):
|
|
||||||
def post(self):
|
|
||||||
ret = self.check_privilege(TP_PRIVILEGE_USER_CREATE)
|
|
||||||
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:
|
|
||||||
cfg = args['ldap']
|
|
||||||
cfg['port'] = int(cfg['port'])
|
|
||||||
except:
|
|
||||||
return self.write_json(TPE_PARAM)
|
|
||||||
|
|
||||||
try:
|
|
||||||
ldap = Ldap(cfg['server'], cfg['port'], cfg['base_dn'])
|
|
||||||
ret, data, err_msg = ldap.get_all_attr(cfg['admin'], cfg['password'], cfg['filter'])
|
|
||||||
if ret != TPE_OK:
|
|
||||||
return self.write_json(ret, message=err_msg)
|
|
||||||
else:
|
|
||||||
return self.write_json(ret, data=data)
|
|
||||||
except:
|
|
||||||
log.e('')
|
|
||||||
return self.write_json(TPE_PARAM)
|
|
||||||
|
|
||||||
|
|
||||||
class DoLdapConfigTestHandler(TPBaseJsonHandler):
|
|
||||||
def post(self):
|
|
||||||
ret = self.check_privilege(TP_PRIVILEGE_USER_CREATE)
|
|
||||||
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:
|
|
||||||
cfg = args['ldap']
|
|
||||||
cfg['port'] = int(cfg['port'])
|
|
||||||
except:
|
|
||||||
return self.write_json(TPE_PARAM)
|
|
||||||
|
|
||||||
try:
|
|
||||||
# ldap = Ldap(cfg['host'], cfg['port'], cfg['base_dn'], cfg['domain'])
|
|
||||||
ldap = Ldap(cfg['server'], cfg['port'], cfg['base_dn'])
|
|
||||||
ret, data, err_msg = ldap.list_users(cfg['admin'], cfg['password'], cfg['filter'], cfg['attr_map'], size_limit=10)
|
|
||||||
if ret != TPE_OK:
|
|
||||||
return self.write_json(ret, message=err_msg)
|
|
||||||
else:
|
|
||||||
return self.write_json(ret, data=data)
|
|
||||||
except:
|
|
||||||
log.e('')
|
|
||||||
return self.write_json(TPE_PARAM)
|
|
||||||
|
|
||||||
|
|
|
@ -11,8 +11,6 @@ class Ldap(object):
|
||||||
def __init__(self, ldap_host, ldap_port, base_dn):
|
def __init__(self, ldap_host, ldap_port, base_dn):
|
||||||
self._server = ldap3.Server(ldap_host, ldap_port, connect_timeout=5, use_ssl=False)
|
self._server = ldap3.Server(ldap_host, ldap_port, connect_timeout=5, use_ssl=False)
|
||||||
self._base_dn = base_dn
|
self._base_dn = base_dn
|
||||||
# self._domain = domain
|
|
||||||
pass
|
|
||||||
|
|
||||||
def _parse_attr_map(self, attr_map):
|
def _parse_attr_map(self, attr_map):
|
||||||
attrs_ldap = []
|
attrs_ldap = []
|
||||||
|
@ -36,9 +34,10 @@ class Ldap(object):
|
||||||
return attrs_ldap, attrs_tp, ''
|
return attrs_ldap, attrs_tp, ''
|
||||||
|
|
||||||
def get_all_attr(self, admin, password, filter):
|
def get_all_attr(self, admin, password, filter):
|
||||||
# user = '{}@{}'.format(admin, self._domain)
|
conn = ldap3.Connection(
|
||||||
user = admin
|
self._server, user=admin, password=password, check_names=True, lazy=False, raise_exceptions=False
|
||||||
conn = ldap3.Connection(self._server, user=user, password=password, check_names=True, lazy=False, raise_exceptions=False)
|
)
|
||||||
|
|
||||||
try:
|
try:
|
||||||
conn.open()
|
conn.open()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -46,7 +45,11 @@ class Ldap(object):
|
||||||
return TPE_FAILED, None, '无法连接到LDAP服务器'
|
return TPE_FAILED, None, '无法连接到LDAP服务器'
|
||||||
|
|
||||||
conn.bind()
|
conn.bind()
|
||||||
if not ('result' in conn.result and 0 == conn.result['result'] and 'description' in conn.result and 'success' == conn.result['description']):
|
if not (
|
||||||
|
('result' in conn.result and 0 == conn.result['result'])
|
||||||
|
and
|
||||||
|
('description' in conn.result and 'success' == conn.result['description'])
|
||||||
|
):
|
||||||
return TPE_FAILED, None, 'LDAP管理员认证失败'
|
return TPE_FAILED, None, 'LDAP管理员认证失败'
|
||||||
|
|
||||||
ret = conn.search(
|
ret = conn.search(
|
||||||
|
@ -62,27 +65,15 @@ class Ldap(object):
|
||||||
if len(conn.response) == 0:
|
if len(conn.response) == 0:
|
||||||
return TPE_FAILED, None, '未能找到任何用户'
|
return TPE_FAILED, None, '未能找到任何用户'
|
||||||
|
|
||||||
# print(conn.entries[0].entry_to_json())
|
|
||||||
result = json.loads(conn.entries[0].entry_to_json())
|
result = json.loads(conn.entries[0].entry_to_json())
|
||||||
|
for attr_name in result:
|
||||||
# attrs = conn.response[0]['attributes']
|
attr_val = result[attr_name]
|
||||||
#
|
if isinstance(result[attr_name], list):
|
||||||
# result = {}
|
if len(attr_val) >= 1:
|
||||||
# for a in attrs:
|
attr_val = attr_val[0]
|
||||||
# if isinstance(attrs[a], list):
|
else:
|
||||||
# val = []
|
attr_val = ''
|
||||||
# for i in attrs[a]:
|
result[attr_name] = attr_val
|
||||||
# if isinstance(i, bytes):
|
|
||||||
# val.append(i.decode())
|
|
||||||
# else:
|
|
||||||
# val.append(i)
|
|
||||||
# result[a] = ', '.join(val)
|
|
||||||
# else:
|
|
||||||
# if isinstance(attrs[a], bytes):
|
|
||||||
# result[a] = attrs[a].decode()
|
|
||||||
# else:
|
|
||||||
# result[a] = attrs[a].__str__()
|
|
||||||
|
|
||||||
return TPE_OK, result, ''
|
return TPE_OK, result, ''
|
||||||
|
|
||||||
def list_users(self, admin, password, filter, attr_map, size_limit=0):
|
def list_users(self, admin, password, filter, attr_map, size_limit=0):
|
||||||
|
@ -90,9 +81,10 @@ class Ldap(object):
|
||||||
if attrs_ldap is None:
|
if attrs_ldap is None:
|
||||||
return TPE_PARAM, None, '属性映射格式错误: {}'.format(msg)
|
return TPE_PARAM, None, '属性映射格式错误: {}'.format(msg)
|
||||||
|
|
||||||
# user = '{}@{}'.format(admin, self._domain)
|
|
||||||
user = admin
|
user = admin
|
||||||
conn = ldap3.Connection(self._server, user=user, password=password, check_names=True, lazy=False, raise_exceptions=False)
|
conn = ldap3.Connection(
|
||||||
|
self._server, user=user, password=password, check_names=True, lazy=False, raise_exceptions=False
|
||||||
|
)
|
||||||
try:
|
try:
|
||||||
conn.open()
|
conn.open()
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
|
@ -100,7 +92,11 @@ class Ldap(object):
|
||||||
return TPE_FAILED, None, '无法连接到LDAP服务器'
|
return TPE_FAILED, None, '无法连接到LDAP服务器'
|
||||||
|
|
||||||
conn.bind()
|
conn.bind()
|
||||||
if not ('result' in conn.result and 0 == conn.result['result'] and 'description' in conn.result and 'success' == conn.result['description']):
|
if not (
|
||||||
|
('result' in conn.result and 0 == conn.result['result'])
|
||||||
|
and
|
||||||
|
('description' in conn.result and 'success' == conn.result['description'])
|
||||||
|
):
|
||||||
return TPE_FAILED, None, 'LDAP管理员认证失败'
|
return TPE_FAILED, None, 'LDAP管理员认证失败'
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -109,7 +105,6 @@ class Ldap(object):
|
||||||
size_limit=size_limit,
|
size_limit=size_limit,
|
||||||
search_filter=filter, # (&(objectClass=person))
|
search_filter=filter, # (&(objectClass=person))
|
||||||
search_scope=ldap3.SUBTREE,
|
search_scope=ldap3.SUBTREE,
|
||||||
|
|
||||||
attributes=attrs_ldap
|
attributes=attrs_ldap
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -123,27 +118,19 @@ class Ldap(object):
|
||||||
result = {}
|
result = {}
|
||||||
|
|
||||||
for i in range(0, len(conn.entries)):
|
for i in range(0, len(conn.entries)):
|
||||||
u = json.loads(conn.entries[0].entry_to_json())
|
attrs = json.loads(conn.entries[i].entry_to_json())
|
||||||
# result.append(u)
|
user = {}
|
||||||
a = {}
|
|
||||||
for m in range(0, len(attrs_ldap)):
|
for m in range(0, len(attrs_ldap)):
|
||||||
a[attrs_tp[m]] = u['attributes'][attrs_ldap[m]]
|
ldap_name = attrs_ldap[m]
|
||||||
# result.append(a)
|
tp_name = attrs_tp[m]
|
||||||
result[u['dn']] = a
|
attr_val = attrs['attributes'][ldap_name]
|
||||||
|
if isinstance(attr_val, list):
|
||||||
# print(conn.entries[0].entry_to_json())
|
if len(attr_val) >= 1:
|
||||||
#
|
attr_val = attr_val[0]
|
||||||
# if ret:
|
else:
|
||||||
# for u in conn.response:
|
attr_val = ''
|
||||||
# # if u['attributes']['cn'].lower() in ['guest', 'krbtgt']:
|
user[tp_name] = attr_val
|
||||||
# # continue
|
result[attrs['dn']] = user
|
||||||
# # print(u)
|
|
||||||
# # print(u['attributes']['cn'])
|
|
||||||
# # result.append(u['attributes'])
|
|
||||||
# a = {}
|
|
||||||
# for i in range(0, len(attrs_ldap)):
|
|
||||||
# a[attrs_tp[i]] = u['attributes'][attrs_ldap[i]]
|
|
||||||
# result.append(a)
|
|
||||||
|
|
||||||
return TPE_OK, result, ''
|
return TPE_OK, result, ''
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue