改进LDAP配置功能,简化管理员填写属性映射关系。

pull/130/head
Apex Liu 2018-12-20 19:05:21 +08:00
parent 44d693a453
commit 47c1c207ea
5 changed files with 128 additions and 53 deletions

View File

@ -36,7 +36,7 @@ $app.on_init = function (cb_stack) {
};
$app.test = function (cb) {
cb.add($app.dlg_ldap_import.show);
cb.add($app.dlg_ldap_config.show);
cb.exec();
};
@ -1256,7 +1256,9 @@ $app.create_dlg_ldap_config = function () {
password: '',
base_dn: '',
filter: '',
attr_map: ''
attr_username: '',
attr_surname: '',
attr_email: ''
};
// {"server":"192.168.0.101","port":3892,"domain":"apexnas.com","admin":"cn=admin,dc=apexnas,dc=com","password":"Abcd1234","base_dn":"ou=people,dc=apexnas,dc=com","filter":"(&(objectClass=person))","attr_map":"tp.username = uid\ntp.surname = cn111\ntp.email = mail"}
@ -1269,7 +1271,10 @@ $app.create_dlg_ldap_config = function () {
password: $('#edit-ldap-password'),
base_dn: $('#edit-ldap-base-dn'),
filter: $('#edit-ldap-filter'),
attr_map: $('#edit-ldap-attr-map'),
// attr_map: $('#edit-ldap-attr-map'),
attr_username: $('#edit-ldap-attr-username'),
attr_surname: $('#edit-ldap-attr-surname'),
attr_email: $('#edit-ldap-attr-email'),
btn_switch_password: $('#btn-switch-ldap-password'),
btn_switch_password_icon: $('#btn-switch-ldap-password i'),
@ -1284,12 +1289,6 @@ $app.create_dlg_ldap_config = function () {
dlg.dom.btn_test.click(dlg.do_test);
dlg.dom.btn_save.click(dlg.do_save);
// dlg.dom.btn_gen_random_password.click(function () {
// dlg.dom.password.val(tp_gen_password(8));
// dlg.dom.password.attr('type', 'text');
// dlg.dom.btn_switch_password_icon.removeClass('fa-eye').addClass('fa-eye-slash')
// });
dlg.dom.btn_switch_password.click(function () {
if ('password' === dlg.dom.password.attr('type')) {
dlg.dom.password.attr('type', 'text');
@ -1317,7 +1316,10 @@ $app.create_dlg_ldap_config = function () {
dlg.dom.admin.val(dlg.ldap_config.admin);
dlg.dom.base_dn.val(dlg.ldap_config.base_dn);
dlg.dom.filter.val(dlg.ldap_config.filter);
dlg.dom.attr_map.text(dlg.ldap_config.attr_map);
// dlg.dom.attr_map.text(dlg.ldap_config.attr_map);
dlg.dom.attr_username.val(dlg.ldap_config.attr_username);
dlg.dom.attr_surname.val(dlg.ldap_config.attr_surname);
dlg.dom.attr_email.val(dlg.ldap_config.attr_email);
}
};
@ -1334,7 +1336,10 @@ $app.create_dlg_ldap_config = function () {
dlg.ldap_config.admin = dlg.dom.admin.val();
dlg.ldap_config.base_dn = dlg.dom.base_dn.val();
dlg.ldap_config.filter = dlg.dom.filter.val();
dlg.ldap_config.attr_map = dlg.dom.attr_map.val();
// dlg.ldap_config.attr_map = dlg.dom.attr_map.val();
dlg.ldap_config.attr_username = dlg.dom.attr_username.val();
dlg.ldap_config.attr_surname = dlg.dom.attr_surname.val();
dlg.ldap_config.attr_email = dlg.dom.attr_email.val();
if (!tp_is_host(dlg.ldap_config.server)) {
dlg.dom.server.focus();
@ -1382,9 +1387,14 @@ $app.create_dlg_ldap_config = function () {
$tp.notify_error('请填写LDAP的用户过滤器');
return false;
}
if (tp_is_empty_str(dlg.ldap_config.attr_map)) {
dlg.dom.attr_map.focus();
$tp.notify_error('请填写LDAP的用户属性与teleport用户属性的映射关系');
// if (tp_is_empty_str(dlg.ldap_config.attr_map)) {
// dlg.dom.attr_map.focus();
// $tp.notify_error('请填写LDAP的用户属性与teleport用户属性的映射关系');
// return false;
// }
if (tp_is_empty_str(dlg.ldap_config.attr_username)) {
dlg.dom.attr_username.focus();
$tp.notify_error('请填写映射为teleport登录账号的LDAP用户属性');
return false;
}

View File

@ -505,8 +505,7 @@
<label for="edit-ldap-base-dn" class="col-sm-2 control-label require">用户基准DN</label>
<div class="col-sm-9">
<input id="edit-ldap-base-dn" type="text" class="form-control" placeholder=""/>
<div class="control-desc-sm">限制用户DN的范围例如 <span class="important">ou=dev,ou=company,ou=com</span>。用户的完整DN为
<span class="important">cn=用户登录名,用户基准DN</span>。
<div class="control-desc-sm">限制用户DN的范围例如 <span class="important">ou=dev,ou=company,ou=com</span>。
</div>
</div>
</div>
@ -522,14 +521,51 @@
</div>
<div class="form-group form-group-sm">
<label for="edit-ldap-attr-map" class="col-sm-2 control-label require">属性映射:</label>
<label class="col-sm-2 control-label require">属性映射:</label>
<div class="col-sm-9">
<textarea id="edit-ldap-attr-map" class="form-control"
style="resize:vertical;height:8em;" placeholder="">t</textarea>
<div class="control-desc-sm">将LDAP的属性映射到 teleport 的用户属性,例如 <span class="important">LDAP中的用户属性 sAMAccountName 映射为teleport的登录账号</span>。如果不清楚此LDAP服务的用户属性可使用下方的“列举属性”按钮进行查询。
<div class="control-desc-sm">将LDAP的属性映射到 teleport 的用户属性,例如 <span class="important">LDAP中的用户属性 sAMAccountName 映射为teleport的登录账号</span>。如果不清楚此LDAP服务的用户属性可使用下方的“列举属性”按钮进行查询。</div>
</div>
</div>
<div class="form-group form-group-sm">
<label for="edit-ldap-attr-username" class="col-sm-offset-1 col-sm-2 control-label require">登录账号字段:</label>
<div class="col-sm-3">
<input id="edit-ldap-attr-username" type="text" class="form-control" placeholder=""/>
</div>
<div class="col-sm-6">
<div class="control-desc-sm">例如<span class="important">sAMAccountName</span>。
</div>
</div>
</div>
<div class="form-group form-group-sm">
<label for="edit-ldap-attr-surname" class="col-sm-offset-1 col-sm-2 control-label">真实姓名字段:</label>
<div class="col-sm-3">
<input id="edit-ldap-attr-surname" type="text" class="form-control" placeholder=""/>
</div>
<div class="col-sm-6">
<div class="control-desc-sm">例如<span class="important">uid</span>。
</div>
</div>
</div>
<div class="form-group form-group-sm">
<label for="edit-ldap-attr-email" class="col-sm-offset-1 col-sm-2 control-label">邮箱地址字段:</label>
<div class="col-sm-3">
<input id="edit-ldap-attr-email" type="text" class="form-control" placeholder=""/>
</div>
<div class="col-sm-6">
<div class="control-desc-sm">例如<span class="important">mail</span>。
</div>
</div>
</div>
## <div class="form-group form-group-sm">
## <label for="edit-ldap-attr-map" class="col-sm-2 control-label require">属性映射:</label>
## <div class="col-sm-9">
## <textarea id="edit-ldap-attr-map" class="form-control" style="resize:vertical;height:8em;" placeholder=""></textarea>
## <div class="control-desc-sm">将LDAP的属性映射到 teleport 的用户属性,例如 <span class="important">LDAP中的用户属性 sAMAccountName 映射为teleport的登录账号</span>。如果不清楚此LDAP服务的用户属性可使用下方的“列举属性”按钮进行查询。</div>
## </div>
## </div>
</div>
@ -537,11 +573,12 @@
<div class="modal-footer">
<div class="row">
<div class="col-sm-6">
<div id="edit-user-message" class="alert alert-danger"
style="text-align:left;display:none;"></div>
<div class="col-sm-12">
<div id="edit-user-message" class="alert alert-danger" style="text-align:left;display:none;"></div>
</div>
<div class="col-sm-6" style="text-align:right;">
</div>
<div class="row">
<div class="col-sm-12" style="text-align:right;">
<button type="button" class="btn btn-sm btn-success" id="btn-ldap-config-list-attr"><i
class="fa fa-list-alt fa-fw"></i> 列举属性
</button>

View File

@ -594,8 +594,12 @@ class AppConfig(BaseAppConfig):
self.sys.ldap.base_dn = ''
if not self.sys.ldap.is_exists('filter'):
self.sys.ldap.filter = ''
if not self.sys.ldap.is_exists('attr_map'):
self.sys.ldap.attr_map = ''
if not self.sys.ldap.is_exists('attr_username'):
self.sys.ldap.attr_username = ''
if not self.sys.ldap.is_exists('attr_surname'):
self.sys.ldap.attr_surname = ''
if not self.sys.ldap.is_exists('attr_email'):
self.sys.ldap.attr_email = ''
if self.sys.ldap.is_exists('password'):
self.sys_ldap_password = self.sys.ldap.password
self.sys.ldap.password = '********'

View File

@ -361,7 +361,9 @@ class DoSaveCfgHandler(TPBaseJsonHandler):
_admin = _cfg['admin']
_base_dn = _cfg['base_dn']
_filter = _cfg['filter']
_attr_map = _cfg['attr_map']
_attr_username = _cfg['attr_username']
_attr_surname = _cfg['attr_surname']
_attr_email = _cfg['attr_email']
if len(_cfg['password']) == 0:
_cfg['password'] = tp_cfg().sys_ldap_password
@ -370,7 +372,6 @@ class DoSaveCfgHandler(TPBaseJsonHandler):
return self.write_json(TPE_PARAM, '请设置LDAP管理员密码')
# TODO: encrypt the password before save by core-service.
# TODO: if not send password, use pre-saved password.
err = system_model.save_config(self, '更新LDAP设置', 'ldap', _cfg)
if err == TPE_OK:
@ -380,7 +381,9 @@ class DoSaveCfgHandler(TPBaseJsonHandler):
tp_cfg().sys.ldap.admin = _admin
tp_cfg().sys.ldap.base_dn = _base_dn
tp_cfg().sys.ldap.filter = _filter
tp_cfg().sys.ldap.attr_map = _attr_map
tp_cfg().sys.ldap.attr_username = _attr_username
tp_cfg().sys.ldap.attr_surname = _attr_surname
tp_cfg().sys.ldap.attr_email = _attr_email
# 特殊处理,防止前端拿到密码
tp_cfg().sys_ldap_password = _cfg['password']
else:
@ -501,7 +504,9 @@ class DoLdapConfigTestHandler(TPBaseJsonHandler):
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
cfg['admin'], cfg['password'], cfg['filter'],
cfg['attr_username'], cfg['attr_surname'], cfg['attr_email'],
size_limit=10
)
if ret != TPE_OK:
@ -538,13 +543,15 @@ class DoLdapGetUsersHandler(TPBaseJsonHandler):
_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
_attr_username = tp_cfg().sys.ldap.attr_username
_attr_surname = tp_cfg().sys.ldap.attr_surname
_attr_email = tp_cfg().sys.ldap.attr_email
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)
ret, data, err_msg = ldap.list_users(_admin, _password, _filter, _attr_username, _attr_surname, _attr_email)
if ret != TPE_OK:
return self.write_json(ret, message=err_msg)
@ -591,13 +598,15 @@ class DoLdapImportHandler(TPBaseJsonHandler):
_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
_attr_username = tp_cfg().sys.ldap.attr_username
_attr_surname = tp_cfg().sys.ldap.attr_surname
_attr_email = tp_cfg().sys.ldap.attr_email
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)
ret, data, err_msg = ldap.list_users(_admin, _password, _filter, _attr_username, _attr_surname, _attr_email)
if ret != TPE_OK:
return self.write_json(ret, message=err_msg)

View File

@ -13,26 +13,41 @@ class Ldap(object):
self._base_dn = base_dn
@staticmethod
def _parse_attr_map(attr_map):
def _parse_attr_map(attr_username, attr_surname, attr_email):
attrs_ldap = []
attrs_tp = []
lines = attr_map.split('\n')
for line in lines:
x = line.split('=')
if len(x) != 2:
return None, None, line
y = x[0].strip().split('.')
if len(y) != 2 or 'tp' != y[0]:
return None, None, line
tp_attr = y[1]
ldap_attr = x[1].strip()
if len(tp_attr) == 0 or len(ldap_attr) == 0:
return None, None, line
attrs_ldap.append(ldap_attr)
attrs_tp.append(tp_attr)
if len(attr_username) > 0:
attrs_ldap.append(attr_username)
attrs_tp.append('username')
if len(attr_surname) > 0:
attrs_ldap.append(attr_surname)
attrs_tp.append('surname')
if len(attr_email) > 0:
attrs_ldap.append(attr_email)
attrs_tp.append('email')
return attrs_ldap, attrs_tp, ''
if len(attrs_ldap) > 0:
return attrs_ldap, attrs_tp
else:
return None, None
# lines = attr_map.split('\n')
# for line in lines:
# x = line.split('=')
# if len(x) != 2:
# return None, None, line
# y = x[0].strip().split('.')
# if len(y) != 2 or 'tp' != y[0]:
# return None, None, line
# tp_attr = y[1]
# ldap_attr = x[1].strip()
# if len(tp_attr) == 0 or len(ldap_attr) == 0:
# return None, None, line
# attrs_ldap.append(ldap_attr)
# attrs_tp.append(tp_attr)
#
# return attrs_ldap, attrs_tp, ''
def get_all_attr(self, admin, password, search_filter):
conn = ldap3.Connection(
@ -77,10 +92,10 @@ class Ldap(object):
result[attr_name] = attr_val
return TPE_OK, result, ''
def list_users(self, admin, password, search_filter, attr_map, size_limit=0):
attrs_ldap, attrs_tp, msg = self._parse_attr_map(attr_map)
def list_users(self, admin, password, search_filter, attr_username, attr_surname, attr_email, size_limit=0):
attrs_ldap, attrs_tp = self._parse_attr_map(attr_username, attr_surname, attr_email)
if attrs_ldap is None:
return TPE_PARAM, None, '属性映射格式错误: {}'.format(msg)
return TPE_PARAM, None, '属性映射错误'
user = admin
conn = ldap3.Connection(