..LDAP配置功能完成,开始实现LDAP用户导入功能。

pull/130/head
Apex Liu 2018-11-05 02:39:02 +08:00
parent 46cd77420d
commit 4c14a58877
9 changed files with 358 additions and 168 deletions

View File

@ -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

View File

@ -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;
};

View File

@ -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>

View File

@ -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),

View File

@ -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'] # 提取表单中namefile的文件元数据 file_metas = self.request.files['csvfile'] # 提取表单中namefile的文件元数据
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

View File

@ -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):

View File

@ -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)

View File

@ -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, ''